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
@@ -5,6 +5,7 @@ import containerItemMixin from "./containerItemMixin";
5
5
 
6
6
  import * as formatUtil from "../../../../components/xform/utils/format.js";
7
7
  import tableConfig from "../../../../components/table/config.js";
8
+ import { getTableStateValue } from "../../../../components/table/state";
8
9
  import { extendDeeply } from "../../../../utils/index.js";
9
10
  import {
10
11
  assembleAxiosConfig,
@@ -26,6 +27,7 @@ import {
26
27
  resolveColumnRequiredFlag,
27
28
  } from "../../../../components/xform/utils/tableColumnHelper";
28
29
  import { mergeQueryParam } from "../../../../components/xform/utils/queryParamUtil";
30
+ import { isFixedQueryWidget } from "../../../../components/xform/utils/fixedQueryUtil";
29
31
  import { isUrlValueColumn } from "../../../../components/xform/utils/attachmentValueUtil";
30
32
  import {
31
33
  EXPORT_TYPE,
@@ -1280,6 +1282,7 @@ modules = {
1280
1282
  const finish = () => {
1281
1283
  this.initFieldSchemaData(true);
1282
1284
  this.afterDynamicColumnsCommonWidget(effectiveColumns);
1285
+ this.emitAfterColumnsCreated(columns);
1283
1286
  resolve(columns);
1284
1287
  };
1285
1288
  if (reloadResult?.then) {
@@ -1288,6 +1291,7 @@ modules = {
1288
1291
  finish();
1289
1292
  }
1290
1293
  } else {
1294
+ this.emitAfterColumnsCreated(columns);
1291
1295
  resolve(columns);
1292
1296
  }
1293
1297
  },
@@ -1295,6 +1299,35 @@ modules = {
1295
1299
  );
1296
1300
  });
1297
1301
  },
1302
+ /**
1303
+ * 表头(列)创建完成后的统一出口:首次建表和运行时重建列(setTableColumns /
1304
+ * 动态列加载)两条链路都经这里,脚本拿到的一定是已经写进 VXE 的最终列。
1305
+ *
1306
+ * 脚本签名:function (dataId, formCode, columns, $grid)
1307
+ * columns —— 应用到 VXE 的列配置数组(含 checkbox 列、分组表头 children)
1308
+ * $grid —— vxe-grid 实例,需要活列对象时用 $grid.getTableColumn()
1309
+ *
1310
+ * 注意:每次表头重建都会触发(动态列表单首屏会触发两次:静态列建表一次、
1311
+ * 动态列回来重建一次),脚本必须幂等。
1312
+ * @param {Array} columns 已应用的列配置。
1313
+ */
1314
+ emitAfterColumnsCreated(columns) {
1315
+ const script = this.widget.options.afterColumnsCreated;
1316
+ if (!script) return;
1317
+ // 列刚写进 vxeOption,DOM 表头还没渲染完,等一拍脚本才能操作表头节点
1318
+ this.$nextTick(() => {
1319
+ try {
1320
+ this.handleCustomEvent(
1321
+ script,
1322
+ ["columns", "$grid"],
1323
+ [columns || [], this.getGridTable()]
1324
+ );
1325
+ } catch (error) {
1326
+ // handleCustomEvent 已按配置弹「前端脚本异常」,这里吞掉避免打断建表后续流程
1327
+ console.error("afterColumnsCreated 脚本执行异常", error);
1328
+ }
1329
+ });
1330
+ },
1298
1331
  /**
1299
1332
  * 替换列配置并刷新 VXE 列、行 schema 和组件选项。
1300
1333
  * @param {Array} tableColumns 新列配置。
@@ -1549,17 +1582,21 @@ modules = {
1549
1582
  * @param {Object} options 可覆盖默认重置行为。
1550
1583
  */
