diff --git a/.eslintrc.js b/.eslintrc.js index f24aa8fce..e5ad37102 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -151,5 +151,6 @@ module.exports = { $clearSelection: true, DlgTransform: true, $select2OpenTemplateResult: true, + $env: true, }, } diff --git a/src/main/java/com/rebuild/core/configuration/general/AutoFillinManager.java b/src/main/java/com/rebuild/core/configuration/general/AutoFillinManager.java index cc7f08350..f245fd807 100644 --- a/src/main/java/com/rebuild/core/configuration/general/AutoFillinManager.java +++ b/src/main/java/com/rebuild/core/configuration/general/AutoFillinManager.java @@ -24,10 +24,7 @@ import com.rebuild.core.metadata.MetadataHelper; import com.rebuild.core.metadata.easymeta.DisplayType; import com.rebuild.core.metadata.easymeta.EasyField; -import com.rebuild.core.metadata.easymeta.EasyFile; -import com.rebuild.core.metadata.easymeta.EasyID; import com.rebuild.core.metadata.easymeta.EasyMetaFactory; -import com.rebuild.core.metadata.easymeta.EasyN2NReference; import com.rebuild.core.metadata.easymeta.MixValue; import com.rebuild.core.metadata.impl.EasyFieldConfigProps; import com.rebuild.core.support.general.CalcFormulaSupport; @@ -313,17 +310,20 @@ protected Object conversionCompatibleValue(Field source, Field target, Object va // 转换成前端可接受的值 - if (sourceEasy.getDisplayType() == targetEasy.getDisplayType() - && sourceEasy.getDisplayType() == DisplayType.MULTISELECT) { + DisplayType sourceEasyType = sourceEasy.getDisplayType(); + DisplayType targetEasyType = targetEasy.getDisplayType(); + + if (sourceEasyType == targetEasyType && sourceEasyType == DisplayType.MULTISELECT) { return newValue; // Long } - if (sourceEasy instanceof EasyID && targetEasy instanceof EasyN2NReference) { + if (sourceEasyType == DisplayType.ID + && (targetEasyType == DisplayType.REFERENCE || targetEasyType == DisplayType.N2NREFERENCE || targetEasyType == DisplayType.ANYREFERENCE)) { newValue = FieldValueHelper.wrapFieldValue(newValue, targetEasy); - } else if (targetEasy instanceof EasyN2NReference) { + } else if (targetEasyType == DisplayType.N2NREFERENCE) { newValue = targetEasy.wrapValue(newValue); } else if (sourceEasy instanceof MixValue) { - if (!(newValue instanceof String) || sourceEasy instanceof EasyFile) { + if (!(newValue instanceof String) || sourceEasyType == DisplayType.FILE) { newValue = sourceEasy.wrapValue(newValue); } } diff --git a/src/main/java/com/rebuild/core/service/query/AdvFilterParser.java b/src/main/java/com/rebuild/core/service/query/AdvFilterParser.java index 50b4735c8..3c33b5902 100644 --- a/src/main/java/com/rebuild/core/service/query/AdvFilterParser.java +++ b/src/main/java/com/rebuild/core/service/query/AdvFilterParser.java @@ -524,6 +524,29 @@ else if (ParseHelper.YTA.equalsIgnoreCase(op)) { op = ParseHelper.BW; } + // v3.9.1 日期查询年月日 0000-00-00 + if (ParseHelper.EQ.equals(op) && (value.startsWith("0000-") || value.contains("-00-") || value.endsWith("-00"))) { + final String[] ymd = value.split("-"); + String format; + if (ymd[0].equals("0000") && ymd[1].equals("00")) { // 0000-00-XX + format = "%d"; + value = ymd[2]; + } else if (ymd[0].equals("0000") && ymd[2].equals("00")) { // 0000-XX-00 + format = "%m"; + value = ymd[1]; + } else if (ymd[1].equals("00") && ymd[2].equals("00")) { // XXXX-00-00 + format = "%Y"; + value = ymd[0]; + } else if (ymd[1].equals("00")) { // XXXX-00-XX + format = "%Y%d"; + value = ymd[0] + ymd[2]; + } else { // 0000-XX-XX + format = "%m%d"; + value = ymd[1] + ymd[2]; + } + field = String.format("DATE_FORMAT(%s, '%s')", field, format); + } + } else if (dt == DisplayType.TIME) { // 前端输入 HH:mm if (value != null && value.length() == 5) { @@ -662,13 +685,13 @@ else if (ParseHelper.SFU.equalsIgnoreCase(op)) { .append(" )"); } + // 当前审批人 if (VF_ACU.equals(field)) { return String.format( "(exists (select recordId from RobotApprovalStep where ^%s = recordId and state = 1 and isCanceled = 'F' and %s) and approvalState = 2)", specRootEntity.getPrimaryField().getName(), sb.toString().replace(VF_ACU, "approver")); - } else { - return sb.toString(); } + return sb.toString(); } /** diff --git a/src/main/java/com/rebuild/core/support/License.java b/src/main/java/com/rebuild/core/support/License.java index 1081060f6..e15bf9394 100644 --- a/src/main/java/com/rebuild/core/support/License.java +++ b/src/main/java/com/rebuild/core/support/License.java @@ -75,7 +75,7 @@ public static JSONObject queryAuthority() { if ((error = auth.getString("error")) != null) { auth = JSONUtils.toJSONObject( new String[] { "sn", "authType", "authObject", "authExpires" }, - new String[] { SN(), "开源社区版", "GitHub", "无" }); + new String[] { SN(), "开源社区版", "OSC", "无" }); } if ("BLOCKED".equals(error)) System.exit(110); return auth; diff --git a/src/main/java/com/rebuild/core/support/general/ContentWithFieldVars.java b/src/main/java/com/rebuild/core/support/general/ContentWithFieldVars.java index 20edebc43..d26ebb499 100644 --- a/src/main/java/com/rebuild/core/support/general/ContentWithFieldVars.java +++ b/src/main/java/com/rebuild/core/support/general/ContentWithFieldVars.java @@ -41,7 +41,7 @@ public class ContentWithFieldVars { /** * 通过 `{}` 包裹的变量或字段 */ - public static final Pattern PATT_VAR = Pattern.compile("\\{([0-9a-zA-Z._$]+)}"); + public static final Pattern PATT_VAR = Pattern.compile("\\{([0-9a-zA-Z._$]{4,})}"); /** * 替换文本中的字段变量 @@ -82,9 +82,7 @@ public static String replaceWithRecord(String content, ID recordId) { * @return */ public static String replaceWithRecord(String content, Record record) { - if (StringUtils.isBlank(content) || record == null) { - return content; - } + if (StringUtils.isBlank(content) || record == null) return content; // 主键占位符 content = content.replace("{ID}", @@ -147,25 +145,19 @@ public static String replaceWithRecord(String content, Record record) { } /** - * 提取内容中的变量 {xxx} + * 提取内容中的变量 {xxxx} * * @param content * @return */ public static Set matchsVars(String content) { - if (StringUtils.isBlank(content)) { - return Collections.emptySet(); - } + if (StringUtils.isBlank(content)) return Collections.emptySet(); Set vars = new HashSet<>(); Matcher m = PATT_VAR.matcher(content); while (m.find()) { String varName = m.group(1); - if (StringUtils.isBlank(varName)) { - log.warn("Blank `\\{\\}` found in `{}`", content); - } else { - vars.add(varName); - } + vars.add(varName); } return vars; } diff --git a/src/main/java/com/rebuild/web/notification/NotificationController.java b/src/main/java/com/rebuild/web/notification/NotificationController.java index 56fbb5421..9b89cb6f9 100644 --- a/src/main/java/com/rebuild/web/notification/NotificationController.java +++ b/src/main/java/com/rebuild/web/notification/NotificationController.java @@ -60,6 +60,7 @@ public JSON checkMessage(HttpServletRequest request) { JSON mm = buildMM(); if (mm != null) state.put("mm", mm); + state.put("st", CalendarUtils.now()); // v3.8 手机版利用通知检查做最近活跃信息存储 String h5referer = getParameter(request, "h5referer"); diff --git a/src/main/resources/i18n/lang.zh_CN.json b/src/main/resources/i18n/lang.zh_CN.json index 9cc251da0..237c88a66 100644 --- a/src/main/resources/i18n/lang.zh_CN.json +++ b/src/main/resources/i18n/lang.zh_CN.json @@ -3345,5 +3345,6 @@ "未备份":"未备份", "选择要备份哪些数据":"选择要备份哪些数据", "分配与共享":"分配与共享", - "最多显示最近 500 条记录":"最多显示最近 500 条记录" + "最多显示最近 500 条记录":"最多显示最近 500 条记录", + "失败时的提示内容。内容支持字段变量,如 `{createdOn}` (其中 createdOn 为源实体的字段内部标识)":"失败时的提示内容。内容支持字段变量,如 `{createdOn}` (其中 createdOn 为源实体的字段内部标识)" } \ No newline at end of file diff --git a/src/main/resources/web/_include/footer.html b/src/main/resources/web/_include/footer.html index e97d80d7e..481fc2f59 100644 --- a/src/main/resources/web/_include/footer.html +++ b/src/main/resources/web/_include/footer.html @@ -33,3 +33,6 @@ + diff --git a/src/main/resources/web/admin/metadata/field-edit.html b/src/main/resources/web/admin/metadata/field-edit.html index 1d4158dba..8dbe1b55b 100644 --- a/src/main/resources/web/admin/metadata/field-edit.html +++ b/src/main/resources/web/admin/metadata/field-edit.html @@ -542,11 +542,11 @@
[[${bundle.L('常用')}]]
/>
-
(this._$tips = c)}> - {$L('请勿在业务高峰时段执行备份')} -
+ {_backup ? ( +
+ + + + + + + + + + + +
{$L('数据库')}{this.state.db ? {this.state.db} : {$L('未备份')}}
{$L('数据目录文件')}{this.state.file ? {this.state.file} : {$L('未备份')}}
+
+ ) : ( +
(this._$tips = c)}> + {$L('请勿在业务高峰时段执行备份')} +
+ )} @@ -367,19 +385,15 @@ class DlgBackup extends RbAlert { } confirm = () => { - let type = ($(this._$bkType).find('input:eq(0)').prop('checked') ? 1 : 0) + ($(this._$bkType).find('input:eq(1)').prop('checked') ? 2 : 0) + const type = ($(this._$bkType).find('input:eq(0)').prop('checked') ? 1 : 0) + ($(this._$bkType).find('input:eq(1)').prop('checked') ? 2 : 0) if (type === 0) return this.disabled(true, true) const $btn = $(this._$btn).button('loading') $.post(`systems/backup?type=${type}`, (res) => { - if (res.error_code === 0) { - const data = res.data || {} - const tips = [$L('数据库'), ' ', data.db || $L('未备份'), '
', $L('数据目录文件'), ' ', data.file || $L('未备份'), ''] - $(this._$tips).html(tips.join('')) - } else { - RbHighbar.error(res.error_msg) - } + if (res.error_code === 0) this.setState({ ...res.data }) + else RbHighbar.error(res.error_msg) + this.disabled(false, false) $btn.button('reset') }) diff --git a/src/main/resources/web/assets/js/file-preview.js b/src/main/resources/web/assets/js/file-preview.js index 87dea0d83..402952e5f 100644 --- a/src/main/resources/web/assets/js/file-preview.js +++ b/src/main/resources/web/assets/js/file-preview.js @@ -210,6 +210,13 @@ class RbPreview extends React.Component { previewUrl = `${rb.baseUrl}/filex/` + url.split('/filex/')[1] } } + + // fix:3.9.1 PC钉钉预览PDF + if ($env.isDingTalk()) { + window.open(previewUrl) + that.hide() + return + } } that.setState({ previewUrl: previewUrl, errorMsg: null }) } diff --git a/src/main/resources/web/assets/js/general/rb-datalist.common.js b/src/main/resources/web/assets/js/general/rb-datalist.common.js index bc54d06cd..cbb37b2c2 100644 --- a/src/main/resources/web/assets/js/general/rb-datalist.common.js +++ b/src/main/resources/web/assets/js/general/rb-datalist.common.js @@ -1739,9 +1739,13 @@ CellRenders.addRender('EMAIL', (v, s, k) => { return (
- $stopEvent(e)}> - {v} - + {$env.isDingTalk() ? ( + {v} + ) : ( + $stopEvent(e)}> + {v} + + )}
) @@ -1750,9 +1754,13 @@ CellRenders.addRender('PHONE', (v, s, k) => { return (
- $stopEvent(e)}> - {v} - + {$env.isDingTalk() || $env.isWxWork() ? ( + {v} + ) : ( + $stopEvent(e)}> + {v} + + )}
) diff --git a/src/main/resources/web/assets/js/general/rb-forms.js b/src/main/resources/web/assets/js/general/rb-forms.js index cac915921..4ea9fa29e 100644 --- a/src/main/resources/web/assets/js/general/rb-forms.js +++ b/src/main/resources/web/assets/js/general/rb-forms.js @@ -1234,9 +1234,13 @@ class RbFormEMail extends RbFormText { return (
- - {this.state.value} - + {$env.isDingTalk() ? ( + {this.state.value} + ) : ( + + {this.state.value} + + )}
) } @@ -1254,9 +1258,13 @@ class RbFormPhone extends RbFormText { return (
- - {this.state.value} - + {$env.isDingTalk() || $env.isWxWork() ? ( + {this.state.value} + ) : ( + + {this.state.value} + + )}
) } diff --git a/src/main/resources/web/assets/js/rb-components.js b/src/main/resources/web/assets/js/rb-components.js index 6a1d53b5d..e3fe625e5 100644 --- a/src/main/resources/web/assets/js/rb-components.js +++ b/src/main/resources/web/assets/js/rb-components.js @@ -991,8 +991,10 @@ class AnyRecordSelector extends RecordSelector { const iv = this.props.initValue if (iv) { $(this._$entity).val(iv.entity).trigger('change') - const option = new Option(iv.text, iv.id, true, true) - $(this._$select).append(option) + setTimeout(() => { + const o = new Option(iv.text, iv.id, true, true) + $(this._$select).append(o) + }, 200) } }) }) diff --git a/src/main/resources/web/assets/js/rb-page.js b/src/main/resources/web/assets/js/rb-page.js index acb229c5e..0fb84c5bc 100644 --- a/src/main/resources/web/assets/js/rb-page.js +++ b/src/main/resources/web/assets/js/rb-page.js @@ -209,6 +209,8 @@ $(window).on('load', () => { if (($(this).attr('href') || '').indexOf('getrebuild.com') > -1) $(this).removeAttr('href') }) } + // vConsole + if (window.VConsole) new window.VConsole() }) // 取消管理中心访问 @@ -387,6 +389,7 @@ var _checkMessage = function () { } _showStateMM(res.data.mm) + _showStateST(res.data.st) setTimeout(_checkMessage, rb.env === 'dev' ? 9000 : 2000) }) } @@ -446,7 +449,6 @@ var _showNotification = function (state) { } var _showStateMM = function (mm) { if ($.cookie('mm_gritter_cancel')) return - if (mm) { var $mm = $('#mm_gritter') if ($mm[0]) { @@ -471,6 +473,25 @@ var _showStateMM = function (mm) { RbGritter.remove('mm_gritter') } } +var _showStateST = function (st) { + if ($.cookie('st_gritter_cancel')) return + st = Math.abs(moment().diff(st, 'seconds')) + if (st > 60) { + if (!$('#gritter-item-st_gritter')[0]) { + RbGritter.create($L('本地计算机与服务器时间存在加大差异,建议立即校正。'), { + timeout: 60 * 1000, + type: 'danger', + icon: 'mdi-clock-remove-outline', + onCancel: function () { + $.cookie('st_gritter_cancel', st, { expires: 1 }) + }, + id: 'st_gritter', + }) + } + } else { + RbGritter.remove('st_gritter') + } +} // 全局搜索 var _initGlobalSearch = function () { $('.global-search2>a').on('click', function () { @@ -1336,3 +1357,15 @@ function $select2OpenTemplateResult(res) { } return $span } + +// 环境 @see LoginChannel.java +var $env = { + // 钉钉 + isDingTalk: function () { + return navigator.userAgent.match(/(DINGTALK)/i) || true + }, + // 企微 + isWxWork: function () { + return navigator.userAgent.match(/(WXWORK)/i) + }, +}