cloud-web-corejs 1.0.54-dev.800 → 1.0.54-dev.802
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/baseArea/index.vue +82 -27
- package/src/components/bizTab/BizBillActions.vue +2 -2
- package/src/components/bizTab/bizBillDetailMixin.js +27 -9
- package/src/components/excelExport/exportFieldDialog.vue +11 -9
- package/src/components/table/config.js +6 -4
- package/src/components/table/index.js +78 -22
- package/src/components/table/state.js +42 -0
- package/src/components/table/tableForm.vue +16 -5
- package/src/components/table/tableFormMixin.js +35 -7
- package/src/components/table/vxeFilter/index.js +4 -2
- package/src/components/table/vxeFilter/mixin.js +10 -4
- package/src/components/wf/content.vue +12 -0
- package/src/components/wf/wf.js +72 -23
- package/src/components/wf/wfActionDropdown.vue +85 -0
- package/src/components/wf/wfActionItems.js +136 -0
- package/src/components/wf/wfAutoConfirm.js +55 -0
- package/src/components/wf/wfUserRange.js +53 -0
- package/src/components/wf/wfUtil.js +46 -2
- package/src/components/xform/form-designer/designer.js +6 -1
- package/src/components/xform/form-designer/form-widget/container-widget/data-table-widget.vue +9 -3
- package/src/components/xform/form-designer/form-widget/dialog/vabSearchDialog.vue +2 -1
- package/src/components/xform/form-designer/form-widget/field-widget/date-range-widget.vue +3 -2
- package/src/components/xform/form-designer/form-widget/field-widget/date-widget.vue +3 -12
- package/src/components/xform/form-designer/form-widget/field-widget/mixins/date-limit-mixin.js +2 -46
- package/src/components/xform/form-designer/form-widget/field-widget/mixins/relative-default-mixin.js +107 -0
- package/src/components/xform/form-designer/form-widget/field-widget/mixins/relativeDateUtil.js +321 -0
- package/src/components/xform/form-designer/form-widget/field-widget/mixins/time-limit-mixin.js +2 -17
- package/src/components/xform/form-designer/form-widget/field-widget/time-range-widget.vue +3 -2
- package/src/components/xform/form-designer/form-widget/field-widget/time-widget.vue +3 -12
- package/src/components/xform/form-designer/setting-panel/form-dynamicField-setting.vue +5 -5
- package/src/components/xform/form-designer/setting-panel/form-setting.vue +48 -26
- package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +16 -19
- package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/gutter-editor.vue +13 -12
- package/src/components/xform/form-designer/setting-panel/property-editor/container-table/table-dynamicField-editor.vue +16 -18
- package/src/components/xform/form-designer/setting-panel/property-editor/event-handler/afterColumnsCreated-editor.vue +30 -0
- package/src/components/xform/form-designer/setting-panel/property-editor/field-button/search-dialog-event-editor.vue +237 -237
- package/src/components/xform/form-designer/setting-panel/property-editor/field-common/keyName-editor.vue +4 -4
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-defaultValue-editor.vue +35 -36
- package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultValue-editor.vue +35 -18
- package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-defaultValue-editor.vue +34 -36
- package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-defaultValue-editor.vue +35 -18
- package/src/components/xform/form-designer/setting-panel/property-editor/fixedQuery-editor.vue +39 -0
- package/src/components/xform/form-designer/setting-panel/property-editor/formScriptEnabled-editor.vue +20 -3
- package/src/components/xform/form-designer/setting-panel/property-editor/name-editor.vue +188 -178
- package/src/components/xform/form-designer/setting-panel/property-editor/relative-default-block.vue +369 -0
- package/src/components/xform/form-designer/setting-panel/property-editor/textFlag-editor.vue +1 -1
- package/src/components/xform/form-designer/setting-panel/propertyRegister.js +2 -0
- package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +35 -2
- package/src/components/xform/form-render/container-item/data-table-mixin.js +150 -75
- package/src/components/xform/form-render/container-item/detail-item.vue +8 -12
- package/src/components/xform/lang/en-US.js +3 -0
- package/src/components/xform/lang/zh-CN.js +3 -0
- package/src/components/xform/mixins/defaultHandle.js +18 -3
- package/src/components/xform/utils/fixedQueryUtil.js +93 -0
- package/src/views/user/outLink/cc_form_view.vue +33 -30
- package/src/views/user/wf/wf_manage/list.vue +17 -1
- package/src/components/xform/form-render/container-item/data-table-mixin copy.js +0 -5910
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 表格运行时状态收口。
|
|
3
|
+
*
|
|
4
|
+
* 背景:initVxeTable 早期把 tableName / isQueryAllPage / exportColumns 等运行时状态
|
|
5
|
+
* 直接挂在 vxe-grid 实例上。页面若用 v-if 销毁重建 grid 而不重跑 initVxeTable
|
|
6
|
+
* (如 pmd/product_problem_record/list.vue 里 showTable false→true 那一段),
|
|
7
|
+
* 新实例上这些属性全为 undefined,表现为:
|
|
8
|
+
* - 导出字段勾选丢失,且下次 addTableJson 会把服务端已存的 exportColumns 一并抹掉;
|
|
9
|
+
* - “查询全部页”偏好静默存不进去(tableName 取不到);
|
|
10
|
+
* - 分页器 total 与切换图标状态错乱(isQueryAllPage 恒 falsy)。
|
|
11
|
+
* 同源问题还导致过筛选面板的 $table.getCellValue is not a function。
|
|
12
|
+
*
|
|
13
|
+
* 现在统一存放在 $grid.params 上:params 对象随 vxeOption 由页面持有,
|
|
14
|
+
* 重建时原样传给新实例,因此状态可以跨重建存活。
|
|
15
|
+
*
|
|
16
|
+
* 兼容:写入时同步回写 $grid 实例属性,读取时 params 里没有再回落到实例属性。
|
|
17
|
+
* 未经 initVxeTable 初始化的表格(xform 自建 option 等)行为与改造前完全一致。
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** 读状态:优先 params,回落实例属性 */
|
|
21
|
+
export function getTableStateValue($grid, key) {
|
|
22
|
+
if (!$grid) return undefined;
|
|
23
|
+
let params = $grid.params;
|
|
24
|
+
if (params) {
|
|
25
|
+
let value = params[key];
|
|
26
|
+
if (value !== undefined && value !== null) return value;
|
|
27
|
+
}
|
|
28
|
+
return $grid[key];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** 写状态:params 与实例属性同时写,保证新旧读法都拿到同一个值 */
|
|
32
|
+
export function setTableState($grid, key, value) {
|
|
33
|
+
if (!$grid) return;
|
|
34
|
+
// params 是 prop 对象,只改其中的 key,不整体重新赋值
|
|
35
|
+
if ($grid.params) $grid.params[key] = value;
|
|
36
|
+
$grid[key] = value;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default {
|
|
40
|
+
getTableStateValue,
|
|
41
|
+
setTableState,
|
|
42
|
+
};
|
|
@@ -222,13 +222,18 @@
|
|
|
222
222
|
<el-table
|
|
223
223
|
ref="singleTable"
|
|
224
224
|
width="100%"
|
|
225
|
-
:data="
|
|
225
|
+
:data="dialogColumns"
|
|
226
226
|
border=""
|
|
227
227
|
row-key="field"
|
|
228
228
|
stripe=""
|
|
229
|
+
:row-class-name="dialogRowClassName"
|
|
229
230
|
>
|
|
230
231
|
<el-table-column type="index" width="35" fixed="left"></el-table-column>
|
|
231
|
-
<el-table-column label="" width="38"
|
|
232
|
+
<el-table-column label="" width="38">
|
|
233
|
+
<template slot-scope="scope">
|
|
234
|
+
<i v-if="!scope.row.lockValue" class="iconfont icon-tuodongweizhi drag-option"></i>
|
|
235
|
+
</template>
|
|
236
|
+
</el-table-column>
|
|
232
237
|
<el-table-column :label="$t2('名称', 'components.table.name')" width="150" prop="title">
|
|
233
238
|
<template slot-scope="scope">
|
|
234
239
|
{{ scope.row.title }}
|
|
@@ -236,8 +241,12 @@
|
|
|
236
241
|
</el-table-column>
|
|
237
242
|
<el-table-column :label="$t2('默认值', 'components.table.defaultValue')" width="375" prop="defaultValue">
|
|
238
243
|
<template slot-scope="scope">
|
|
244
|
+
<!-- 固定查询条件的值由业务通道注入,这里不给改,也不参与还原/确定的写值 -->
|
|
245
|
+
<span v-if="scope.row.lockValue" class="text-tip">
|
|
246
|
+
{{ $t1('固定条件') }}
|
|
247
|
+
</span>
|
|
239
248
|
<template
|
|
240
|
-
v-if="scope.row.defaultValueEnabled!==false && (scope.row.defaultValueEnabled || !scope.row.slot)">
|
|
249
|
+
v-else-if="scope.row.defaultValueEnabled!==false && (scope.row.defaultValueEnabled || !scope.row.slot)">
|
|
241
250
|
<template v-if="scope.row.type =='input'">
|
|
242
251
|
<el-input v-model="scope.row.defaultValue" size="small" clearable></el-input>
|
|
243
252
|
</template>
|
|
@@ -280,7 +289,7 @@
|
|
|
280
289
|
</el-table-column>
|
|
281
290
|
<el-table-column :label="$t2('是否常用', 'components.table.common')" width="70" prop="common">
|
|
282
291
|
<template slot-scope="scope">
|
|
283
|
-
<el-switch v-model="scope.row.common"></el-switch>
|
|
292
|
+
<el-switch v-model="scope.row.common" :disabled="scope.row.lockValue === true"></el-switch>
|
|
284
293
|
</template>
|
|
285
294
|
</el-table-column>
|
|
286
295
|
</el-table>
|
|
@@ -315,5 +324,7 @@ export default {
|
|
|
315
324
|
</script>
|
|
316
325
|
|
|
317
326
|
<style scoped>
|
|
318
|
-
|
|
327
|
+
.text-tip {
|
|
328
|
+
color: #909399;
|
|
329
|
+
}
|
|
319
330
|
</style>
|
|
@@ -15,7 +15,10 @@ modules = {
|
|
|
15
15
|
showAdvancedSearch: false,
|
|
16
16
|
form1Fields: [],
|
|
17
17
|
form2Fields: [],
|
|
18
|
+
/* 全量列,「确定」按它回写,隐藏列也在里面(不能丢,它照样往上送条件) */
|
|
18
19
|
tableColumns: [],
|
|
20
|
+
/* 弹框实际渲染的列,是 tableColumns 里非隐藏项的**引用**(同一批对象,改默认值直接生效) */
|
|
21
|
+
dialogColumns: [],
|
|
19
22
|
dialogVisible: false,
|
|
20
23
|
advancedFormData: {},
|
|
21
24
|
formDataClone: {},
|
|
@@ -213,13 +216,17 @@ modules = {
|
|
|
213
216
|
},
|
|
214
217
|
openTableColumnsDialog() {
|
|
215
218
|
let $grid = this.$parent;
|
|
216
|
-
let tableColumns = (tableColumns =
|
|
219
|
+
// 原写法 let tableColumns = (tableColumns = ...) 自引用触发 TDZ,
|
|
220
|
+
// 只因 Babel 把 let 降成 var 才没在浏览器里炸
|
|
221
|
+
let tableColumns = this.$baseLodash.cloneDeep(
|
|
217
222
|
$grid.params.searchColumns || []
|
|
218
|
-
)
|
|
223
|
+
);
|
|
219
224
|
tableColumns.forEach((item) => {
|
|
220
225
|
if (!item.widgetConfig) item.widgetConfig = {};
|
|
221
226
|
});
|
|
222
227
|
this.tableColumns = tableColumns;
|
|
228
|
+
// 隐藏字段(如查询区里存树ID的隐藏输入框)是内部条件,不给用户看也不给拖
|
|
229
|
+
this.dialogColumns = tableColumns.filter((item) => !item.hidden);
|
|
223
230
|
this.dialogVisible = true;
|
|
224
231
|
this.$nextTick(() => {
|
|
225
232
|
this.$nextTick(() => {
|
|
@@ -231,20 +238,34 @@ modules = {
|
|
|
231
238
|
let e = this.$refs.singleTable.$el.querySelectorAll(
|
|
232
239
|
".el-table__body-wrapper > table > tbody"
|
|
233
240
|
)[0],
|
|
234
|
-
t = this.tableColumns
|
|
241
|
+
t = this.tableColumns,
|
|
242
|
+
visible = this.dialogColumns;
|
|
235
243
|
this.sortable = Sortable.create(e, {
|
|
236
244
|
ghostClass: "sortable-ghost",
|
|
245
|
+
// 固定查询条件不可拖动(它的位置由配置决定,个性化也不该记)
|
|
246
|
+
filter: ".drag-disabled",
|
|
237
247
|
setData: function (e) {
|
|
238
248
|
e.setData("Text", "");
|
|
239
249
|
},
|
|
240
250
|
onEnd: function (e) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
251
|
+
// 拖拽发生在「可见列」上,隐藏列不在其中,所以要把新次序同步回全量列:
|
|
252
|
+
// 先在可见列里挪好,再按「新位置的后一个可见列」定位插到全量列的哪里。
|
|
253
|
+
let moved = visible.splice(e.oldIndex, 1)[0];
|
|
254
|
+
visible.splice(e.newIndex, 0, moved);
|
|
255
|
+
let fullIndex = t.indexOf(moved);
|
|
256
|
+
if (fullIndex > -1) {
|
|
257
|
+
t.splice(fullIndex, 1);
|
|
258
|
+
}
|
|
259
|
+
let nextVisible = visible[e.newIndex + 1];
|
|
260
|
+
let insertAt = nextVisible ? t.indexOf(nextVisible) : t.length;
|
|
261
|
+
t.splice(insertAt < 0 ? t.length : insertAt, 0, moved);
|
|
245
262
|
},
|
|
246
263
|
});
|
|
247
264
|
},
|
|
265
|
+
/** 固定查询条件行加标记类:禁拖拽(Sortable filter)+ 视觉上区分 */
|
|
266
|
+
dialogRowClassName({ row }) {
|
|
267
|
+
return row && row.lockValue ? "drag-disabled" : "";
|
|
268
|
+
},
|
|
248
269
|
dialogPrimary(newTableColumns) {
|
|
249
270
|
let searchColumns = this.$baseLodash.cloneDeep(
|
|
250
271
|
newTableColumns || this.tableColumns
|
|
@@ -266,6 +287,13 @@ modules = {
|
|
|
266
287
|
// this.$set(this, "formData", {});
|
|
267
288
|
// this.$set(this, "advancedFormData", {});
|
|
268
289
|
searchColumns.forEach((form1Field) => {
|
|
290
|
+
// 固定查询条件:值由业务通道(树点选 / 脚本 setValue / 页面回填)注入,
|
|
291
|
+
// 「确定」「还原」都不许覆盖它,否则一点设置就把当前上下文查丢了。
|
|
292
|
+
// 注意只认 lockValue,不认 fixed —— 手写页面的 fixed 列(如分支)
|
|
293
|
+
// 正是靠这里按 defaultValue 回填的,跳过它们会打掉原有行为。
|
|
294
|
+
if (form1Field.lockValue) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
269
297
|
let nullValue = this.getNullValue(form1Field);
|
|
270
298
|
let defaultValue = nullValue;
|
|
271
299
|
if (form1Field.defaultValueEnabled !== false) {
|
|
@@ -3,6 +3,8 @@ import XEUtils from 'xe-utils';
|
|
|
3
3
|
import FilterComplex from './FilterComplex.vue';
|
|
4
4
|
import FilterContent from './FilterContent.vue';
|
|
5
5
|
import FilterInput from './FilterInput.vue';
|
|
6
|
+
// 同 mixin.js:直接引用工具函数,避免依赖 $table 实例上的补丁方法
|
|
7
|
+
import { getCellValue } from '../util/index';
|
|
6
8
|
|
|
7
9
|
let moudule = {};
|
|
8
10
|
let configUtil = {
|
|
@@ -77,7 +79,7 @@ configUtil.VXETable.renderer.add('FilterContent', {
|
|
|
77
79
|
const {
|
|
78
80
|
vals
|
|
79
81
|
} = option.data;
|
|
80
|
-
let cellValue =
|
|
82
|
+
let cellValue = getCellValue(obj);
|
|
81
83
|
return vals.includes(cellValue);
|
|
82
84
|
}
|
|
83
85
|
});
|
|
@@ -140,7 +142,7 @@ configUtil.VXETable.renderer.add('FilterInput', {
|
|
|
140
142
|
data
|
|
141
143
|
} = option;
|
|
142
144
|
|
|
143
|
-
let cellValue =
|
|
145
|
+
let cellValue = getCellValue(obj);
|
|
144
146
|
|
|
145
147
|
if (cellValue) {
|
|
146
148
|
return cellValue.indexOf(data) > -1;
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
// 直接引用工具函数,不走 $table 实例上的补丁方法:
|
|
2
|
+
// initVxeTable 只把 getCellValue/createParams 挂在初始化时的那个 xTable 实例上,
|
|
3
|
+
// 页面若用 v-if 销毁重建 vxe-grid(如 product_problem_record/list.vue),
|
|
4
|
+
// 新实例上没有这两个方法,筛选面板会报 $table.getCellValue is not a function
|
|
5
|
+
import { getCellValue, createParams } from "../util/index";
|
|
6
|
+
|
|
1
7
|
let modules = {};
|
|
2
8
|
|
|
3
9
|
modules = {
|
|
@@ -51,7 +57,7 @@ modules = {
|
|
|
51
57
|
let lsm = {};
|
|
52
58
|
let colValList = [];
|
|
53
59
|
fullData.map((row, $rowIndex) => {
|
|
54
|
-
let cellValue =
|
|
60
|
+
let cellValue = getCellValue({
|
|
55
61
|
row,
|
|
56
62
|
$rowIndex,
|
|
57
63
|
$table,
|
|
@@ -100,19 +106,19 @@ modules = {
|
|
|
100
106
|
return false;
|
|
101
107
|
}
|
|
102
108
|
const vals = option1.data.vals || [];
|
|
103
|
-
let param =
|
|
109
|
+
let param = createParams({
|
|
104
110
|
$table: $table,
|
|
105
111
|
row,
|
|
106
112
|
column: filterColumn,
|
|
107
113
|
});
|
|
108
|
-
let cellValue =
|
|
114
|
+
let cellValue = getCellValue(param);
|
|
109
115
|
return !vals.includes(cellValue);
|
|
110
116
|
});
|
|
111
117
|
return item == null;
|
|
112
118
|
});
|
|
113
119
|
let lsm2 = {};
|
|
114
120
|
datas.map((row, $rowIndex) => {
|
|
115
|
-
let cellValue =
|
|
121
|
+
let cellValue = getCellValue({
|
|
116
122
|
row,
|
|
117
123
|
$rowIndex,
|
|
118
124
|
$table,
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
v-if="!isHideWf"
|
|
7
7
|
>
|
|
8
8
|
<template #default>
|
|
9
|
+
<!-- 审批按钮条留在流程模块内,不随 wfActionInHeaderEnabled 搬走或隐藏。
|
|
10
|
+
开了该开关时,详情标题栏另挂一份(wfActionDropdown.vue):通过/驳回/撤回平铺,
|
|
11
|
+
其余收进「流程操作」下拉。 -->
|
|
9
12
|
<div
|
|
13
|
+
ref="wfActionBar"
|
|
10
14
|
style="margin: -36px 0 8px 124px; position: relative; z-index: 2; height: 28px"
|
|
11
15
|
v-if="!wfConfig.hiddenAllButton"
|
|
12
16
|
>
|
|
@@ -97,6 +101,7 @@
|
|
|
97
101
|
</el-button>
|
|
98
102
|
<addOpinionButton
|
|
99
103
|
v-if="showAddOpinionButton"
|
|
104
|
+
ref="addOpinionBtn"
|
|
100
105
|
@confirm="reloadContent()"
|
|
101
106
|
:wfInfo="wfInfo"
|
|
102
107
|
:wfSendTaskId="wfSendTaskId"
|
|
@@ -625,6 +630,8 @@
|
|
|
625
630
|
</span>
|
|
626
631
|
</el-dialog>
|
|
627
632
|
|
|
633
|
+
<!-- append-to-body 必须留着:本弹框在 baseTabPane 的 v-show 子树里,
|
|
634
|
+
「流程信息」一折叠就跟着 display:none,标题栏那份审批入口点了会毫无反应 -->
|
|
628
635
|
<el-dialog
|
|
629
636
|
v-if="rejectDialogVisible"
|
|
630
637
|
:visible.sync="rejectDialogVisible"
|
|
@@ -634,6 +641,7 @@
|
|
|
634
641
|
custom-class="dialog-style wf-dialog"
|
|
635
642
|
v-el-drag-dialog
|
|
636
643
|
v-el-dialog-center
|
|
644
|
+
:append-to-body="true"
|
|
637
645
|
>
|
|
638
646
|
<template #title>
|
|
639
647
|
<span class="el-dialog__title"
|
|
@@ -711,6 +719,7 @@
|
|
|
711
719
|
</el-button>
|
|
712
720
|
</span>
|
|
713
721
|
</el-dialog>
|
|
722
|
+
<!-- 同上:折叠态下要能弹出来,append-to-body 不能去掉 -->
|
|
714
723
|
<el-dialog
|
|
715
724
|
v-if="agreeDialogVisible"
|
|
716
725
|
:visible.sync="agreeDialogVisible"
|
|
@@ -720,6 +729,7 @@
|
|
|
720
729
|
custom-class="dialog-style wf-dialog"
|
|
721
730
|
v-el-drag-dialog
|
|
722
731
|
v-el-dialog-center
|
|
732
|
+
:append-to-body="true"
|
|
723
733
|
>
|
|
724
734
|
<template #title>
|
|
725
735
|
<span class="el-dialog__title"
|
|
@@ -935,6 +945,7 @@
|
|
|
935
945
|
>
|
|
936
946
|
</span>
|
|
937
947
|
</el-dialog>
|
|
948
|
+
<!-- 同上:折叠态下要能弹出来,append-to-body 不能去掉 -->
|
|
938
949
|
<el-dialog
|
|
939
950
|
v-if="revokeDialogVisible"
|
|
940
951
|
:visible.sync="revokeDialogVisible"
|
|
@@ -944,6 +955,7 @@
|
|
|
944
955
|
custom-class="dialog-style wf-dialog"
|
|
945
956
|
v-el-drag-dialog
|
|
946
957
|
v-el-dialog-center
|
|
958
|
+
:append-to-body="true"
|
|
947
959
|
>
|
|
948
960
|
<template #title>
|
|
949
961
|
<span class="el-dialog__title"
|
package/src/components/wf/wf.js
CHANGED
|
@@ -3,6 +3,8 @@ import {getToken} from "../../utils/auth";
|
|
|
3
3
|
import settingConfig from "@/settings.js";
|
|
4
4
|
import {selectDialogMixins} from "../../mixins/selectDialog";
|
|
5
5
|
import {requireViewCompat} from "@base/utils/resolveViewComponent";
|
|
6
|
+
import {getWfButtonNames, loadWfButtonNames} from "./wfButtonName";
|
|
7
|
+
import {isWfAutoConfirm, loadWfAutoConfirm} from "./wfAutoConfirm";
|
|
6
8
|
|
|
7
9
|
let configUtil = {
|
|
8
10
|
baseUrl: process.env.VUE_APP_BASE_API,
|
|
@@ -1681,7 +1683,9 @@ wfStartMixin = {
|
|
|
1681
1683
|
wfUserRangeEnabled: false,
|
|
1682
1684
|
preStartResult:[],
|
|
1683
1685
|
showSetCandidateDialog2:false,
|
|
1684
|
-
wfSubmitted: false
|
|
1686
|
+
wfSubmitted: false,
|
|
1687
|
+
//param19 自动确认:确认框延后到 subWfStartForm(保存之后、preStart 之后)再决定弹不弹
|
|
1688
|
+
deferStartConfirm: false
|
|
1685
1689
|
};
|
|
1686
1690
|
},
|
|
1687
1691
|
computed: {
|
|
@@ -1707,6 +1711,50 @@ wfStartMixin = {
|
|
|
1707
1711
|
});
|
|
1708
1712
|
})
|
|
1709
1713
|
},
|
|
1714
|
+
buildStartFormData(){
|
|
1715
|
+
return {
|
|
1716
|
+
modelId: this.wfStartForm.modelId,
|
|
1717
|
+
objTypeCode: this.code,
|
|
1718
|
+
objId: this.dataId,
|
|
1719
|
+
formData: this.startParam || {},
|
|
1720
|
+
formCode: this.formCode || null
|
|
1721
|
+
// name:this.wfName
|
|
1722
|
+
};
|
|
1723
|
+
},
|
|
1724
|
+
//启动确认框的默认文案。param18 配了按钮名就跟随它,没配维持原有的 $t2 兜底链。
|
|
1725
|
+
async getDefaultStartTip(){
|
|
1726
|
+
await loadWfButtonNames(getTarget(this));
|
|
1727
|
+
let btnName = getWfButtonNames().submitBtn;
|
|
1728
|
+
if (btnName) {
|
|
1729
|
+
//只能用 $t1(找不到 key 原样返回),$t2 在 i18n 命中 key 时会把拼进去的名字吞掉
|
|
1730
|
+
return this.$t1(`您确定要${btnName}吗?`);
|
|
1731
|
+
}
|
|
1732
|
+
let wfStartOperateName =
|
|
1733
|
+
settingConfig.wfStartOperateName ||
|
|
1734
|
+
settingConfig.wfStartButtonName ||
|
|
1735
|
+
"启动流程";
|
|
1736
|
+
return this.$t2(
|
|
1737
|
+
"您确定要" + wfStartOperateName + "吗?",
|
|
1738
|
+
'components.wf.startTip'
|
|
1739
|
+
);
|
|
1740
|
+
},
|
|
1741
|
+
/**
|
|
1742
|
+
* param19 延后的那道确认框,由 subWfStartForm 在 preStart 之后调。
|
|
1743
|
+
* @returns {Promise<Boolean>} true 继续启动,false 已取消
|
|
1744
|
+
*/
|
|
1745
|
+
async confirmDeferredStart(){
|
|
1746
|
+
let that = getTarget(this);
|
|
1747
|
+
let startTip = await this.getDefaultStartTip();
|
|
1748
|
+
try {
|
|
1749
|
+
await that.$baseConfirm(startTip);
|
|
1750
|
+
return true;
|
|
1751
|
+
} catch (e) {
|
|
1752
|
+
//这时候单据可能已经被自动保存过了,必须走 close() 触发 onCancel,
|
|
1753
|
+
//否则宿主那边的提交态(bizTab 的 billSubmitting 之类)没人来解,保存按钮会永久禁用。
|
|
1754
|
+
this.close();
|
|
1755
|
+
return false;
|
|
1756
|
+
}
|
|
1757
|
+
},
|
|
1710
1758
|
initWfUserRangeParam(){
|
|
1711
1759
|
let that = getTarget(this);
|
|
1712
1760
|
return that.$http({
|
|
@@ -1783,16 +1831,25 @@ wfStartMixin = {
|
|
|
1783
1831
|
}
|
|
1784
1832
|
);
|
|
1785
1833
|
}
|
|
1786
|
-
let wfStartOperateName =
|
|
1787
|
-
settingConfig.wfStartOperateName ||
|
|
1788
|
-
settingConfig.wfStartButtonName ||
|
|
1789
|
-
"启动流程";
|
|
1790
|
-
let defaultStartTip = "您确定要" + wfStartOperateName + "吗?";
|
|
1791
1834
|
let startTip;
|
|
1792
1835
|
if (typeof customStartTip === "string" && customStartTip.trim()) {
|
|
1836
|
+
//模板脚本 wfStartConfirmText 自定义的提示语:多是金额超限之类的业务告警,
|
|
1837
|
+
//必须由人确认,不受 param19 自动确认影响。
|
|
1793
1838
|
startTip = customStartTip;
|
|
1794
1839
|
} else {
|
|
1795
|
-
|
|
1840
|
+
//系统默认文案才受自动确认开关管
|
|
1841
|
+
await loadWfAutoConfirm(that);
|
|
1842
|
+
//param12 关着时压根不会有「修改候选人」弹框,延后就没有意义,
|
|
1843
|
+
//确认框留在原位(保存之前);两个开关都为 true 才延后。
|
|
1844
|
+
if (isWfAutoConfirm() && this.wfUserRangeEnabled) {
|
|
1845
|
+
//确认框延后到 subWfStartForm:那里才是「单据已保存(如果开了自动保存)、
|
|
1846
|
+
//preStart 也探过」的时点。探到候选人就由「修改候选人」弹框顶替这道确认框,
|
|
1847
|
+
//探不到才把它补上——没有候选人弹框时它是唯一的把关,不能省。
|
|
1848
|
+
this.deferStartConfirm = true;
|
|
1849
|
+
this.startSubmit();
|
|
1850
|
+
return;
|
|
1851
|
+
}
|
|
1852
|
+
startTip = await this.getDefaultStartTip();
|
|
1796
1853
|
}
|
|
1797
1854
|
that
|
|
1798
1855
|
.$baseConfirm(startTip)
|
|
@@ -1827,30 +1884,22 @@ wfStartMixin = {
|
|
|
1827
1884
|
return false;
|
|
1828
1885
|
}
|
|
1829
1886
|
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
var objId = this.dataId;
|
|
1833
|
-
|
|
1834
|
-
let startParam = this.startParam || {};
|
|
1835
|
-
let formCode = this.formCode || null;
|
|
1836
|
-
|
|
1837
|
-
var data = {
|
|
1838
|
-
modelId: modelId,
|
|
1839
|
-
objTypeCode: this.code,
|
|
1840
|
-
objId: objId,
|
|
1841
|
-
formData: startParam,
|
|
1842
|
-
formCode: formCode
|
|
1843
|
-
// name:this.wfName
|
|
1844
|
-
};
|
|
1845
|
-
this.startFormData = data;
|
|
1887
|
+
this.startFormData = this.buildStartFormData();
|
|
1846
1888
|
|
|
1847
1889
|
if(this.wfUserRangeEnabled){
|
|
1848
1890
|
this.preStartResult = await this.preStart() || []
|
|
1849
1891
|
if(this.preStartResult.length){
|
|
1892
|
+
//有候选人弹框顶替确认框,param19 延后的那道就不用补了
|
|
1893
|
+
this.deferStartConfirm = false;
|
|
1850
1894
|
this.openSetCandidateDialog()
|
|
1851
1895
|
return
|
|
1852
1896
|
}
|
|
1853
1897
|
}
|
|
1898
|
+
//没有候选人弹框 → 把 param19 延后的确认框补上(见 initWfInfo)
|
|
1899
|
+
if (this.deferStartConfirm) {
|
|
1900
|
+
this.deferStartConfirm = false;
|
|
1901
|
+
if (!(await this.confirmDeferredStart())) return;
|
|
1902
|
+
}
|
|
1854
1903
|
this.startSubmitHanlde(this.startFormData);
|
|
1855
1904
|
|
|
1856
1905
|
},
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="wf-action-dropdown-wrap button-sty" v-show="items.length">
|
|
3
|
+
<!-- 通过 / 驳回 / 撤回 挪出下拉,在标题栏直接平铺;其余操作仍收在「流程操作」下拉里 -->
|
|
4
|
+
<el-button
|
|
5
|
+
v-for="item in standaloneItems"
|
|
6
|
+
:key="item.key"
|
|
7
|
+
:type="item.buttonType || 'primary'"
|
|
8
|
+
:icon="item.iconClass || item.elIcon"
|
|
9
|
+
class="button-sty"
|
|
10
|
+
@click="item.run(wfVm)"
|
|
11
|
+
>{{ itemLabel(item) }}
|
|
12
|
+
</el-button>
|
|
13
|
+
<el-dropdown trigger="hover" v-if="dropdownItems.length">
|
|
14
|
+
<el-button type="primary" class="button-sty">
|
|
15
|
+
{{ $t1("流程操作") }}
|
|
16
|
+
<i class="el-icon-arrow-down el-icon--right"></i>
|
|
17
|
+
</el-button>
|
|
18
|
+
<el-dropdown-menu slot="dropdown">
|
|
19
|
+
<el-dropdown-item
|
|
20
|
+
v-for="item in dropdownItems"
|
|
21
|
+
:key="item.key"
|
|
22
|
+
:icon="item.elIcon"
|
|
23
|
+
@click.native="item.run(wfVm)"
|
|
24
|
+
>
|
|
25
|
+
<i v-if="item.iconClass" :class="item.iconClass"></i>
|
|
26
|
+
{{ itemLabel(item) }}
|
|
27
|
+
</el-dropdown-item>
|
|
28
|
+
</el-dropdown-menu>
|
|
29
|
+
</el-dropdown>
|
|
30
|
+
</div>
|
|
31
|
+
</template>
|
|
32
|
+
|
|
33
|
+
<script>
|
|
34
|
+
import {
|
|
35
|
+
getVisibleWfActionItems,
|
|
36
|
+
HEADER_STANDALONE_KEYS,
|
|
37
|
+
} from "./wfActionItems";
|
|
38
|
+
|
|
39
|
+
export default {
|
|
40
|
+
name: "WfActionDropdown",
|
|
41
|
+
props: {
|
|
42
|
+
// 流程面板实例(content.vue),下拉项显隐读它的 wfInfo,点击调它的方法
|
|
43
|
+
wfVm: {
|
|
44
|
+
type: Object,
|
|
45
|
+
required: true,
|
|
46
|
+
},
|
|
47
|
+
// 不收进下拉、直接平铺成独立按钮的操作 key
|
|
48
|
+
standaloneKeys: {
|
|
49
|
+
type: Array,
|
|
50
|
+
default: () => HEADER_STANDALONE_KEYS,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
computed: {
|
|
54
|
+
// 求值时会读 wfVm 上的响应式字段,跨实例也能跟着流程状态更新
|
|
55
|
+
items() {
|
|
56
|
+
return getVisibleWfActionItems(this.wfVm);
|
|
57
|
+
},
|
|
58
|
+
standaloneItems() {
|
|
59
|
+
return this.items.filter((item) => this.isStandalone(item));
|
|
60
|
+
},
|
|
61
|
+
dropdownItems() {
|
|
62
|
+
return this.items.filter((item) => !this.isStandalone(item));
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
methods: {
|
|
66
|
+
isStandalone(item) {
|
|
67
|
+
return (this.standaloneKeys || []).indexOf(item.key) > -1;
|
|
68
|
+
},
|
|
69
|
+
itemLabel(item) {
|
|
70
|
+
if (item.i18nPath) {
|
|
71
|
+
return this.$t2(item.defaultLabel, item.i18nPath);
|
|
72
|
+
}
|
|
73
|
+
return this.$t1 ? this.$t1(item.defaultLabel) : item.defaultLabel;
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<style scoped>
|
|
80
|
+
/* 标题栏 .fr 内其余按钮都是行内元素,包裹层必须跟着行内排,否则会另起一行 */
|
|
81
|
+
.wf-action-dropdown-wrap {
|
|
82
|
+
display: inline-block;
|
|
83
|
+
vertical-align: middle;
|
|
84
|
+
}
|
|
85
|
+
</style>
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 流程审批操作清单。详情标题栏下拉与流程模块按钮条共用同一套显隐条件,
|
|
3
|
+
* 避免两处各写一遍之后漂移。
|
|
4
|
+
*
|
|
5
|
+
* vm 是 content.vue 实例(挂了 wfContentMixin)。
|
|
6
|
+
*
|
|
7
|
+
* buttonType 只在「平铺成独立按钮」时用得上(见 HEADER_STANDALONE_KEYS),
|
|
8
|
+
* 取值与流程模块按钮条里同名按钮保持一致。
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/* 详情标题栏里不收进下拉、直接平铺成独立按钮的操作。
|
|
12
|
+
顺序按 getWfActionItems 的定义序,不按这里的书写序。 */
|
|
13
|
+
export const HEADER_STANDALONE_KEYS = ["agree", "reject", "revoke"];
|
|
14
|
+
|
|
15
|
+
export function getWfActionItems(vm) {
|
|
16
|
+
let wfInfo = (vm && vm.wfInfo) || {};
|
|
17
|
+
let toTransfer
|
|
18
|
+
= wfInfo.toTransfer === null || wfInfo.toTransfer === undefined
|
|
19
|
+
? !!wfInfo.toSubmit
|
|
20
|
+
: !!wfInfo.toTransfer;
|
|
21
|
+
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
key: "agree",
|
|
25
|
+
buttonType: "success",
|
|
26
|
+
show: !!wfInfo.toSubmit,
|
|
27
|
+
defaultLabel: "通过",
|
|
28
|
+
i18nPath: "components.wf.agree",
|
|
29
|
+
iconClass: "iconfont icon-tongguo",
|
|
30
|
+
run: (wfVm) => wfVm.openAgreeDialog(),
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
key: "manual",
|
|
34
|
+
buttonType: "warning",
|
|
35
|
+
show: !!wfInfo.toInterrupt,
|
|
36
|
+
defaultLabel: "中断",
|
|
37
|
+
i18nPath: "components.wf.manual",
|
|
38
|
+
iconClass: "iconfont icon-caozuozhongduan",
|
|
39
|
+
run: (wfVm) => wfVm.openManualDialog(),
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
key: "reject",
|
|
43
|
+
buttonType: "danger",
|
|
44
|
+
show: !!wfInfo.toReject,
|
|
45
|
+
defaultLabel: "驳回",
|
|
46
|
+
i18nPath: "components.wf.reject",
|
|
47
|
+
iconClass: "iconfont icon-a-bohui1",
|
|
48
|
+
run: (wfVm) => wfVm.rejectWfTask(),
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
key: "transfer",
|
|
52
|
+
buttonType: "primary",
|
|
53
|
+
show: toTransfer,
|
|
54
|
+
defaultLabel: "转办",
|
|
55
|
+
i18nPath: "components.wf.transfer",
|
|
56
|
+
iconClass: "iconfont icon-zhuanban",
|
|
57
|
+
run: (wfVm) => wfVm.openChangeWfForm(),
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
key: "urging",
|
|
61
|
+
buttonType: "primary",
|
|
62
|
+
show: !!wfInfo.toInterrupt,
|
|
63
|
+
defaultLabel: "催办",
|
|
64
|
+
i18nPath: "components.wf.urging",
|
|
65
|
+
iconClass: "iconfont icon-cuiban",
|
|
66
|
+
run: (wfVm) => wfVm.openUrgingDialog(),
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
key: "addIncreaseSign",
|
|
70
|
+
buttonType: "primary",
|
|
71
|
+
show: !!(vm.increaseSignEnabled && wfInfo.toAddIncreaseSign),
|
|
72
|
+
defaultLabel: "加签",
|
|
73
|
+
i18nPath: "components.wf.addIncreaseSign",
|
|
74
|
+
elIcon: "el-icon-plus",
|
|
75
|
+
run: (wfVm) => wfVm.openAddIncreaseSign(),
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
key: "deleteIncreaseSign",
|
|
79
|
+
buttonType: "primary",
|
|
80
|
+
show: !!(vm.increaseSignEnabled && wfInfo.toDeleteIncreaseSign),
|
|
81
|
+
defaultLabel: "减签",
|
|
82
|
+
i18nPath: "components.wf.deleteIncreaseSign",
|
|
83
|
+
elIcon: "el-icon-delete",
|
|
84
|
+
run: (wfVm) => wfVm.openDeleteTaskUserDialog(),
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
key: "talk",
|
|
88
|
+
buttonType: "primary",
|
|
89
|
+
show: !!(vm.toTalk && wfInfo.toLinkup),
|
|
90
|
+
defaultLabel: "沟通",
|
|
91
|
+
i18nPath: "components.wf.talk",
|
|
92
|
+
elIcon: "el-icon-chat-dot-square",
|
|
93
|
+
run: (wfVm) => wfVm.openTalkDialog(),
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
key: "setCandidate",
|
|
97
|
+
buttonType: "primary",
|
|
98
|
+
show: !!wfInfo.toSetCandidate,
|
|
99
|
+
defaultLabel: "修改候选人",
|
|
100
|
+
i18nPath: "components.wf.setCandidate",
|
|
101
|
+
elIcon: "el-icon-user",
|
|
102
|
+
run: (wfVm) => wfVm.openSetCandidateDialog(null),
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
key: "revoke",
|
|
106
|
+
buttonType: "danger",
|
|
107
|
+
show: !!wfInfo.toRevoke,
|
|
108
|
+
defaultLabel: "撤回",
|
|
109
|
+
i18nPath: "components.wf.revoke",
|
|
110
|
+
elIcon: "el-icon-document-delete",
|
|
111
|
+
run: (wfVm) => wfVm.openRevokeDialog(null),
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
key: "addOpinion",
|
|
115
|
+
buttonType: "primary",
|
|
116
|
+
show: !!vm.showAddOpinionButton,
|
|
117
|
+
defaultLabel: "补充意见",
|
|
118
|
+
run: (wfVm) => {
|
|
119
|
+
let btn = wfVm.$refs && wfVm.$refs.addOpinionBtn;
|
|
120
|
+
if (btn && btn.openDialog) btn.openDialog();
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
key: "editScript",
|
|
125
|
+
buttonType: "primary",
|
|
126
|
+
show: !!wfInfo.wfAdmin,
|
|
127
|
+
defaultLabel: "修改脚本",
|
|
128
|
+
elIcon: "el-icon-edit",
|
|
129
|
+
run: (wfVm) => wfVm.openWfFlowEleScriptDialog(),
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function getVisibleWfActionItems(vm) {
|
|
135
|
+
return getWfActionItems(vm).filter((item) => item.show);
|
|
136
|
+
}
|