1551
1584
  resetForm(options) {
1552
- let formData = this.formModel;
1553
1585
  let ignoreFields = options?.ignoreFields || [];
1554
- this.widget.widgetList.forEach((subWidget) => {
1555
- if (
1556
- !ignoreFields.length ||
1557
- !ignoreFields.includes(subWidget.options.name)
1558
- ) {
1559
- let widgetRef = this.getWidgetRef(subWidget.options.name);
1560
- if (widgetRef && widgetRef.setValue) widgetRef.setValue(null);
1561
- if (this.isVabsearchFlagWidget(subWidget))
1562
- widgetRef.setShowValue(null);
1586
+ // getSearchFormData 同口径递归各类容器:查询字段放进栅格/标签页等容器后
1587
+ // 一样要被清空,容器节点本身跳过。
1588
+ loopHandleWidget(this.widget.widgetList, (subWidget) => {
1589
+ if (subWidget.category === "container") return;
1590
+ let widgetName = subWidget.options.name;
1591
+ // 固定查询条件与调用方传的 ignoreFields 取并集,一并跳过
1592
+ if (ignoreFields.includes(widgetName) || isFixedQueryWidget(subWidget)) {
1593
+ return;
1594
+ }
1595
+ let widgetRef = this.getWidgetRef(widgetName);
1596
+ if (!widgetRef) return;
1597
+ if (widgetRef.setValue) widgetRef.setValue(null);
1598
+ if (this.isVabsearchFlagWidget(subWidget) && widgetRef.setShowValue) {
1599
+ widgetRef.setShowValue(null);
1563
1600
  }
1564
1601
  });
1565
1602
  },
@@ -1651,17 +1688,22 @@ modules = {
1651
1688
  getSearchCondition: function () {
1652
1689
  let extraAccessData = this.extraAccessData || {};
1653
1690
  let searchFormData = this.getSearchFormData();
1654
- let defaultData = {};
1655
1691
 
1656
1692
  // let globalReqData = baseRefUtil.getReportGlobalMap();//全局请求参数
1657
- let tableCondition = this.getTableCondition();
1693
+ let tableCondition = this.getTableCondition() || {};
1658
1694
  let conditions = {
1659
- ...defaultData,
1660
1695
  ...tableCondition,
1661
1696
  ...searchFormData,
1662
1697
  ...extraAccessData,
1663
1698
  // ...globalReqData
1664
1699
  };
1700
+ // tableCondition 的 condition 此前恒被 searchFormData 顶掉(getSearchFormData
1701
+ // 一定返回 condition 数组),等于这个通道只能传平铺参数。改为与宿主 queryParam
1702
+ // 同一套追加合并规则:同 field 以 tableCondition 为准。整体优先级
1703
+ // 查询区用户输入 < tableCondition < 宿主 queryParam(后者在 ajax.query 里合并)。
1704
+ if (tableCondition.condition) {
1705
+ mergeQueryParam(conditions, { condition: tableCondition.condition });
1706
+ }
1665
1707
  return conditions;
1666
1708
  },
1667
1709
  /**
@@ -2017,7 +2059,7 @@ modules = {
2017
2059
  if (this.widget.options.showPagination) {
2018
2060
  let proxyInfo = $grid.getProxyInfo();
2019
2061
  let searchCount = true;
2020
- let isQueryAllPage = $grid.isQueryAllPage;
2062
+ let isQueryAllPage = getTableStateValue($grid, "isQueryAllPage");
2021
2063
  if (isQueryAllPage === false) {
2022
2064
  searchCount = false;
2023
2065
  }
@@ -2088,6 +2130,10 @@ modules = {
2088
2130
  let type = item.type ?? null;
2089
2131
  // let widgetType = item.widgetType ?? widgetType;
2090
2132
  // let isRange = item.isRange || false;
2133
+ // 固定查询条件:lockValue 让公共表格层跳过写值(刷新/还原/确定都不清它),
2134
+ // fixed 复用公共层已有语义,让个性化 json 回灌时不挪位置、不改常用。
2135
+ // 两者分开的原因见 utils/fixedQueryUtil.js 文件头。
2136
+ let fixedQuery = isFixedQueryWidget(widget);
2091
2137
  searchColumns.push({
2092
2138
  title: this.getI18nLabel(options.label),
2093
2139
  field: this.getFieldKeyName(widget),
@@ -2096,6 +2142,11 @@ modules = {
2096
2142
  // isRange,
2097
2143
  common: true,
2098
2144
  disabled: options.disabled,
2145
+ // hidden 的字段仍要留在 searchColumns(它照样往上送条件),
2146
+ // 只是不进「查询条件设置」弹框的列表,见 table/tableFormMixin.js
2147
+ hidden: !!options.hidden,
2148
+ lockValue: fixedQuery,
2149
+ fixed: fixedQuery,
2099
2150
  defaultValueEnabled: !!type,
2100
2151
  slot: options.name,
2101
2152
  widget: widget,
@@ -2576,67 +2627,72 @@ modules = {
2576
2627
  let scriptCode = this.getScriptCode();
2577
2628
  let $grid = this.getGridTable();
2578
2629
  let originOption = $grid.params.originOption;
2579
- let formData = {};
2630
+ // 组装请求参数。必须等 tableFormStop 闸门放开后才求值,所以整体包成
2631
+ // 函数、由 toDo 调用:查询区默认值的写入(tableForm 的 handleSyncFun)
2632
+ // 与搜索控件实例化都发生在闸门释放之后,提前取参只会拿到一份空条件——
2633
+ // 「查询条件设置」存的默认值、控件 options.defaultValue、控件 created
2634
+ // 里赋的值,首查一律带不上。口径与 components/table/index.js 的通用表格
2635
+ // 一致(那边 param() 本就写在 toDo 内)。
2636
+ const buildReqData = () => {
2637
+ let formData = {};
2638
+
2639
+ // 明细·选择导出已按勾选行 id 精确定位,再叠加主表搜索条件既无意义、又可能
2640
+ // 与明细口径的字段名冲突造成双重过滤,故只有它排除搜索条件;
2641
+ // 明细·条件导出与主表条件导出一样,必须带上搜索条件。
2642
+ if (
2643
+ customParam?.exportParam?.type !== EXPORT_TYPE.ITEM_SELECTED
2644
+ ) {
2645
+ formData = tableOption.param ? tableOption.param() || {} : {};
2646
+ }
2647
+ const queryParams = Object.assign({}, formData);
2648
+
2649
+ // 处理排序条件
2650
+ /*if (sorts) {
2651
+ const firstSort = sorts[0];
2652
+ if (firstSort) {
2653
+ queryParams.sort = firstSort.property;
2654
+ queryParams.order = firstSort.order;
2655
+ }
2656
+ }*/
2580
2657
 
2581
- // 明细·选择导出已按勾选行 id 精确定位,再叠加主表搜索条件既无意义、又可能
2582
- // 与明细口径的字段名冲突造成双重过滤,故只有它排除搜索条件;
2583
- // 明细·条件导出与主表条件导出一样,必须带上搜索条件。
2584
- if (
2585
- customParam?.exportParam?.type !== EXPORT_TYPE.ITEM_SELECTED
2586
- ) {
2587
- formData = tableOption.param ? tableOption.param() || {} : {};
2588
- }
2589
- const queryParams = Object.assign({}, formData);
2590
-
2591
- // 处理排序条件
2592
- /*if (sorts) {
2593
- const firstSort = sorts[0];
2594
- if (firstSort) {
2595
- queryParams.sort = firstSort.property;
2596
- queryParams.order = firstSort.order;
2658
+ // 处理筛选条件
2659
+ if (filters) {
2660
+ filters.forEach(({ property, values }) => {
2661
+ queryParams[property] = values.join(",");
2662
+ });
2597
2663
  }
2598
- }*/
2599
2664
 
2600
- // 处理筛选条件
2601
- if (filters) {
2602
- filters.forEach(({ property, values }) => {
2603
- queryParams[property] = values.join(",");
2604
- });
2605
- }
2665
+ if (page.pageSize !== undefined) {
2666
+ queryParams["size"] = page.pageSize;
2667
+ queryParams["current"] = page.currentPage;
2668
+ }
2606
2669
 
2607
- if (page.pageSize !== undefined) {
2608
- queryParams["size"] = page.pageSize;
2609
- queryParams["current"] = page.currentPage;
2610
- }
2670
+ let isQueryAllPage = getTableStateValue($grid, "isQueryAllPage");
2671
+ /* if (isQueryAllPage === false) {
2672
+ queryParams.searchCount = false;
2673
+ } */
2674
+ queryParams.searchCount = isQueryAllPage !== false;
2675
+ Object.assign(queryParams, param);
2676
+
2677
+ // 宿主(选择弹框/表单弹框/表单抽屉)注入的查询参数:condition 追加合并,
2678
+ // 其余键平铺覆盖,见 utils/queryParamUtil.js
2679
+ if (that.dataTableConfig.queryParam) {
2680
+ mergeQueryParam(queryParams, that.dataTableConfig.queryParam);
2681
+ }
2611
2682
 
2612
- // let $grid = this.getGridTable();
2613
- let isQueryAllPage = $grid.isQueryAllPage;
2614
- let pathStr1 = "";
2615
- /* if (isQueryAllPage === false) {
2616
- queryParams.searchCount = false;
2617
- } */
2618
- queryParams.searchCount = isQueryAllPage !== false;
2619
- Object.assign(queryParams, param);
2620
-
2621
- // let formRef = that.getFormRef();
2622
- // let dataTableConfig = formRef.$attrs.dataTableOption || {};
2623
- // 宿主(选择弹框/表单弹框/表单抽屉)注入的查询参数:condition 追加合并,
2624
- // 其余键平铺覆盖,见 utils/queryParamUtil.js
2625
- if (that.dataTableConfig.queryParam) {
2626
- mergeQueryParam(queryParams, that.dataTableConfig.queryParam);
2627
- }
2683
+ return {
2684
+ ...queryParams,
2685
+ };
2686
+ };
2628
2687
 
2629
2688
  let reqPath = typeof path === "function" ? path() : path;
2630
2689
  let accessReturnType =
2631
2690
  this.widget.options.accessReturnType || "2";
2632
2691
 
2633
2692
  return new Promise((resolve, reject) => {
2634
- let reqData = {
2635
- ...queryParams,
2636
- };
2637
2693
  if (scriptCode) {
2638
- let index = 0;
2639
2694
  let toDo = () => {
2695
+ let reqData = buildReqData();
2640
2696
  // let f = new Function("dataId", "formCode", "param", "done", accessScript);
2641
2697
  let done = (res) => {
2642
2698
  // this.clearRowWidgets();
@@ -2750,19 +2806,7 @@ modules = {
2750
2806
  };
2751
2807
  this.loadDefaultQueryList(reqData, done, customParam);
2752
2808
  };
2753
- let loopHandle = () => {
2754
- if (index < 500 && $grid.tableFormStop === true) {
2755
- //阻塞列表查询,或者次数达到500时,自动释放
2756
- index++;
2757
- setTimeout(() => {
2758
- loopHandle();
2759
- }, 10);
2760
- } else {
2761
- if ($grid.tableFormStop) $grid.tableFormStop = false;
2762
- toDo();
2763
- }
2764
- };
2765
- loopHandle();
2809
+ this.runAfterTableFormReady($grid, toDo);
2766
2810
  } else {
2767
2811
  resolve();
2768
2812
  }
@@ -2894,6 +2938,7 @@ modules = {
2894
2938
  }
2895
2939
  // 列已就绪,补建 created 阶段被延后的行 schema
2896
2940
  this.flushPendingSchemaInit();
2941
+ this.emitAfterColumnsCreated(opts?.columns || columns);
2897
2942
  this.tryAutoLoadDynamicColumns().finally(() => {
2898
2943
  if (!isQueryTable) {
2899
2944
  setTimeout(() => {
@@ -2903,6 +2948,36 @@ modules = {
2903
2948
  });
2904
2949
  });
2905
2950
  },
2951
+ /**
2952
+ * 等查询区就绪后再执行 fn。
2953
+ *
2954
+ * tableForm 挂载时立刻把 $grid.tableFormStop 置 true 把列表查询拦下,直到它
2955
+ * 把查询条件的默认值写进 formModel、并渲染出查询控件后才释放(见
2956
+ * components/table/tableFormMixin.js 的 mounted / handleSyncFun)。
2957
+ *
2958
+ * 调用方必须把「取查询条件」也放进 fn 里:闸门只推迟 fn 的执行时机,在闸门
2959
+ * 之外提前求值的参数拿到的是查询区还没初始化时的空条件。
2960
+ *
2961
+ * 兜底:最多等 500×10ms(5s),超时强制放行,避免查询区异常时列表空转。
2962
+ * @param {Object} $grid VXE Grid 实例。
2963
+ * @param {Function} fn 放行后执行的回调。
2964
+ */
2965
+ runAfterTableFormReady($grid, fn) {
2966
+ let index = 0;
2967
+ let loopHandle = () => {
2968
+ if (index < 500 && $grid.tableFormStop === true) {
2969
+ //阻塞列表查询,或者次数达到500时,自动释放
2970
+ index++;
2971
+ setTimeout(() => {
2972
+ loopHandle();
2973
+ }, 10);
2974
+ } else {
2975
+ if ($grid.tableFormStop) $grid.tableFormStop = false;
2976
+ fn();
2977
+ }
2978
+ };
2979
+ loopHandle();
2980
+ },
2906
2981
  /**
2907
2982
  * 深度遍历分组列和叶子列。
2908
2983
  * @param {Array} columns 列配置。
@@ -175,6 +175,8 @@ import {
175
175
  DEFAULT_SUBMIT_BTN,
176
176
  DEFAULT_SAVE_SUBMIT_BTN,
177
177
  } from "../../../../components/wf/wfButtonName";
178
+ import { loadWfAutoConfirm } from "../../../../components/wf/wfAutoConfirm";
179
+ import { loadWfUserRange } from "../../../../components/wf/wfUserRange";
178
180
  import settingConfig from "@/settings.js";
179
181
 
180
182
  export default {
@@ -193,9 +195,11 @@ export default {
193
195
  created() {
194
196
  this.initRefList();
195
197
  this.handleOnCreated();
196
- //只有流程表单才需要按钮名,避免给普通详情页平白多一次请求(模块内全局只发一次)
198
+ //只有流程表单才需要按钮名/自动确认开关,避免给普通详情页平白多一次请求(模块内全局只发一次)
197
199
  if (this.getFormRef()?.formConfig?.wfEnabled) {
198
200
  loadWfButtonNames(this);
201
+ loadWfAutoConfirm(this);
202
+ loadWfUserRange(this);
199
203
  }
200
204
  },
201
205
  mounted() {
@@ -349,12 +353,9 @@ export default {
349
353
  startWf() {
350
354
  let ws = this.wfStart();
351
355
  if (!ws || !ws.option || !ws.ctx) return;
352
- // 启动确认提示语跟随「提交流程按钮名」:包一层现成的 startConfirmText 钩子,
353
- // 既保住模板脚本 wfStartConfirmText 的最高优先级,又不必改公共的 wf.js
354
- // (wf.js 默认分支走 $t2(文案, key),i18n 命中 key 会把自定义按钮名吞掉)。
355
- let inner = ws.option.startConfirmText;
356
- //只有后台真配了按钮名才改提示语;没配就返空,让 wf.js 走它自己的默认链
357
- let btnName = getWfButtonNames().submitBtn;
356
+ // startConfirmText 原样透传:它只承载模板脚本 wfStartConfirmText 的文案(见 indexMixin
357
+ // option 构造)。按钮名拼接与「后台 param19 自动确认」都由 wf.js 统一处理——
358
+ // 在这里替它拼默认文案的话,wf.js 会把它当成脚本自定义的告警,自动确认就失效了。
358
359
  let innerOnStart = ws.option.onStart;
359
360
  let formRef = this.getFormRef && this.getFormRef();
360
361
  openStartWfDialog(ws.ctx, {
@@ -377,11 +378,6 @@ export default {
377
378
  runBefore();
378
379
  }
379
380
  },
380
- startConfirmText: async (ctx) => {
381
- let text = typeof inner === "function" ? await inner.call(this, ctx) : inner;
382
- if (typeof text === "string" && text.trim()) return text; //模板脚本优先
383
- return btnName ? `您确定要${btnName}吗?` : ""; //返空 → wf.js 走自身默认
384
- },
385
381
  });
386
382
  },
387
383
  // 触发宿主翻单:step = -1 上一单 / +1 下一单
@@ -190,6 +190,9 @@ export default {
190
190
  readonly: "Readonly",
191
191
  disabled: "Disabled",
192
192
  hidden: "Hidden",
193
+ fixedQuery: "Fixed Query Condition",
194
+ fixedQueryHelp:
195
+ "Keeps its value when Refresh / Revert / Confirm runs, and is read-only in Query Condition Setting",
193
196
  textContent: "Text",
194
197
  htmlContent: "HTML",
195
198
  clearable: "Clearable",
@@ -344,6 +344,9 @@ export default {
344
344
  readonly: "只读",
345
345
  disabled: "禁用",
346
346
  hidden: "隐藏",
347
+ fixedQuery: "固定查询条件",
348
+ fixedQueryHelp:
349
+ "开启后该条件不被刷新、查询条件设置的还原/确定清空,且在查询条件设置里只读",
347
350
  textContent: "静态文字",
348
351
  preWrap: "自动换行",
349
352
  htmlContent: "HTML",
@@ -3,6 +3,14 @@ import { saveUserLog } from "@base/api/user";
3
3
  import settingConfig from "@/settings";
4
4
  import { openStartWfDialog } from "../../../components/wf/wfUtil";
5
5
  import { getWfButtonNames } from "../../../components/wf/wfButtonName";
6
+ import {
7
+ isWfAutoConfirm,
8
+ loadWfAutoConfirm,
9
+ } from "../../../components/wf/wfAutoConfirm";
10
+ import {
11
+ isWfUserRangeEnabled,
12
+ loadWfUserRange,
13
+ } from "../../../components/wf/wfUserRange";
6
14
 
7
15
  let modules = {};
8
16
  modules = {
@@ -134,7 +142,7 @@ modules = {
134
142
  });
135
143
  }
136
144
  },
137
- saveAndSubmitWfHandle(option) {
145
+ async saveAndSubmitWfHandle(option) {
138
146
  let formRef = this.getFormRef ? this.getFormRef() : this;
139
147
  let formConfig = formRef.formConfig;
140
148
  let reportTemplate = formRef.reportTemplate;
@@ -159,12 +167,18 @@ modules = {
159
167
  ? this.$t1(`您确定要${btnName}吗?`)
160
168
  : this.$t1("您确定要保存并提交流程吗?"));
161
169
 
170
+ // param19 + param12 都开:这道「保存前」的确认框不弹,把确认交给 wfStartDialog——
171
+ // 它在保存之后才探 preStart,探到候选人就由「修改候选人」弹框顶替,探不到才弹确认框。
172
+ // 任一为 false 都当场弹:param12 关着后面不可能有候选人弹框,延后没有意义。
173
+ await Promise.all([loadWfAutoConfirm(this), loadWfUserRange(this)]);
174
+ let autoConfirm = isWfAutoConfirm() && isWfUserRangeEnabled();
175
+
162
176
  return this.saveDefaultHandle({
163
177
  ...option,
164
178
  config: {
165
179
  ...option?.config,
166
180
  successMsg: option?.config?.successMsg ?? true,
167
- isConfirm: option?.config?.isConfirm ?? true,
181
+ isConfirm: option?.config?.isConfirm ?? !autoConfirm,
168
182
  confirmText: option?.config?.confirmText || confirmText,
169
183
  skipHostReloadAfterSave: true,
170
184
  //提交前置处理(与「提交流程」按钮共用同一个表单脚本)
@@ -187,7 +201,8 @@ modules = {
187
201
  wfCode: reportTemplate.objTypeCode,
188
202
  formCode: reportTemplate.formCode,
189
203
  serviceId: reportTemplate.serviceName,
190
- skipStartConfirm: true,
204
+ // 上面确认过就不再弹第二次;上面因 param19 跳过了,就得让弹框自己去确认
205
+ skipStartConfirm: !autoConfirm,
191
206
  // 提交后行为复用 xform 侧统一方法:
192
207
  // 成功 → onWfStartSuccess(关页签/刷新本页);失败/取消 → onWfStartAbort(刷新到编辑态)
193
208
  onStartSuccess: () =>
@@ -0,0 +1,93 @@
1
+ /**
2
+ * 「固定查询条件」判定工具。
3
+ *
4
+ * 数据表格查询区的字段值存在整张表单的 formModel 上,三条通道会把它清掉:
5
+ * 1. 刷新按钮 → resetForm 逐个 setValue(null)
6
+ * 2. 「查询条件设置」的「确定」→ tableFormMixin.dialogPrimary 按列写默认值
7
+ * 3. 「查询条件设置」的「还原」→ 走的就是 dialogPrimary
8
+ * 字段勾上 options.fixedQuery 之后,这三条通道一律跳过它,值保持原样
9
+ * (值本身仍由树点选/脚本 setValue 等业务通道注入,本开关只管「不被清掉」)。
10
+ *
11
+ * 组装 searchColumns 时(见 container-item/data-table-mixin.js)由 fixedQuery
12
+ * 派生出两个列级标记:
13
+ * - lockValue:公共表格层(components/table)据此跳过写值,语义是「值锁定」
14
+ * - fixed:复用公共层已有语义,让个性化 json 回灌时不挪位置、不改常用
15
+ * 两者必须分开:手写页面的固定列(如 branchSearchPage 的分支)只打 fixed,
16
+ * 它**依赖** dialogPrimary 按 defaultValue 回填,不能被 lockValue 一起跳过。
17
+ */
18
+
19
+ /* 能承载子组件的字段名,覆盖各类容器(含 vf-dialog/vf-drawer,loopHandleWidget 不进这两个) */
20
+ const CHILD_KEYS = [
21
+ "widgetList",
22
+ "cols",
23
+ "rows",
24
+ "tabs",
25
+ "panes",
26
+ "buttons",
27
+ "buttonWidgetList",
28
+ "leftWidgetList",
29
+ ];
30
+
31
+ /**
32
+ * 深度遍历组件树节点(含 rows 这类只有 cols 的中间层对象)。
33
+ * @param {Object} node 起始节点
34
+ * @param {Function} callback 每个节点回调
35
+ */
36
+ function walkWidget(node, callback) {
37
+ if (!node || typeof node !== "object") return;
38
+ callback(node);
39
+ CHILD_KEYS.forEach((key) => {
40
+ let children = node[key];
41
+ if (Array.isArray(children)) {
42
+ children.forEach((child) => walkWidget(child, callback));
43
+ }
44
+ });
45
+ }
46
+
47
+ /**
48
+ * 该字段是否勾选了「固定查询条件」。
49
+ * @param {Object} widget 字段组件 schema
50
+ * @returns {Boolean}
51
+ */
52
+ export function isFixedQueryWidget(widget) {
53
+ return !!(widget && widget.options && widget.options.fixedQuery);
54
+ }
55
+
56
+ /**
57
+ * 该列是否为「值锁定」列(公共表格层的口径,见文件头注释)。
58
+ * @param {Object} column searchColumns 的列配置
59
+ * @returns {Boolean}
60
+ */
61
+ export function isLockedSearchColumn(column) {
62
+ return !!(column && column.lockValue);
63
+ }
64
+
65
+ /**
66
+ * 组件是否位于某个数据表格的查询区(data-table 的 widgetList 分支,不含 buttons、
67
+ * 不含表格列组件)。属性面板据此决定要不要显示「固定查询条件」开关。
68
+ * @param {Array} widgetList 表单顶层组件列表(designer.widgetList)
69
+ * @param {Object} widget 待判定的字段组件
70
+ * @returns {Boolean}
71
+ */
72
+ export function isQueryAreaWidget(widgetList, widget) {
73
+ if (!widget || !widget.id || !Array.isArray(widgetList)) return false;
74
+ let inQueryArea = false;
75
+ widgetList.forEach((item) => {
76
+ walkWidget(item, (node) => {
77
+ if (inQueryArea) return;
78
+ if (
79
+ node.category !== "container"
80
+ || node.type !== "data-table"
81
+ || !Array.isArray(node.widgetList)
82
+ ) {
83
+ return;
84
+ }
85
+ node.widgetList.forEach((child) => {
86
+ walkWidget(child, (sub) => {
87
+ if (sub.id === widget.id) inQueryArea = true;
88
+ });
89
+ });
90
+ });
91
+ });
92
+ return inQueryArea;
93
+ }