cloud-web-corejs 1.0.54-dev.794 → 1.0.54-dev.796
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/formDialog/README.md +32 -6
- package/src/components/luckysheet/dialog.vue +1 -1
- package/src/components/wf/wfButtonName.js +60 -0
- package/src/components/xform/form-designer/designer.js +2 -1
- package/src/components/xform/form-designer/form-widget/field-widget/fieldMixin.js +65 -29
- package/src/components/xform/form-designer/form-widget/field-widget/save_submit_wf_button-widget.vue +3 -0
- package/src/components/xform/form-designer/setting-panel/form-setting.vue +111 -8
- package/src/components/xform/form-designer/setting-panel/property-editor/field-button/addTableData-event-editor.vue +0 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-button/clickBindActions.js +253 -0
- package/src/components/xform/form-designer/setting-panel/property-editor/field-button/clickBindEvent-editor.vue +49 -40
- package/src/components/xform/form-designer/setting-panel/property-editor/field-button/form-host-event-editor.vue +175 -0
- package/src/components/xform/form-designer/setting-panel/property-editor/field-button/search-dialog-event-editor.vue +20 -5
- package/src/components/xform/form-designer/widget-panel/indexMixin.js +2 -1
- package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +3 -0
- package/src/components/xform/form-render/container-item/data-table-mixin.js +5 -11
- package/src/components/xform/form-render/container-item/detail-item.vue +116 -3
- package/src/components/xform/form-render/index.vue +0 -7
- package/src/components/xform/form-render/indexMixin.js +65 -31
- package/src/components/xform/mixins/defaultHandle.js +50 -38
- package/src/components/xform/utils/util.js +7 -0
- package/src/views/bd/setting/formVersion/ftHistoryDialog.vue +2 -0
- package/src/components/xform/form-designer/form-widget/dialog/formDrawer.vue +0 -307
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 「点击绑定事件」动作注册表。
|
|
3
|
+
*
|
|
4
|
+
* 设计器(clickBindEvent-editor.vue)与运行时(field-widget/fieldMixin.js)共用这一份,
|
|
5
|
+
* 因此**本文件不得 import 任何 .vue**——否则设计器的属性编辑器会被打进表单渲染包。
|
|
6
|
+
* 编辑器组件映射留在 clickBindEvent-editor.vue 自己的 components 里,这里只存 editorName 字符串。
|
|
7
|
+
*
|
|
8
|
+
* 方案见 docs/点击绑定事件重构与表单弹框抽屉动作方案.md
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* widgetsConfig 只在真正要造默认配置时才引。
|
|
13
|
+
* 它顶层就有 containers 提前引用 defaultWfConfig 的 TDZ 问题(见该文件头部注释),
|
|
14
|
+
* webpack 侧被 Babel 的 const→var 掩盖了,jest 侧会直接抛 —— 顶层 import 会让本模块
|
|
15
|
+
* 连同引它的运行时一起不可测。
|
|
16
|
+
*/
|
|
17
|
+
function getDefaultSearchDialogConfig() {
|
|
18
|
+
return require("../../../widget-panel/widgetsConfig")
|
|
19
|
+
.defaultSearchDialogConfig;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const CLICK_BIND = {
|
|
23
|
+
SEARCH_DIALOG: "1", // 打开选择弹框
|
|
24
|
+
ADD_TABLE_DATA: "2", // 列表添加数据
|
|
25
|
+
FORM_DIALOG: "3", // 打开表单弹框
|
|
26
|
+
FORM_DRAWER: "4", // 打开表单抽屉
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// 有自身值的控件:dataId 缺省取控件值;按钮类没有值,缺省取当前表格行字段
|
|
30
|
+
const VALUE_WIDGET_TYPES = ["vabsearch", "singerSearch", "multiSearch"];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 「打开表单弹框 / 打开表单抽屉」共用配置。两个动作共用一个 configKey,
|
|
34
|
+
* 弹框/抽屉互切时配置不丢。
|
|
35
|
+
*/
|
|
36
|
+
export function buildDefaultFormHostConfig(ctx = {}) {
|
|
37
|
+
let isValueWidget
|
|
38
|
+
= VALUE_WIDGET_TYPES.indexOf(ctx.widgetType) > -1
|
|
39
|
+
|| ctx.widgetTextLinkFlag === true;
|
|
40
|
+
return {
|
|
41
|
+
// 目标表单
|
|
42
|
+
formCode: null,
|
|
43
|
+
formCodeScript: null,
|
|
44
|
+
host: null, // null=直接渲染该表单;"list"=用列表宿主页承载
|
|
45
|
+
title: null,
|
|
46
|
+
// 数据
|
|
47
|
+
openMode: "1", // 1=新增;2=详情
|
|
48
|
+
dataIdFrom: isValueWidget ? "1" : "3",
|
|
49
|
+
dataIdField: null,
|
|
50
|
+
dataIdScript: null,
|
|
51
|
+
paramScript: null,
|
|
52
|
+
// 呈现
|
|
53
|
+
readonly: false,
|
|
54
|
+
showFooter: true,
|
|
55
|
+
plain: false, // 仅抽屉
|
|
56
|
+
dialogWidth: null, // 仅弹框
|
|
57
|
+
fullscreen: false, // 仅弹框
|
|
58
|
+
drawerSize: null, // 仅抽屉,缺省 62%(host:"list" 时 85%)
|
|
59
|
+
drawerDirection: null, // 仅抽屉,缺省 rtl
|
|
60
|
+
// 收尾
|
|
61
|
+
onCloseScript: null,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const clickBindActions = [
|
|
66
|
+
{
|
|
67
|
+
value: CLICK_BIND.SEARCH_DIALOG,
|
|
68
|
+
label: "打开选择弹框",
|
|
69
|
+
editorName: "searchDialogEventEditor",
|
|
70
|
+
configKey: "searchDialogConfig",
|
|
71
|
+
// vabsearch 的多选由控件自身的 multipleChoices 决定,这里缺省给 false(沿用存量判定)
|
|
72
|
+
defaultConfig: (ctx) => ({
|
|
73
|
+
...getDefaultSearchDialogConfig(),
|
|
74
|
+
multipleChoices: !(ctx && ctx.widgetType === "vabsearch"),
|
|
75
|
+
}),
|
|
76
|
+
run: (ctx) => ctx.vm.openSearchDialog(ctx.tableParam, ctx.flag),
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
value: CLICK_BIND.ADD_TABLE_DATA,
|
|
80
|
+
label: "列表添加数据",
|
|
81
|
+
editorName: "addTableDataEventEditor",
|
|
82
|
+
configKey: "addTableDataConfig",
|
|
83
|
+
defaultConfig: () => ({
|
|
84
|
+
tableRef: null,
|
|
85
|
+
tableData: {},
|
|
86
|
+
}),
|
|
87
|
+
run: (ctx) => ctx.vm.handleAddTableDataEvent(ctx.flag),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
value: CLICK_BIND.FORM_DIALOG,
|
|
91
|
+
label: "打开表单弹框",
|
|
92
|
+
editorName: "formHostEventEditor",
|
|
93
|
+
configKey: "formHostConfig",
|
|
94
|
+
defaultConfig: buildDefaultFormHostConfig,
|
|
95
|
+
run: (ctx) => openFormHost(ctx, "dialog"),
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
value: CLICK_BIND.FORM_DRAWER,
|
|
99
|
+
label: "打开表单抽屉",
|
|
100
|
+
editorName: "formHostEventEditor",
|
|
101
|
+
configKey: "formHostConfig",
|
|
102
|
+
defaultConfig: buildDefaultFormHostConfig,
|
|
103
|
+
run: (ctx) => openFormHost(ctx, "drawer"),
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
export function getClickBindAction(value) {
|
|
108
|
+
if (!value) return null;
|
|
109
|
+
return clickBindActions.find((action) => action.value === value) || null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** 传给承载壳前剔除 undefined:两个壳都是 Object.assign({默认}, 配置),undefined 会把默认值覆盖成空 */
|
|
113
|
+
export function dropUndefined(obj) {
|
|
114
|
+
let result = {};
|
|
115
|
+
Object.keys(obj || {}).forEach((key) => {
|
|
116
|
+
if (obj[key] !== undefined) result[key] = obj[key];
|
|
117
|
+
});
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* 详情态单据 ID 求值。openMode="1"(新增)恒返回 null。
|
|
123
|
+
* 取不到时提示并返回 undefined,调用方据此中断——详情表单空开一张没有意义。
|
|
124
|
+
*/
|
|
125
|
+
export function resolveDataId(ctx, cfg) {
|
|
126
|
+
if (!cfg || cfg.openMode !== "2") return null;
|
|
127
|
+
|
|
128
|
+
let dataId = null;
|
|
129
|
+
switch (cfg.dataIdFrom) {
|
|
130
|
+
case "2":
|
|
131
|
+
dataId = cfg.dataIdField
|
|
132
|
+
? ctx.formRef && ctx.formRef.getFieldValue(cfg.dataIdField)
|
|
133
|
+
: null;
|
|
134
|
+
break;
|
|
135
|
+
case "3":
|
|
136
|
+
dataId
|
|
137
|
+
= cfg.dataIdField && ctx.rowData ? ctx.rowData[cfg.dataIdField] : null;
|
|
138
|
+
break;
|
|
139
|
+
case "4":
|
|
140
|
+
dataId = cfg.dataIdScript
|
|
141
|
+
? ctx.vm.handleCustomEvent(cfg.dataIdScript, ["rowData"], [ctx.rowData])
|
|
142
|
+
: null;
|
|
143
|
+
break;
|
|
144
|
+
default:
|
|
145
|
+
// "1" 当前控件值
|
|
146
|
+
dataId = ctx.vm.getValue ? ctx.vm.getValue() : ctx.vm.fieldModel;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (dataId === null || dataId === undefined || dataId === "") {
|
|
151
|
+
ctx.vm.$message.warning("未取到单据ID");
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
return dataId;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* 打开一张 formCode 表单。
|
|
159
|
+
* - 弹框走 xform 内部通道 getFormRef().openFormDialog(formConfig 可透传 VFormRender props)
|
|
160
|
+
* - 抽屉走全局 $formDrawer(能力最全:dataId/param/plain/readonly/host/fillHeight/报错处理)
|
|
161
|
+
* 不回填、不选行;结果只通过 onCloseScript 的 result 参数交给脚本。
|
|
162
|
+
*/
|
|
163
|
+
export function openFormHost(ctx, mode) {
|
|
164
|
+
let cfg = (ctx.optionModel && ctx.optionModel.formHostConfig) || {};
|
|
165
|
+
let formCode = cfg.formCodeScript
|
|
166
|
+
? ctx.vm.handleCustomEvent(cfg.formCodeScript, ["rowData"], [ctx.rowData])
|
|
167
|
+
: cfg.formCode;
|
|
168
|
+
if (!formCode) return;
|
|
169
|
+
|
|
170
|
+
let dataId = resolveDataId(ctx, cfg);
|
|
171
|
+
if (dataId === undefined) return; // 详情态取不到单据 ID,已提示
|
|
172
|
+
|
|
173
|
+
let param = cfg.paramScript
|
|
174
|
+
? ctx.vm.handleCustomEvent(cfg.paramScript, ["rowData"], [ctx.rowData])
|
|
175
|
+
: undefined;
|
|
176
|
+
let onClose = (formRef, result) => {
|
|
177
|
+
if (cfg.onCloseScript) {
|
|
178
|
+
ctx.vm.handleCustomEvent(
|
|
179
|
+
cfg.onCloseScript,
|
|
180
|
+
["formRef", "result"],
|
|
181
|
+
[formRef, result]
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
if (mode === "drawer") {
|
|
187
|
+
// 全局抽屉每次新建实例,可叠开;连点两次会叠两层,这里挂标记防重
|
|
188
|
+
if (ctx.vm._formHostOpening) return;
|
|
189
|
+
ctx.vm._formHostOpening = true;
|
|
190
|
+
let clearFlag = () => {
|
|
191
|
+
ctx.vm._formHostOpening = false;
|
|
192
|
+
};
|
|
193
|
+
let openDrawer = ctx.vm.$formDrawer
|
|
194
|
+
? ctx.vm.$formDrawer.bind(ctx.vm)
|
|
195
|
+
: (option) =>
|
|
196
|
+
import("../../../../../formDrawer").then((m) =>
|
|
197
|
+
m.default.open(option)
|
|
198
|
+
);
|
|
199
|
+
return openDrawer(
|
|
200
|
+
dropUndefined({
|
|
201
|
+
formCode: formCode,
|
|
202
|
+
host: cfg.host || undefined,
|
|
203
|
+
title: cfg.title || undefined,
|
|
204
|
+
param: param,
|
|
205
|
+
dataId: dataId, // null=新增态
|
|
206
|
+
plain: !!cfg.plain,
|
|
207
|
+
readonly: !!cfg.readonly,
|
|
208
|
+
showFooter: cfg.showFooter !== false,
|
|
209
|
+
size: cfg.drawerSize || undefined,
|
|
210
|
+
direction: cfg.drawerDirection || undefined,
|
|
211
|
+
})
|
|
212
|
+
).then(
|
|
213
|
+
(result) => {
|
|
214
|
+
clearFlag();
|
|
215
|
+
onClose(null, result);
|
|
216
|
+
},
|
|
217
|
+
(error) => {
|
|
218
|
+
clearFlag();
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 内部壳是回调式:onAction(配置按钮)/ confirm(默认「确定」)先把结果存下,
|
|
225
|
+
// close 时一起交给脚本。注意内部弹框的默认「确定」不做表单校验。
|
|
226
|
+
let lastResult = null;
|
|
227
|
+
ctx.formRef.openFormDialog(
|
|
228
|
+
dropUndefined({
|
|
229
|
+
formCode: formCode,
|
|
230
|
+
host: cfg.host || undefined,
|
|
231
|
+
param: param,
|
|
232
|
+
// v-bind 到 VFormRender 的 props,只放 props(禁止 param/formJson/formData)
|
|
233
|
+
formConfig: dropUndefined({
|
|
234
|
+
dataId: dataId,
|
|
235
|
+
disabledMode: !!cfg.readonly,
|
|
236
|
+
}),
|
|
237
|
+
showFooter: cfg.showFooter !== false,
|
|
238
|
+
dialogConfig: dropUndefined({
|
|
239
|
+
title: cfg.title || undefined,
|
|
240
|
+
width: cfg.dialogWidth || undefined,
|
|
241
|
+
fullscreen: !!cfg.fullscreen,
|
|
242
|
+
}),
|
|
243
|
+
onAction: (payload) => {
|
|
244
|
+
lastResult = payload;
|
|
245
|
+
},
|
|
246
|
+
confirm: (formRef) => {
|
|
247
|
+
lastResult
|
|
248
|
+
= formRef && formRef.getFormData ? formRef.getFormData(false) : true;
|
|
249
|
+
},
|
|
250
|
+
close: (formRef) => onClose(formRef, lastResult),
|
|
251
|
+
})
|
|
252
|
+
);
|
|
253
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
3
|
<el-form-item label="点击绑定事件">
|
|
4
|
-
<el-select v-model="optionModel.clickBindEvent" clearable>
|
|
5
|
-
<el-option
|
|
6
|
-
|
|
4
|
+
<el-select v-model="optionModel.clickBindEvent" clearable @change="onActionChange">
|
|
5
|
+
<el-option v-for="action in actions" :key="action.value"
|
|
6
|
+
:value="action.value" :label="action.label"></el-option>
|
|
7
7
|
</el-select>
|
|
8
8
|
</el-form-item>
|
|
9
9
|
<el-form-item label="点击前置事件" label-width="150px">
|
|
@@ -13,31 +13,27 @@
|
|
|
13
13
|
<i class="el-icon-edit"></i>
|
|
14
14
|
</a>
|
|
15
15
|
</el-form-item>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
<!-- 子编辑器由注册表的 editorName 决定,新增动作不用再加 v-if 分支 -->
|
|
17
|
+
<component v-if="currentAction && currentAction.editorName"
|
|
18
|
+
:is="currentAction.editorName"
|
|
19
|
+
:designer="designer" :selectedWidget="selectedWidget"
|
|
20
|
+
:optionModel.sync="optionModel"
|
|
21
|
+
:actionValue="optionModel.clickBindEvent"></component>
|
|
20
22
|
</div>
|
|
21
23
|
</template>
|
|
22
24
|
<script>
|
|
23
25
|
import searchDialogEventEditor from "./search-dialog-event-editor.vue";
|
|
24
26
|
import addTableDataEventEditor from "./addTableData-event-editor.vue";
|
|
25
|
-
import
|
|
27
|
+
import formHostEventEditor from "./form-host-event-editor.vue";
|
|
28
|
+
import {
|
|
29
|
+
clickBindActions,
|
|
30
|
+
getClickBindAction,
|
|
31
|
+
} from "./clickBindActions";
|
|
26
32
|
|
|
27
33
|
import i18n from "../../../../../../components/xform/utils/i18n";
|
|
28
34
|
import eventMixin
|
|
29
35
|
from "../../../../../../components/xform/form-designer/setting-panel/property-editor/event-handler/eventMixin";
|
|
30
36
|
|
|
31
|
-
let clickBindEventConfig = {
|
|
32
|
-
searchDialogConfig: {
|
|
33
|
-
...defaultSearchDialogConfig
|
|
34
|
-
},
|
|
35
|
-
addTableDataConfig: {
|
|
36
|
-
tableRef: null,
|
|
37
|
-
tableData: {}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
37
|
export default {
|
|
42
38
|
name: "clickBindEvent-editor",
|
|
43
39
|
mixins: [i18n, eventMixin],
|
|
@@ -48,37 +44,50 @@ export default {
|
|
|
48
44
|
},
|
|
49
45
|
components: {
|
|
50
46
|
searchDialogEventEditor,
|
|
51
|
-
addTableDataEventEditor
|
|
52
|
-
|
|
53
|
-
provide() {
|
|
54
|
-
return {
|
|
55
|
-
defaultClickBindEventConfig: clickBindEventConfig
|
|
56
|
-
}
|
|
47
|
+
addTableDataEventEditor,
|
|
48
|
+
formHostEventEditor
|
|
57
49
|
},
|
|
58
50
|
data() {
|
|
59
51
|
return {
|
|
52
|
+
actions: clickBindActions,
|
|
60
53
|
evnentParams: ["dataId", "formCode", "done"]
|
|
61
54
|
}
|
|
62
55
|
},
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
if (!this.optionModel.searchDialogConfig) {
|
|
68
|
-
this.$set(this.optionModel, 'searchDialogConfig', this.$baseLodash.cloneDeep(clickBindEventConfig.searchDialogConfig));
|
|
69
|
-
}
|
|
70
|
-
if (this.optionModel.searchDialogConfig.multipleChoices === void 0) {
|
|
71
|
-
if (this.selectedWidget.type == 'vabsearch') {
|
|
72
|
-
this.$set(this.optionModel.searchDialogConfig, 'multipleChoices', false);
|
|
73
|
-
} else {
|
|
74
|
-
this.$set(this.optionModel.searchDialogConfig, 'multipleChoices', true);
|
|
75
|
-
}
|
|
56
|
+
computed: {
|
|
57
|
+
currentAction() {
|
|
58
|
+
return getClickBindAction(this.optionModel.clickBindEvent);
|
|
76
59
|
}
|
|
77
60
|
},
|
|
61
|
+
created() {
|
|
62
|
+
// 存量模板兜底:只补当前已选动作的配置块,不再无条件塞两份空壳
|
|
63
|
+
this.ensureActionConfig(this.optionModel.clickBindEvent);
|
|
64
|
+
},
|
|
78
65
|
methods: {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
66
|
+
// 切换动作时惰性注入配置:已有则保留("3"↔"4" 共用 formHostConfig,互切不丢配置)
|
|
67
|
+
onActionChange(value) {
|
|
68
|
+
this.ensureActionConfig(value);
|
|
69
|
+
},
|
|
70
|
+
ensureActionConfig(value) {
|
|
71
|
+
let action = getClickBindAction(value);
|
|
72
|
+
if (!action || !action.configKey) return;
|
|
73
|
+
if (!this.optionModel[action.configKey]) {
|
|
74
|
+
this.$set(
|
|
75
|
+
this.optionModel,
|
|
76
|
+
action.configKey,
|
|
77
|
+
action.defaultConfig({widgetType: this.selectedWidget.type})
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
// 存量模板可能缺 multipleChoices,沿用原判定补上
|
|
81
|
+
if (
|
|
82
|
+
action.configKey === "searchDialogConfig"
|
|
83
|
+
&& this.optionModel.searchDialogConfig.multipleChoices === void 0
|
|
84
|
+
) {
|
|
85
|
+
this.$set(
|
|
86
|
+
this.optionModel.searchDialogConfig,
|
|
87
|
+
"multipleChoices",
|
|
88
|
+
this.selectedWidget.type !== "vabsearch"
|
|
89
|
+
);
|
|
90
|
+
}
|
|
82
91
|
}
|
|
83
92
|
}
|
|
84
93
|
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<el-form-item label-width="0">
|
|
4
|
+
<el-divider class="custom-divider">{{ drawerMode ? '表单抽屉配置' : '表单弹框配置' }}</el-divider>
|
|
5
|
+
</el-form-item>
|
|
6
|
+
<el-form-item label="表单编码">
|
|
7
|
+
<el-input type="text" v-model="eventConfig.formCode"></el-input>
|
|
8
|
+
</el-form-item>
|
|
9
|
+
<el-form-item label="表单编码脚本" label-width="150px">
|
|
10
|
+
<a href="javascript:void(0);" class="a-link link-oneLind"
|
|
11
|
+
@click="editEventHandler('formCodeScript', scriptParams, optionFormCode)">
|
|
12
|
+
<span>{{ eventConfig.formCodeScript }}</span>
|
|
13
|
+
<i class="el-icon-edit"></i>
|
|
14
|
+
</a>
|
|
15
|
+
</el-form-item>
|
|
16
|
+
<el-form-item label="以列表页承载">
|
|
17
|
+
<el-switch v-model="listHost"></el-switch>
|
|
18
|
+
<span class="tips">开启后按「常规/列表」页签的列表页打开</span>
|
|
19
|
+
</el-form-item>
|
|
20
|
+
<el-form-item label="标题">
|
|
21
|
+
<el-input type="text" v-model="eventConfig.title" placeholder="缺省取表单模板名称"></el-input>
|
|
22
|
+
</el-form-item>
|
|
23
|
+
|
|
24
|
+
<template v-if="!listHost">
|
|
25
|
+
<el-form-item label="打开方式">
|
|
26
|
+
<el-select v-model="eventConfig.openMode">
|
|
27
|
+
<el-option value="1" label="新增"></el-option>
|
|
28
|
+
<el-option value="2" label="详情"></el-option>
|
|
29
|
+
</el-select>
|
|
30
|
+
</el-form-item>
|
|
31
|
+
<template v-if="eventConfig.openMode === '2'">
|
|
32
|
+
<el-form-item label="单据ID来源">
|
|
33
|
+
<el-select v-model="eventConfig.dataIdFrom">
|
|
34
|
+
<el-option value="1" label="当前控件值"></el-option>
|
|
35
|
+
<el-option value="2" label="指定表单字段"></el-option>
|
|
36
|
+
<el-option value="3" label="当前表格行字段"></el-option>
|
|
37
|
+
<el-option value="4" label="脚本"></el-option>
|
|
38
|
+
</el-select>
|
|
39
|
+
</el-form-item>
|
|
40
|
+
<el-form-item label="来源字段名"
|
|
41
|
+
v-if="eventConfig.dataIdFrom === '2' || eventConfig.dataIdFrom === '3'">
|
|
42
|
+
<el-input type="text" v-model="eventConfig.dataIdField"></el-input>
|
|
43
|
+
</el-form-item>
|
|
44
|
+
<el-form-item label="单据ID脚本" label-width="150px" v-if="eventConfig.dataIdFrom === '4'">
|
|
45
|
+
<a href="javascript:void(0);" class="a-link link-oneLind"
|
|
46
|
+
@click="editEventHandler('dataIdScript', scriptParams, optionDataId)">
|
|
47
|
+
<span>{{ eventConfig.dataIdScript }}</span>
|
|
48
|
+
<i class="el-icon-edit"></i>
|
|
49
|
+
</a>
|
|
50
|
+
</el-form-item>
|
|
51
|
+
</template>
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<el-form-item label="自定义参数" label-width="150px">
|
|
55
|
+
<a href="javascript:void(0);" class="a-link link-oneLind"
|
|
56
|
+
@click="editEventHandler('paramScript', scriptParams, optionParam)">
|
|
57
|
+
<span>{{ eventConfig.paramScript }}</span>
|
|
58
|
+
<i class="el-icon-edit"></i>
|
|
59
|
+
</a>
|
|
60
|
+
</el-form-item>
|
|
61
|
+
<el-form-item label="只读">
|
|
62
|
+
<el-switch v-model="eventConfig.readonly"></el-switch>
|
|
63
|
+
<span class="tips">{{ drawerMode ? '只读态渲染,底部仅保留「关闭」' : '整表禁用,底部按钮不变' }}</span>
|
|
64
|
+
</el-form-item>
|
|
65
|
+
<el-form-item label="显示底部按钮">
|
|
66
|
+
<el-switch v-model="eventConfig.showFooter"></el-switch>
|
|
67
|
+
<span class="tips">按钮由目标表单的「表单操作按钮」决定</span>
|
|
68
|
+
</el-form-item>
|
|
69
|
+
|
|
70
|
+
<!-- 形态字段:弹框/抽屉各一组 -->
|
|
71
|
+
<template v-if="drawerMode">
|
|
72
|
+
<el-form-item label="素身详情">
|
|
73
|
+
<el-switch v-model="eventConfig.plain"></el-switch>
|
|
74
|
+
<span class="tips">不渲染详情标题栏与模块导航</span>
|
|
75
|
+
</el-form-item>
|
|
76
|
+
<el-form-item label="抽屉尺寸">
|
|
77
|
+
<el-input type="text" v-model="eventConfig.drawerSize" placeholder="缺省 62%,列表页 85%"></el-input>
|
|
78
|
+
</el-form-item>
|
|
79
|
+
<el-form-item label="弹出方向">
|
|
80
|
+
<el-select v-model="eventConfig.drawerDirection" clearable placeholder="缺省 右侧滑出">
|
|
81
|
+
<el-option value="rtl" label="右侧滑出"></el-option>
|
|
82
|
+
<el-option value="ltr" label="左侧滑出"></el-option>
|
|
83
|
+
<el-option value="ttb" label="顶部滑出"></el-option>
|
|
84
|
+
<el-option value="btt" label="底部滑出"></el-option>
|
|
85
|
+
</el-select>
|
|
86
|
+
</el-form-item>
|
|
87
|
+
</template>
|
|
88
|
+
<template v-else>
|
|
89
|
+
<el-form-item label="弹框宽度">
|
|
90
|
+
<el-input type="text" v-model="eventConfig.dialogWidth" placeholder="缺省 1200px"></el-input>
|
|
91
|
+
</el-form-item>
|
|
92
|
+
<el-form-item label="全屏">
|
|
93
|
+
<el-switch v-model="eventConfig.fullscreen"></el-switch>
|
|
94
|
+
</el-form-item>
|
|
95
|
+
</template>
|
|
96
|
+
|
|
97
|
+
<el-form-item label="关闭后事件" label-width="150px">
|
|
98
|
+
<a href="javascript:void(0);" class="a-link link-oneLind"
|
|
99
|
+
@click="editEventHandler('onCloseScript', closeScriptParams, optionClose)">
|
|
100
|
+
<span>{{ eventConfig.onCloseScript }}</span>
|
|
101
|
+
<i class="el-icon-edit"></i>
|
|
102
|
+
</a>
|
|
103
|
+
</el-form-item>
|
|
104
|
+
</div>
|
|
105
|
+
</template>
|
|
106
|
+
|
|
107
|
+
<script>
|
|
108
|
+
import i18n from "../../../../../../components/xform/utils/i18n"
|
|
109
|
+
import eventMixin
|
|
110
|
+
from "../../../../../../components/xform/form-designer/setting-panel/property-editor/event-handler/eventMixin"
|
|
111
|
+
import {CLICK_BIND} from "./clickBindActions";
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 「打开表单弹框 / 打开表单抽屉」共用配置编辑器(optionModel.formHostConfig)。
|
|
115
|
+
* 两个动作共用一份配置,形态字段按 actionValue 切换,弹框/抽屉互切时配置不丢。
|
|
116
|
+
*/
|
|
117
|
+
export default {
|
|
118
|
+
mixins: [i18n, eventMixin],
|
|
119
|
+
props: {
|
|
120
|
+
designer: Object,
|
|
121
|
+
selectedWidget: Object,
|
|
122
|
+
optionModel: Object,
|
|
123
|
+
actionValue: String,
|
|
124
|
+
},
|
|
125
|
+
data() {
|
|
126
|
+
return {
|
|
127
|
+
optionFormCode: this.buildScriptOption("formCodeScript"),
|
|
128
|
+
optionDataId: this.buildScriptOption("dataIdScript"),
|
|
129
|
+
optionParam: this.buildScriptOption("paramScript"),
|
|
130
|
+
optionClose: this.buildScriptOption("onCloseScript"),
|
|
131
|
+
// 脚本可用参数:dataId/formCode 由 getEventParam 统一注入,这里只列附加项
|
|
132
|
+
scriptParams: ["dataId", "formCode", "rowData"],
|
|
133
|
+
closeScriptParams: ["dataId", "formCode", "formRef", "result"],
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
computed: {
|
|
137
|
+
drawerMode() {
|
|
138
|
+
return this.actionValue === CLICK_BIND.FORM_DRAWER;
|
|
139
|
+
},
|
|
140
|
+
eventConfig() {
|
|
141
|
+
return this.optionModel.formHostConfig || {};
|
|
142
|
+
},
|
|
143
|
+
// 列表页承载时不需要新增/详情与素身设置,统一按开关处理
|
|
144
|
+
listHost: {
|
|
145
|
+
get() {
|
|
146
|
+
return this.eventConfig.host === "list";
|
|
147
|
+
},
|
|
148
|
+
set(val) {
|
|
149
|
+
this.eventConfig.host = val ? "list" : null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
methods: {
|
|
154
|
+
buildScriptOption(key) {
|
|
155
|
+
return {
|
|
156
|
+
customCode: () => {
|
|
157
|
+
return this.eventConfig[key];
|
|
158
|
+
},
|
|
159
|
+
callback: (code) => {
|
|
160
|
+
this.eventConfig[key] = code;
|
|
161
|
+
this.$forceUpdate();
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
</script>
|
|
168
|
+
|
|
169
|
+
<style scoped>
|
|
170
|
+
.tips {
|
|
171
|
+
margin-left: 8px;
|
|
172
|
+
color: #909399;
|
|
173
|
+
font-size: 12px;
|
|
174
|
+
}
|
|
175
|
+
</style>
|
|
@@ -3,10 +3,14 @@
|
|
|
3
3
|
<el-form-item label-width="0">
|
|
4
4
|
<el-divider class="custom-divider">选择弹框配置</el-divider>
|
|
5
5
|
</el-form-item>
|
|
6
|
+
<!-- 搜索类控件的多选是结构性的(决定字段值是数组还是标量),由控件自身的「是否多选」决定,
|
|
7
|
+
这里只做展示,避免两个开关各说各话 -->
|
|
6
8
|
<el-form-item label="是否多选">
|
|
7
|
-
<el-switch v-model="eventConfig.multipleChoices"
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
<el-switch v-model="eventConfig.multipleChoices" v-if="!vabsearchFlag"></el-switch>
|
|
10
|
+
<template v-else>
|
|
11
|
+
<span>{{ optionModel.multipleChoices ? '是' : '否' }}</span>
|
|
12
|
+
<span class="tips">由控件自身的「是否多选」决定</span>
|
|
13
|
+
</template>
|
|
10
14
|
</el-form-item>
|
|
11
15
|
<el-form-item label="弹框表单编码">
|
|
12
16
|
<el-input type="text" v-model="eventConfig.formCode"></el-input>
|
|
@@ -160,7 +164,6 @@ export default {
|
|
|
160
164
|
selectedWidget: Object,
|
|
161
165
|
optionModel: Object,
|
|
162
166
|
},
|
|
163
|
-
inject: ['defaultClickBindEventConfig'],
|
|
164
167
|
data() {
|
|
165
168
|
return {
|
|
166
169
|
showDialog: false,
|
|
@@ -197,6 +200,14 @@ export default {
|
|
|
197
200
|
computed: {
|
|
198
201
|
eventConfig() {
|
|
199
202
|
return this.optionModel.searchDialogConfig || {};
|
|
203
|
+
},
|
|
204
|
+
vabsearchFlag() {
|
|
205
|
+
let type = this.selectedWidget.type;
|
|
206
|
+
return (
|
|
207
|
+
type === "vabsearch"
|
|
208
|
+
|| type === "singerSearch"
|
|
209
|
+
|| type === "multiSearch"
|
|
210
|
+
);
|
|
200
211
|
}
|
|
201
212
|
},
|
|
202
213
|
created() {
|
|
@@ -216,5 +227,9 @@ export default {
|
|
|
216
227
|
</script>
|
|
217
228
|
|
|
218
229
|
<style scoped>
|
|
219
|
-
|
|
230
|
+
.tips {
|
|
231
|
+
margin-left: 8px;
|
|
232
|
+
color: #909399;
|
|
233
|
+
font-size: 12px;
|
|
234
|
+
}
|
|
220
235
|
</style>
|
|
@@ -215,7 +215,8 @@ modules = {
|
|
|
215
215
|
displayName: this.i18n2t(`designer.widgetLabel.${fld.type}`, `extension.widgetLabel.${fld.type}`)
|
|
216
216
|
};
|
|
217
217
|
}).filter(fld => {
|
|
218
|
-
|
|
218
|
+
/* deprecated: 已被表单设置取代的组件,面板下架但保留定义供老模板渲染 */
|
|
219
|
+
return !fld.deprecated && !this.isBanned(fld.type) && this.getIsShow(fld);
|
|
219
220
|
});
|
|
220
221
|
|
|
221
222
|
this.commonAdvancedFields = this.sortByPanelOrder(advancedFields.map(fld => {
|
|
@@ -4092,6 +4092,9 @@ export const businessFields = [
|
|
|
4092
4092
|
commonFlag: !0,
|
|
4093
4093
|
columnFlag: true,
|
|
4094
4094
|
formItemFlag: !1,
|
|
4095
|
+
/* 已被表单设置「启用保存并提交流程」取代:从组件面板下架,不再允许新拖入。
|
|
4096
|
+
条目必须保留——getFieldWidgetByType 按 type 反查定义,老模板加载还要用它。 */
|
|
4097
|
+
deprecated: true,
|
|
4095
4098
|
options: {
|
|
4096
4099
|
name: "",
|
|
4097
4100
|
label: "保存并提交",
|
|
@@ -3892,13 +3892,11 @@ modules = {
|
|
|
3892
3892
|
}
|
|
3893
3893
|
if (transactional) {
|
|
3894
3894
|
let formRef = this.getFormRef();
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
: formRef?.reloadForm;
|
|
3899
|
-
if (typeof reloadMethod === "function") {
|
|
3895
|
+
// 整单刷新只能走宿主重挂载:就地 setFormData 会在表单已挂载时逐字段广播赋值,
|
|
3896
|
+
// 当场触发各字段 onChange(读到兄弟组件的旧值)并清空子表。
|
|
3897
|
+
if (typeof formRef?.reloadForm === "function") {
|
|
3900
3898
|
try {
|
|
3901
|
-
await
|
|
3899
|
+
await formRef.reloadForm();
|
|
3902
3900
|
} catch (error) {
|
|
3903
3901
|
let reloadError = error instanceof Error
|
|
3904
3902
|
? error
|
|
@@ -4071,17 +4069,13 @@ modules = {
|
|
|
4071
4069
|
}
|
|
4072
4070
|
this.treeSingleSavePending = true;
|
|
4073
4071
|
let keepSaveLocked = false;
|
|
4074
|
-
let reloadMethod
|
|
4075
|
-
= typeof formRef.reloadSavedFormData === "function"
|
|
4076
|
-
? formRef.reloadSavedFormData
|
|
4077
|
-
: formRef.reloadForm;
|
|
4078
4072
|
let installReloadRetry = () => {
|
|
4079
4073
|
let retryPromise = null;
|
|
4080
4074
|
this.treeSingleSaveReconcileTask = () => {
|
|
4081
4075
|
if (retryPromise) return retryPromise;
|
|
4082
4076
|
retryPromise = (async () => {
|
|
4083
4077
|
try {
|
|
4084
|
-
await
|
|
4078
|
+
await formRef.reloadForm();
|
|
4085
4079
|
delete obj.$table.editCloneRow;
|
|
4086
4080
|
this.treeSingleSaveReconcileTask = null;
|
|
4087
4081
|
this.treeSingleSavePending = false;
|