diff --git a/@rbv b/@rbv index ebcc65495..d8bfac898 160000 --- a/@rbv +++ b/@rbv @@ -1 +1 @@ -Subproject commit ebcc6549551569bebdb6f7afeaef09d8d967366b +Subproject commit d8bfac898caa63ba19f870450e8002467e7c0b77 diff --git a/src/main/java/com/rebuild/core/service/approval/ApprovalProcessor.java b/src/main/java/com/rebuild/core/service/approval/ApprovalProcessor.java index 51b4c3272..eee28e21b 100644 --- a/src/main/java/com/rebuild/core/service/approval/ApprovalProcessor.java +++ b/src/main/java/com/rebuild/core/service/approval/ApprovalProcessor.java @@ -17,9 +17,11 @@ import com.rebuild.core.Application; import com.rebuild.core.configuration.ConfigurationException; import com.rebuild.core.metadata.EntityHelper; import com.rebuild.core.metadata.MetadataHelper; +import com.rebuild.core.metadata.easymeta.EasyMetaFactory; import com.rebuild.core.privileges.PrivilegesGuardContextHolder; import com.rebuild.core.privileges.UserHelper; import com.rebuild.core.service.general.EntityService; +import com.rebuild.core.service.notification.MessageBuilder; import com.rebuild.core.support.SetUser; import com.rebuild.core.support.i18n.Language; import com.rebuild.utils.JSONUtils; @@ -147,7 +149,7 @@ public class ApprovalProcessor extends SetUser { .unique(); if (stepApprover == null || (Integer) stepApprover[1] != ApprovalState.DRAFT.getState()) { throw new ApprovalException(Language.L(stepApprover == null - ? Language.L("当前流程已经被他人审批") : Language.L("你已经审批过当前流程"))); + ? Language.L("当前流程已经被其他人审批") : Language.L("你已经审批过当前流程"))); } Record approvedStep = EntityHelper.forUpdate((ID) stepApprover[0], approver); @@ -211,6 +213,34 @@ public class ApprovalProcessor extends SetUser { this.record, status.getApprovalId(), getCurrentNodeId(status), false); } + /** + * 3.1.催审 + * + * @return + */ + public boolean urge() { + if (this.approval == null) { + Object[] o = Application.getQueryFactory().unique(this.record, EntityHelper.ApprovalId); + this.approval = (ID) o[0]; + } + + int sent = 0; + String entityLabel = EasyMetaFactory.getLabel(MetadataHelper.getEntity(this.record.getEntityCode())); + + JSONArray step = getCurrentStep(null); + for (Object o : step) { + JSONObject s = (JSONObject) o; + if (s.getIntValue("state") != 1) continue; + + ID approver = ID.valueOf(s.getString("approver")); + String urgeMsg = Language.L("有一条 %s 记录正在等待你审批,请尽快审批", entityLabel); + Application.getNotifications().send(MessageBuilder.createApproval(approver, urgeMsg, this.record)); + sent++; + } + + return sent > 0; + } + /** * 3.撤销(管理员) * diff --git a/src/main/java/com/rebuild/core/service/general/RecordDifference.java b/src/main/java/com/rebuild/core/service/general/RecordDifference.java index d221d0120..328a74f3a 100644 --- a/src/main/java/com/rebuild/core/service/general/RecordDifference.java +++ b/src/main/java/com/rebuild/core/service/general/RecordDifference.java @@ -132,8 +132,8 @@ public class RecordDifference { || EntityHelper.CreatedOn.equalsIgnoreCase(fieldName) || EntityHelper.CreatedBy.equalsIgnoreCase(fieldName) || EntityHelper.QuickCode.equalsIgnoreCase((fieldName)) - || (MetadataHelper.isApprovalField(fieldName) && !EntityHelper.ApprovalState.equalsIgnoreCase(fieldName)) - || field.getType() == FieldType.PRIMARY; + || field.getType() == FieldType.PRIMARY + || MetadataHelper.isApprovalField(fieldName); } /** diff --git a/src/main/java/com/rebuild/core/service/general/RevisionHistoryObserver.java b/src/main/java/com/rebuild/core/service/general/RevisionHistoryObserver.java index 2f4109207..8878569f3 100644 --- a/src/main/java/com/rebuild/core/service/general/RevisionHistoryObserver.java +++ b/src/main/java/com/rebuild/core/service/general/RevisionHistoryObserver.java @@ -22,6 +22,7 @@ import com.rebuild.core.service.trigger.RobotTriggerObserver; import com.rebuild.core.service.trigger.TriggerSource; import com.rebuild.utils.JSONUtils; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; /** * 记录变更历史 @@ -59,7 +60,10 @@ public class RevisionHistoryObserver extends OperatingObserver { @Override public void onUpdate(OperatingContext context) { Record revision = newRevision(context, true); - Application.getCommonsService().create(revision); + // v3.1 无变更不记录 + if (StringUtils.length(revision.getString("revisionContent")) > 2 /* [] */) { + Application.getCommonsService().create(revision); + } } @Override diff --git a/src/main/java/com/rebuild/core/service/query/ParseHelper.java b/src/main/java/com/rebuild/core/service/query/ParseHelper.java index e0f54f590..b4daec4dd 100644 --- a/src/main/java/com/rebuild/core/service/query/ParseHelper.java +++ b/src/main/java/com/rebuild/core/service/query/ParseHelper.java @@ -181,32 +181,38 @@ public class ParseHelper { * 字段是否可用于快速查询 * * @param field + * @param fieldPath * @return */ - public static String useQuickField(Field field) { + protected static String useQuickField(Field field, String fieldPath) { DisplayType dt = EasyMetaFactory.getDisplayType(field); // 引用字段要保证其兼容 LIKE 条件的语法要求 if (dt == DisplayType.REFERENCE) { Field nameField = field.getReferenceEntity().getNameField(); if (nameField.getType() == FieldType.REFERENCE) { - log.warn("Quick field cannot be circular reference : " + nameField); + log.warn("Quick field cannot be circular-reference : " + nameField); return null; } - String can = useQuickField(nameField); - return can == null ? null : (QueryCompiler.NAME_FIELD_PREFIX + field.getName()); + String can = useQuickField(nameField, fieldPath); + if (can == null) return null; + else if (can.startsWith("&")) return can; + else return QueryCompiler.NAME_FIELD_PREFIX + can; } else if (dt == DisplayType.PICKLIST || dt == DisplayType.CLASSIFICATION) { - return QueryCompiler.NAME_FIELD_PREFIX + field.getName(); + String can = StringUtils.defaultIfEmpty(fieldPath, field.getName()); + if (can.startsWith("&")) return can; + else return QueryCompiler.NAME_FIELD_PREFIX + can; } else if (dt == DisplayType.TEXT || dt == DisplayType.EMAIL || dt == DisplayType.URL || dt == DisplayType.PHONE - || dt == DisplayType.SERIES) { - return field.getName(); + || dt == DisplayType.SERIES + || dt == DisplayType.LOCATION) { + return StringUtils.defaultIfEmpty(fieldPath, field.getName()); } else { return null; @@ -233,7 +239,7 @@ public class ParseHelper { for (String field : quickFields.split(",")) { Field validField = MetadataHelper.getLastJoinField(entity, field); if (validField != null) { - String can = useQuickField(validField); + String can = useQuickField(validField, field); if (can != null) { usesFields.add(can); } @@ -247,7 +253,7 @@ public class ParseHelper { if (usesFields.isEmpty()) { // 名称字段 Field nameField = entity.getNameField(); - String can = useQuickField(nameField); + String can = useQuickField(nameField, null); if (can != null) { usesFields.add(can); } else { diff --git a/src/main/java/com/rebuild/core/support/general/BarCodeSupport.java b/src/main/java/com/rebuild/core/support/general/BarCodeSupport.java index d16dbb034..2293ea296 100644 --- a/src/main/java/com/rebuild/core/support/general/BarCodeSupport.java +++ b/src/main/java/com/rebuild/core/support/general/BarCodeSupport.java @@ -39,7 +39,6 @@ import java.util.Map; * @since 2020/6/5 */ @Slf4j -@SuppressWarnings({"unused", "UnnecessaryLocalVariable"}) public class BarCodeSupport { // 二维码(默认) @@ -147,7 +146,7 @@ public class BarCodeSupport { } /** - * 保存 + * 保存文件 * * @param content * @param format @@ -159,6 +158,7 @@ public class BarCodeSupport { String fileName = String.format("BarCode-%d.png", System.currentTimeMillis()); File dest = RebuildConfiguration.getFileOfTemp(fileName); + try { MatrixToImageWriter.writeToPath(bitMatrix, "png", dest.toPath()); return dest; diff --git a/src/main/java/com/rebuild/web/OnlineSessionStore.java b/src/main/java/com/rebuild/web/OnlineSessionStore.java index 47007ba39..4bb9c0d2f 100644 --- a/src/main/java/com/rebuild/web/OnlineSessionStore.java +++ b/src/main/java/com/rebuild/web/OnlineSessionStore.java @@ -59,14 +59,12 @@ public class OnlineSessionStore implements HttpSessionListener { if (log.isDebugEnabled()) log.info("Destroyed session : {}", event.getSession().getId()); HttpSession s = event.getSession(); - if (ONLINE_SESSIONS.contains(s)) { - ONLINE_SESSIONS.remove(s); - } else { - for (Map.Entry e : ONLINE_USERS.entrySet()) { - if (s.equals(e.getValue())) { - ONLINE_USERS.remove(e.getKey()); - break; - } + ONLINE_SESSIONS.remove(s); + + for (Map.Entry e : ONLINE_USERS.entrySet()) { + if (s.equals(e.getValue())) { + ONLINE_USERS.remove(e.getKey()); + break; } } } @@ -113,7 +111,7 @@ public class OnlineSessionStore implements HttpSessionListener { if (!RebuildConfiguration.getBool(ConfigurationItem.MultipleSessions)) { HttpSession previous = getSession((ID) loginUser); if (previous != null) { - log.warn("Kill previous session : {} < {}", loginUser, previous.getId()); + log.warn("Kill previous session : {} ({})", previous.getId(), loginUser); try { previous.invalidate(); @@ -122,7 +120,6 @@ public class OnlineSessionStore implements HttpSessionListener { } } - ONLINE_SESSIONS.remove(s); ONLINE_USERS.put((ID) loginUser, s); } } diff --git a/src/main/java/com/rebuild/web/admin/audit/LoginLogController.java b/src/main/java/com/rebuild/web/admin/audit/LoginLogController.java index 542ed9a6a..75ac148ed 100644 --- a/src/main/java/com/rebuild/web/admin/audit/LoginLogController.java +++ b/src/main/java/com/rebuild/web/admin/audit/LoginLogController.java @@ -64,8 +64,8 @@ public class LoginLogController extends EntityController { } JSONObject item = JSONUtils.toJSONObject( - new String[] { "user", "fullName", "activeTime", "activeUrl", "activeIp" }, - new Object[] { user, UserHelper.getName(user), active[0], active[1], active[2] }); + new String[] { "user", "fullName", "activeTime", "activeUrl", "activeIp", "sid" }, + new Object[] { user, UserHelper.getName(user), active[0], active[1], active[2], s.getId() }); users.add(item); } return users; @@ -73,14 +73,16 @@ public class LoginLogController extends EntityController { @RequestMapping("/admin/audit/kill-session") public RespBody killSession(HttpServletRequest request) { - final ID user = getIdParameterNotNull(request, "user"); + String sessionId = getParameterNotNull(request, "user"); - HttpSession s = Application.getSessionStore().getSession(user); - if (s != null) { - log.warn("Admin kill session : {} > {} ", s.getId(), user); - try { - s.invalidate(); - } catch (Exception ignored) { + for (HttpSession s : Application.getSessionStore().getAllSession()) { + if (s.getId().equals(sessionId)) { + log.warn("Admin kill session : {} ({})", sessionId, s.getAttribute(WebUtils.CURRENT_USER)); + try { + s.invalidate(); + } catch (Exception ignored) { + } + break; } } return RespBody.ok(); diff --git a/src/main/java/com/rebuild/web/commons/BarCodeGeneratorController.java b/src/main/java/com/rebuild/web/commons/BarCodeGeneratorController.java index 69d7b298f..6af5ca33a 100644 --- a/src/main/java/com/rebuild/web/commons/BarCodeGeneratorController.java +++ b/src/main/java/com/rebuild/web/commons/BarCodeGeneratorController.java @@ -53,16 +53,18 @@ public class BarCodeGeneratorController extends BaseController { String content = getParameterNotNull(request, "t"); int w = getIntParameter(request, "w", 0); - // 4小时缓存 - ServletUtils.addCacheHead(response, 240); - + BufferedImage bi; if (request.getRequestURI().endsWith("render-qr")) { - writeTo(BarCodeSupport.createQRCode(content, w), response); + bi = BarCodeSupport.createQRCode(content, w); } else { // 条形码文字 boolean showText = getBoolParameter(request, "b", true); - writeTo(BarCodeSupport.createBarCode(content, w, showText), response); + bi = BarCodeSupport.createBarCode(content, w, showText); } + + // 4小时缓存 + ServletUtils.addCacheHead(response, 240); + writeTo(bi, response); } private void writeTo(BufferedImage image, HttpServletResponse response) throws IOException { diff --git a/src/main/java/com/rebuild/web/robot/approval/ApprovalController.java b/src/main/java/com/rebuild/web/robot/approval/ApprovalController.java index ec581b370..97bd4f8b4 100644 --- a/src/main/java/com/rebuild/web/robot/approval/ApprovalController.java +++ b/src/main/java/com/rebuild/web/robot/approval/ApprovalController.java @@ -93,7 +93,7 @@ public class ApprovalController extends BaseController { } } - // 审批中提交人可撤回 + // 审批中提交人可撤回、催审 if (stateVal == ApprovalState.PROCESSING.getState() && user.equals(ApprovalHelper.getSubmitter(recordId, useApproval))) { data.put("canCancel", true); @@ -220,6 +220,12 @@ public class ApprovalController extends BaseController { } } + @RequestMapping("urge") + public RespBody doUrge(@IdParam(name = "record") ID recordId) { + boolean s = new ApprovalProcessor(recordId).urge(); + return s ? RespBody.ok() : RespBody.errorl("无法发送催审通知"); + } + @RequestMapping("revoke") public RespBody doRevoke(@IdParam(name = "record") ID recordId) { try { diff --git a/src/main/resources/i18n/lang.zh_CN.json b/src/main/resources/i18n/lang.zh_CN.json index bc188fcb2..b4dc1b281 100644 --- a/src/main/resources/i18n/lang.zh_CN.json +++ b/src/main/resources/i18n/lang.zh_CN.json @@ -351,7 +351,7 @@ "你可以选择来自 [RB 仓库](https://getrebuild.com/market/go/1220-rb-store) 的业务实体使用,或在安装完成后自行添加":"你可以选择来自 [RB 仓库](https://getrebuild.com/market/go/1220-rb-store) 的业务实体使用,或在安装完成后自行添加", "你可在导入后进行适当调整。开始导入吗?":"你可在导入后进行适当调整。开始导入吗?", "你已完成所有审批":"你已完成所有审批", - "你已审批同意,正在等待他人审批":"你已审批同意,正在等待他人审批", + "你已审批同意,正在等待其他人审批":"你已审批同意,正在等待其他人审批", "你已经审批过当前流程":"你已经审批过当前流程", "你已驳回审批":"你已驳回审批", "你无权查看此任务":"你无权查看此任务", @@ -783,7 +783,7 @@ "当前数据已过滤":"当前数据已过滤", "当前日期":"当前日期", "当前时间":"当前时间", - "当前流程已经被他人审批":"当前流程已经被他人审批", + "当前流程已经被其他人审批":"当前流程已经被其他人审批", "当前用户":"当前用户", "当前用户处于未激活状态,因为其 %s":"当前用户处于未激活状态,因为其 %s", "当前记录不符合转换条件":"当前记录不符合转换条件", diff --git a/src/main/resources/web/admin/audit/login-logs.html b/src/main/resources/web/admin/audit/login-logs.html index 29e69c0fb..61d37ba94 100644 --- a/src/main/resources/web/admin/audit/login-logs.html +++ b/src/main/resources/web/admin/audit/login-logs.html @@ -31,7 +31,7 @@
- +
diff --git a/src/main/resources/web/assets/css/rb-page.css b/src/main/resources/web/assets/css/rb-page.css index 19af0f9fd..6d09f2f97 100644 --- a/src/main/resources/web/assets/css/rb-page.css +++ b/src/main/resources/web/assets/css/rb-page.css @@ -2905,25 +2905,24 @@ form { padding: 10px 10px 10px 0; } -.approval-pane .alert .close.btn { +.approval-pane .alert > .close { + top: 0; + opacity: 1; + padding: 0; +} + +.approval-pane .alert > .close .btn { padding: 8px 0; font-size: 12px; - opacity: 1; - font-weight: normal; line-height: 1.1; - background-color: #fff; min-height: 0; min-width: 78px; margin-top: 8px; - box-shadow: 0 0 0 #fff; + border: 0 none; } -.approval-pane .alert .close.btn + .btn { - margin-right: 88px; -} - -.approval-pane .alert .close.btn + .btn + .btn { - margin-right: 176px; +.approval-pane .alert > .close > .btn + .btn { + margin-left: 10px; } .form.approval-form { @@ -4698,18 +4697,35 @@ pre.unstyle { .quick-filter-pane .col { padding-left: 8px; padding-right: 8px; + max-width: 20%; + flex: 0 0 20%; display: none; } +.quick-filter-pane .col.show, .quick-filter-pane.extended .col { display: block; } -.quick-filter-pane .col:nth-child(1), -.quick-filter-pane .col:nth-child(2), -.quick-filter-pane .col:nth-child(3), -.quick-filter-pane .col:last-child { - display: block; +@media (max-width: 1400px) { + .quick-filter-pane .col { + max-width: 25%; + flex: 0 0 25%; + } +} + +@media (max-width: 1200px) { + .quick-filter-pane .col { + max-width: 33.3333%; + flex: 0 0 33.3333%; + } +} + +@media (max-width: 992px) { + .quick-filter-pane .col { + max-width: 50%; + flex: 0 0 50%; + } } .quick-filter-pane .col > div > label { @@ -4723,13 +4739,15 @@ pre.unstyle { display: none; } -.quick-filter-pane .operating-btn { +.quick-filter-pane .col.operating-btn { min-height: 50px; + display: block; } .quick-filter-pane .operating-btn > div { position: absolute; bottom: 0; + white-space: nowrap; } .quick-filter-pane .operating-btn a { @@ -4740,8 +4758,13 @@ pre.unstyle { line-height: 1; } +.quick-filter-pane .operating-btn .btn { + min-height: 37px; +} + .quick-filter-pane .operating-btn a .icon { font-size: 1.231rem; + display: inline-block; } .quick-filter-pane .operating-btn a:hover { @@ -4749,11 +4772,11 @@ pre.unstyle { } .quick-filter-pane .operating-btn a.admin-show { - display: none; + visibility: hidden; } .quick-filter-pane .operating-btn:hover a.admin-show { - display: inline-block; + visibility: visible; } .quick-filter-pane .operating-btn .dropdown-menu { @@ -4763,6 +4786,14 @@ pre.unstyle { align-items: center; } +.quick-filter-pane .form-control { + max-width: 227px; +} + +.quick-filter-pane .form-control:focus { + border-color: #bababa; +} + /* col-sm-8 */ .quick-filter-pane .col > div .filter-items .col-sm-5.val { -webkit-box-flex: 0; diff --git a/src/main/resources/web/assets/js/admin/login-logs.js b/src/main/resources/web/assets/js/admin/login-logs.js index 04e25ef85..c20bf1094 100644 --- a/src/main/resources/web/assets/js/admin/login-logs.js +++ b/src/main/resources/web/assets/js/admin/login-logs.js @@ -5,10 +5,12 @@ rebuild is dual-licensed under commercial and open source licenses (GPLv3). See LICENSE and COMMERCIAL in the project root for license information. */ -$(document).ready(function () { - renderRbcomp(, 'react-list') +$(document).ready(() => { + renderRbcomp(, 'react-list', function () { + RbListPage._RbList = this._List + }) - $('.J_view-online').on('click', () => renderRbcomp()) + $('.J_view-online').on('click', () => renderRbcomp()) }) // 列表配置 @@ -18,7 +20,7 @@ const ListConfig = { { field: 'user', label: $L('登录用户'), type: 'REFERENCE' }, { field: 'loginTime', label: $L('登录时间'), type: 'DATETIME' }, { field: 'ipAddr', label: $L('IP 地址') }, - { field: 'userAgent', label: $L('客户端') }, + { field: 'userAgent', label: $L('客户端'), width: 250 }, ], sort: 'loginTime:desc', } @@ -27,13 +29,6 @@ class DataList extends React.Component { render() { return (this._List = c)} config={ListConfig} /> } - - componentDidMount() { - const $btn = $('.input-search .btn'), - $input = $('.input-search input') - $btn.click(() => this._List.searchQuick()) - $input.keydown((e) => (e.which === 13 ? $btn.trigger('click') : true)) - } } const _pageIps = [] @@ -65,48 +60,50 @@ RbList.renderAfter = function () { } // ~ 在线用户 -class OnlineUserViewer extends RbModalHandler { - render() { +class OnlineUserViewer extends RbAlert { + renderContent() { return ( - (this._dlg = c)} title={$L('查看在线用户')} disposeOnHide={true}> - - - - - - - - - {(this.state.users || []).map((item) => { - return ( - - - - - - ) - })} - -
{$L('用户')}{$L('最近活跃')} -
- Avatar - {item.fullName} - - {item.activeUrl || 'n/a'} - - - {item.activeIp} - - - -
-
+ + + + + + + + + {(this.state.users || []).map((item) => { + return ( + + + + + + ) + })} + +
{$L('用户')}{$L('最近活跃')} +
+ Avatar + {item.fullName} + + {item.activeUrl || 'n/a'} + + + {item.activeIp} + + + +
) } - componentDidMount = () => this._load() + componentDidMount() { + super.componentDidMount() + this._load() + } + _load() { $.get('/admin/audit/online-users', (res) => { if (res.error_code === 0) this.setState({ users: res.data }) diff --git a/src/main/resources/web/assets/js/admin/recycle-bin.js b/src/main/resources/web/assets/js/admin/recycle-bin.js index 2595e409b..ef58a7215 100644 --- a/src/main/resources/web/assets/js/admin/recycle-bin.js +++ b/src/main/resources/web/assets/js/admin/recycle-bin.js @@ -17,7 +17,9 @@ $(document).ready(() => { _ENTITIES[this.name] = this.label }) - renderRbcomp(, 'react-list') + renderRbcomp(, 'react-list', function () { + RbListPage._RbList = this._List + }) }) }) @@ -52,13 +54,13 @@ class DataList extends React.Component { const $btn = $('.input-search .btn'), $input = $('.input-search input') - $btn.click(() => this.queryList()) - $input.keydown((e) => (e.which === 13 ? $btn.trigger('click') : true)) + $btn.off('click').on('click', () => this.queryList()) + $input.off('keydown').on('keydown', (e) => (e.which === 13 ? $btn.trigger('click') : true)) this._$belongEntity = $s2 this._$recordName = $input - $('.J_restore').click(() => this.restore()) + $('.J_restore').on('click', () => this.restore()) } queryList() { diff --git a/src/main/resources/web/assets/js/admin/revision-history.js b/src/main/resources/web/assets/js/admin/revision-history.js index 930b4e935..83141e8ba 100644 --- a/src/main/resources/web/assets/js/admin/revision-history.js +++ b/src/main/resources/web/assets/js/admin/revision-history.js @@ -20,7 +20,9 @@ $(document).ready(() => { $(``).appendTo('#belongEntity') } - renderRbcomp(, 'react-list') + renderRbcomp(, 'react-list', function () { + RbListPage._RbList = this._List + }) }) }) @@ -47,7 +49,7 @@ const RevTypes = { 32: $L('共享'), 64: $L('取消共享'), 991: $L('审批通过'), - 992: $L('审批撤销') + 992: $L('审批撤销'), } class DataList extends React.Component { @@ -65,17 +67,18 @@ class DataList extends React.Component { }) .val('$ALL$') .trigger('change') + $s2.on('change', () => this.queryList()) const $btn = $('.input-search .btn'), $input = $('.input-search input') - $btn.click(() => this.queryList()) - $input.keydown((e) => (e.which === 13 ? $btn.trigger('click') : true)) + $btn.off('click').on('click', () => this.queryList()) + $input.off('keydown').on('keydown', (e) => (e.which === 13 ? $btn.trigger('click') : true)) this._$belongEntity = $s2 this._$recordName = $input - $('.J_details').click(() => this.showDetails()) + $('.J_details').on('click', () => this.showDetails()) } queryList() { @@ -141,7 +144,7 @@ class DlgDetails extends RbAlert { - + diff --git a/src/main/resources/web/assets/js/metadata/entity-edit.js b/src/main/resources/web/assets/js/metadata/entity-edit.js index 6515d300f..ee4e29e83 100644 --- a/src/main/resources/web/assets/js/metadata/entity-edit.js +++ b/src/main/resources/web/assets/js/metadata/entity-edit.js @@ -85,6 +85,7 @@ $(document).ready(function () { item.type === 'URL' || item.type === 'PHONE' || item.type === 'SERIES' || + item.type === 'LOCATION' || item.type === 'PICKLIST' || item.type === 'CLASSIFICATION' || item.type === 'DATE' || @@ -117,6 +118,7 @@ $(document).ready(function () { item.type === 'URL' || item.type === 'PHONE' || item.type === 'SERIES' || + item.type === 'LOCATION' || item.type === 'PICKLIST' || item.type === 'CLASSIFICATION' || // item.type === 'DATE' || diff --git a/src/main/resources/web/assets/js/rb-advfilter.js b/src/main/resources/web/assets/js/rb-advfilter.js index e7e14dd6f..e36ab7050 100644 --- a/src/main/resources/web/assets/js/rb-advfilter.js +++ b/src/main/resources/web/assets/js/rb-advfilter.js @@ -659,7 +659,9 @@ class FilterItem extends React.Component { renderPickListAfter() { const that = this const $s2val = $(this._filterVal) - .select2({}) + .select2({ + width: this.props.select2Width, + }) .on('change.select2', function () { that.setState({ value: $s2val.val().join('|') }) }) @@ -693,6 +695,7 @@ class FilterItem extends React.Component { const that = this const $s2val = $(this._filterVal) .select2({ + width: this.props.select2Width, minimumInputLength: 1, ajax: { url: '/commons/search/search', @@ -791,6 +794,7 @@ class FilterItem extends React.Component { const that = this const $s2val = $(this._filterVal) .select2({ + width: this.props.select2Width, allowClear: this.props.allowClear === true, placeholder: this.props.allowClear === true ? $L('全部') : null, }) diff --git a/src/main/resources/web/assets/js/rb-approval.js b/src/main/resources/web/assets/js/rb-approval.js index 6e5501843..d91c1c0df 100644 --- a/src/main/resources/web/assets/js/rb-approval.js +++ b/src/main/resources/web/assets/js/rb-approval.js @@ -29,9 +29,12 @@ class ApprovalProcessor extends React.Component { renderStateDraft() { return (
- + + + +
@@ -46,25 +49,33 @@ class ApprovalProcessor extends React.Component { let aMsg = $L('当前记录正在审批中') if (this.state.imApprover) { if (this.state.imApproveSatate === 1) aMsg = $L('当前记录正在等待你审批') - else if (this.state.imApproveSatate === 10) aMsg = $L('你已审批同意,正在等待他人审批') + else if (this.state.imApproveSatate === 10) aMsg = $L('你已审批同意,正在等待其他人审批') else if (this.state.imApproveSatate === 11) aMsg = $L('你已驳回审批') } return (
- - {this.state.canCancel && ( - + )} + {this.state.canCancel && ( + + + + + )} + - )} - {this.state.imApprover && this.state.imApproveSatate === 1 && ( - - )} + +
@@ -78,14 +89,17 @@ class ApprovalProcessor extends React.Component { return (
- - {rb.isAdminUser && ( - + )} + - )} + +
@@ -97,12 +111,15 @@ class ApprovalProcessor extends React.Component { renderStateRejected() { return (
- - + + + + +
@@ -114,12 +131,15 @@ class ApprovalProcessor extends React.Component { renderStateCanceled() { return (
- - + + + + +
@@ -131,12 +151,15 @@ class ApprovalProcessor extends React.Component { renderStateRevoked() { return (
- - + + + + +
@@ -179,7 +202,7 @@ class ApprovalProcessor extends React.Component { cancel = () => { const that = this - RbAlert.create($L('确认撤回当前审批?'), { + RbAlert.create($L('将要撤回已提交审批。是否继续?'), { confirm: function () { this.disabled(true) $.post(`/app/entity/approval/cancel?record=${that.props.id}`, (res) => { @@ -191,9 +214,27 @@ class ApprovalProcessor extends React.Component { }) } + urge = () => { + const that = this + RbAlert.create($L('将向当前审批人发送催审通知。是否继续?'), { + confirm: function () { + this.disabled(true) + $.post(`/app/entity/approval/urge?record=${that.props.id}`, (res) => { + if (res.error_code > 0) { + RbHighbar.error(res.error_msg) + this.disabled() + } else { + RbHighbar.success($L('通知已发送')) + this.hide() + } + }) + }, + }) + } + revoke = () => { const that = this - RbAlert.create($L('将要撤销已通过审批。确认吗?'), { + RbAlert.create($L('将要撤销已通过审批。是否继续?'), { type: 'danger', confirm: function () { this.disabled(true) diff --git a/src/main/resources/web/assets/js/rb-datalist.common.js b/src/main/resources/web/assets/js/rb-datalist.common.js index ed67cae6d..a2ef03525 100644 --- a/src/main/resources/web/assets/js/rb-datalist.common.js +++ b/src/main/resources/web/assets/js/rb-datalist.common.js @@ -699,6 +699,7 @@ const RbListCommon = { } const entity = wpc.entity + if (!entity) return RbListPage.init(wpc.listConfig, entity, wpc.privileges) if (wpc.advFilter !== false) AdvFilters.init('.adv-search', entity[0]) @@ -907,7 +908,7 @@ class RbList extends React.Component { if (wpc.advFilter !== true) this.fetchList(this._buildQuick()) // 按键操作 - if (wpc.type === 'RecordList') $(document).on('keydown', (e) => this._keyEvent(e)) + if (wpc.type === 'RecordList' || wpc.type === 'DetailList') $(document).on('keydown', (e) => this._keyEvent(e)) } fetchList(filter) { @@ -1092,6 +1093,7 @@ class RbList extends React.Component { } _openView($tr) { + if (!wpc.type) return const id = $($tr).data('id') if (!wpc.forceSubView) { location.hash = `!/View/${this._entity}/${id}` diff --git a/src/main/resources/web/assets/js/rb-datalist.js b/src/main/resources/web/assets/js/rb-datalist.js index 8a1d3a029..cc0db5137 100644 --- a/src/main/resources/web/assets/js/rb-datalist.js +++ b/src/main/resources/web/assets/js/rb-datalist.js @@ -93,7 +93,7 @@ const RbListPage = { } // Filter Pane - if ($('.quick-filter-pane').length > 0) { + if ($('.quick-filter-pane')[0]) { // eslint-disable-next-line react/jsx-no-undef renderRbcomp( RbListPage._RbList.search(s)} />, $('.quick-filter-pane')[0]) } diff --git a/src/main/resources/web/assets/js/rb-filterpane.js b/src/main/resources/web/assets/js/rb-filterpane.js deleted file mode 100644 index e97b96382..000000000 --- a/src/main/resources/web/assets/js/rb-filterpane.js +++ /dev/null @@ -1,171 +0,0 @@ -/*! -Copyright (c) REBUILD and/or its owners. All rights reserved. - -rebuild is dual-licensed under commercial and open source licenses (GPLv3). -See LICENSE and COMMERCIAL in the project root for license information. -*/ -// deps: rb-advfilter.js - -const REFENTITY_CACHE = window.REFENTITY_CACHE || {} -const IS_N2NREF = window.IS_N2NREF || {} -const BIZZ_ENTITIES = window.BIZZ_ENTITIES || [] - -// eslint-disable-next-line no-unused-vars -class AdvFilterPane extends React.Component { - constructor(props) { - super(props) - - this.state = {} - this._itemsRef = [] - } - - onRef = (c) => this._itemsRef.push(c) - - componentDidMount() { - const items = (this.props.fields || []).map((item) => { - if (item.type === 'REFERENCE' || item.type === 'N2NREFERENCE') { - REFENTITY_CACHE[`${this.props.entity}.${item.name}`] = item.ref - if (item.type === 'N2NREFERENCE') IS_N2NREF.push(item.name) - - // NOTE: Use `NameField` field-type - if (!BIZZ_ENTITIES.includes(item.ref[0])) { - item.type = item.ref[1] - } - } - return item - }) - - this.setState({ items }, () => { - setTimeout(() => this.clearFilter(), 200) - }) - } - - render() { - if (!this.state.items) return null - - return ( -
this.searchNow(e)}> - {this.state.items.map((item, i) => { - return ( -
-
- -
-
- -
-
-
-
- ) - })} - -
-
-
- - -
- - -
-
- this.clearFilter(true)}> - - - {(this.props.fields || []).length > 4 && ( - this.toggleExtended()}> - - - )} - {rb.isAdminUser && ( - { - RbModal.create( - `/p/admin/metadata/list-filterpane?entity=${this.props.entity}`, - - {$L('配置查询面板字段')} - - - ) - }}> - - - )} -
-
- - ) - } - - searchNow(e) { - $stopEvent(e, true) - - const filters = [] - for (let i = 0; i < this._itemsRef.length; i++) { - const item = this._itemsRef[i].getFilterJson() - if (item) filters.push(item) - } - - const s = { - entity: this.props.entity, - equation: this._$useEquationAnd.checked ? 'AND' : 'OR', - items: filters, - } - - if (rb.env === 'dev') console.log(JSON.stringify(s)) - typeof this.props.onSearch === 'function' && this.props.onSearch(s) - } - - clearFilter(searchNow) { - this._itemsRef.forEach((i) => i.clear()) - searchNow === true && setTimeout(() => this.searchNow(), 200) - } - - toggleExtended() { - this.setState({ extended: !this.state.extended }, () => { - if (this.state.extended) $('.quick-filter-pane').addClass('extended') - else $('.quick-filter-pane').removeClass('extended') - }) - } -} - -// eslint-disable-next-line no-undef -class FilterItemExt extends FilterItem { - constructor(props) { - super(props) - } - - componentDidMount() { - super.componentDidMount() - - const $s2op = this.__select2[1] - - setTimeout(() => { - if (this.state.type === 'DATE' || this.state.type === 'DATETIME' || this.state.type === 'TIME') { - $s2op.val('EQ').trigger('change') - } - }, 200) - } - - // @e = el or event - valueCheck(e) { - const v = e.target ? e.target.value : e.val() - if (!v) return - - super.valueCheck(e) - // $el.removeClass('is-invalid') - } -} diff --git a/src/main/resources/web/general/detail-list.html b/src/main/resources/web/general/detail-list.html index 78fdd3f12..3ab8c57e7 100644 --- a/src/main/resources/web/general/detail-list.html +++ b/src/main/resources/web/general/detail-list.html @@ -132,7 +132,7 @@ - + diff --git a/src/main/resources/web/general/record-list.html b/src/main/resources/web/general/record-list.html index 9ba2d417d..b5f98073d 100644 --- a/src/main/resources/web/general/record-list.html +++ b/src/main/resources/web/general/record-list.html @@ -135,7 +135,7 @@ - +
{$L('字段')}{$L('字段')} {$L('变更前')} {$L('变更后')}