workflow-editor 0.9.85-dw-tmp3 → 0.9.87-dw
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/workflow-editor.css +1 -0
- package/lib/workflow-editor.umd.min.js +39 -0
- package/package.json +23 -50
- package/{src → packages}/index.js +12 -15
- package/packages/plugins/formValidatorUtil.js +528 -0
- package/packages/plugins/index.js +8 -0
- package/packages/workflow-editor/index.js +14 -0
- package/packages/workflow-editor/src/api.js +7 -0
- package/packages/workflow-editor/src/assets/wf-editor-icons.js +2 -0
- package/packages/workflow-editor/src/constant.js +8 -0
- package/packages/workflow-editor/src/json-object-templates/copy-task.js +67 -0
- package/packages/workflow-editor/src/json-object-templates/decision.js +11 -0
- package/packages/workflow-editor/src/json-object-templates/end.js +14 -0
- package/packages/workflow-editor/src/json-object-templates/fork.js +10 -0
- package/packages/workflow-editor/src/json-object-templates/human-decision.js +9 -0
- package/packages/workflow-editor/src/json-object-templates/human-task.js +199 -0
- package/packages/workflow-editor/src/json-object-templates/join.js +10 -0
- package/packages/workflow-editor/src/json-object-templates/process.js +98 -0
- package/packages/workflow-editor/src/json-object-templates/start.js +13 -0
- package/packages/workflow-editor/src/json-object-templates/subprocess.js +30 -0
- package/packages/workflow-editor/src/json-object-templates/transition.js +26 -0
- package/packages/workflow-editor/src/main/admin-save-dialog.vue +66 -0
- package/packages/workflow-editor/src/main/canvas.vue +479 -0
- package/packages/workflow-editor/src/main/context-menu.vue +132 -0
- package/packages/workflow-editor/src/main/icon-svg.vue +32 -0
- package/packages/workflow-editor/src/main/selection-region.vue +66 -0
- package/packages/workflow-editor/src/main/tache-history-tooltip.vue +38 -0
- package/packages/workflow-editor/src/main/tache-name-input.vue +19 -0
- package/packages/workflow-editor/src/main/tache-subprocess-history-dialog.vue +35 -0
- package/packages/workflow-editor/src/main/toolbox.vue +60 -0
- package/packages/workflow-editor/src/main/wf-history-canvas.vue +302 -0
- package/packages/workflow-editor/src/process-json.js +622 -0
- package/packages/workflow-editor/src/process-service.js +31 -0
- package/packages/workflow-editor/src/properties-editors/common/additional-condition-utils.js +531 -0
- package/packages/workflow-editor/src/properties-editors/common/additional-condition.vue +276 -0
- package/packages/workflow-editor/src/properties-editors/common/auto-filled-fields-utils.js +34 -0
- package/packages/workflow-editor/src/properties-editors/common/auto-filled-fields.vue +239 -0
- package/packages/workflow-editor/src/properties-editors/common/common-notice-tool.vue +47 -0
- package/packages/workflow-editor/src/properties-editors/common/common-user-condition.vue +241 -0
- package/packages/workflow-editor/src/properties-editors/common/form-fields-utils.js +23 -0
- package/packages/workflow-editor/src/properties-editors/common/form-fields.vue +116 -0
- package/packages/workflow-editor/src/properties-editors/common/i18n-input.vue +75 -0
- package/packages/workflow-editor/src/properties-editors/common/i18n-set-dialog.vue +125 -0
- package/packages/workflow-editor/src/properties-editors/common/notice.vue +98 -0
- package/packages/workflow-editor/src/properties-editors/common/reminder.vue +179 -0
- package/packages/workflow-editor/src/properties-editors/common/select-mail-template.vue +83 -0
- package/packages/workflow-editor/src/properties-editors/common/standard-fields.vue +65 -0
- package/packages/workflow-editor/src/properties-editors/common/system-role-tree-inline.vue +355 -0
- package/packages/workflow-editor/src/properties-editors/common/system-role-tree.vue +63 -0
- package/packages/workflow-editor/src/properties-editors/common/task-title.vue +148 -0
- package/packages/workflow-editor/src/properties-editors/common/transactor-settings.vue +233 -0
- package/packages/workflow-editor/src/properties-editors/common/user-selection.vue +386 -0
- package/packages/workflow-editor/src/properties-editors/common/value-selection-dialog.vue +209 -0
- package/packages/workflow-editor/src/properties-editors/common/variables.vue +135 -0
- package/packages/workflow-editor/src/properties-editors/copy-task/basic-properties.vue +90 -0
- package/packages/workflow-editor/src/properties-editors/copy-task/permission-settings.vue +155 -0
- package/packages/workflow-editor/src/properties-editors/copy-task.vue +80 -0
- package/packages/workflow-editor/src/properties-editors/decision.vue +90 -0
- package/packages/workflow-editor/src/properties-editors/fork.vue +72 -0
- package/packages/workflow-editor/src/properties-editors/human-decision.vue +44 -0
- package/packages/workflow-editor/src/properties-editors/human-task/additional-condition-dialog.vue +60 -0
- package/packages/workflow-editor/src/properties-editors/human-task/basic-properties.vue +156 -0
- package/packages/workflow-editor/src/properties-editors/human-task/componentsConfigUtil.js +291 -0
- package/packages/workflow-editor/src/properties-editors/human-task/custom-actions.vue +249 -0
- package/packages/workflow-editor/src/properties-editors/human-task/editable-child-field-setting.vue +392 -0
- package/packages/workflow-editor/src/properties-editors/human-task/editable-child-fields.vue +241 -0
- package/packages/workflow-editor/src/properties-editors/human-task/editable-field-selection.vue +220 -0
- package/packages/workflow-editor/src/properties-editors/human-task/editable-fields.vue +204 -0
- package/packages/workflow-editor/src/properties-editors/human-task/events.vue +59 -0
- package/packages/workflow-editor/src/properties-editors/human-task/permission-settings.vue +207 -0
- package/packages/workflow-editor/src/properties-editors/human-task/selection-conditions.vue +390 -0
- package/packages/workflow-editor/src/properties-editors/human-task.vue +103 -0
- package/packages/workflow-editor/src/properties-editors/join.vue +44 -0
- package/packages/workflow-editor/src/properties-editors/process/basic-properties.vue +273 -0
- package/packages/workflow-editor/src/properties-editors/process/events.vue +76 -0
- package/packages/workflow-editor/src/properties-editors/process/notice-settings.vue +60 -0
- package/packages/workflow-editor/src/properties-editors/process/parameter-settings.vue +95 -0
- package/packages/workflow-editor/src/properties-editors/process/permission-settings.vue +28 -0
- package/packages/workflow-editor/src/properties-editors/process/selectPage.vue +81 -0
- package/packages/workflow-editor/src/properties-editors/process.vue +109 -0
- package/packages/workflow-editor/src/properties-editors/subprocess/basic-properties.vue +187 -0
- package/packages/workflow-editor/src/properties-editors/subprocess/events.vue +26 -0
- package/packages/workflow-editor/src/properties-editors/subprocess/field-mappings.vue +206 -0
- package/packages/workflow-editor/src/properties-editors/subprocess/transactor-settings.vue +64 -0
- package/packages/workflow-editor/src/properties-editors/subprocess.vue +79 -0
- package/packages/workflow-editor/src/properties-editors/transition/basic-properties.vue +53 -0
- package/packages/workflow-editor/src/properties-editors/transition.vue +74 -0
- package/packages/workflow-editor/src/properties-editors/user-condition.js +177 -0
- package/packages/workflow-editor/src/store/getters.js +27 -0
- package/packages/workflow-editor/src/store/workflow-editor.js +125 -0
- package/packages/workflow-editor/src/taches/common-methods.js +21 -0
- package/packages/workflow-editor/src/taches/copy-task.vue +99 -0
- package/packages/workflow-editor/src/taches/custom-task.vue +88 -0
- package/packages/workflow-editor/src/taches/decision.vue +102 -0
- package/packages/workflow-editor/src/taches/end.vue +76 -0
- package/packages/workflow-editor/src/taches/fork.vue +102 -0
- package/packages/workflow-editor/src/taches/human-decision.vue +102 -0
- package/packages/workflow-editor/src/taches/human-task.vue +113 -0
- package/packages/workflow-editor/src/taches/join.vue +91 -0
- package/packages/workflow-editor/src/taches/joint.vue +177 -0
- package/packages/workflow-editor/src/taches/start.vue +76 -0
- package/packages/workflow-editor/src/taches/subprocess.vue +99 -0
- package/packages/workflow-editor/src/taches/tache-resizer.vue +80 -0
- package/packages/workflow-editor/src/transitions/broken-line.vue +91 -0
- package/packages/workflow-editor/src/transitions/curve-line.vue +91 -0
- package/packages/workflow-editor/src/transitions/straight-line.vue +26 -0
- package/packages/workflow-editor/src/transitions/transition.vue +212 -0
- package/packages/workflow-editor/src/transitions/virtual-transition.vue +43 -0
- package/packages/workflow-editor/src/util.js +493 -0
- package/packages/workflow-editor/src/workflow-editor.vue +605 -0
- package/packages/workflow-editor/src/workflow-history.vue +153 -0
- package/.babelrc +0 -40
- package/build/components.json +0 -3
- package/build/gen-style.js +0 -32
- package/build/webpack.base.js +0 -173
- package/build/webpack.component.js +0 -46
- package/build/webpack.prod.js +0 -31
- package/lib/css/workflow-editor.css +0 -16
- package/lib/workflow-editor.js +0 -27
- package/lib/workflow-editor.min.js +0 -27
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "workflow-editor",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.87-dw",
|
|
4
4
|
"description": "流程编辑器",
|
|
5
|
-
"main": "lib/workflow-editor.min.js",
|
|
5
|
+
"main": "lib/workflow-editor.umd.min.js",
|
|
6
6
|
"private": false,
|
|
7
7
|
"scripts": {
|
|
8
8
|
"serve": "vue-cli-service serve",
|
|
@@ -10,11 +10,7 @@
|
|
|
10
10
|
"lib": "vue-cli-service build --modern --target lib --name workflow-editor --dest lib packages/index.js",
|
|
11
11
|
"lint": "vue-cli-service lint",
|
|
12
12
|
"test:e2e": "vue-cli-service test:e2e",
|
|
13
|
-
"test:unit": "vue-cli-service test:unit"
|
|
14
|
-
"build:style": "gulp --gulpfile build/gen-style.js",
|
|
15
|
-
"build:prod": "webpack --config build/webpack.prod.js",
|
|
16
|
-
"build:components": "webpack --config build/webpack.component.js",
|
|
17
|
-
"dist": "npm run build:prod && npm run build:components"
|
|
13
|
+
"test:unit": "vue-cli-service test:unit"
|
|
18
14
|
},
|
|
19
15
|
"dependencies": {
|
|
20
16
|
"babel-plugin-prismjs": "^1.0.2",
|
|
@@ -24,52 +20,29 @@
|
|
|
24
20
|
"xml-js": "^1.6.11"
|
|
25
21
|
},
|
|
26
22
|
"devDependencies": {
|
|
27
|
-
"@babel/core": "^7.5.5",
|
|
28
|
-
"@babel/plugin-transform-runtime": "^7.5.5",
|
|
29
|
-
"@babel/preset-env": "^7.5.5",
|
|
30
|
-
"@gcommon/gcommon-ui": "1.8.0",
|
|
31
23
|
"@vue/cli-plugin-babel": "3.8.0",
|
|
32
|
-
"@vue/
|
|
24
|
+
"@vue/cli-plugin-e2e-cypress": "3.8.0",
|
|
25
|
+
"@vue/cli-plugin-eslint": "3.8.0",
|
|
26
|
+
"@vue/cli-plugin-unit-mocha": "3.8.0",
|
|
27
|
+
"@vue/cli-service": "3.8.0",
|
|
28
|
+
"@vue/eslint-config-standard": "^4.0.0",
|
|
29
|
+
"@vue/test-utils": "^1.0.0-beta.29",
|
|
33
30
|
"axios": "0.19.0",
|
|
34
|
-
"babel-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"gulp-clean-css": "^4.2.0",
|
|
44
|
-
"gulp-rename": "^1.4.0",
|
|
45
|
-
"gulp-sass": "^4.0.2",
|
|
46
|
-
"imatrix-ui": "2.9.0-dw-tmp13",
|
|
47
|
-
"karma": "^4.2.0",
|
|
48
|
-
"karma-chai": "^0.1.0",
|
|
49
|
-
"karma-chrome-launcher": "^3.1.0",
|
|
50
|
-
"karma-coverage": "^2.0.1",
|
|
51
|
-
"karma-mocha": "^1.3.0",
|
|
52
|
-
"karma-sinon-chai": "^2.0.2",
|
|
53
|
-
"karma-sourcemap-loader": "^0.3.7",
|
|
54
|
-
"karma-spec-reporter": "^0.0.32",
|
|
55
|
-
"karma-webpack": "^4.0.2",
|
|
56
|
-
"less": "^3.10.2",
|
|
57
|
-
"less-loader": "^5.0.0",
|
|
58
|
-
"mocha": "^6.2.0",
|
|
59
|
-
"node-sass": "^4.12.0",
|
|
60
|
-
"rimraf": "^3.0.0",
|
|
61
|
-
"sass-loader": "^7.3.1",
|
|
31
|
+
"babel-eslint": "^10.0.1",
|
|
32
|
+
"chai": "4.2.0",
|
|
33
|
+
"element-ui": "2.15.3",
|
|
34
|
+
"eslint": "5.16.0",
|
|
35
|
+
"eslint-plugin-vue": "5.2.2",
|
|
36
|
+
"imatrix-ui": "2.9.8-dw",
|
|
37
|
+
"node-sass": "4.12.0",
|
|
38
|
+
"nprogress": "^0.2.0",
|
|
39
|
+
"sass-loader": "^7.1.0",
|
|
62
40
|
"sessionstorage": "^0.1.0",
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"style-loader": "^0.23.1",
|
|
66
|
-
"url-loader": "^2.1.0",
|
|
41
|
+
"vue": "^2.6.10",
|
|
42
|
+
"vue-cli-plugin-element": "^1.0.1",
|
|
67
43
|
"vue-i18n": "^8.17.4",
|
|
68
|
-
"vue-
|
|
69
|
-
"vue-
|
|
70
|
-
"
|
|
71
|
-
"vuex": "^3.1.1",
|
|
72
|
-
"webpack": "^4.39.2",
|
|
73
|
-
"webpack-cli": "^3.3.7"
|
|
44
|
+
"vue-router": "^3.0.6",
|
|
45
|
+
"vue-template-compiler": "^2.6.10",
|
|
46
|
+
"vuex": "^3.1.1"
|
|
74
47
|
}
|
|
75
48
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
// 依次导入组件库的各个组件
|
|
2
|
-
import workflow from '
|
|
2
|
+
import workflow from './workflow-editor'
|
|
3
3
|
import formValidator from './../packages/plugins/index'
|
|
4
|
-
|
|
4
|
+
const WorkflowEditor = workflow.WorkflowEditor
|
|
5
5
|
const WorkflowHistory = workflow.WorkflowHistory
|
|
6
6
|
const wfEditorStore = workflow.wfEditorStore
|
|
7
7
|
|
|
8
8
|
// 将所有组件都存储起来,方便后续统一注册
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const components = [
|
|
10
|
+
WorkflowEditor,
|
|
11
|
+
WorkflowHistory
|
|
12
|
+
]
|
|
13
13
|
|
|
14
14
|
// 定义 install 方法,接收 Vue 作为参数。如果使用 use 注册插件,则所有的组件都将被注册
|
|
15
15
|
const install = function(Vue) {
|
|
16
16
|
if (install.installed) return
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
components.forEach(component => {
|
|
18
|
+
Vue.component(component.name, component)
|
|
19
|
+
})
|
|
20
20
|
// components.map(component => Vue.component(component.name, component))
|
|
21
21
|
Vue.use(formValidator)
|
|
22
22
|
}
|
|
@@ -26,12 +26,9 @@ if (typeof window !== 'undefined' && window.Vue) {
|
|
|
26
26
|
install(window.Vue)
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export {
|
|
30
|
-
WorkflowHistory,
|
|
31
|
-
wfEditorStore
|
|
32
|
-
}
|
|
33
|
-
|
|
34
29
|
export default {
|
|
35
30
|
// 导出的对象必须具有 install,才能被 Vue.use() 方法安装
|
|
36
|
-
install
|
|
31
|
+
install,
|
|
32
|
+
WorkflowEditor,
|
|
33
|
+
wfEditorStore
|
|
37
34
|
}
|
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
import Validator from 'async-validator'
|
|
2
|
+
import {
|
|
3
|
+
getI18n
|
|
4
|
+
} from '../workflow-editor/src/util'
|
|
5
|
+
import {
|
|
6
|
+
parseSubTablePermissionCondition
|
|
7
|
+
} from 'imatrix-ui/src/utils/calculator/calculator-util'
|
|
8
|
+
function getLeafPropRule(editField, dataTypeMap) {
|
|
9
|
+
const rule = {}
|
|
10
|
+
const dataType = editField.dataType
|
|
11
|
+
if (dataType === 'DATE' || dataType === 'TIME') {
|
|
12
|
+
// 对象的值需要是毫秒值数字
|
|
13
|
+
if (editField.valueType && editField.valueType === 'number') {
|
|
14
|
+
// 表示值是毫秒值
|
|
15
|
+
rule.type = 'number'
|
|
16
|
+
}
|
|
17
|
+
rule.message = editField.label + ' ' + getI18n().t('workflowEditorMessage.requiredAndMustBeADate')
|
|
18
|
+
} else if (dataType === 'INTEGER' || dataType === 'LONG') {
|
|
19
|
+
rule.type = 'number'
|
|
20
|
+
rule.message = editField.label + ' ' + getI18n().t('workflowEditorMessage.requiredAndMustBeAnInteger')
|
|
21
|
+
} else if (dataType === 'FLOAT' || dataType === 'DOUBLE') {
|
|
22
|
+
rule.pattern = new RegExp('^(-?\\d+)(\\.\\d+)?$')
|
|
23
|
+
rule.message = editField.label + ' ' + getI18n().t('workflowEditorMessage.requiredAndMustBeDecimal')
|
|
24
|
+
} else if (dataType === 'BOOLEAN') {
|
|
25
|
+
rule.message = editField.label + ' ' + getI18n().t('workflowEditorMessage.mustFill')
|
|
26
|
+
} else {
|
|
27
|
+
rule.message = editField.label + ' ' + getI18n().t('workflowEditorMessage.mustFill')
|
|
28
|
+
}
|
|
29
|
+
if (editField.canEdit) {
|
|
30
|
+
rule.required = true
|
|
31
|
+
// 失去焦点时触发
|
|
32
|
+
rule.trigger = 'blur'
|
|
33
|
+
}
|
|
34
|
+
if (editField.rowIndexes) {
|
|
35
|
+
// 子表时受控制的行记录下标
|
|
36
|
+
rule.rowIndexes = editField.rowIndexes
|
|
37
|
+
}
|
|
38
|
+
if (editField.condition) {
|
|
39
|
+
// 必填条件
|
|
40
|
+
rule.condition = editField.condition
|
|
41
|
+
}
|
|
42
|
+
dataTypeMap[editField.name] = editField.dataType
|
|
43
|
+
return rule
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 获得对象验证规则
|
|
48
|
+
* @param {*} editField 字段信息
|
|
49
|
+
* @param {*} rules 验证规则
|
|
50
|
+
*/
|
|
51
|
+
function setObjectPropRule(editField, rules, isSql, dataTypeMap) {
|
|
52
|
+
const rule = {}
|
|
53
|
+
let prop = editField.name
|
|
54
|
+
if (isSql === true) {
|
|
55
|
+
prop = underscoreName(prop)
|
|
56
|
+
}
|
|
57
|
+
if (!rules) {
|
|
58
|
+
rules = {}
|
|
59
|
+
}
|
|
60
|
+
const props = prop.split('.')
|
|
61
|
+
for (let num = 0; num < props.length; num++) {
|
|
62
|
+
const subProp = props[num]
|
|
63
|
+
let objectRule
|
|
64
|
+
if (num === props.length - 1) {
|
|
65
|
+
// 说明是最后一个
|
|
66
|
+
objectRule = getEndObjectRule(rule, props, subProp)
|
|
67
|
+
objectRule.fields[subProp] = getLeafPropRule(editField, dataTypeMap)
|
|
68
|
+
} else {
|
|
69
|
+
let lastObjectRule
|
|
70
|
+
if (num === 0) {
|
|
71
|
+
objectRule = rules
|
|
72
|
+
} else {
|
|
73
|
+
lastObjectRule = getLastObjectRule(rule, props, props[num - 1])
|
|
74
|
+
objectRule = lastObjectRule.fields
|
|
75
|
+
}
|
|
76
|
+
if (!objectRule[subProp]) {
|
|
77
|
+
objectRule[subProp] = {
|
|
78
|
+
type: 'object',
|
|
79
|
+
required: true,
|
|
80
|
+
fields: {}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (num === 0) {
|
|
84
|
+
rule[subProp] = objectRule[subProp]
|
|
85
|
+
} else {
|
|
86
|
+
lastObjectRule.fields[subProp] = objectRule[subProp]
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function getLastObjectRule(rule, props, currentProp) {
|
|
93
|
+
let lastObjectdRule
|
|
94
|
+
for (let i = 0; i < props.length; i++) {
|
|
95
|
+
const subProp = props[i]
|
|
96
|
+
if (i === 0) {
|
|
97
|
+
lastObjectdRule = rule[subProp]
|
|
98
|
+
} else {
|
|
99
|
+
lastObjectdRule = lastObjectdRule.fields[props[i]]
|
|
100
|
+
}
|
|
101
|
+
if (subProp === currentProp) {
|
|
102
|
+
break
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return lastObjectdRule
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function getEndObjectRule(rule, props, currentProp) {
|
|
109
|
+
let lastObjectdRule
|
|
110
|
+
for (let i = 0; i < props.length; i++) {
|
|
111
|
+
if (i === 0) {
|
|
112
|
+
lastObjectdRule = rule[props[i]]
|
|
113
|
+
} else {
|
|
114
|
+
lastObjectdRule = lastObjectdRule.fields[props[i]]
|
|
115
|
+
}
|
|
116
|
+
if (i !== props.length - 1) {
|
|
117
|
+
const leafSubProp = props[i + 1]
|
|
118
|
+
if (leafSubProp === currentProp) {
|
|
119
|
+
break
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return lastObjectdRule
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* 获得主表及子表验证规则
|
|
128
|
+
* @param {editFieldInfos} editFieldInfos 编辑字段信息集合
|
|
129
|
+
* @param {entity} entity 当前表单数据model
|
|
130
|
+
* @param {isSql} isSql 是否是sql操作流程表单,如果是字段名需要修改为下划线命名规则
|
|
131
|
+
*/
|
|
132
|
+
function getValidator(editFieldInfos, entity, isSql, additionalParamMap, taskParamMap, contextParameter) {
|
|
133
|
+
// console.log('workflowEditor-getValidator-editFieldInfos=', editFieldInfos, 'entity=', entity, 'isSql', isSql)
|
|
134
|
+
if (typeof (isSql) === 'undefined') {
|
|
135
|
+
isSql = false
|
|
136
|
+
}
|
|
137
|
+
// 主表验证规则
|
|
138
|
+
const rules = {}
|
|
139
|
+
// 子表验证规则,格式为:
|
|
140
|
+
// {prop:
|
|
141
|
+
// {subField1:{required: true},
|
|
142
|
+
// subField2:{required: true}
|
|
143
|
+
// }
|
|
144
|
+
// }
|
|
145
|
+
// 子表整个表的权限
|
|
146
|
+
// {
|
|
147
|
+
// 子表表名1:{required:true/false(必填/禁止编辑),message:'xxx子表必需录入数据'},
|
|
148
|
+
// 子表表名2:{required:true/false(必填/禁止编辑),message:'xxx子表必需录入数据'}
|
|
149
|
+
// }
|
|
150
|
+
const dataTypeMap = {}
|
|
151
|
+
const totalSubRules = {}
|
|
152
|
+
const subRules = {}
|
|
153
|
+
if (editFieldInfos) {
|
|
154
|
+
editFieldInfos.forEach(editField => {
|
|
155
|
+
const canEdit = editField.canEdit
|
|
156
|
+
// 必填
|
|
157
|
+
if (typeof (canEdit) !== 'undefined' && canEdit === true) {
|
|
158
|
+
let prop = editField.name
|
|
159
|
+
if (prop) {
|
|
160
|
+
if (isSql === true) {
|
|
161
|
+
prop = underscoreName(prop)
|
|
162
|
+
}
|
|
163
|
+
const condition = editField.condition
|
|
164
|
+
const parentFormData = null
|
|
165
|
+
let result = null
|
|
166
|
+
if (prop.indexOf('.') > 0 && prop.indexOf('$') === 0) {
|
|
167
|
+
// 当是子表记录时候 result设置为true 获取行记录校验条件
|
|
168
|
+
result = true
|
|
169
|
+
} else {
|
|
170
|
+
result = parseSubTablePermissionCondition(condition, dataTypeMap, parentFormData, entity, additionalParamMap, taskParamMap, contextParameter)
|
|
171
|
+
}
|
|
172
|
+
if (result !== undefined && result !== null && result === true) {
|
|
173
|
+
let rule = {}
|
|
174
|
+
if (prop.indexOf('.') > 0) {
|
|
175
|
+
if (prop.indexOf('$') === 0) {
|
|
176
|
+
// 表示是子表字段
|
|
177
|
+
setSubObjectFieldRule(editField, subRules, entity, isSql, dataTypeMap)
|
|
178
|
+
} else {
|
|
179
|
+
// 表示是主表的关联属性字段。
|
|
180
|
+
setMainObjectFieldRule(editField, rules, entity, isSql, dataTypeMap)
|
|
181
|
+
}
|
|
182
|
+
} else if (prop.indexOf('$') === 0) {
|
|
183
|
+
// 表示是子表整个表的权限
|
|
184
|
+
// 获得子表表名
|
|
185
|
+
const subTable = prop.substring(prop.indexOf('$') + 1)
|
|
186
|
+
totalSubRules[subTable] = {
|
|
187
|
+
required: true,
|
|
188
|
+
message: getI18n().t('workflowEditorMessage.subTableMustInputDatas', {
|
|
189
|
+
subTable: editField.label
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
// 表示是主表的直接属性
|
|
194
|
+
rule = getLeafPropRule(editField, dataTypeMap)
|
|
195
|
+
rules[prop] = rule
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
// console.log('rules', rules, 'subRules=', subRules, 'totalSubRules=', totalSubRules)
|
|
203
|
+
const subRulesKeys = Object.keys(subRules)
|
|
204
|
+
if (subRulesKeys.length > 0 || Object.keys(totalSubRules).length > 0) {
|
|
205
|
+
// 表示有子表规则
|
|
206
|
+
return {
|
|
207
|
+
rules,
|
|
208
|
+
subRules,
|
|
209
|
+
totalSubRules,
|
|
210
|
+
dataTypeMap
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
// 表示只有主表规则
|
|
214
|
+
return rules
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* 设置主对象字段验证规则
|
|
220
|
+
*/
|
|
221
|
+
function setMainObjectFieldRule(editField, rules, entity, isSql, dataTypeMap) {
|
|
222
|
+
// 例如:a.b.c
|
|
223
|
+
let prop = editField.name
|
|
224
|
+
if (isSql === true) {
|
|
225
|
+
prop = underscoreName(prop)
|
|
226
|
+
}
|
|
227
|
+
// 获得a
|
|
228
|
+
const mainProp = prop.substring(0, prop.indexOf('.'))
|
|
229
|
+
if (entity) {
|
|
230
|
+
if (!entity[mainProp]) {
|
|
231
|
+
entity[mainProp] = {}
|
|
232
|
+
}
|
|
233
|
+
const mainEntity = entity[mainProp]
|
|
234
|
+
// 说明这个字段是该表单的字段,才需要添加验证
|
|
235
|
+
// 不是该表单的字段的情况,可能是被数据表删除的字段,但是没有修改流程图表单字段权限设置导致的
|
|
236
|
+
// 获得b.c
|
|
237
|
+
const mainSubProp = prop.substring(prop.indexOf('.') + 1)
|
|
238
|
+
if (isNeedValidate(mainSubProp, mainEntity)) {
|
|
239
|
+
// 需要验证该字段,表示是表单的字段
|
|
240
|
+
setObjectPropRule(editField, rules, isSql, dataTypeMap)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* 是否需要验证该属性,例如:b.c 或 a
|
|
247
|
+
* @param {*} mainSubProp 字段信息,例如:字段为:a.b.c,则mainSubProp应为b.c
|
|
248
|
+
* @param {*} mainEntity
|
|
249
|
+
*/
|
|
250
|
+
function isNeedValidate(mainSubProp, mainEntity) {
|
|
251
|
+
// 表示由可以必填
|
|
252
|
+
if (mainSubProp.indexOf('.') > 0) {
|
|
253
|
+
let parentObject = mainEntity
|
|
254
|
+
const subProps = mainSubProp.split('.')
|
|
255
|
+
for (let num = 0; num < subProps.length - 1; num++) {
|
|
256
|
+
const subProp = subProps[num]
|
|
257
|
+
if (!parentObject || !parentObject[subProp]) {
|
|
258
|
+
// 当前对象不存在,不是该表单的字段,不需要验证
|
|
259
|
+
return false
|
|
260
|
+
}
|
|
261
|
+
// 重新给"父对象"赋值,为下次循环准备
|
|
262
|
+
parentObject = parentObject[subProp]
|
|
263
|
+
}
|
|
264
|
+
return true
|
|
265
|
+
} else {
|
|
266
|
+
return true
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function setSubObjectFieldRule(editField, subRules, entity, isSql, dataTypeMap) {
|
|
271
|
+
let prop = editField.name
|
|
272
|
+
if (isSql === true) {
|
|
273
|
+
prop = underscoreName(prop)
|
|
274
|
+
}
|
|
275
|
+
// 获得主表字段名称
|
|
276
|
+
const mainProp = prop.substring(prop.indexOf('$') + 1, prop.indexOf('.'))
|
|
277
|
+
if (!entity) {
|
|
278
|
+
return
|
|
279
|
+
}
|
|
280
|
+
const tableData = entity[mainProp]
|
|
281
|
+
if (typeof (tableData) === 'undefined' || tableData === null || tableData.length === 0) {
|
|
282
|
+
// 表单中不存在该子表字段,不需要验证
|
|
283
|
+
return
|
|
284
|
+
}
|
|
285
|
+
// 获得子表字段名
|
|
286
|
+
const subProp = prop.substring(prop.indexOf('.') + 1)
|
|
287
|
+
// mainProp对应的所有子表字段验证规则信息
|
|
288
|
+
if (!subRules[mainProp]) {
|
|
289
|
+
subRules[mainProp] = {}
|
|
290
|
+
}
|
|
291
|
+
// 修改属性名为去掉$mainProp的字段名
|
|
292
|
+
// 此处要重新拷贝一份字段,否则会导致原字段的name信息被修改
|
|
293
|
+
const copyEditField = JSON.parse(JSON.stringify(editField))
|
|
294
|
+
copyEditField.name = subProp
|
|
295
|
+
if (subProp.indexOf('.') > 0) {
|
|
296
|
+
// 表示关联属性
|
|
297
|
+
const subEntity = tableData[0]
|
|
298
|
+
setMainObjectFieldRule(copyEditField, subRules[mainProp], subEntity, isSql, dataTypeMap)
|
|
299
|
+
} else {
|
|
300
|
+
// 表示是子表的直接属性
|
|
301
|
+
subRules[mainProp][subProp] = getLeafPropRule(copyEditField, dataTypeMap)
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function validator(entity, validateRules, rowIndex, isSql, pageNum, pageRowIndex) {
|
|
306
|
+
return validatorEntity(entity, validateRules, rowIndex, true, isSql, pageNum, pageRowIndex)
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
*
|
|
310
|
+
* @param {*} entity
|
|
311
|
+
* @param {*} validateRules
|
|
312
|
+
* @param {*} rowIndex
|
|
313
|
+
* @param {*} isShouldRepeateValdate 是否需要再次验证大写字段名
|
|
314
|
+
* @returns
|
|
315
|
+
*/
|
|
316
|
+
function validatorEntity(entity, validateRules, rowIndex, isShouldRepeateValdate, isSql, pageNum, pageRowIndex) {
|
|
317
|
+
let result = false
|
|
318
|
+
const validator = new Validator(validateRules)
|
|
319
|
+
|
|
320
|
+
validator.validate(entity, {
|
|
321
|
+
first: true
|
|
322
|
+
},
|
|
323
|
+
(errors, fields) => {
|
|
324
|
+
let fieldName
|
|
325
|
+
if (errors) {
|
|
326
|
+
const message = errors[0]['message']
|
|
327
|
+
fieldName = errors[0]['field']
|
|
328
|
+
if (typeof (rowIndex) !== 'undefined' && rowIndex !== null) {
|
|
329
|
+
// 表示是子表字段验证失败
|
|
330
|
+
if (pageNum !== undefined && pageRowIndex !== undefined) {
|
|
331
|
+
// 表示子表分页时的验证提示信息
|
|
332
|
+
result = getI18n().t('workflowEditorMessage.pageRecordLine', {
|
|
333
|
+
pageNum: pageNum,
|
|
334
|
+
row: pageRowIndex
|
|
335
|
+
}) + ',' + message
|
|
336
|
+
} else {
|
|
337
|
+
result = getI18n().t('workflowEditorMessage.recordLine', {
|
|
338
|
+
row: (rowIndex + 1)
|
|
339
|
+
}) + ',' + message
|
|
340
|
+
}
|
|
341
|
+
} else {
|
|
342
|
+
// 表示是主表字段验证失败
|
|
343
|
+
result = message
|
|
344
|
+
}
|
|
345
|
+
} else {
|
|
346
|
+
result = true
|
|
347
|
+
}
|
|
348
|
+
if (fieldName && isShouldRepeateValdate === true) {
|
|
349
|
+
// 将实体中字段名改为大写,然后再验证一次该字段是否已填值。因为mysql中jdbc获得实体记录字段名是小写的,但是验证规则中字段名是大写的,所以会导致字段验证失败
|
|
350
|
+
const reg1 = /[A-Z]+/ // 大写字母
|
|
351
|
+
if (isSql !== undefined && isSql === true && reg1.test(fieldName) && entity[fieldName.toLowerCase()] !== undefined) {
|
|
352
|
+
const copyEntity = JSON.parse(JSON.stringify(entity))
|
|
353
|
+
copyEntity[fieldName.toUpperCase()] = entity[fieldName.toLowerCase()]
|
|
354
|
+
delete copyEntity[fieldName.toLowerCase()]
|
|
355
|
+
result = validatorEntity(copyEntity, validateRules, rowIndex, false, isSql, pageNum, pageRowIndex)
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
return result
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* 验证子表必填验证
|
|
365
|
+
* @param {*}} entity
|
|
366
|
+
* @param {*} subRules
|
|
367
|
+
* @param {*} subTablePageInfo 列表分页信息{列表编码: 每页显示多少条记录}
|
|
368
|
+
*/
|
|
369
|
+
function validateSub(entity, subRules, totalSubRules, isSql, dataTypeMap, additionalParamMap, taskParamMap, contextParameter, subTablePageInfo) {
|
|
370
|
+
let copyTotalSubRules = {}
|
|
371
|
+
if (totalSubRules) {
|
|
372
|
+
copyTotalSubRules = JSON.parse(JSON.stringify(totalSubRules))
|
|
373
|
+
}
|
|
374
|
+
if (subRules) {
|
|
375
|
+
console.log('formValidator333--subRules=', subRules)
|
|
376
|
+
const subProps = Object.keys(subRules)
|
|
377
|
+
for (let i = 0; i < subProps.length; i++) {
|
|
378
|
+
const prop = subProps[i]
|
|
379
|
+
const subFieldRule = subRules[prop]
|
|
380
|
+
console.log('formValidator44--subFieldRule=', subFieldRule)
|
|
381
|
+
// 受控制的行下标集合
|
|
382
|
+
const subFieldProps = Object.keys(subFieldRule)
|
|
383
|
+
console.log('formValidator555--subFieldProps=', subFieldProps)
|
|
384
|
+
let subTableData = entity[prop]
|
|
385
|
+
if (!subTableData) {
|
|
386
|
+
// 如果子表集合数据不存在
|
|
387
|
+
subTableData = []
|
|
388
|
+
}
|
|
389
|
+
// 验证整个子表是否已填记录,如果是必填,但是没有子记录集合,则提示
|
|
390
|
+
const validateResult = validateTotalSubTable(copyTotalSubRules, entity, prop)
|
|
391
|
+
if (validateResult !== true) {
|
|
392
|
+
delete copyTotalSubRules[prop]
|
|
393
|
+
return validateResult
|
|
394
|
+
}
|
|
395
|
+
let pageSize
|
|
396
|
+
if (subTablePageInfo && subTablePageInfo[prop]) {
|
|
397
|
+
pageSize = subTablePageInfo[prop].pageSize
|
|
398
|
+
}
|
|
399
|
+
for (let j = 0; j < subTableData.length; j++) {
|
|
400
|
+
const rowData = subTableData[j]
|
|
401
|
+
const rowRule = packageRowRule(subFieldProps, subFieldRule, subTableData[j], dataTypeMap, entity, additionalParamMap, taskParamMap, contextParameter)
|
|
402
|
+
console.log('formValidator666--rowRule=', rowRule)
|
|
403
|
+
let pageNum
|
|
404
|
+
// 每页的记录下标,提示时使用
|
|
405
|
+
let pageRowIndex
|
|
406
|
+
if (pageSize !== undefined && pageSize > 0) {
|
|
407
|
+
pageNum = Math.ceil((j + 1) / pageSize)
|
|
408
|
+
pageRowIndex = (j + 1) - ((pageNum - 1) * pageSize)
|
|
409
|
+
}
|
|
410
|
+
const validateResult = validator(rowData, rowRule, j, isSql, pageNum, pageRowIndex)
|
|
411
|
+
if (validateResult !== true) {
|
|
412
|
+
// 表示验证失败,无需继续验证
|
|
413
|
+
return validateResult
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
for (const subTableName in copyTotalSubRules) {
|
|
420
|
+
const validateResult = validateTotalSubTable(copyTotalSubRules, entity, subTableName)
|
|
421
|
+
if (validateResult !== true) {
|
|
422
|
+
return validateResult
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return true
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function getEntityId(row) {
|
|
429
|
+
if (row && row.id) {
|
|
430
|
+
return row.id
|
|
431
|
+
} else if (row && row.ID) {
|
|
432
|
+
return row.ID
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* 封装行记录的验证规则
|
|
438
|
+
* @param {*}} subProps
|
|
439
|
+
* @param {*} subFieldRule
|
|
440
|
+
* @param {*} rowIndex
|
|
441
|
+
* @returns
|
|
442
|
+
*/
|
|
443
|
+
function packageRowRule(subProps, subFieldRule, row, dataTypeMap, parentFormData, additionalParamMap, taskParamMap, contextParameter) {
|
|
444
|
+
const rowId = getEntityId(row)
|
|
445
|
+
const rowRule = {}
|
|
446
|
+
for (let n = 0; n < subProps.length; n++) {
|
|
447
|
+
const field = subProps[n]
|
|
448
|
+
const fieldRule = subFieldRule[field]
|
|
449
|
+
const condition = fieldRule.condition
|
|
450
|
+
const result = parseSubTablePermissionCondition(condition, dataTypeMap, parentFormData, row, additionalParamMap, taskParamMap, contextParameter)
|
|
451
|
+
if (result !== undefined && result !== null && result === true) {
|
|
452
|
+
// 表示由可以必填
|
|
453
|
+
if (rowId === undefined) {
|
|
454
|
+
// 表示是新建的记录,需要验证
|
|
455
|
+
rowRule[field] = fieldRule
|
|
456
|
+
} else {
|
|
457
|
+
// 表示是已保存的记录,验证id是否在可修改的集合内
|
|
458
|
+
const rowIndexes = fieldRule.rowIndexes
|
|
459
|
+
if (!rowIndexes || rowIndexes.indexOf(rowId) >= 0) {
|
|
460
|
+
// 表示该行记录的该字段需要做必填验证
|
|
461
|
+
rowRule[field] = fieldRule
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return rowRule
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// 验证整个子表是否已填记录
|
|
470
|
+
function validateTotalSubTable(totalSubRules, entity, subTableName) {
|
|
471
|
+
let subTableData = entity[subTableName]
|
|
472
|
+
if (!subTableData) {
|
|
473
|
+
// 如果子表集合数据不存在
|
|
474
|
+
subTableData = []
|
|
475
|
+
}
|
|
476
|
+
if (subTableData.length === 0 && totalSubRules && totalSubRules[subTableName] &&
|
|
477
|
+
totalSubRules[subTableName].required !== undefined && totalSubRules[subTableName].required === true) {
|
|
478
|
+
return totalSubRules[subTableName].message
|
|
479
|
+
}
|
|
480
|
+
return true
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
function formValidator(entity, validateRules, isSql, additionalParamMap, taskParamMap, contextParameter, subTablePageInfo) {
|
|
484
|
+
const validateRulesKeys = Object.keys(validateRules)
|
|
485
|
+
if (validateRulesKeys.indexOf('rules') >= 0 &&
|
|
486
|
+
validateRulesKeys.indexOf('subRules') >= 0 &&
|
|
487
|
+
validateRulesKeys.indexOf('totalSubRules') >= 0) {
|
|
488
|
+
// 表示是带有子表验证规则的
|
|
489
|
+
const rules = validateRules.rules
|
|
490
|
+
const subRules = validateRules.subRules
|
|
491
|
+
const totalSubRules = validateRules.totalSubRules
|
|
492
|
+
const dataTypeMap = validateRules.dataTypeMap
|
|
493
|
+
let validateResult = validator(entity, rules, null, isSql)
|
|
494
|
+
if (validateResult === true) {
|
|
495
|
+
if (subRules || totalSubRules) {
|
|
496
|
+
validateResult = validateSub(entity, subRules, totalSubRules, isSql, dataTypeMap, additionalParamMap, taskParamMap, contextParameter, subTablePageInfo)
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return validateResult
|
|
500
|
+
} else {
|
|
501
|
+
// 表示没有子表验证规则
|
|
502
|
+
return validator(entity, validateRules, null, isSql)
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// 驼峰命名改为下划线命名,例如:helloWord->hello_world
|
|
507
|
+
function underscoreName(name) {
|
|
508
|
+
// if (name.indexOf('_') > 0) {
|
|
509
|
+
// 如果包括下划线,表示是下划线命名,需要再转换
|
|
510
|
+
return name
|
|
511
|
+
// }
|
|
512
|
+
// return name.replace(/([A-Z])/g, '_$1').toLowerCase()
|
|
513
|
+
}
|
|
514
|
+
// 下划线命名改为驼峰命名,例如:hello_word->helloWorld
|
|
515
|
+
// function camelName(name) {
|
|
516
|
+
// if (name.indexOf('_') < 0) {
|
|
517
|
+
// // 如果不包括下划线不需要转换
|
|
518
|
+
// return name
|
|
519
|
+
// }
|
|
520
|
+
// return name.replace(/_(\w)/g, function(all, letter) {
|
|
521
|
+
// return letter.toUpperCase()
|
|
522
|
+
// })
|
|
523
|
+
// }
|
|
524
|
+
|
|
525
|
+
export default {
|
|
526
|
+
formValidator,
|
|
527
|
+
getValidator
|
|
528
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import WorkflowEditor from './src/workflow-editor'
|
|
2
|
+
import wfEditorStore from './src/store/workflow-editor'
|
|
3
|
+
import WorkflowHistory from './src/workflow-history'
|
|
4
|
+
|
|
5
|
+
WorkflowEditor.install = function(Vue) {
|
|
6
|
+
Vue.component(WorkflowEditor.name, WorkflowEditor)
|
|
7
|
+
Vue.component(WorkflowHistory.name, WorkflowHistory)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
WorkflowEditor,
|
|
12
|
+
WorkflowHistory,
|
|
13
|
+
wfEditorStore
|
|
14
|
+
}
|