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.
Files changed (59) hide show
  1. package/package.json +1 -1
  2. package/src/components/baseArea/index.vue +82 -27
  3. package/src/components/bizTab/BizBillActions.vue +2 -2
  4. package/src/components/bizTab/bizBillDetailMixin.js +27 -9
  5. package/src/components/excelExport/exportFieldDialog.vue +11 -9
  6. package/src/components/table/config.js +6 -4
  7. package/src/components/table/index.js +78 -22
  8. package/src/components/table/state.js +42 -0
  9. package/src/components/table/tableForm.vue +16 -5
  10. package/src/components/table/tableFormMixin.js +35 -7
  11. package/src/components/table/vxeFilter/index.js +4 -2
  12. package/src/components/table/vxeFilter/mixin.js +10 -4
  13. package/src/components/wf/content.vue +12 -0
  14. package/src/components/wf/wf.js +72 -23
  15. package/src/components/wf/wfActionDropdown.vue +85 -0
  16. package/src/components/wf/wfActionItems.js +136 -0
  17. package/src/components/wf/wfAutoConfirm.js +55 -0
  18. package/src/components/wf/wfUserRange.js +53 -0
  19. package/src/components/wf/wfUtil.js +46 -2
  20. package/src/components/xform/form-designer/designer.js +6 -1
  21. package/src/components/xform/form-designer/form-widget/container-widget/data-table-widget.vue +9 -3
  22. package/src/components/xform/form-designer/form-widget/dialog/vabSearchDialog.vue +2 -1
  23. package/src/components/xform/form-designer/form-widget/field-widget/date-range-widget.vue +3 -2
  24. package/src/components/xform/form-designer/form-widget/field-widget/date-widget.vue +3 -12
  25. package/src/components/xform/form-designer/form-widget/field-widget/mixins/date-limit-mixin.js +2 -46
  26. package/src/components/xform/form-designer/form-widget/field-widget/mixins/relative-default-mixin.js +107 -0
  27. package/src/components/xform/form-designer/form-widget/field-widget/mixins/relativeDateUtil.js +321 -0
  28. package/src/components/xform/form-designer/form-widget/field-widget/mixins/time-limit-mixin.js +2 -17
  29. package/src/components/xform/form-designer/form-widget/field-widget/time-range-widget.vue +3 -2
  30. package/src/components/xform/form-designer/form-widget/field-widget/time-widget.vue +3 -12
  31. package/src/components/xform/form-designer/setting-panel/form-dynamicField-setting.vue +5 -5
  32. package/src/components/xform/form-designer/setting-panel/form-setting.vue +48 -26
  33. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +16 -19
  34. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/gutter-editor.vue +13 -12
  35. package/src/components/xform/form-designer/setting-panel/property-editor/container-table/table-dynamicField-editor.vue +16 -18
  36. package/src/components/xform/form-designer/setting-panel/property-editor/event-handler/afterColumnsCreated-editor.vue +30 -0
  37. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/search-dialog-event-editor.vue +237 -237
  38. package/src/components/xform/form-designer/setting-panel/property-editor/field-common/keyName-editor.vue +4 -4
  39. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-defaultValue-editor.vue +35 -36
  40. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultValue-editor.vue +35 -18
  41. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +1 -1
  42. package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-defaultValue-editor.vue +34 -36
  43. package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-defaultValue-editor.vue +35 -18
  44. package/src/components/xform/form-designer/setting-panel/property-editor/fixedQuery-editor.vue +39 -0
  45. package/src/components/xform/form-designer/setting-panel/property-editor/formScriptEnabled-editor.vue +20 -3
  46. package/src/components/xform/form-designer/setting-panel/property-editor/name-editor.vue +188 -178
  47. package/src/components/xform/form-designer/setting-panel/property-editor/relative-default-block.vue +369 -0
  48. package/src/components/xform/form-designer/setting-panel/property-editor/textFlag-editor.vue +1 -1
  49. package/src/components/xform/form-designer/setting-panel/propertyRegister.js +2 -0
  50. package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +35 -2
  51. package/src/components/xform/form-render/container-item/data-table-mixin.js +150 -75
  52. package/src/components/xform/form-render/container-item/detail-item.vue +8 -12
  53. package/src/components/xform/lang/en-US.js +3 -0
  54. package/src/components/xform/lang/zh-CN.js +3 -0
  55. package/src/components/xform/mixins/defaultHandle.js +18 -3
  56. package/src/components/xform/utils/fixedQueryUtil.js +93 -0
  57. package/src/views/user/outLink/cc_form_view.vue +33 -30
  58. package/src/views/user/wf/wf_manage/list.vue +17 -1
  59. 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="tableColumns"
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"><i class="iconfont icon-tuodongweizhi drag-option"></i></el-table-column>
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 = this.$baseLodash.cloneDeep(
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
- let i = t.splice(e.oldIndex, 1)[0];
242
- t.splice(e.newIndex, 0, i);
243
- /*t[e.newIndex].value;
244
- t[e.newIndex - 1] && t[e.newIndex - 1].value, t[e.newIndex + 1] && t[e.newIndex + 1].value;*/
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 = obj.$table.getCellValue(obj);
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 = obj.$table.getCellValue(obj);
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 = $table.getCellValue({
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 = $table.createParams({
109
+ let param = createParams({
104
110
  $table: $table,
105
111
  row,
106
112
  column: filterColumn,
107
113
  });
108
- let cellValue = $table.getCellValue(param);
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 = $table.getCellValue({
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"
@@ -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
- startTip = this.$t2(defaultStartTip, 'components.wf.startTip');
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
- let option = this.option;
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
+ }