cloud-web-corejs 1.1.0-dev.20 → 1.1.0-dev.22
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/package.json +1 -1
- package/src/components/excelExport/conditionExportConfig.js +112 -0
- package/src/components/excelExport/exportType.js +8 -0
- package/src/components/excelExport/index.vue +7 -1
- package/src/components/excelExport/mixins.js +410 -259
- package/src/components/xform/form-designer/designer.js +0 -15
- package/src/components/xform/form-designer/form-widget/field-widget/fieldMixin.js +2 -2
- package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +2 -1
- package/src/components/xform/form-designer/form-widget/field-widget/table-export-button-widget.vue +2 -1
- package/src/components/xform/form-designer/setting-panel/form-dynamicField-setting.vue +163 -136
- package/src/components/xform/form-designer/setting-panel/form-setting.vue +74 -9
- package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/empty-number-input.vue +51 -0
- package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-item-button-editor.vue +27 -2
- package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/table-export-button-editor.vue +33 -3
- package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +6 -0
- package/src/components/xform/form-render/container-item/data-table-mixin.js +6 -6
- package/src/components/xform/form-render/container-item/dynamicFieldMixin.js +4 -4
- package/src/components/xform/form-render/container-item/tab-item.vue +1 -1
- package/src/components/xform/form-render/fieldControlEngine.js +18 -0
- package/src/components/xform/form-render/fieldControlMixin.js +39 -29
- package/src/components/xform/form-render/index.vue +7 -4
- package/src/components/xform/form-render/indexMixin.js +26 -15
- package/src/components/xform/utils/util.js +0 -1
- package/src/views/user/home/default.vue +6 -3
- package/src/views/user/home/wjl/content.vue +3 -2
- package/src/components/xform/form-render/container-item/dynamicFieldEngine.js +0 -285
- package/src/components/xform/form-render/formDynamicFieldMixin.js +0 -133
|
@@ -106,7 +106,6 @@ let chartContainers = [],
|
|
|
106
106
|
globalConfig: null,
|
|
107
107
|
// 表单级动态字段规则
|
|
108
108
|
dynamicFieldEnabled: false,
|
|
109
|
-
dynamicFieldRuleVersion: 2,
|
|
110
109
|
dynamicFieldRunMode: "auto",
|
|
111
110
|
dynamicFieldAllowValue: false,
|
|
112
111
|
dynamicFieldSourceType: "local",
|
|
@@ -282,13 +281,6 @@ let chartContainers = [],
|
|
|
282
281
|
modifiedFlag = true;
|
|
283
282
|
}
|
|
284
283
|
if (!!formJson && !!formJson.formConfig) {
|
|
285
|
-
// 旧模板缺少版本时不能继承新建模板的 V2 默认值。
|
|
286
|
-
this.vueInstance.$set(this.formConfig, "dynamicFieldRuleVersion",
|
|
287
|
-
formJson.formConfig.dynamicFieldRuleVersion || 1);
|
|
288
|
-
this.vueInstance.$set(this.formConfig, "dynamicFieldRunMode",
|
|
289
|
-
formJson.formConfig.dynamicFieldRunMode || "auto");
|
|
290
|
-
this.vueInstance.$set(this.formConfig, "dynamicFieldAllowValue",
|
|
291
|
-
!!formJson.formConfig.dynamicFieldAllowValue);
|
|
292
284
|
//this.formConfig = importObj.formConfig
|
|
293
285
|
baseRefUtil.overwriteObj(
|
|
294
286
|
this.formConfig,
|
|
@@ -1970,13 +1962,6 @@ let chartContainers = [],
|
|
|
1970
1962
|
"form__config__backup"
|
|
1971
1963
|
);
|
|
1972
1964
|
if (!!formConfigBackup) {
|
|
1973
|
-
const restoredConfig = JSON.parse(formConfigBackup);
|
|
1974
|
-
this.vueInstance.$set(this.formConfig, "dynamicFieldRuleVersion",
|
|
1975
|
-
restoredConfig.dynamicFieldRuleVersion || 1);
|
|
1976
|
-
this.vueInstance.$set(this.formConfig, "dynamicFieldRunMode",
|
|
1977
|
-
restoredConfig.dynamicFieldRunMode || "auto");
|
|
1978
|
-
this.vueInstance.$set(this.formConfig, "dynamicFieldAllowValue",
|
|
1979
|
-
!!restoredConfig.dynamicFieldAllowValue);
|
|
1980
1965
|
//this.formConfig = JSON.parse(formConfigBackup)
|
|
1981
1966
|
baseRefUtil.overwriteObj(
|
|
1982
1967
|
this.formConfig,
|
|
@@ -120,7 +120,7 @@ modules = {
|
|
|
120
120
|
},
|
|
121
121
|
mounted() {
|
|
122
122
|
const formRef = this.getFormRef && this.getFormRef();
|
|
123
|
-
if (formRef && formRef.
|
|
123
|
+
if (formRef && formRef.isFieldControlEnabled()) {
|
|
124
124
|
this.initFieldAttrs();
|
|
125
125
|
formRef.syncFieldControlValidation();
|
|
126
126
|
}
|
|
@@ -1047,7 +1047,7 @@ modules = {
|
|
|
1047
1047
|
},
|
|
1048
1048
|
buildFieldRules() {
|
|
1049
1049
|
const formRef = this.getFormRef && this.getFormRef();
|
|
1050
|
-
if (formRef && formRef.
|
|
1050
|
+
if (formRef && formRef.isFieldControlEnabled() &&
|
|
1051
1051
|
!formRef.isFieldControlFieldVisible(this.field)) {
|
|
1052
1052
|
this.clearFieldRules();
|
|
1053
1053
|
return;
|
|
@@ -44,6 +44,7 @@ import i18n from "../../../utils/i18n";
|
|
|
44
44
|
import fieldMixin from "./fieldMixin";
|
|
45
45
|
import StaticContentWrapper from "./static-content-wrapper.vue";
|
|
46
46
|
import { EXPORT_TYPE } from "../../../../excelExport/exportType";
|
|
47
|
+
import { pickConditionExportOverrides } from "@base/components/excelExport/conditionExportConfig";
|
|
47
48
|
|
|
48
49
|
export default {
|
|
49
50
|
name: "select-export-item-button-widget",
|
|
@@ -101,8 +102,8 @@ export default {
|
|
|
101
102
|
let opt = {
|
|
102
103
|
title: this.field.options.exportFileName || null,
|
|
103
104
|
targetRef: this.field.options.tableRef || null,
|
|
104
|
-
pageSize: this.field.options.exportPageSize || null,
|
|
105
105
|
showImageAtTable: this.field.options.showImageAtTable || null,
|
|
106
|
+
...pickConditionExportOverrides(this.field.options),
|
|
106
107
|
// 明细导出的列 / 脚本编码 / 取数参数三项各自独立:按钮上维护了哪项就以哪项为准,
|
|
107
108
|
// 留空的那项沿用数据表格属性上那套。参数脚本原样下发,由数据表格求值(this 是
|
|
108
109
|
// 表格组件,与配在表格属性上时同义)
|
package/src/components/xform/form-designer/form-widget/field-widget/table-export-button-widget.vue
CHANGED
|
@@ -32,6 +32,7 @@ import emitter from "../../../../../components/xform/utils/emitter";
|
|
|
32
32
|
import i18n from "../../../../../components/xform/utils/i18n";
|
|
33
33
|
import fieldMixin from "../../../../../components/xform/form-designer/form-widget/field-widget/fieldMixin";
|
|
34
34
|
import StaticContentWrapper from "../../../../../components/xform/form-designer/form-widget/field-widget/static-content-wrapper.vue";
|
|
35
|
+
import { pickConditionExportOverrides } from "@base/components/excelExport/conditionExportConfig";
|
|
35
36
|
|
|
36
37
|
export default {
|
|
37
38
|
name: "table-export-button-widget",
|
|
@@ -81,8 +82,8 @@ export default {
|
|
|
81
82
|
let opt = {
|
|
82
83
|
title: this.field.options.exportFileName || null,
|
|
83
84
|
targetRef: this.field.options.tableRef || null,
|
|
84
|
-
pageSize: this.field.options.exportPageSize || null,
|
|
85
85
|
showImageAtTable: this.field.options.showImageAtTable || null,
|
|
86
|
+
...pickConditionExportOverrides(this.field.options),
|
|
86
87
|
};
|
|
87
88
|
let tableExportParam = this.handleCustomEvent(this.field.options.tableExportParam);
|
|
88
89
|
let options = { ...opt, ...tableExportParam, type: type };
|
|
@@ -2,123 +2,48 @@
|
|
|
2
2
|
<div class="form-dynamic-field-setting">
|
|
3
3
|
<el-form-item label="启用动态字段">
|
|
4
4
|
<el-switch v-model="formConfig.dynamicFieldEnabled"></el-switch>
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
</
|
|
5
|
+
<el-tooltip content="根据表单数据动态控制字段、容器的显隐、必填、只读和禁用状态。" placement="left" popper-class="xform-setting-help">
|
|
6
|
+
<i class="el-icon-info setting-help-icon" tabindex="0" aria-label="动态字段说明"></i>
|
|
7
|
+
</el-tooltip>
|
|
8
8
|
</el-form-item>
|
|
9
9
|
|
|
10
10
|
<template v-if="formConfig.dynamicFieldEnabled">
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<el-option label="
|
|
11
|
+
<div v-if="fieldControlTreeState.error" class="tip-text tree-options-error">{{ fieldControlTreeState.error }}</div>
|
|
12
|
+
<el-form-item label="执行方式">
|
|
13
|
+
<el-select :value="formConfig.dynamicFieldRunMode || 'auto'" size="mini"
|
|
14
|
+
@input="$set(formConfig, 'dynamicFieldRunMode', $event)">
|
|
15
|
+
<el-option label="按场景默认" value="auto" />
|
|
16
|
+
<el-option label="仅初始化" value="initialOnly" />
|
|
17
|
+
<el-option label="持续生效" value="continuous" />
|
|
16
18
|
</el-select>
|
|
19
|
+
<el-tooltip content="默认:有流程仅初始化,无流程持续联动。仅初始化保留首次结果;持续模式每轮均由流程规则收尾。" placement="left" popper-class="xform-setting-help">
|
|
20
|
+
<i class="el-icon-info setting-help-icon" tabindex="0" aria-label="执行方式说明"></i>
|
|
21
|
+
</el-tooltip>
|
|
17
22
|
</el-form-item>
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
</el-form-item>
|
|
29
|
-
<el-form-item label="允许自动赋值" v-if="formConfig.dynamicFieldSourceType === 'script'">
|
|
30
|
-
<el-switch :value="!!formConfig.dynamicFieldAllowValue"
|
|
31
|
-
@input="$set(formConfig, 'dynamicFieldAllowValue', $event)" />
|
|
32
|
-
<div class="tip-text">开启前需确认后台 value 覆盖条件;规则未返回 value 时保留用户输入。</div>
|
|
33
|
-
</el-form-item>
|
|
34
|
-
</template>
|
|
35
|
-
<div v-else class="tip-text">历史模板保持原执行顺序。迁移前请核对流程放开、持续联动与后台状态快照。</div>
|
|
36
|
-
<el-form-item label="数据来源" class="form-item-label-top">
|
|
37
|
-
<el-radio-group v-model="formConfig.dynamicFieldSourceType" size="mini">
|
|
38
|
-
<el-radio-button label="local">本地规则</el-radio-button>
|
|
39
|
-
<el-radio-button label="script">后台脚本</el-radio-button>
|
|
40
|
-
</el-radio-group>
|
|
23
|
+
<el-form-item label="字段规则" class="el-form-item-second">
|
|
24
|
+
<el-button
|
|
25
|
+
type="primary"
|
|
26
|
+
plain
|
|
27
|
+
size="mini"
|
|
28
|
+
icon="el-icon-setting"
|
|
29
|
+
@click="openRuleDialog"
|
|
30
|
+
>
|
|
31
|
+
配置规则({{ (formConfig.dynamicFieldRules || []).length }})
|
|
32
|
+
</el-button>
|
|
41
33
|
</el-form-item>
|
|
42
|
-
|
|
43
|
-
<template v-if="formConfig.dynamicFieldSourceType === 'local'">
|
|
44
|
-
<el-form-item label="字段规则" class="el-form-item-second">
|
|
45
|
-
<el-button
|
|
46
|
-
type="primary"
|
|
47
|
-
plain
|
|
48
|
-
size="mini"
|
|
49
|
-
icon="el-icon-setting"
|
|
50
|
-
@click="openRuleDialog"
|
|
51
|
-
>
|
|
52
|
-
配置规则({{ (formConfig.dynamicFieldRules || []).length }})
|
|
53
|
-
</el-button>
|
|
54
|
-
</el-form-item>
|
|
55
|
-
</template>
|
|
56
|
-
|
|
57
|
-
<template v-if="formConfig.dynamicFieldSourceType === 'script'">
|
|
58
|
-
<el-form-item class="form-item-label-top el-form-item-second" label="脚本编码">
|
|
59
|
-
<el-input
|
|
60
|
-
v-model="formConfig.dynamicFieldScriptCode"
|
|
61
|
-
size="mini"
|
|
62
|
-
placeholder="scriptCode 或 formCode/scriptCode"
|
|
63
|
-
></el-input>
|
|
64
|
-
</el-form-item>
|
|
65
|
-
<el-form-item label="额外参数" class="el-form-item-second">
|
|
66
|
-
<a
|
|
67
|
-
href="javascript:void(0);"
|
|
68
|
-
class="a-link link-oneLind"
|
|
69
|
-
@click="editDynamicFieldScriptParam"
|
|
70
|
-
>
|
|
71
|
-
<span>{{ formConfig.dynamicFieldScriptParam }}</span>
|
|
72
|
-
<i class="el-icon-edit"></i>
|
|
73
|
-
</a>
|
|
74
|
-
<div class="tip-text">
|
|
75
|
-
格式: return { stage:
|
|
76
|
-
this.formModel.status }
|
|
77
|
-
</div>
|
|
78
|
-
</el-form-item>
|
|
79
|
-
<el-form-item class="form-item-label-top el-form-item-second" label="触发字段">
|
|
80
|
-
<el-select
|
|
81
|
-
v-model="formConfig.dynamicFieldTriggerFields"
|
|
82
|
-
multiple
|
|
83
|
-
filterable
|
|
84
|
-
size="mini"
|
|
85
|
-
style="width: 100%"
|
|
86
|
-
placeholder="字段值变化时重新请求后台"
|
|
87
|
-
>
|
|
88
|
-
<el-option
|
|
89
|
-
v-for="(n, idx) in treeOptions"
|
|
90
|
-
:key="n.value + '#' + idx"
|
|
91
|
-
:value="n.value"
|
|
92
|
-
:label="optPlainLabel(n)"
|
|
93
|
-
:disabled="n.isContainer"
|
|
94
|
-
>
|
|
95
|
-
<span
|
|
96
|
-
:style="{ paddingLeft: n.depth * 14 + 'px' }"
|
|
97
|
-
:class="{ 'opt-container': n.isContainer }"
|
|
98
|
-
>
|
|
99
|
-
<span v-if="n.isContainer" class="opt-tag"
|
|
100
|
-
>[{{ containerTypeLabel(n.type) }}]</span
|
|
101
|
-
>{{ n.baseLabel }}
|
|
102
|
-
</span>
|
|
103
|
-
</el-option>
|
|
104
|
-
</el-select>
|
|
105
|
-
<div class="tip-text">未配置数据触发字段时,编辑数据不会自动请求;新版持续模式在流程上下文刷新时仍会重算。</div>
|
|
106
|
-
</el-form-item>
|
|
107
|
-
<div class="tip-text">
|
|
108
|
-
后台返回 fieldStates 的 key
|
|
109
|
-
可为字段名,也可为「命名容器」名以控制其显隐(容器仅 visible 生效)
|
|
110
|
-
</div>
|
|
111
|
-
</template>
|
|
112
34
|
</template>
|
|
113
35
|
|
|
114
36
|
<el-dialog
|
|
115
37
|
title="表单动态字段规则"
|
|
116
38
|
:visible.sync="ruleDialogVisible"
|
|
117
39
|
:append-to-body="true"
|
|
118
|
-
width="
|
|
40
|
+
width="880px"
|
|
41
|
+
top="6vh"
|
|
119
42
|
custom-class="dynamic-field-rule-dialog"
|
|
120
43
|
>
|
|
44
|
+
<div class="rule-dialog-summary">配置触发条件与字段状态,规则按排列顺序执行。</div>
|
|
121
45
|
<div class="rule-list">
|
|
46
|
+
<div v-if="!editingRules.length" class="rule-empty">暂无规则,点击下方「添加规则」开始配置</div>
|
|
122
47
|
<div
|
|
123
48
|
v-for="(rule, rIdx) in editingRules"
|
|
124
49
|
:key="rule.id"
|
|
@@ -147,13 +72,13 @@
|
|
|
147
72
|
<div
|
|
148
73
|
v-for="(cond, cIdx) in rule.conditions"
|
|
149
74
|
:key="cIdx"
|
|
150
|
-
class="rule-row"
|
|
75
|
+
class="rule-row condition-row"
|
|
151
76
|
>
|
|
152
77
|
<el-select
|
|
153
78
|
v-model="cond.field"
|
|
154
79
|
filterable
|
|
155
80
|
size="mini"
|
|
156
|
-
placeholder="
|
|
81
|
+
placeholder="选择条件字段"
|
|
157
82
|
class="cell-field"
|
|
158
83
|
>
|
|
159
84
|
<el-option
|
|
@@ -189,14 +114,15 @@
|
|
|
189
114
|
<el-input
|
|
190
115
|
v-model="cond.value"
|
|
191
116
|
size="mini"
|
|
192
|
-
placeholder="
|
|
117
|
+
placeholder="输入比较值"
|
|
193
118
|
class="cell-value"
|
|
194
119
|
:disabled="op_noValue(cond.operator)"
|
|
195
120
|
></el-input>
|
|
196
121
|
<el-button
|
|
197
122
|
type="text"
|
|
198
123
|
icon="el-icon-remove-outline"
|
|
199
|
-
class="danger-text"
|
|
124
|
+
class="danger-text row-remove"
|
|
125
|
+
aria-label="删除条件"
|
|
200
126
|
@click="removeCondition(rule, cIdx)"
|
|
201
127
|
></el-button>
|
|
202
128
|
</div>
|
|
@@ -294,7 +220,8 @@
|
|
|
294
220
|
<el-button
|
|
295
221
|
type="text"
|
|
296
222
|
icon="el-icon-remove-outline"
|
|
297
|
-
class="danger-text"
|
|
223
|
+
class="danger-text row-remove"
|
|
224
|
+
aria-label="删除目标字段"
|
|
298
225
|
@click="removeTarget(rule, tIdx)"
|
|
299
226
|
></el-button>
|
|
300
227
|
</div>
|
|
@@ -319,7 +246,8 @@
|
|
|
319
246
|
</el-button>
|
|
320
247
|
</div>
|
|
321
248
|
|
|
322
|
-
<div slot="footer">
|
|
249
|
+
<div slot="footer" class="rule-dialog-footer">
|
|
250
|
+
<span class="rule-count">共 {{ editingRules.length }} 条规则</span>
|
|
323
251
|
<el-button size="mini" @click="ruleDialogVisible = false"
|
|
324
252
|
>取消</el-button
|
|
325
253
|
>
|
|
@@ -372,9 +300,8 @@
|
|
|
372
300
|
</template>
|
|
373
301
|
|
|
374
302
|
<script>
|
|
375
|
-
import { fieldControlTreeOptions,
|
|
303
|
+
import { fieldControlTreeOptions, commitLocalFieldRules } from "@base/components/xform/form-render/fieldControlEngine";
|
|
376
304
|
import i18n from "../../../../components/xform/utils/i18n";
|
|
377
|
-
import { buildWidgetTreeOptions } from "../../../../components/xform/form-render/container-item/dynamicFieldEngine";
|
|
378
305
|
|
|
379
306
|
const NO_VALUE_OPERATORS = ["empty", "notEmpty"];
|
|
380
307
|
|
|
@@ -409,9 +336,6 @@ export default {
|
|
|
409
336
|
computed: {
|
|
410
337
|
fieldControlTreeState() {
|
|
411
338
|
const list = (this.designer && this.designer.widgetList) || [];
|
|
412
|
-
if (this.formConfig.dynamicFieldRuleVersion !== 2) {
|
|
413
|
-
return { options: buildWidgetTreeOptions(list), error: "" };
|
|
414
|
-
}
|
|
415
339
|
try {
|
|
416
340
|
return { options: fieldControlTreeOptions(list), error: "" };
|
|
417
341
|
} catch (error) {
|
|
@@ -531,29 +455,11 @@ export default {
|
|
|
531
455
|
rule.targets.splice(idx, 1);
|
|
532
456
|
},
|
|
533
457
|
saveRules() {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
const normalized = normalizeLocalRules(this.editingRules);
|
|
540
|
-
normalized.forEach(rule => {
|
|
541
|
-
rule.conditions.forEach(condition => {
|
|
542
|
-
if (!fields.has(condition.field)) throw new Error("条件字段不存在或不支持:" + condition.field);
|
|
543
|
-
});
|
|
544
|
-
rule.targets.forEach(target => {
|
|
545
|
-
if (!targets.has(target.field)) throw new Error("目标不存在或不支持:" + target.field);
|
|
546
|
-
});
|
|
547
|
-
});
|
|
548
|
-
this.formConfig.dynamicFieldRules = normalized;
|
|
549
|
-
this.ruleDialogVisible = false;
|
|
550
|
-
} catch (error) { this.$message.error(error.message); }
|
|
551
|
-
return;
|
|
552
|
-
}
|
|
553
|
-
this.formConfig.dynamicFieldRules = JSON.parse(
|
|
554
|
-
JSON.stringify(this.editingRules)
|
|
555
|
-
);
|
|
556
|
-
this.ruleDialogVisible = false;
|
|
458
|
+
try {
|
|
459
|
+
this.formConfig.dynamicFieldRules = commitLocalFieldRules(
|
|
460
|
+
this.editingRules, this.designer?.widgetList || []);
|
|
461
|
+
this.ruleDialogVisible = false;
|
|
462
|
+
} catch (error) { this.$message.error(error.message); }
|
|
557
463
|
},
|
|
558
464
|
},
|
|
559
465
|
};
|
|
@@ -658,3 +564,124 @@ export default {
|
|
|
658
564
|
margin-right: 4px;
|
|
659
565
|
}
|
|
660
566
|
</style>
|
|
567
|
+
|
|
568
|
+
<!-- 弹框挂载到 body,以独立类名隔离样式,并覆盖设置面板的控件宽度。 -->
|
|
569
|
+
<style lang="scss">
|
|
570
|
+
.el-dialog.dynamic-field-rule-dialog {
|
|
571
|
+
display: flex;
|
|
572
|
+
flex-direction: column;
|
|
573
|
+
max-width: calc(100vw - 32px);
|
|
574
|
+
max-height: 88vh;
|
|
575
|
+
margin-bottom: 0;
|
|
576
|
+
border-radius: 8px;
|
|
577
|
+
|
|
578
|
+
> .el-dialog__header {
|
|
579
|
+
flex: none;
|
|
580
|
+
padding: 20px 24px;
|
|
581
|
+
border-bottom: 1px solid #ebeef5;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
> .el-dialog__body {
|
|
585
|
+
display: flex;
|
|
586
|
+
flex-direction: column;
|
|
587
|
+
min-height: 0;
|
|
588
|
+
padding: 16px 24px;
|
|
589
|
+
overflow: hidden;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
> .el-dialog__footer {
|
|
593
|
+
flex: none;
|
|
594
|
+
padding: 14px 24px;
|
|
595
|
+
border-top: 1px solid #ebeef5;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.rule-dialog-summary {
|
|
599
|
+
flex: none;
|
|
600
|
+
margin-bottom: 14px;
|
|
601
|
+
color: #909399;
|
|
602
|
+
font-size: 13px;
|
|
603
|
+
line-height: 20px;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.rule-list {
|
|
607
|
+
min-height: 0;
|
|
608
|
+
max-height: none;
|
|
609
|
+
overflow-y: auto;
|
|
610
|
+
overflow-x: hidden;
|
|
611
|
+
padding-right: 4px;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
.rule-empty {
|
|
615
|
+
padding: 40px 12px;
|
|
616
|
+
text-align: center;
|
|
617
|
+
color: #909399;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
.rule-card {
|
|
621
|
+
padding: 0 16px 16px;
|
|
622
|
+
margin-bottom: 16px;
|
|
623
|
+
border: 1px solid #e4e7ed;
|
|
624
|
+
border-radius: 6px;
|
|
625
|
+
background: #fff;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
.rule-card-header {
|
|
629
|
+
min-height: 44px;
|
|
630
|
+
margin: 0 -16px 14px;
|
|
631
|
+
padding: 0 16px;
|
|
632
|
+
background: #f5f7fa;
|
|
633
|
+
border-bottom: 1px solid #ebeef5;
|
|
634
|
+
border-radius: 6px 6px 0 0;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
.rule-title { font-size: 14px; color: #303133; }
|
|
638
|
+
.rule-section + .rule-section { margin-top: 14px; padding-top: 14px; border-top: 1px dashed #e4e7ed; }
|
|
639
|
+
.rule-section-title { margin-bottom: 12px; gap: 12px; }
|
|
640
|
+
|
|
641
|
+
.rule-row {
|
|
642
|
+
display: grid;
|
|
643
|
+
gap: 10px;
|
|
644
|
+
margin-bottom: 10px;
|
|
645
|
+
min-width: 0;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
.condition-row { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr) 28px; }
|
|
649
|
+
.target-row {
|
|
650
|
+
grid-template-columns: repeat(4, minmax(0, 1fr)) 28px;
|
|
651
|
+
padding: 12px;
|
|
652
|
+
background: #fafbfd;
|
|
653
|
+
border: 1px solid #ebeef5;
|
|
654
|
+
border-radius: 4px;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
.target-row > .cell-field { grid-column: 1 / 5; }
|
|
658
|
+
.target-row > .row-remove { grid-column: 5; grid-row: 1; }
|
|
659
|
+
.target-attr { display: flex; flex-direction: column; align-items: stretch; gap: 6px; min-width: 0; }
|
|
660
|
+
.target-attr .attr-label { color: #606266; font-size: 12px; line-height: 18px; }
|
|
661
|
+
|
|
662
|
+
.rule-row .el-select,
|
|
663
|
+
.rule-row .el-input,
|
|
664
|
+
.rule-row .cell-field,
|
|
665
|
+
.rule-row .cell-op,
|
|
666
|
+
.rule-row .cell-value,
|
|
667
|
+
.rule-row .cell-tri { width: 100% !important; min-width: 0; margin: 0; }
|
|
668
|
+
|
|
669
|
+
.row-remove { width: 28px; margin: 0; padding: 8px 0; }
|
|
670
|
+
.rule-dialog-footer { display: flex; align-items: center; gap: 10px; }
|
|
671
|
+
.rule-dialog-footer .el-button { margin: 0; }
|
|
672
|
+
.rule-count { margin-right: auto; font-size: 13px; color: #909399; }
|
|
673
|
+
|
|
674
|
+
@media (max-width: 600px) {
|
|
675
|
+
> .el-dialog__body { padding: 12px; }
|
|
676
|
+
.condition-row { grid-template-columns: minmax(0, 1fr) 28px; }
|
|
677
|
+
.condition-row > .cell-field { grid-column: 1; }
|
|
678
|
+
.condition-row > .row-remove { grid-column: 2; grid-row: 1; }
|
|
679
|
+
.condition-row > .cell-op, .condition-row > .cell-value { grid-column: 1; }
|
|
680
|
+
.target-row { grid-template-columns: repeat(2, minmax(0, 1fr)) 28px; }
|
|
681
|
+
.target-row > .cell-field { grid-column: 1 / 3; }
|
|
682
|
+
.target-row > .row-remove { grid-column: 3; }
|
|
683
|
+
.target-attr:nth-of-type(odd) { grid-column: 1; }
|
|
684
|
+
.target-attr:nth-of-type(even) { grid-column: 2; }
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
</style>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
size="mini"
|
|
6
6
|
label-position="left"
|
|
7
7
|
label-width="120px"
|
|
8
|
-
class="setting-form"
|
|
8
|
+
class="setting-form form-settings-panel"
|
|
9
9
|
@submit.native.prevent
|
|
10
10
|
>
|
|
11
11
|
<el-collapse v-model="formActiveCollapseNames" class="setting-collapse">
|
|
@@ -359,9 +359,12 @@
|
|
|
359
359
|
</el-collapse-item>
|
|
360
360
|
<el-collapse-item name="4" title="列表标签页信息(仅列表表单生效)">
|
|
361
361
|
<el-form-item label-width="0">
|
|
362
|
-
<
|
|
362
|
+
<el-tooltip placement="left" popper-class="xform-setting-help">
|
|
363
|
+
<span slot="content">
|
|
363
364
|
本组配置只从「查询列表页」所用的表单读取,在详情/编辑表单里设置不会生效
|
|
364
365
|
</span>
|
|
366
|
+
<span>适用范围<i class="el-icon-info setting-help-icon" tabindex="0"></i></span>
|
|
367
|
+
</el-tooltip>
|
|
365
368
|
</el-form-item>
|
|
366
369
|
<el-form-item :label="i18nt('列表启用详情多标签')">
|
|
367
370
|
<el-switch v-model="formConfig.multiTabEnabled"></el-switch>
|
|
@@ -379,17 +382,21 @@
|
|
|
379
382
|
>
|
|
380
383
|
<el-switch v-model="formConfig.addTabEnabled"></el-switch>
|
|
381
384
|
<span style="margin-left: 8px; color: #999; font-size: 12px">
|
|
382
|
-
|
|
385
|
+
<el-tooltip content="开启后新增打开独立可关闭页签,需配置标签名称字段。" placement="left" popper-class="xform-setting-help">
|
|
386
|
+
<i class="el-icon-info setting-help-icon" tabindex="0" aria-label="新增页签说明"></i>
|
|
387
|
+
</el-tooltip>
|
|
383
388
|
</span>
|
|
384
389
|
</el-form-item>
|
|
385
|
-
<el-form-item
|
|
390
|
+
<el-form-item class="stacked-setting submit-behavior-setting">
|
|
391
|
+
<span slot="label">{{ i18nt('流程启动后行为') }}
|
|
392
|
+
<el-tooltip content="详情页保存并提交、直接启动流程成功后的行为,不填默认刷新当前页签。" placement="left" popper-class="xform-setting-help">
|
|
393
|
+
<i class="el-icon-info setting-help-icon" tabindex="0" aria-label="流程启动后行为说明"></i>
|
|
394
|
+
</el-tooltip>
|
|
395
|
+
</span>
|
|
386
396
|
<el-radio-group v-model="formConfig.submitBehavior">
|
|
387
397
|
<el-radio label="closeToList">关闭页签并回列表刷新</el-radio>
|
|
388
398
|
<el-radio label="refreshCurrent">刷新当前页签</el-radio>
|
|
389
399
|
</el-radio-group>
|
|
390
|
-
<div style="color: #999; font-size: 12px; line-height: 1.6">
|
|
391
|
-
详情页「保存并提交」「直接启动流程」成功后的行为,不填默认「刷新当前页签」
|
|
392
|
-
</div>
|
|
393
400
|
</el-form-item>
|
|
394
401
|
</el-collapse-item>
|
|
395
402
|
<el-collapse-item name="5" title="其他标签页信息">
|
|
@@ -406,11 +413,11 @@
|
|
|
406
413
|
<el-form-item :label="i18nt('隐藏常规标签')">
|
|
407
414
|
<el-switch v-model="formConfig.hideNormalTab"></el-switch>
|
|
408
415
|
</el-form-item>
|
|
409
|
-
<el-form-item :label="i18nt('其他标签页配置')" class="
|
|
416
|
+
<el-form-item :label="i18nt('其他标签页配置')" class="stacked-setting other-tabs-setting">
|
|
410
417
|
<div>
|
|
411
418
|
<draggable
|
|
412
419
|
tag="ul"
|
|
413
|
-
class="
|
|
420
|
+
class="other-tabs-list"
|
|
414
421
|
:list="formConfig.otherTabList"
|
|
415
422
|
v-bind="{
|
|
416
423
|
group: 'optionsGroup',
|
|
@@ -1792,3 +1799,61 @@ $\{wf.starterName\}提交的$\{pm_product_project.product_code\}$\{pm_product_pr
|
|
|
1792
1799
|
word-break: break-all;
|
|
1793
1800
|
}
|
|
1794
1801
|
</style>
|
|
1802
|
+
|
|
1803
|
+
<style lang="scss">
|
|
1804
|
+
.form-settings-panel.setting-form {
|
|
1805
|
+
.el-form-item {
|
|
1806
|
+
min-width: 0;
|
|
1807
|
+
}
|
|
1808
|
+
.el-form-item > .el-form-item__label {
|
|
1809
|
+
flex-shrink: 0;
|
|
1810
|
+
white-space: normal !important;
|
|
1811
|
+
overflow-wrap: anywhere;
|
|
1812
|
+
line-height: 20px;
|
|
1813
|
+
text-align: left;
|
|
1814
|
+
}
|
|
1815
|
+
.el-form-item > .el-form-item__content {
|
|
1816
|
+
min-width: 0;
|
|
1817
|
+
line-height: 28px;
|
|
1818
|
+
}
|
|
1819
|
+
.el-form-item__content > .el-input,
|
|
1820
|
+
.el-form-item__content > .el-select,
|
|
1821
|
+
.el-form-item__content > .el-textarea { width: 100% !important; min-width: 0; }
|
|
1822
|
+
.el-form-item__content > .el-select { width: calc(100% - 28px) !important; }
|
|
1823
|
+
.el-form-item__content > a { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
|
|
1824
|
+
.el-radio { margin: 0 12px 4px 0; white-space: normal; line-height: 22px; }
|
|
1825
|
+
.el-collapse-item__header { height: auto; min-height: 42px; line-height: 22px; padding: 8px 0; }
|
|
1826
|
+
.el-collapse-item__arrow { flex-shrink: 0; }
|
|
1827
|
+
.el-form-item.stacked-setting {
|
|
1828
|
+
display: block !important;
|
|
1829
|
+
> .el-form-item__label {
|
|
1830
|
+
float: none;
|
|
1831
|
+
display: block !important;
|
|
1832
|
+
width: 100% !important;
|
|
1833
|
+
padding: 0 0 8px;
|
|
1834
|
+
}
|
|
1835
|
+
> .el-form-item__content { margin-left: 0 !important; width: 100%; }
|
|
1836
|
+
}
|
|
1837
|
+
.submit-behavior-setting .el-radio-group { display: flex; flex-direction: column; gap: 8px; }
|
|
1838
|
+
.submit-behavior-setting .el-radio { display: flex; align-items: baseline; margin: 0; }
|
|
1839
|
+
.other-tabs-list { padding: 0; margin: 0; width: 100%; }
|
|
1840
|
+
.other-tabs-list > li {
|
|
1841
|
+
display: grid;
|
|
1842
|
+
grid-template-columns: 18px minmax(0, 1fr) 28px;
|
|
1843
|
+
align-items: center;
|
|
1844
|
+
gap: 8px;
|
|
1845
|
+
padding: 10px 8px;
|
|
1846
|
+
margin-bottom: 10px;
|
|
1847
|
+
list-style: none;
|
|
1848
|
+
background: #f5f7fa;
|
|
1849
|
+
border-radius: 4px;
|
|
1850
|
+
}
|
|
1851
|
+
.other-tabs-list > li > .el-input { grid-column: 2; width: 100% !important; min-width: 0; margin: 0; }
|
|
1852
|
+
.other-tabs-list .drag-option { grid-column: 1; grid-row: 1 / 3; cursor: move; color: #909399; }
|
|
1853
|
+
.other-tabs-list .col-delete-button { grid-column: 3; grid-row: 1 / 3; margin: 0; padding: 6px; }
|
|
1854
|
+
.tree-options-error { overflow-wrap: anywhere; margin-bottom: 8px; }
|
|
1855
|
+
}
|
|
1856
|
+
.setting-help-icon { margin-left: 8px; color: #909399; cursor: help; font-size: 14px; }
|
|
1857
|
+
.setting-help-icon:hover, .setting-help-icon:focus { color: #409eff; }
|
|
1858
|
+
.el-tooltip__popper.xform-setting-help { max-width: 300px; line-height: 1.7; overflow-wrap: anywhere; }
|
|
1859
|
+
</style>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<base-input-number
|
|
3
|
+
:value="innerValue"
|
|
4
|
+
v-bind="$attrs"
|
|
5
|
+
v-on="listeners"
|
|
6
|
+
@input="onInput"
|
|
7
|
+
/>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script>
|
|
11
|
+
/**
|
|
12
|
+
* 未配置(null / undefined / 非正数)时显示空白,而不是 el-input-number 默认的 0。
|
|
13
|
+
* 清空后回写 null,运行时会回落到全局逻辑参数。
|
|
14
|
+
*/
|
|
15
|
+
function toDisplayNumber(value) {
|
|
16
|
+
if (value == null || value === "") return undefined;
|
|
17
|
+
let num = Number(value);
|
|
18
|
+
if (!Number.isFinite(num) || num <= 0) return undefined;
|
|
19
|
+
return num;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function toStoredNumber(value) {
|
|
23
|
+
if (value == null || value === "") return null;
|
|
24
|
+
let num = Number(value);
|
|
25
|
+
if (!Number.isFinite(num) || num <= 0) return null;
|
|
26
|
+
return num;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default {
|
|
30
|
+
name: "empty-number-input",
|
|
31
|
+
inheritAttrs: false,
|
|
32
|
+
props: {
|
|
33
|
+
value: {},
|
|
34
|
+
},
|
|
35
|
+
computed: {
|
|
36
|
+
innerValue() {
|
|
37
|
+
return toDisplayNumber(this.value);
|
|
38
|
+
},
|
|
39
|
+
listeners() {
|
|
40
|
+
let listeners = Object.assign({}, this.$listeners);
|
|
41
|
+
delete listeners.input;
|
|
42
|
+
return listeners;
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
methods: {
|
|
46
|
+
onInput(val) {
|
|
47
|
+
this.$emit("input", toStoredNumber(val));
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
</script>
|