cloud-web-corejs 1.1.0-dev.22 → 1.1.0-dev.24
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/bizTab/BizTabListPage.vue +66 -33
- package/src/components/bizTab/README.md +3 -1
- package/src/components/mobile/wf/content.vue +27 -3
- package/src/components/table/index.js +5 -2
- package/src/components/table/plugins/cell-area/index.js +10 -3
- package/src/components/wf/wfStartDialog.vue +1 -0
- package/src/components/wf/wfUtil.js +47 -29
- package/src/components/wf/wfVisibility.js +6 -0
- package/src/components/xform/form-designer/form-widget/container-widget/data-table-mixin.js +7 -0
- package/src/components/xform/form-designer/form-widget/container-widget/data-table-widget.vue +3 -1
- package/src/components/xform/form-designer/form-widget/field-widget/fieldMixin.js +25 -1
- package/src/components/xform/form-designer/setting-panel/form-setting.vue +14 -2
- package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +318 -12
- package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/table-column-dialog.vue +23 -7
- package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +48 -0
- package/src/components/xform/form-render/container-item/data-table-item.vue +8 -6
- package/src/components/xform/form-render/container-item/data-table-mixin.js +584 -24
- package/src/components/xform/form-render/container-item/detail-h5-item.vue +26 -16
- package/src/components/xform/form-render/container-item/detail-item.vue +350 -446
- package/src/components/xform/form-render/fieldControlMixin.js +2 -0
- package/src/components/xform/form-render/indexMixin.js +25 -15
- package/src/components/xform/mixins/businessLock.js +59 -0
- package/src/components/xform/mixins/wfStart.js +103 -0
- package/src/components/xform/mixins/wfVisibility.js +33 -0
- package/src/components/xform/styles/h5.scss +6 -1
- package/src/components/xform/utils/util.js +2 -0
- package/src/views/user/home/index.vue +1 -1
- package/src/views/user/home/net/distributor.vue +1015 -0
- package/src/views/user/home/net/index.vue +61 -0
|
@@ -1,446 +1,350 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
/**
|
|
3
|
-
* author: vformAdmin
|
|
4
|
-
* email: vdpadmin@163.com
|
|
5
|
-
* website: https://www.vform666.com
|
|
6
|
-
* date: 2021.08.18
|
|
7
|
-
* remark: 如果要分发VForm源码,需在本文件顶部保留此文件头信息!!
|
|
8
|
-
*/
|
|
9
|
-
-->
|
|
10
|
-
|
|
11
|
-
<template>
|
|
12
|
-
<container-item-wrapper :widget="widget">
|
|
13
|
-
<div
|
|
14
|
-
class="detail-wrap grid-container"
|
|
15
|
-
:class="[customClass]"
|
|
16
|
-
:ref="widget.id"
|
|
17
|
-
>
|
|
18
|
-
<div class="d-header clearfix" v-if="showHeader">
|
|
19
|
-
<div class="fl">
|
|
20
|
-
<i class="el-icon-info" />
|
|
21
|
-
{{ getI18nLabel(widget.options.label) }}
|
|
22
|
-
</div>
|
|
23
|
-
<!-- <div class="fr">
|
|
24
|
-
<el-button type="primary" plain class="button-sty" icon="el-icon-refresh-right" @click="reload">重置
|
|
25
|
-
</el-button>
|
|
26
|
-
<el-button type="primary" class="button-sty" icon="el-icon-check" @click="saveData" v-if="!wfInfo.id">保存
|
|
27
|
-
</el-button>
|
|
28
|
-
</div>-->
|
|
29
|
-
<div class="fr">
|
|
30
|
-
<template v-if="billNav">
|
|
31
|
-
<el-button
|
|
32
|
-
class="button-sty"
|
|
33
|
-
size="mini"
|
|
34
|
-
icon="el-icon-arrow-left"
|
|
35
|
-
:disabled="!billNav.canPrev"
|
|
36
|
-
@click="navBill(-1)"
|
|
37
|
-
>上一单</el-button
|
|
38
|
-
>
|
|
39
|
-
<el-button
|
|
40
|
-
class="button-sty"
|
|
41
|
-
size="mini"
|
|
42
|
-
:disabled="!billNav.canNext"
|
|
43
|
-
@click="navBill(1)"
|
|
44
|
-
>下一单<i class="el-icon-arrow-right el-icon--right"></i
|
|
45
|
-
></el-button>
|
|
46
|
-
</template>
|
|
47
|
-
<el-button
|
|
48
|
-
v-if="showSaveSubmitBtn()"
|
|
49
|
-
class="button-sty"
|
|
50
|
-
type="success"
|
|
51
|
-
icon="el-icon-video-play"
|
|
52
|
-
@click="saveAndSubmitWfHandle()"
|
|
53
|
-
>{{ saveSubmitButtonName }}</el-button
|
|
54
|
-
>
|
|
55
|
-
<el-button
|
|
56
|
-
v-if="showWfStartBtn()"
|
|
57
|
-
class="button-sty yyy"
|
|
58
|
-
type="success"
|
|
59
|
-
icon="el-icon-video-play"
|
|
60
|
-
@click="startWf"
|
|
61
|
-
>{{ wfStartButtonName }}</el-button
|
|
62
|
-
>
|
|
63
|
-
<template v-for="(subWidget, swIdx) in widget.widgetList">
|
|
64
|
-
<template v-if="'container' === subWidget.category">
|
|
65
|
-
<component
|
|
66
|
-
:is="subWidget.type + '-item'"
|
|
67
|
-
:widget="subWidget"
|
|
68
|
-
:key="swIdx"
|
|
69
|
-
:parent-list="widget.widgetList"
|
|
70
|
-
:index-of-parent-list="swIdx"
|
|
71
|
-
:parent-widget="widget"
|
|
72
|
-
>
|
|
73
|
-
<!-- 递归传递插槽!!! -->
|
|
74
|
-
<template
|
|
75
|
-
v-for="slot in Object.keys($scopedSlots)"
|
|
76
|
-
v-slot:[slot]="scope"
|
|
77
|
-
>
|
|
78
|
-
<slot :name="slot" v-bind="scope" />
|
|
79
|
-
</template>
|
|
80
|
-
</component>
|
|
81
|
-
</template>
|
|
82
|
-
<template v-else>
|
|
83
|
-
<component
|
|
84
|
-
:is="subWidget.type + '-widget'"
|
|
85
|
-
:field="subWidget"
|
|
86
|
-
:designer="null"
|
|
87
|
-
:key="swIdx"
|
|
88
|
-
:parent-list="widget.widgetList"
|
|
89
|
-
:index-of-parent-list="swIdx"
|
|
90
|
-
:parent-widget="widget"
|
|
91
|
-
>
|
|
92
|
-
<!-- 递归传递插槽!!! -->
|
|
93
|
-
<template
|
|
94
|
-
v-for="slot in Object.keys($scopedSlots)"
|
|
95
|
-
v-slot:[slot]="scope"
|
|
96
|
-
>
|
|
97
|
-
<slot :name="slot" v-bind="scope" />
|
|
98
|
-
</template>
|
|
99
|
-
</component>
|
|
100
|
-
</template>
|
|
101
|
-
</template>
|
|
102
|
-
</div>
|
|
103
|
-
</div>
|
|
104
|
-
<!-- 正文区:panes 是通用容器列表,既可直接挂 detail-pane(模块),也可挂 tab 等其它容器。
|
|
105
|
-
baseTabs 的锚点导航靠 getTabs() 探测 slot 子级:detail-pane 带 tabPaneGrade=2 会被收进
|
|
106
|
-
navList;tab 等容器两个条件都不满足,被静默跳过——即标签内的模块不进外层导航,由标签内
|
|
107
|
-
自己的 detail-plain 负责(见 docs/详情模块标签承载方案.md)。 -->
|
|
108
|
-
<baseTabs :showNav="!widget.options.hideNav && !plainMode">
|
|
109
|
-
<template v-for="(paneWidget, index) in widget.panes">
|
|
110
|
-
<detail-pane-widget
|
|
111
|
-
v-if="paneWidget.type === 'detail-pane'"
|
|
112
|
-
:key="paneWidget.id || index"
|
|
113
|
-
:widget="paneWidget"
|
|
114
|
-
:parent-list="widget.panes"
|
|
115
|
-
:index-of-parent-list="index"
|
|
116
|
-
:parent-widget="widget"
|
|
117
|
-
:col-height="widget.options.colHeight"
|
|
118
|
-
tabRef="baseTabRef"
|
|
119
|
-
:tabPaneGrade="2"
|
|
120
|
-
></detail-pane-widget>
|
|
121
|
-
<component
|
|
122
|
-
v-else-if="'container' === paneWidget.category"
|
|
123
|
-
:is="paneWidget.type + '-item'"
|
|
124
|
-
:key="paneWidget.id || index"
|
|
125
|
-
:widget="paneWidget"
|
|
126
|
-
:parent-list="widget.panes"
|
|
127
|
-
:index-of-parent-list="index"
|
|
128
|
-
:parent-widget="widget"
|
|
129
|
-
>
|
|
130
|
-
<!-- 递归传递插槽!!! -->
|
|
131
|
-
<template
|
|
132
|
-
v-for="slot in Object.keys($scopedSlots)"
|
|
133
|
-
v-slot:[slot]="scope"
|
|
134
|
-
>
|
|
135
|
-
<slot :name="slot" v-bind="scope" />
|
|
136
|
-
</template>
|
|
137
|
-
</component>
|
|
138
|
-
<component
|
|
139
|
-
v-else
|
|
140
|
-
:is="paneWidget.type + '-widget'"
|
|
141
|
-
:key="paneWidget.id || index"
|
|
142
|
-
:field="paneWidget"
|
|
143
|
-
:designer="null"
|
|
144
|
-
:parent-list="widget.panes"
|
|
145
|
-
:index-of-parent-list="index"
|
|
146
|
-
:parent-widget="widget"
|
|
147
|
-
>
|
|
148
|
-
<!-- 递归传递插槽!!! -->
|
|
149
|
-
<template
|
|
150
|
-
v-for="slot in Object.keys($scopedSlots)"
|
|
151
|
-
v-slot:[slot]="scope"
|
|
152
|
-
>
|
|
153
|
-
<slot :name="slot" v-bind="scope" />
|
|
154
|
-
</template>
|
|
155
|
-
</component>
|
|
156
|
-
</template>
|
|
157
|
-
</baseTabs>
|
|
158
|
-
</div>
|
|
159
|
-
</container-item-wrapper>
|
|
160
|
-
</template>
|
|
161
|
-
|
|
162
|
-
<script>
|
|
163
|
-
import emitter from "../../../../components/xform/utils/emitter";
|
|
164
|
-
import i18n from "../../../../components/xform/utils/i18n";
|
|
165
|
-
import refMixin from "../../../../components/xform/form-render/refMixin";
|
|
166
|
-
import ContainerItemWrapper from "./container-item-wrapper";
|
|
167
|
-
import containerItemMixin from "./containerItemMixin";
|
|
168
|
-
import detailPaneWidget from "../../../../components/xform/form-render/container-item/detail-pane-item";
|
|
169
|
-
import FieldComponents from "../../../../components/xform/form-designer/form-widget/field-widget/index";
|
|
170
|
-
|
|
171
|
-
import { initWf
|
|
172
|
-
import {
|
|
173
|
-
getWfButtonNames,
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
this.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
},
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
},
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
},
|
|
229
|
-
//
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
);
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if (
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
},
|
|
352
|
-
// 声明式触发流程启动(替代原注入按钮的点击),复用 wfUtil 的 openStartWfDialog
|
|
353
|
-
startWf() {
|
|
354
|
-
let ws = this.wfStart();
|
|
355
|
-
if (!ws || !ws.option || !ws.ctx) return;
|
|
356
|
-
// startConfirmText 原样透传:它只承载模板脚本 wfStartConfirmText 的文案(见 indexMixin
|
|
357
|
-
// 的 option 构造)。按钮名拼接与「后台 param19 自动确认」都由 wf.js 统一处理——
|
|
358
|
-
// 在这里替它拼默认文案的话,wf.js 会把它当成脚本自定义的告警,自动确认就失效了。
|
|
359
|
-
let innerOnStart = ws.option.onStart;
|
|
360
|
-
let formRef = this.getFormRef && this.getFormRef();
|
|
361
|
-
openStartWfDialog(ws.ctx, {
|
|
362
|
-
...ws.option, //浅拷贝:wfStartOption 是 formRef 上的共享对象,不可原地改
|
|
363
|
-
// 提交前置处理:确认框在 wfStartDialog 内部,这里(打开弹框前)是唯一能拦的位置。
|
|
364
|
-
// 既有的 onStart 是表单校验(仅 wfStartBindSave 开启时注入),把它的 done 换成
|
|
365
|
-
// 「跑前置脚本」,即得到「先校验、后脚本、再确认框」;没开自动保存时直接跑脚本。
|
|
366
|
-
onStart: (done) => {
|
|
367
|
-
let runBefore = () => {
|
|
368
|
-
if (!formRef || typeof formRef.runBeforeSubmitWf !== "function") {
|
|
369
|
-
return done();
|
|
370
|
-
}
|
|
371
|
-
formRef.runBeforeSubmitWf("wfStart").then((pass) => {
|
|
372
|
-
if (pass) done();
|
|
373
|
-
});
|
|
374
|
-
};
|
|
375
|
-
if (typeof innerOnStart === "function") {
|
|
376
|
-
innerOnStart(runBefore);
|
|
377
|
-
} else {
|
|
378
|
-
runBefore();
|
|
379
|
-
}
|
|
380
|
-
},
|
|
381
|
-
});
|
|
382
|
-
},
|
|
383
|
-
// 触发宿主翻单:step = -1 上一单 / +1 下一单
|
|
384
|
-
navBill(step) {
|
|
385
|
-
let host = this.getFormRef && this.getFormRef();
|
|
386
|
-
host = host && host.getListPageRef && host.getListPageRef();
|
|
387
|
-
host && host.navigateActiveBill && host.navigateActiveBill(step);
|
|
388
|
-
},
|
|
389
|
-
reload() {
|
|
390
|
-
this.getFormRef().$parent.$baseReload();
|
|
391
|
-
},
|
|
392
|
-
saveData() {
|
|
393
|
-
if (!!this.previewState) return;
|
|
394
|
-
this.getFormRef().saveForm();
|
|
395
|
-
},
|
|
396
|
-
createWf() {
|
|
397
|
-
if (!!this.previewState || !this.widget.options.wfEnabled) return;
|
|
398
|
-
let formTarget = this.getFormRef();
|
|
399
|
-
let formData = formTarget.formData;
|
|
400
|
-
if (formData && formData.object_foreign_id) {
|
|
401
|
-
let reportTemplate = formTarget.reportTemplate;
|
|
402
|
-
let formCode = reportTemplate.formCode;
|
|
403
|
-
let option = {
|
|
404
|
-
objId: formData.object_foreign_id, //单据ID
|
|
405
|
-
wfCode: formCode, //流程编码
|
|
406
|
-
showStartBtn: true, //需要启动按钮(语义不变)
|
|
407
|
-
injectStartBtn: false, //不走 DOM 强制注入,改由本组件模板声明式渲染
|
|
408
|
-
serviceId: "user",
|
|
409
|
-
startConfirmText: () => formTarget.getWfStartConfirmText(),
|
|
410
|
-
callback: ({ wfInfo, hasWf }) => {
|
|
411
|
-
this.wfInfo = wfInfo;
|
|
412
|
-
this.wfHasStarted = !!hasWf; //已启动则不显示启动按钮(与原注入条件 !hasWf 一致)
|
|
413
|
-
this.wfReady = true; //状态就绪后才显示按钮,避免回调前闪现
|
|
414
|
-
},
|
|
415
|
-
};
|
|
416
|
-
this.wfStartOption = option;
|
|
417
|
-
this.wfStartCtx = formTarget.$parent; //与 initWf 执行上下文一致,供 openStartWfDialog 使用
|
|
418
|
-
initWf.call(formTarget.$parent, option);
|
|
419
|
-
}
|
|
420
|
-
},
|
|
421
|
-
},
|
|
422
|
-
};
|
|
423
|
-
</script>
|
|
424
|
-
|
|
425
|
-
<style lang="scss" scoped>
|
|
426
|
-
.grid-container {
|
|
427
|
-
min-height: 50px;
|
|
428
|
-
//line-height: 48px;
|
|
429
|
-
//padding: 6px;
|
|
430
|
-
outline: 1px dashed #336699;
|
|
431
|
-
|
|
432
|
-
> div {
|
|
433
|
-
height: 100%;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
.form-widget-list {
|
|
437
|
-
// min-height: 28px;
|
|
438
|
-
height: 100%;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
.grid-container.selected,
|
|
443
|
-
.grid-cell.selected {
|
|
444
|
-
outline: 2px solid $--color-primary !important;
|
|
445
|
-
}
|
|
446
|
-
</style>
|
|
1
|
+
<!--
|
|
2
|
+
/**
|
|
3
|
+
* author: vformAdmin
|
|
4
|
+
* email: vdpadmin@163.com
|
|
5
|
+
* website: https://www.vform666.com
|
|
6
|
+
* date: 2021.08.18
|
|
7
|
+
* remark: 如果要分发VForm源码,需在本文件顶部保留此文件头信息!!
|
|
8
|
+
*/
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<container-item-wrapper :widget="widget">
|
|
13
|
+
<div
|
|
14
|
+
class="detail-wrap grid-container"
|
|
15
|
+
:class="[customClass]"
|
|
16
|
+
:ref="widget.id"
|
|
17
|
+
>
|
|
18
|
+
<div class="d-header clearfix" v-if="showHeader">
|
|
19
|
+
<div class="fl">
|
|
20
|
+
<i class="el-icon-info" />
|
|
21
|
+
{{ getI18nLabel(widget.options.label) }}
|
|
22
|
+
</div>
|
|
23
|
+
<!-- <div class="fr">
|
|
24
|
+
<el-button type="primary" plain class="button-sty" icon="el-icon-refresh-right" @click="reload">重置
|
|
25
|
+
</el-button>
|
|
26
|
+
<el-button type="primary" class="button-sty" icon="el-icon-check" @click="saveData" v-if="!wfInfo.id">保存
|
|
27
|
+
</el-button>
|
|
28
|
+
</div>-->
|
|
29
|
+
<div class="fr">
|
|
30
|
+
<template v-if="billNav">
|
|
31
|
+
<el-button
|
|
32
|
+
class="button-sty"
|
|
33
|
+
size="mini"
|
|
34
|
+
icon="el-icon-arrow-left"
|
|
35
|
+
:disabled="!billNav.canPrev"
|
|
36
|
+
@click="navBill(-1)"
|
|
37
|
+
>上一单</el-button
|
|
38
|
+
>
|
|
39
|
+
<el-button
|
|
40
|
+
class="button-sty"
|
|
41
|
+
size="mini"
|
|
42
|
+
:disabled="!billNav.canNext"
|
|
43
|
+
@click="navBill(1)"
|
|
44
|
+
>下一单<i class="el-icon-arrow-right el-icon--right"></i
|
|
45
|
+
></el-button>
|
|
46
|
+
</template>
|
|
47
|
+
<el-button
|
|
48
|
+
v-if="showSaveSubmitBtn()"
|
|
49
|
+
class="button-sty"
|
|
50
|
+
type="success"
|
|
51
|
+
icon="el-icon-video-play"
|
|
52
|
+
@click="saveAndSubmitWfHandle()"
|
|
53
|
+
>{{ saveSubmitButtonName }}</el-button
|
|
54
|
+
>
|
|
55
|
+
<el-button
|
|
56
|
+
v-if="showWfStartBtn()"
|
|
57
|
+
class="button-sty yyy"
|
|
58
|
+
type="success"
|
|
59
|
+
icon="el-icon-video-play"
|
|
60
|
+
@click="startWf"
|
|
61
|
+
>{{ wfStartButtonName }}</el-button
|
|
62
|
+
>
|
|
63
|
+
<template v-for="(subWidget, swIdx) in widget.widgetList">
|
|
64
|
+
<template v-if="'container' === subWidget.category">
|
|
65
|
+
<component
|
|
66
|
+
:is="subWidget.type + '-item'"
|
|
67
|
+
:widget="subWidget"
|
|
68
|
+
:key="swIdx"
|
|
69
|
+
:parent-list="widget.widgetList"
|
|
70
|
+
:index-of-parent-list="swIdx"
|
|
71
|
+
:parent-widget="widget"
|
|
72
|
+
>
|
|
73
|
+
<!-- 递归传递插槽!!! -->
|
|
74
|
+
<template
|
|
75
|
+
v-for="slot in Object.keys($scopedSlots)"
|
|
76
|
+
v-slot:[slot]="scope"
|
|
77
|
+
>
|
|
78
|
+
<slot :name="slot" v-bind="scope" />
|
|
79
|
+
</template>
|
|
80
|
+
</component>
|
|
81
|
+
</template>
|
|
82
|
+
<template v-else>
|
|
83
|
+
<component
|
|
84
|
+
:is="subWidget.type + '-widget'"
|
|
85
|
+
:field="subWidget"
|
|
86
|
+
:designer="null"
|
|
87
|
+
:key="swIdx"
|
|
88
|
+
:parent-list="widget.widgetList"
|
|
89
|
+
:index-of-parent-list="swIdx"
|
|
90
|
+
:parent-widget="widget"
|
|
91
|
+
>
|
|
92
|
+
<!-- 递归传递插槽!!! -->
|
|
93
|
+
<template
|
|
94
|
+
v-for="slot in Object.keys($scopedSlots)"
|
|
95
|
+
v-slot:[slot]="scope"
|
|
96
|
+
>
|
|
97
|
+
<slot :name="slot" v-bind="scope" />
|
|
98
|
+
</template>
|
|
99
|
+
</component>
|
|
100
|
+
</template>
|
|
101
|
+
</template>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
<!-- 正文区:panes 是通用容器列表,既可直接挂 detail-pane(模块),也可挂 tab 等其它容器。
|
|
105
|
+
baseTabs 的锚点导航靠 getTabs() 探测 slot 子级:detail-pane 带 tabPaneGrade=2 会被收进
|
|
106
|
+
navList;tab 等容器两个条件都不满足,被静默跳过——即标签内的模块不进外层导航,由标签内
|
|
107
|
+
自己的 detail-plain 负责(见 docs/详情模块标签承载方案.md)。 -->
|
|
108
|
+
<baseTabs :showNav="!widget.options.hideNav && !plainMode">
|
|
109
|
+
<template v-for="(paneWidget, index) in widget.panes">
|
|
110
|
+
<detail-pane-widget
|
|
111
|
+
v-if="paneWidget.type === 'detail-pane'"
|
|
112
|
+
:key="paneWidget.id || index"
|
|
113
|
+
:widget="paneWidget"
|
|
114
|
+
:parent-list="widget.panes"
|
|
115
|
+
:index-of-parent-list="index"
|
|
116
|
+
:parent-widget="widget"
|
|
117
|
+
:col-height="widget.options.colHeight"
|
|
118
|
+
tabRef="baseTabRef"
|
|
119
|
+
:tabPaneGrade="2"
|
|
120
|
+
></detail-pane-widget>
|
|
121
|
+
<component
|
|
122
|
+
v-else-if="'container' === paneWidget.category"
|
|
123
|
+
:is="paneWidget.type + '-item'"
|
|
124
|
+
:key="paneWidget.id || index"
|
|
125
|
+
:widget="paneWidget"
|
|
126
|
+
:parent-list="widget.panes"
|
|
127
|
+
:index-of-parent-list="index"
|
|
128
|
+
:parent-widget="widget"
|
|
129
|
+
>
|
|
130
|
+
<!-- 递归传递插槽!!! -->
|
|
131
|
+
<template
|
|
132
|
+
v-for="slot in Object.keys($scopedSlots)"
|
|
133
|
+
v-slot:[slot]="scope"
|
|
134
|
+
>
|
|
135
|
+
<slot :name="slot" v-bind="scope" />
|
|
136
|
+
</template>
|
|
137
|
+
</component>
|
|
138
|
+
<component
|
|
139
|
+
v-else
|
|
140
|
+
:is="paneWidget.type + '-widget'"
|
|
141
|
+
:key="paneWidget.id || index"
|
|
142
|
+
:field="paneWidget"
|
|
143
|
+
:designer="null"
|
|
144
|
+
:parent-list="widget.panes"
|
|
145
|
+
:index-of-parent-list="index"
|
|
146
|
+
:parent-widget="widget"
|
|
147
|
+
>
|
|
148
|
+
<!-- 递归传递插槽!!! -->
|
|
149
|
+
<template
|
|
150
|
+
v-for="slot in Object.keys($scopedSlots)"
|
|
151
|
+
v-slot:[slot]="scope"
|
|
152
|
+
>
|
|
153
|
+
<slot :name="slot" v-bind="scope" />
|
|
154
|
+
</template>
|
|
155
|
+
</component>
|
|
156
|
+
</template>
|
|
157
|
+
</baseTabs>
|
|
158
|
+
</div>
|
|
159
|
+
</container-item-wrapper>
|
|
160
|
+
</template>
|
|
161
|
+
|
|
162
|
+
<script>
|
|
163
|
+
import emitter from "../../../../components/xform/utils/emitter";
|
|
164
|
+
import i18n from "../../../../components/xform/utils/i18n";
|
|
165
|
+
import refMixin from "../../../../components/xform/form-render/refMixin";
|
|
166
|
+
import ContainerItemWrapper from "./container-item-wrapper";
|
|
167
|
+
import containerItemMixin from "./containerItemMixin";
|
|
168
|
+
import detailPaneWidget from "../../../../components/xform/form-render/container-item/detail-pane-item";
|
|
169
|
+
import FieldComponents from "../../../../components/xform/form-designer/form-widget/field-widget/index";
|
|
170
|
+
|
|
171
|
+
import { initWf } from "../../../../components/wf/wfUtil";
|
|
172
|
+
import {
|
|
173
|
+
getWfButtonNames,
|
|
174
|
+
DEFAULT_SAVE_SUBMIT_BTN,
|
|
175
|
+
} from "../../../../components/wf/wfButtonName";
|
|
176
|
+
import wfStartMixin from "@base/components/xform/mixins/wfStart";
|
|
177
|
+
|
|
178
|
+
export default {
|
|
179
|
+
name: "detail-item",
|
|
180
|
+
componentName: "ContainerItem",
|
|
181
|
+
mixins: [emitter, i18n, refMixin, containerItemMixin, wfStartMixin],
|
|
182
|
+
components: {
|
|
183
|
+
ContainerItemWrapper,
|
|
184
|
+
detailPaneWidget,
|
|
185
|
+
...FieldComponents,
|
|
186
|
+
},
|
|
187
|
+
props: {
|
|
188
|
+
widget: Object,
|
|
189
|
+
},
|
|
190
|
+
inject: ["refList", "sfRefList", "globalModel", "previewState"],
|
|
191
|
+
created() {
|
|
192
|
+
this.initRefList();
|
|
193
|
+
this.handleOnCreated();
|
|
194
|
+
this.initWfStartSettings();
|
|
195
|
+
},
|
|
196
|
+
mounted() {
|
|
197
|
+
this.handleOnMounted();
|
|
198
|
+
this.$nextTick(() => {
|
|
199
|
+
this.createWf();
|
|
200
|
+
});
|
|
201
|
+
},
|
|
202
|
+
beforeDestroy() {
|
|
203
|
+
this.unregisterFromRefList();
|
|
204
|
+
},
|
|
205
|
+
data() {
|
|
206
|
+
return {
|
|
207
|
+
wfInfo: {},
|
|
208
|
+
wfReady: false, // 流程状态是否已就绪(callback 返回后)
|
|
209
|
+
wfHasStarted: false, // 流程是否已启动(已启动则不显示启动按钮)
|
|
210
|
+
wfStartOption: null, // 启动流程所需 option(createWf 构造)
|
|
211
|
+
wfStartCtx: null, // openStartWfDialog 的执行上下文(与 initWf 一致)
|
|
212
|
+
};
|
|
213
|
+
},
|
|
214
|
+
computed: {
|
|
215
|
+
// 素身详情模式(宿主 VFormRender 传 plainDetailMode):去标题栏、去模块导航,只留模块
|
|
216
|
+
plainMode() {
|
|
217
|
+
let formRef = this.getFormRef && this.getFormRef();
|
|
218
|
+
return !!(formRef && formRef.plainDetailMode);
|
|
219
|
+
},
|
|
220
|
+
// 标题栏:模板配 hideHeader 或宿主素身模式,两者任一命中即不渲染
|
|
221
|
+
showHeader() {
|
|
222
|
+
return !this.plainMode && !this.widget.options.hideHeader;
|
|
223
|
+
},
|
|
224
|
+
saveSubmitButtonName() {
|
|
225
|
+
return (
|
|
226
|
+
getWfButtonNames().saveSubmitBtn || this.$t1(DEFAULT_SAVE_SUBMIT_BTN)
|
|
227
|
+
);
|
|
228
|
+
},
|
|
229
|
+
// 「上一单/下一单」翻单按钮状态:详情表单开启 billNavEnabled 且宿主列表有翻单快照时才显示。
|
|
230
|
+
// detail-item 在每次翻单时随详情表单重挂载,故此处按当前挂载时机取一次即可。
|
|
231
|
+
billNav() {
|
|
232
|
+
let formRef = this.getFormRef && this.getFormRef();
|
|
233
|
+
if (
|
|
234
|
+
!formRef ||
|
|
235
|
+
!formRef.formConfig ||
|
|
236
|
+
!formRef.formConfig.billNavEnabled
|
|
237
|
+
) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
let host = formRef.getListPageRef && formRef.getListPageRef();
|
|
241
|
+
if (!host || typeof host.getActiveBillNavState !== "function")
|
|
242
|
+
return null;
|
|
243
|
+
let state = host.getActiveBillNavState();
|
|
244
|
+
if (!state) return null;
|
|
245
|
+
return {
|
|
246
|
+
canPrev: state.index > 0,
|
|
247
|
+
canNext: state.index < state.rows.length - 1,
|
|
248
|
+
};
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
methods: {
|
|
252
|
+
// 解析流程启动信息:优先取表单实例(indexMixin,xform 主链路)暴露的,回退到本组件 createWf(旧路径)。
|
|
253
|
+
// 用方法实时求值,避免 computed 缓存导致早于 wf 就绪时求值后不再更新。
|
|
254
|
+
wfStart() {
|
|
255
|
+
let formRef = this.getFormRef && this.getFormRef();
|
|
256
|
+
if (formRef && formRef.wfStartOption) {
|
|
257
|
+
return {
|
|
258
|
+
ctx: formRef.wfStartCtx || formRef,
|
|
259
|
+
option: formRef.wfStartOption,
|
|
260
|
+
hasWf: !!formRef.hasWf,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
if (this.wfReady && this.wfStartOption && this.wfStartCtx) {
|
|
264
|
+
return {
|
|
265
|
+
ctx: this.wfStartCtx,
|
|
266
|
+
option: this.wfStartOption,
|
|
267
|
+
hasWf: this.wfHasStarted,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
return null;
|
|
271
|
+
},
|
|
272
|
+
// 与 showWfStartBtn 一样用方法而非 computed:流程状态是异步就绪的,computed 缓存会漏更新。
|
|
273
|
+
showSaveSubmitBtn() {
|
|
274
|
+
if (this.previewState) return false;
|
|
275
|
+
let formRef = this.getFormRef && this.getFormRef();
|
|
276
|
+
let formConfig = formRef && formRef.formConfig;
|
|
277
|
+
if (formRef && formRef.businessLocked) return false;
|
|
278
|
+
if (!formConfig || !formConfig.wfEnabled || !formConfig.saveSubmitEnabled)
|
|
279
|
+
return false;
|
|
280
|
+
if (formRef.dataId) return false; //只有新增页(编辑态一律不显示)
|
|
281
|
+
let wfParam = formRef.wfParam || {};
|
|
282
|
+
//流程已启动不显示(与 save_submit_wf_button-widget 的 isWfStarted 同口径)
|
|
283
|
+
if (formRef.hasWf || wfParam.hasWf || wfParam.wfInfo?.procInstId)
|
|
284
|
+
return false;
|
|
285
|
+
return true;
|
|
286
|
+
},
|
|
287
|
+
// 触发宿主翻单:step = -1 上一单 / +1 下一单
|
|
288
|
+
navBill(step) {
|
|
289
|
+
let host = this.getFormRef && this.getFormRef();
|
|
290
|
+
host = host && host.getListPageRef && host.getListPageRef();
|
|
291
|
+
host && host.navigateActiveBill && host.navigateActiveBill(step);
|
|
292
|
+
},
|
|
293
|
+
reload() {
|
|
294
|
+
this.getFormRef().$parent.$baseReload();
|
|
295
|
+
},
|
|
296
|
+
saveData() {
|
|
297
|
+
if (!!this.previewState) return;
|
|
298
|
+
this.getFormRef().saveForm();
|
|
299
|
+
},
|
|
300
|
+
createWf() {
|
|
301
|
+
if (!!this.previewState || !this.widget.options.wfEnabled) return;
|
|
302
|
+
let formTarget = this.getFormRef();
|
|
303
|
+
let formData = formTarget.formData;
|
|
304
|
+
if (formData && formData.object_foreign_id) {
|
|
305
|
+
let reportTemplate = formTarget.reportTemplate;
|
|
306
|
+
let formCode = reportTemplate.formCode;
|
|
307
|
+
let option = {
|
|
308
|
+
objId: formData.object_foreign_id, //单据ID
|
|
309
|
+
wfCode: formCode, //流程编码
|
|
310
|
+
showStartBtn: true, //需要启动按钮(语义不变)
|
|
311
|
+
injectStartBtn: false, //不走 DOM 强制注入,改由本组件模板声明式渲染
|
|
312
|
+
serviceId: "user",
|
|
313
|
+
startConfirmText: () => formTarget.getWfStartConfirmText(),
|
|
314
|
+
callback: ({ wfInfo, hasWf }) => {
|
|
315
|
+
this.wfInfo = wfInfo;
|
|
316
|
+
this.wfHasStarted = !!hasWf; //已启动则不显示启动按钮(与原注入条件 !hasWf 一致)
|
|
317
|
+
this.wfReady = true; //状态就绪后才显示按钮,避免回调前闪现
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
this.wfStartOption = option;
|
|
321
|
+
this.wfStartCtx = formTarget.$parent; //与 initWf 执行上下文一致,供 openStartWfDialog 使用
|
|
322
|
+
initWf.call(formTarget.$parent, option);
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
</script>
|
|
328
|
+
|
|
329
|
+
<style lang="scss" scoped>
|
|
330
|
+
.grid-container {
|
|
331
|
+
min-height: 50px;
|
|
332
|
+
//line-height: 48px;
|
|
333
|
+
//padding: 6px;
|
|
334
|
+
outline: 1px dashed #336699;
|
|
335
|
+
|
|
336
|
+
> div {
|
|
337
|
+
height: 100%;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.form-widget-list {
|
|
341
|
+
// min-height: 28px;
|
|
342
|
+
height: 100%;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.grid-container.selected,
|
|
347
|
+
.grid-cell.selected {
|
|
348
|
+
outline: 2px solid $--color-primary !important;
|
|
349
|
+
}
|
|
350
|
+
</style>
|