mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 15:35:55 +08:00
trigger: AUTOUPDATE
This commit is contained in:
parent
a8ae03afd1
commit
89fe2a1582
|
@ -60,6 +60,7 @@ module.exports = {
|
||||||
$cleanMap: true,
|
$cleanMap: true,
|
||||||
$pages: true,
|
$pages: true,
|
||||||
$same: true,
|
$same: true,
|
||||||
|
$is: true,
|
||||||
$unmount: true,
|
$unmount: true,
|
||||||
$initReferenceSelect2: true,
|
$initReferenceSelect2: true,
|
||||||
$keepModalOpen: true,
|
$keepModalOpen: true,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
printWidth: 200,
|
printWidth: 120,
|
||||||
singleQuote: true,
|
singleQuote: true,
|
||||||
bracketSpacing: true,
|
bracketSpacing: true,
|
||||||
proseWrap: 'preserve',
|
proseWrap: 'preserve',
|
||||||
|
|
|
@ -20,7 +20,6 @@ import com.rebuild.core.metadata.EntityHelper;
|
||||||
import com.rebuild.core.metadata.MetadataHelper;
|
import com.rebuild.core.metadata.MetadataHelper;
|
||||||
import com.rebuild.core.service.trigger.RobotTriggerManager;
|
import com.rebuild.core.service.trigger.RobotTriggerManager;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
|
@ -23,14 +23,14 @@ public enum ActionType {
|
||||||
|
|
||||||
FIELDAGGREGATION("数据聚合", FieldAggregation.class),
|
FIELDAGGREGATION("数据聚合", FieldAggregation.class),
|
||||||
FIELDWRITEBACK("数据转写", FieldWriteback.class),
|
FIELDWRITEBACK("数据转写", FieldWriteback.class),
|
||||||
SENDNOTIFICATION("发送通知", SendNotification.class),
|
AUTOUPDATE("自动更新", AutoUpdate.class),
|
||||||
|
AUTOCREATE("自动创建", AutoCreate.class),
|
||||||
AUTOSHARE("自动共享", AutoShare.class),
|
AUTOSHARE("自动共享", AutoShare.class),
|
||||||
AUTOASSIGN("自动分派", AutoAssign.class),
|
AUTOASSIGN("自动分派", AutoAssign.class),
|
||||||
AUTOAPPROVAL("自动审批", AutoApproval.class),
|
AUTOAPPROVAL("自动审批", AutoApproval.class),
|
||||||
HOOKURL("回调 URL", "com.rebuild.rbv.trigger.HookUrl"),
|
|
||||||
AUTOTRANSFORM("自动记录转换", "com.rebuild.rbv.trigger.AutoTransform"),
|
AUTOTRANSFORM("自动记录转换", "com.rebuild.rbv.trigger.AutoTransform"),
|
||||||
|
SENDNOTIFICATION("发送通知", SendNotification.class),
|
||||||
AUTOUPDATE("自动更新", AutoUpdate.class),
|
HOOKURL("回调 URL", "com.rebuild.rbv.trigger.HookUrl"),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) REBUILD <https://getrebuild.com/> 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.rebuild.core.service.trigger.impl;
|
||||||
|
|
||||||
|
import com.rebuild.core.service.general.OperatingContext;
|
||||||
|
import com.rebuild.core.service.trigger.ActionType;
|
||||||
|
import com.rebuild.core.service.trigger.TriggerAction;
|
||||||
|
import com.rebuild.core.service.trigger.TriggerException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author devezhao
|
||||||
|
* @since 2021/3/30
|
||||||
|
*/
|
||||||
|
public class AutoCreate implements TriggerAction {
|
||||||
|
|
||||||
|
public ActionType getType() {
|
||||||
|
return ActionType.AUTOCREATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(OperatingContext operatingContext) throws TriggerException {
|
||||||
|
throw new UnsupportedOperationException("TODO 自动创建");
|
||||||
|
}
|
||||||
|
}
|
|
@ -85,8 +85,7 @@ public class BatchUpdateController extends BaseController {
|
||||||
|| dt == DisplayType.LOCATION
|
|| dt == DisplayType.LOCATION
|
||||||
|| dt == DisplayType.BARCODE
|
|| dt == DisplayType.BARCODE
|
||||||
|| dt == DisplayType.SERIES
|
|| dt == DisplayType.SERIES
|
||||||
|| dt == DisplayType.ANYREFERENCE
|
|| dt == DisplayType.ANYREFERENCE) {
|
||||||
|| dt == DisplayType.N2NREFERENCE) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +98,7 @@ public class BatchUpdateController extends BaseController {
|
||||||
* @param field
|
* @param field
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private JSONObject buildField(EasyField field) {
|
public static JSONObject buildField(EasyField field) {
|
||||||
JSONObject map = (JSONObject) field.toJSON();
|
JSONObject map = (JSONObject) field.toJSON();
|
||||||
|
|
||||||
// 字段选项
|
// 字段选项
|
||||||
|
|
|
@ -22,6 +22,7 @@ import com.rebuild.core.service.approval.RobotApprovalManager;
|
||||||
import com.rebuild.utils.JSONUtils;
|
import com.rebuild.utils.JSONUtils;
|
||||||
import com.rebuild.web.BaseController;
|
import com.rebuild.web.BaseController;
|
||||||
import com.rebuild.web.EntityParam;
|
import com.rebuild.web.EntityParam;
|
||||||
|
import com.rebuild.web.general.BatchUpdateController;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
@ -50,7 +51,10 @@ public class FieldWritebackController extends BaseController {
|
||||||
|
|
||||||
sourceFields.add(EasyMetaFactory.toJSON(sourceEntity.getPrimaryField()));
|
sourceFields.add(EasyMetaFactory.toJSON(sourceEntity.getPrimaryField()));
|
||||||
for (Field field : MetadataSorter.sortFields(sourceEntity)) {
|
for (Field field : MetadataSorter.sortFields(sourceEntity)) {
|
||||||
sourceFields.add(EasyMetaFactory.toJSON(field));
|
EasyField easyField = EasyMetaFactory.valueOf(field);
|
||||||
|
if (easyField.getDisplayType() == DisplayType.BARCODE) continue;
|
||||||
|
|
||||||
|
sourceFields.add(easyField.toJSON());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关联实体的
|
// 关联实体的
|
||||||
|
@ -63,8 +67,12 @@ public class FieldWritebackController extends BaseController {
|
||||||
|
|
||||||
String fieldRefName = fieldRef.getName() + ".";
|
String fieldRefName = fieldRef.getName() + ".";
|
||||||
String fieldRefLabel = EasyMetaFactory.getLabel(fieldRef) + ".";
|
String fieldRefLabel = EasyMetaFactory.getLabel(fieldRef) + ".";
|
||||||
|
|
||||||
for (Field field : MetadataSorter.sortFields(refEntity)) {
|
for (Field field : MetadataSorter.sortFields(refEntity)) {
|
||||||
JSONObject subField = EasyMetaFactory.toJSON(field);
|
EasyField easyField = EasyMetaFactory.valueOf(field);
|
||||||
|
if (easyField.getDisplayType() == DisplayType.BARCODE) continue;
|
||||||
|
|
||||||
|
JSONObject subField = (JSONObject) easyField.toJSON();
|
||||||
subField.put("name", fieldRefName + subField.getString("name"));
|
subField.put("name", fieldRefName + subField.getString("name"));
|
||||||
subField.put("label", fieldRefLabel + subField.getString("label"));
|
subField.put("label", fieldRefLabel + subField.getString("label"));
|
||||||
sourceFields.add(subField);
|
sourceFields.add(subField);
|
||||||
|
@ -77,10 +85,12 @@ public class FieldWritebackController extends BaseController {
|
||||||
for (Field field : MetadataSorter.sortFields(targetEntity)) {
|
for (Field field : MetadataSorter.sortFields(targetEntity)) {
|
||||||
EasyField easyField = EasyMetaFactory.valueOf(field);
|
EasyField easyField = EasyMetaFactory.valueOf(field);
|
||||||
DisplayType dt = easyField.getDisplayType();
|
DisplayType dt = easyField.getDisplayType();
|
||||||
if (dt == DisplayType.SERIES || dt == DisplayType.BARCODE || easyField.isBuiltin()) {
|
if (dt == DisplayType.SERIES || dt == DisplayType.BARCODE
|
||||||
|
|| dt == DisplayType.ANYREFERENCE || easyField.isBuiltin()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
targetFields.add(EasyMetaFactory.toJSON(field));
|
|
||||||
|
targetFields.add(BatchUpdateController.buildField(easyField));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,10 @@ public class RobotTriggerController extends BaseController {
|
||||||
public List<String[]> getAvailableActions(HttpServletRequest request) {
|
public List<String[]> getAvailableActions(HttpServletRequest request) {
|
||||||
List<String[]> alist = new ArrayList<>();
|
List<String[]> alist = new ArrayList<>();
|
||||||
for (ActionType t : ActionFactory.getAvailableActions()) {
|
for (ActionType t : ActionFactory.getAvailableActions()) {
|
||||||
alist.add(new String[]{t.name(), getLang(request, t.name())});
|
if (!Application.devMode() && (t == ActionType.FIELDWRITEBACK || t == ActionType.AUTOCREATE)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
alist.add(new String[] { t.name(), getLang(request, t.name()) });
|
||||||
}
|
}
|
||||||
return alist;
|
return alist;
|
||||||
}
|
}
|
||||||
|
|
|
@ -699,6 +699,8 @@
|
||||||
"AUTOSHARE": "自动共享",
|
"AUTOSHARE": "自动共享",
|
||||||
"AUTOASSIGN": "自动分派",
|
"AUTOASSIGN": "自动分派",
|
||||||
"AUTOAPPROVAL": "自动审批",
|
"AUTOAPPROVAL": "自动审批",
|
||||||
|
"AUTOUPDATE": "自动更新",
|
||||||
|
"AUTOCREATE": "自动创建",
|
||||||
"HowWriteTemplateTips": "如何编写模板文件?[查看帮助](https://getrebuild.com/docs/admin/excel-admin)",
|
"HowWriteTemplateTips": "如何编写模板文件?[查看帮助](https://getrebuild.com/docs/admin/excel-admin)",
|
||||||
"ExistsInvalidFieldsX": "存在无效字段 %s 建议修改",
|
"ExistsInvalidFieldsX": "存在无效字段 %s 建议修改",
|
||||||
"FieldMapping": "字段映射",
|
"FieldMapping": "字段映射",
|
||||||
|
|
|
@ -166,6 +166,7 @@
|
||||||
</script>
|
</script>
|
||||||
<script th:src="@{/assets/js/rb-advfilter.js}" type="text/babel"></script>
|
<script th:src="@{/assets/js/rb-advfilter.js}" type="text/babel"></script>
|
||||||
<script th:src="@{/assets/js/metadata/field-compatible.js}" type="text/babel"></script>
|
<script th:src="@{/assets/js/metadata/field-compatible.js}" type="text/babel"></script>
|
||||||
|
<script th:src="@{/assets/js/metadata/field-valueset.js}" type="text/babel"></script>
|
||||||
<script th:src="@{/assets/js/trigger/trigger-design.js}" type="text/babel"></script>
|
<script th:src="@{/assets/js/trigger/trigger-design.js}" type="text/babel"></script>
|
||||||
<script th:src="|${baseUrl}/assets/js/trigger/trigger.${actionType}.js?v=2.1.0.1207|" type="text/babel"></script>
|
<script th:src="|${baseUrl}/assets/js/trigger/trigger.${actionType}.js?v=2.1.0.1207|" type="text/babel"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
179
src/main/resources/web/assets/js/metadata/field-valueset.js
Normal file
179
src/main/resources/web/assets/js/metadata/field-valueset.js
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) REBUILD <https://getrebuild.com/> 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 字段值设置
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
class FieldValueSet extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
console.log(JSON.stringify(this.props.field))
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const field = this.props.field
|
||||||
|
if (field.type === 'ID' || field.type === 'AVATAR' || field.type === 'IMAGE' || field.type === 'FILE' || field.type === 'BARCODE' || field.type === 'SERIES') {
|
||||||
|
return <div className="form-control-plaintext text-danger">{$L('Unsupport')}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
field.type === 'PICKLIST' ||
|
||||||
|
field.type === 'STATE' ||
|
||||||
|
field.type === 'MULTISELECT' ||
|
||||||
|
field.type === 'BOOL' ||
|
||||||
|
field.type === 'REFERENCE' ||
|
||||||
|
field.type === 'N2NREFERENCE' ||
|
||||||
|
field.type === 'CLASSIFICATION'
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<select className="form-control form-control-sm" multiple={field.type === 'MULTISELECT' || field.type === 'N2NREFERENCE'} ref={(c) => (this._value = c)} key={field.name}>
|
||||||
|
{(field.options || []).map((item) => {
|
||||||
|
let value = item.id || item.mask
|
||||||
|
// for BOOL
|
||||||
|
if (item.id === false) value = 'false'
|
||||||
|
if (item.id === true) value = 'true'
|
||||||
|
|
||||||
|
return (
|
||||||
|
<option key={value} value={value}>
|
||||||
|
{item.text}
|
||||||
|
</option>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <input className="form-control form-control-sm" placeholder={this.props.placeholder} ref={(c) => (this._value = c)} key={field.name} maxLength="255" />
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
if (!this._value) return
|
||||||
|
|
||||||
|
const field = this.props.field
|
||||||
|
if (this._value.tagName === 'SELECT') {
|
||||||
|
if (field.type === 'REFERENCE' || field.type === 'N2NREFERENCE' || field.type === 'CLASSIFICATION') {
|
||||||
|
this.__$select2 = $initReferenceSelect2(this._value, {
|
||||||
|
entity: this.props.entity,
|
||||||
|
name: field.name,
|
||||||
|
label: field.label,
|
||||||
|
searchType: field.type === 'CLASSIFICATION' ? 'classification' : null,
|
||||||
|
placeholder: this.props.placeholder || ' ',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.__$select2 = $(this._value).select2({
|
||||||
|
placeholder: this.props.placeholder,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.__$select2.val(null).trigger('change')
|
||||||
|
} else if (field.type === 'DATE' || field.type === 'DATETIME') {
|
||||||
|
this.__$datetimepicker = $(this._value).datetimepicker({
|
||||||
|
format: field.type === 'DATE' ? 'yyyy-mm-dd' : 'yyyy-mm-dd hh:ii:ss',
|
||||||
|
minView: field.type === 'DATE' ? 'month' : 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
if (this.__$select2) {
|
||||||
|
this.__$select2.select2('destroy')
|
||||||
|
this.__$select2 = null
|
||||||
|
}
|
||||||
|
if (this.__$datetimepicker) {
|
||||||
|
this.__$datetimepicker.datetimepicker('remove')
|
||||||
|
this.__$datetimepicker = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val() {
|
||||||
|
if (!this._value) return null
|
||||||
|
|
||||||
|
const field = this.props.field
|
||||||
|
let value
|
||||||
|
if (field.type === 'MULTISELECT') {
|
||||||
|
let masks = 0
|
||||||
|
this.__$select2.val().forEach((mask) => (masks += ~~mask))
|
||||||
|
value = masks
|
||||||
|
} else if (this._value.tagName === 'SELECT') {
|
||||||
|
value = this.__$select2.val()
|
||||||
|
} else {
|
||||||
|
value = $(this._value).val()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!value) return null
|
||||||
|
if (typeof value === 'object' && value.length === 0) return null // 空数组
|
||||||
|
|
||||||
|
// 验证
|
||||||
|
|
||||||
|
if (field.type === 'NUMBER' || field.type === 'DECIMAL') {
|
||||||
|
if (isNaN(value)) {
|
||||||
|
RbHighbar.create($L('SomeNotFormatWell').replace('{0}', field.label))
|
||||||
|
return null
|
||||||
|
} else if ($isTrue(field.notNegative) && ~~value < 0) {
|
||||||
|
RbHighbar.create($L('SomeNotBeNegative').replace('{0}', field.label))
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
} else if (field.type === 'EMAIL') {
|
||||||
|
if (!$regex.isMail(value)) {
|
||||||
|
RbHighbar.create($L('SomeNotFormatWell').replace('{0}', field.label))
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
} else if (field.type === 'URL') {
|
||||||
|
if (!$regex.isUrl(value)) {
|
||||||
|
RbHighbar.create($L('SomeNotFormatWell').replace('{0}', field.label))
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
} else if (field.type === 'PHONE') {
|
||||||
|
if (!$regex.isTel(value)) {
|
||||||
|
RbHighbar.create($L('SomeNotFormatWell').replace('{0}', field.label))
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeof value === 'object' ? value.join(',') : value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取字段值文本
|
||||||
|
FieldValueSet.formatFieldText = function (value, field) {
|
||||||
|
if (!value) return null
|
||||||
|
if (!field) return value
|
||||||
|
|
||||||
|
if (field.options) {
|
||||||
|
if (field.type === 'MULTISELECT') {
|
||||||
|
const texts = []
|
||||||
|
field.options.forEach((item) => {
|
||||||
|
if ((value & item.mask) !== 0) texts.push(item.text)
|
||||||
|
})
|
||||||
|
return texts.join(', ')
|
||||||
|
} else {
|
||||||
|
const found = field.options.find((x) => $is(x.id, value))
|
||||||
|
return found ? found.text : value.toUpperCase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field.type === 'REFERENCE' || field.type === 'N2NREFERENCE' || field.type === 'CLASSIFICATION') {
|
||||||
|
const result = $.ajax({
|
||||||
|
url: `/commons/search/read-labels?ids=${value}`,
|
||||||
|
async: false,
|
||||||
|
}).responseJSON
|
||||||
|
|
||||||
|
if (result && result.data) {
|
||||||
|
if (field.type === 'N2NREFERENCE') {
|
||||||
|
const texts = []
|
||||||
|
value.split(',').forEach((item) => {
|
||||||
|
texts.push(result.data[item])
|
||||||
|
})
|
||||||
|
value = texts.join(', ')
|
||||||
|
} else {
|
||||||
|
value = result.data[value]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = `@${value.toUpperCase()}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
|
@ -401,9 +401,12 @@ var $same = function (a, b) {
|
||||||
if (a === b) return true
|
if (a === b) return true
|
||||||
if (a === 0) a = '0'
|
if (a === 0) a = '0'
|
||||||
if (b === 0) b = '0'
|
if (b === 0) b = '0'
|
||||||
|
if (a === true || a === false) a = a + ''
|
||||||
|
if (b === true || b === false) b = b + ''
|
||||||
// eslint-disable-next-line eqeqeq
|
// eslint-disable-next-line eqeqeq
|
||||||
return a == b
|
return a == b
|
||||||
}
|
}
|
||||||
|
var $is = $same
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否为空。兼容对象或数组
|
* 是否为空。兼容对象或数组
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) REBUILD <https://getrebuild.com/> 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ~~ 自动新建(记录)
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
class ContentAutoCreate extends ActionContentSpec {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <div>TODO</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
buildContent() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
renderContentComp = function (props) {
|
||||||
|
renderRbcomp(<ContentAutoCreate {...props} />, 'react-content', function () {
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
contentComp = this
|
||||||
|
})
|
||||||
|
}
|
|
@ -4,12 +4,13 @@ Copyright (c) REBUILD <https://getrebuild.com/> and/or its owners. All rights re
|
||||||
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
|
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
|
||||||
See LICENSE and COMMERCIAL in the project root for license information.
|
See LICENSE and COMMERCIAL in the project root for license information.
|
||||||
*/
|
*/
|
||||||
|
/* global FieldValueSet */
|
||||||
|
|
||||||
const UPDATE_MODES = {
|
const UPDATE_MODES = {
|
||||||
FIELD: $L('UpdateByField'),
|
FIELD: $L('UpdateByField'),
|
||||||
VALUE: $L('UpdateByValue'),
|
VFIXED: $L('UpdateByValue'),
|
||||||
NULLV: $L('BatchUpdateOpNULL'),
|
|
||||||
FORMULA: $L('CalcFORMULA'),
|
FORMULA: $L('CalcFORMULA'),
|
||||||
|
VNULL: $L('BatchUpdateOpNULL'),
|
||||||
}
|
}
|
||||||
|
|
||||||
// ~~ 自动更新(字段)
|
// ~~ 自动更新(字段)
|
||||||
|
@ -55,19 +56,21 @@ class ContentAutoUpdate extends ActionContentSpec {
|
||||||
<div className="items">
|
<div className="items">
|
||||||
{(this.state.items || []).length > 0 &&
|
{(this.state.items || []).length > 0 &&
|
||||||
this.state.items.map((item) => {
|
this.state.items.map((item) => {
|
||||||
|
const field = item.updateMode === 'VFIXED' ? this.state.targetFields.find((x) => x.name === item.targetField) : null
|
||||||
return (
|
return (
|
||||||
<div key={item.targetField}>
|
<div key={item.targetField}>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-5">
|
<div className="col-5">
|
||||||
<span className="badge badge-warning">{this._getFieldLabel(this.state.targetFields, item.targetField)}</span>
|
<span className="badge badge-warning">{_getFieldLabel(this.state.targetFields, item.targetField)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-2">
|
<div className="col-2">
|
||||||
<span className="zmdi zmdi-forward zmdi-hc-rotate-180"></span>
|
<span className="zmdi zmdi-forward zmdi-hc-rotate-180"></span>
|
||||||
<span className="badge badge-warning">{UPDATE_MODES[item.updateMode]}</span>
|
<span className="badge badge-warning">{UPDATE_MODES[item.updateMode]}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-5 del-wrap">
|
<div className="col-5 del-wrap">
|
||||||
{item.updateMode === 'FIELD' && <span className="badge badge-warning">{this._getFieldLabel(this.state.sourceFields, item.source)}</span>}
|
{item.updateMode === 'FIELD' && <span className="badge badge-warning">{_getFieldLabel(this.__sourceFieldsCache, item.sourceAny)}</span>}
|
||||||
{item.updateMode === 'VALUE' && <span className="badge badge-light">{item.source}</span>}
|
{item.updateMode === 'VFIXED' && <span className="badge badge-light text-break">{FieldValueSet.formatFieldText(item.sourceAny, field)}</span>}
|
||||||
|
{item.updateMode === 'FORMULA' && <span className="badge badge-warning">{item.sourceAny}</span>}
|
||||||
<a className="del" title={$L('Remove')} onClick={() => this.delItem(item.targetField)}>
|
<a className="del" title={$L('Remove')} onClick={() => this.delItem(item.targetField)}>
|
||||||
<span className="zmdi zmdi-close"></span>
|
<span className="zmdi zmdi-close"></span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -116,8 +119,10 @@ class ContentAutoUpdate extends ActionContentSpec {
|
||||||
</select>
|
</select>
|
||||||
<p>{$L('SourceField')}</p>
|
<p>{$L('SourceField')}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className={this.state.updateMode === 'VALUE' ? '' : 'hide'}>
|
<div className={this.state.updateMode === 'VFIXED' ? '' : 'hide'}>
|
||||||
<input type="text" className="form-control form-control-sm" ref={(c) => (this._sourceValue = c)} />
|
{this.state.updateMode === 'VFIXED' && this.state.targetField && (
|
||||||
|
<FieldValueSet entity={this.state.targetEntity} field={this.state.targetField} placeholder="固定值" ref={(c) => (this._sourceValue = c)} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={this.state.updateMode === 'FORMULA' ? '' : 'hide'}>
|
<div className={this.state.updateMode === 'FORMULA' ? '' : 'hide'}>
|
||||||
<div className="form-control-plaintext formula" _title={$L('CalcFORMULA')} ref={(c) => (this._sourceFormula = c)} onClick={this.showFormula}></div>
|
<div className="form-control-plaintext formula" _title={$L('CalcFORMULA')} ref={(c) => (this._sourceFormula = c)} onClick={this.showFormula}></div>
|
||||||
|
@ -151,16 +156,17 @@ class ContentAutoUpdate extends ActionContentSpec {
|
||||||
this.__select2 = []
|
this.__select2 = []
|
||||||
$.get(`/admin/robot/trigger/field-aggregation-entities?source=${this.props.sourceEntity}`, (res) => {
|
$.get(`/admin/robot/trigger/field-aggregation-entities?source=${this.props.sourceEntity}`, (res) => {
|
||||||
this.setState({ targetEntities: res.data }, () => {
|
this.setState({ targetEntities: res.data }, () => {
|
||||||
const s2te = $(this._targetEntity)
|
const $s2te = $(this._targetEntity)
|
||||||
.select2({ placeholder: $L('SelectSome,TargetEntity') })
|
.select2({ placeholder: $L('SelectSome,TargetEntity') })
|
||||||
.on('change', () => this.changeTargetEntity())
|
.on('change', () => this._changeTargetEntity())
|
||||||
|
|
||||||
if (content && content.targetEntity) {
|
if (content && content.targetEntity) {
|
||||||
s2te.val(content.targetEntity)
|
$s2te.val(content.targetEntity)
|
||||||
if (rb.env !== 'dev') s2te.attr('disabled', true)
|
if (rb.env !== 'dev') $s2te.attr('disabled', true)
|
||||||
}
|
}
|
||||||
s2te.trigger('change')
|
|
||||||
this.__select2.push(s2te)
|
$s2te.trigger('change')
|
||||||
|
this.__select2.push($s2te)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -169,85 +175,96 @@ class ContentAutoUpdate extends ActionContentSpec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
changeTargetEntity() {
|
_changeTargetEntity() {
|
||||||
const te = ($(this._targetEntity).val() || '').split('.')[1]
|
const te = ($(this._targetEntity).val() || '').split('.')[1]
|
||||||
if (!te) return
|
if (!te) return
|
||||||
// 清空现有规则
|
// 清空现有规则
|
||||||
this.setState({ items: [] })
|
this.setState({ targetEntity: te, items: [] })
|
||||||
|
|
||||||
$.get(`/admin/robot/trigger/field-writeback-fields?source=${this.props.sourceEntity}&target=${te}`, (res) => {
|
$.get(`/admin/robot/trigger/field-writeback-fields?source=${this.props.sourceEntity}&target=${te}`, (res) => {
|
||||||
this.setState({ hadApproval: res.data.hadApproval })
|
this.setState({ hadApproval: res.data.hadApproval })
|
||||||
|
this.__sourceFieldsCache = res.data.source
|
||||||
|
|
||||||
if (this.state.targetFields) {
|
if (this.state.targetFields) {
|
||||||
this.setState({ targetFields: res.data.target })
|
this.setState({ targetFields: res.data.target })
|
||||||
} else {
|
} else {
|
||||||
this.setState({ sourceFields: res.data.source, targetFields: res.data.target }, () => {
|
this.setState({ sourceFields: res.data.source, targetFields: res.data.target }, () => {
|
||||||
const s2sf = $(this._sourceField)
|
const $s2tf = $(this._targetField)
|
||||||
.select2({ placeholder: $L('SelectSome,SourceField') })
|
.select2({ placeholder: $L('SelectSome,TargetField') })
|
||||||
.on('change', (e) => {
|
.on('change', () => this._changeTargetField())
|
||||||
console.log(e.target.value)
|
const $s2um = $(this._updateMode)
|
||||||
})
|
|
||||||
const s2um = $(this._updateMode)
|
|
||||||
.select2({ placeholder: $L('SelectSome,UpdateMode') })
|
.select2({ placeholder: $L('SelectSome,UpdateMode') })
|
||||||
.on('change', (e) => this.setState({ updateMode: e.target.value }))
|
.on('change', (e) => {
|
||||||
const s2tf = $(this._targetField).select2({ placeholder: $L('SelectSome,TargetField') })
|
this.setState({ updateMode: e.target.value })
|
||||||
|
})
|
||||||
|
const $s2sf = $(this._sourceField).select2({ placeholder: $L('SelectSome,SourceField') })
|
||||||
|
|
||||||
this.__select2.push(s2sf)
|
$s2tf.trigger('change')
|
||||||
this.__select2.push(s2um)
|
|
||||||
this.__select2.push(s2tf)
|
this.__select2.push($s2tf)
|
||||||
|
this.__select2.push($s2um)
|
||||||
|
this.__select2.push($s2sf)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (this.props.content) this.setState({ items: this.props.content.items || [] })
|
if (this.props.content) {
|
||||||
|
this.setState({ items: this.props.content.items || [] })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_getFieldLabel(fields, field) {
|
_changeTargetField() {
|
||||||
let found = fields.find((x) => x[0] === field)
|
const fieldName = $(this._targetField).val()
|
||||||
if (found) found = found[1]
|
const targetField = this.state.targetFields.find((x) => x.name === fieldName)
|
||||||
return found || '[' + field.toUpperCase() + ']'
|
|
||||||
|
// 获取可回填字段(兼容的)
|
||||||
|
const sourceFields = []
|
||||||
|
$(this.__sourceFieldsCache).each(function () {
|
||||||
|
if ($fieldIsCompatible(this, targetField)) {
|
||||||
|
sourceFields.push(this)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.setState({ targetField: null, sourceFields: sourceFields }, () => {
|
||||||
|
if (sourceFields.length > 0) $(this._sourceField).val(sourceFields[0].name)
|
||||||
|
})
|
||||||
|
// 强制销毁后再渲染
|
||||||
|
setTimeout(() => this.setState({ targetField: targetField }), 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
addItem() {
|
addItem() {
|
||||||
const tf = $(this._targetField).val()
|
const tf = $(this._targetField).val()
|
||||||
const mode = $(this._updateMode).val()
|
const mode = $(this._updateMode).val()
|
||||||
if (!tf) {
|
if (!tf) return RbHighbar.create($L('PlsSelectSome,TargetField'))
|
||||||
RbHighbar.create($L('PlsSelectSome,TargetField'))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
let sourceAny = null
|
let sourceAny = null
|
||||||
if (mode === 'FIELD') {
|
if (mode === 'FIELD') {
|
||||||
sourceAny = $(this._sourceField).val()
|
sourceAny = $(this._sourceField).val()
|
||||||
|
|
||||||
// 目标字段=源字段
|
// 目标字段=源字段
|
||||||
if (sourceAny === $(this._targetEntity).val().split('.')[0] + '.' + tf) {
|
const tfFull = `${$(this._targetEntity).val().split('.')[0]}.${tf}`.replace('$PRIMARY$.', '')
|
||||||
RbHighbar.create($L('TargetAndSourceNotSame'))
|
if (tfFull === sourceAny) return RbHighbar.create($L('TargetAndSourceNotSame'))
|
||||||
return false
|
} else if (mode === 'VFIXED') {
|
||||||
}
|
sourceAny = this._sourceValue.val()
|
||||||
} else if (mode === 'VALUE') {
|
if (!sourceAny) return
|
||||||
sourceAny = $(this._sourceValue).val()
|
} else if (mode === 'FORMULA') {
|
||||||
if (!sourceAny) {
|
sourceAny = $(this._sourceFormula).attr('data-value')
|
||||||
RbHighbar.create('填写值')
|
if (!sourceAny) return RbHighbar.create('填写公式')
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const items = this.state.items || []
|
const items = this.state.items || []
|
||||||
const exists = items.find((x) => x.targetField === tf)
|
const exists = items.find((x) => x.targetField === tf)
|
||||||
if (exists) {
|
if (exists) return RbHighbar.create($L('SomeDuplicate,TargetField'))
|
||||||
RbHighbar.create($L('SomeDuplicate,TargetField'))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
items.push({ targetField: tf, updateMode: mode, source: sourceAny })
|
items.push({ targetField: tf, updateMode: mode, sourceAny: sourceAny })
|
||||||
this.setState({ items: items })
|
this.setState({ items: items })
|
||||||
}
|
}
|
||||||
|
|
||||||
delItem(targetField) {
|
delItem(targetField) {
|
||||||
const items = (this.state.items || []).filter((item) => {
|
const itemsNew = (this.state.items || []).filter((item) => {
|
||||||
return item.targetField !== targetField
|
return item.targetField !== targetField
|
||||||
})
|
})
|
||||||
this.setState({ items: items })
|
this.setState({ items: itemsNew })
|
||||||
}
|
}
|
||||||
|
|
||||||
buildContent() {
|
buildContent() {
|
||||||
|
@ -268,6 +285,12 @@ class ContentAutoUpdate extends ActionContentSpec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _getFieldLabel = function (fields, fieldName) {
|
||||||
|
let found = fields.find((x) => x.name === fieldName)
|
||||||
|
if (found) found = found.label
|
||||||
|
return found || '[' + fieldName.toUpperCase() + ']'
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
renderContentComp = function (props) {
|
renderContentComp = function (props) {
|
||||||
renderRbcomp(<ContentAutoUpdate {...props} />, 'react-content', function () {
|
renderRbcomp(<ContentAutoUpdate {...props} />, 'react-content', function () {
|
||||||
|
|
Loading…
Reference in a new issue