cloud-web-corejs 1.1.0-dev.11 → 1.1.0-dev.14
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/VabUpload/view.vue +25 -25
- package/src/components/excelExport/exportColumnMemory.js +118 -0
- package/src/components/excelExport/exportFieldDialog.vue +50 -38
- package/src/components/excelExport/index.js +30 -13
- package/src/components/excelExport/mixins.js +403 -65
- package/src/components/excelImport/mixins.js +898 -850
- package/src/components/mobile/wf/addTaskUserdialog.vue +100 -100
- package/src/components/mobile/wf/content.vue +4 -4
- package/src/components/mobile/wf/deleteTaskUserDialog.vue +73 -73
- package/src/components/mobile/wf/setCandidateDialog.vue +69 -69
- package/src/components/mobile/wf/urgingDialog.vue +75 -75
- package/src/components/table/index.js +14 -1
- package/src/components/table/vxeFilter/mixin.js +28 -18
- package/src/components/xform/docs/2026-07 table/344/270/216excelExport/344/277/256/345/244/215/345/217/212/345/257/274/345/207/272/344/274/230/345/214/226.md" +64 -57
- package/src/components/xform/docs/2026-08 xform H5 P0 /345/256/236/347/216/260/350/247/204/346/240/274.md" +528 -0
- package/src/components/xform/docs/2026-08 xform H5 P1 /345/256/236/347/216/260/350/247/204/346/240/274.md" +412 -0
- package/src/components/xform/docs/2026-08 xform H5 P2 /345/256/236/347/216/260/350/247/204/346/240/274.md" +287 -0
- package/src/components/xform/docs/2026-08 xform /347/247/273/345/212/250/347/253/257/345/270/203/345/261/200/345/257/271/351/275/220 bill_setting /346/226/271/346/241/210.md" +400 -0
- package/src/components/xform/docs/2026-09 /346/235/241/344/273/266/345/257/274/345/207/272/345/244/247/346/225/260/346/215/256/351/207/217/345/264/251/346/272/203/346/216/222/346/237/245.md" +389 -0
- package/src/components/xform/form-designer/form-widget/container-widget/detail-h5-widget.vue +243 -243
- package/src/components/xform/form-designer/form-widget/container-widget/h5-card-pane-widget.vue +228 -228
- package/src/components/xform/form-designer/form-widget/container-widget/h5-card-widget.vue +165 -165
- package/src/components/xform/form-designer/form-widget/dialog/importDialogMixin.js +61 -2
- package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +3 -0
- package/src/components/xform/form-designer/form-widget/field-widget/singleUpload-widget.vue +145 -145
- package/src/components/xform/form-render/container-item/data-table-item.vue +350 -347
- package/src/components/xform/form-render/container-item/data-table-mixin.js +251 -37
- package/src/components/xform/form-render/container-item/list-h5-item.vue +1 -1
- package/src/components/xform/utils/dynamicSchemaUtil.js +385 -361
- package/src/layout/components/TagsView/index.vue +325 -323
- package/src/store/modules/tagsView.js +241 -217
- package/src/utils/importLimit.js +72 -0
- package/src/utils/pdfUtil.js +6 -1
- package/src/utils/request.js +17 -0
- package/src/views/demo/bizTab/bill/billConfig.js +41 -0
- package/src/views/demo/bizTab/bill/detail.vue +436 -0
- package/src/views/demo/bizTab/bill/list.vue +288 -0
- package/src/views/demo/bizTab/bill/productDialog.vue +176 -0
- package/src/views/demo/bizTab/simple/billApi.js +123 -0
- package/src/views/demo/bizTab/simple/detail.vue +407 -0
- package/src/views/demo/bizTab/simple/list.vue +217 -0
- package/src/views/demo/bizTab/standalone/index.vue +121 -0
- package/src/views/demo/bizTab/wf/billConfig.js +44 -0
- package/src/views/demo/bizTab/wf/detail.vue +661 -0
- package/src/views/demo/bizTab/wf/list.vue +242 -0
- package/src/views/user/home/wjl/content.vue +1569 -0
- package/src/views/user/outLink/cc_form_view.vue +188 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Vue from "vue";
|
|
1
2
|
import emitter from "../../../../components/xform/utils/emitter";
|
|
2
3
|
import i18n from "../../../../components/xform/utils/i18n";
|
|
3
4
|
import refMixin from "../../../../components/xform/form-render/refMixin";
|
|
@@ -47,6 +48,7 @@ import {
|
|
|
47
48
|
getDynamicSchemaOption,
|
|
48
49
|
isActionColumnFormat,
|
|
49
50
|
isNonDataExportColumn,
|
|
51
|
+
isBlankExportColumn,
|
|
50
52
|
normalizeDynamicColumns as normalizeDynamicColumnList,
|
|
51
53
|
resolveDynamicSchemaResponse,
|
|
52
54
|
} from "../../utils/dynamicSchemaUtil";
|
|
@@ -72,6 +74,22 @@ import {
|
|
|
72
74
|
} from "../../utils/treeTableUtil";
|
|
73
75
|
import { tableTreeMixins } from "../../../../mixins/tableTree/index.js";
|
|
74
76
|
|
|
77
|
+
/**
|
|
78
|
+
* 列一直建不出来时,行级 schema 重建的最大重试次数(每次隔一帧)。
|
|
79
|
+
* 见 initFieldSchemaData:那里的 $nextTick 自递归原本没有上限。
|
|
80
|
+
*/
|
|
81
|
+
const MAX_SCHEMA_INIT_RETRY = 50;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 超过多少行就不再预建全量行级 schema,改由 getRowFieldSchema 按需建。
|
|
85
|
+
* 预建是按「行数 × 组件列数」做 deepClone(createRowFieldSchemaMap),万行量级是
|
|
86
|
+
* GB 级内存 —— 与条件导出那次标签页崩溃是同一个根因,只是这里常驻 fieldSchemaMap。
|
|
87
|
+
* 触发口:表单导入一次灌入大批行、树表全量加载(BOM)。
|
|
88
|
+
* 阈值取 1000:列表分页最大档是 500,普通分页列表永远不会进懒建模式,行为零变化。
|
|
89
|
+
* 可由 widget.options.lazyRowSchemaThreshold 覆盖。
|
|
90
|
+
*/
|
|
91
|
+
const LAZY_ROW_SCHEMA_THRESHOLD = 1000;
|
|
92
|
+
|
|
75
93
|
let modules = {};
|
|
76
94
|
const baseRefUtil = {
|
|
77
95
|
emitter,
|
|
@@ -300,6 +318,74 @@ modules = {
|
|
|
300
318
|
}
|
|
301
319
|
return widget.options.labelKey || "label";
|
|
302
320
|
},
|
|
321
|
+
/** @returns {Number} 超过多少行改走行级 schema 懒建。 */
|
|
322
|
+
getLazyRowSchemaThreshold() {
|
|
323
|
+
let value = Number(this.widget?.options?.lazyRowSchemaThreshold);
|
|
324
|
+
if (isFinite(value) && value > 0) return value;
|
|
325
|
+
return LAZY_ROW_SCHEMA_THRESHOLD;
|
|
326
|
+
},
|
|
327
|
+
/**
|
|
328
|
+
* 行级 schema 的统一读取口:预建模式下就是 fieldSchemaMap 里的那份,懒建模式下
|
|
329
|
+
* (行数超阈值,见 LAZY_ROW_SCHEMA_THRESHOLD)按需创建,只有真正渲染/校验到的行
|
|
330
|
+
* 才付克隆代价 —— vxe 虚拟滚动下这远小于全量。
|
|
331
|
+
*
|
|
332
|
+
* 懒建刻意**不用 $set**:本方法会在渲染期被模板调用(#widget / #widgetList /
|
|
333
|
+
* #editWidget 都要读行级 schema),给被 render 依赖的 fieldSchemaMap 新增响应式
|
|
334
|
+
* 属性会当场触发重渲染,形成 "infinite update loop"。改为 Vue.observable 让 schema
|
|
335
|
+
* 对象自身保持响应(行内脚本 setDisabled / setOptionItems 仍能刷新视图),再普通
|
|
336
|
+
* 赋值挂进 map;同一行同一次渲染内多次读取拿到的是同一个对象,不会对不上。
|
|
337
|
+
* @param {Object} row 行数据。
|
|
338
|
+
* @returns {Object|null}
|
|
339
|
+
*/
|
|
340
|
+
getRowFieldSchema(row) {
|
|
341
|
+
let rowKey = row && row._X_ROW_KEY;
|
|
342
|
+
if (!rowKey) return null;
|
|
343
|
+
// 导出行有自己的惰性克隆通道(getExportRowWidget),不进 fieldSchemaMap
|
|
344
|
+
if (row._X_EXPORT_ROW) return null;
|
|
345
|
+
let rowSchema = this.fieldSchemaMap[rowKey];
|
|
346
|
+
if (rowSchema) return rowSchema;
|
|
347
|
+
if (!this.getTableFullColumns().length) return null;
|
|
348
|
+
rowSchema = Vue.observable(this.createRowFieldSchemaMap());
|
|
349
|
+
this.fieldSchemaMap[rowKey] = rowSchema;
|
|
350
|
+
return rowSchema;
|
|
351
|
+
},
|
|
352
|
+
/**
|
|
353
|
+
* 导出行的行级组件 schema:按需惰性克隆,缓存挂在行对象上、随行一起丢弃。
|
|
354
|
+
*
|
|
355
|
+
* 导出行不进 fieldSchemaMap(见 initExportRows),但**不能**直接把列模板交出去:
|
|
356
|
+
* 仍会逐单元格挂载的那几类列(widgetRender 自定义组件列、Image2 但本次没开
|
|
357
|
+
* showImageAtTable 的附件列)在挂载时会跑用户脚本,而 setDisabled / setHidden /
|
|
358
|
+
* setOptionItems 这些 API 是直接写 field.options 的 —— 交出模板就等于让脚本改到
|
|
359
|
+
* 列模板本身,而 createRowFieldSchemaMap 又是从该模板克隆各行 schema,污染会一直
|
|
360
|
+
* 留到重新加载表单配置为止。
|
|
361
|
+
*
|
|
362
|
+
* 必须**记忆化**:`#widget` 插槽一个单元格里会多次调用取值(v-if / :field / :key /
|
|
363
|
+
* 字段名),每次返回新对象会让这几处互相对不上。
|
|
364
|
+
*
|
|
365
|
+
* 代价只落在真正会挂载的少数列上,不会退回按「行数 × 列数」克隆。
|
|
366
|
+
* @param {Object} row 导出行。
|
|
367
|
+
* @param {Object} widget 列模板组件 schema。
|
|
368
|
+
* @returns {Object|null}
|
|
369
|
+
*/
|
|
370
|
+
getExportRowWidget(row, widget) {
|
|
371
|
+
if (!widget || !widget.id) return widget || null;
|
|
372
|
+
let cache = row.__X_EXPORT_WIDGETS;
|
|
373
|
+
if (!cache) {
|
|
374
|
+
cache = {};
|
|
375
|
+
// 不可枚举:避免混进行数据被序列化或遍历到
|
|
376
|
+
Object.defineProperty(row, "__X_EXPORT_WIDGETS", {
|
|
377
|
+
value: cache,
|
|
378
|
+
enumerable: false,
|
|
379
|
+
configurable: true,
|
|
380
|
+
writable: true,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
// 用原模板 id 做键:克隆体自己的 id 是新生成的,不能拿来查
|
|
384
|
+
if (!cache[widget.id]) {
|
|
385
|
+
cache[widget.id] = this.cloneFieldSchema(widget);
|
|
386
|
+
}
|
|
387
|
+
return cache[widget.id];
|
|
388
|
+
},
|
|
303
389
|
/**
|
|
304
390
|
* 获取当前行独立的列组件 schema;缺失时按列模板即时创建。
|
|
305
391
|
* @param {Object} obj VXE 单元格参数。
|
|
@@ -311,11 +397,17 @@ modules = {
|
|
|
311
397
|
if (!rowKey || !widget?.id) {
|
|
312
398
|
return null;
|
|
313
399
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
400
|
+
// 导出行不进 fieldSchemaMap(见 initExportRows)。这里必须短路:取值兜底渲染会
|
|
401
|
+
// 走到本方法,缺 schema 时下面那段会按行懒建一整套再 $set 进 fieldSchemaMap,把
|
|
402
|
+
// initExportRows 省下的开销原样加回来,且因为走 $set 还会被深度观测,比原来更贵。
|
|
403
|
+
// 但也不能直接交出列模板——挂载时跑的用户脚本会写进 field.options,
|
|
404
|
+
// 详见 getExportRowWidget。
|
|
405
|
+
if (obj.row._X_EXPORT_ROW) {
|
|
406
|
+
return this.getExportRowWidget(obj.row, widget);
|
|
407
|
+
}
|
|
408
|
+
let rowSchema = this.getRowFieldSchema(obj.row);
|
|
409
|
+
if (!rowSchema) return null;
|
|
410
|
+
if (!rowSchema[widget.id]) {
|
|
319
411
|
this.$set(rowSchema, widget.id, this.cloneFieldSchema(widget));
|
|
320
412
|
}
|
|
321
413
|
return rowSchema[widget.id] || null;
|
|
@@ -595,7 +687,14 @@ modules = {
|
|
|
595
687
|
let row = rowParam.row;
|
|
596
688
|
let params = rowParam.column.params;
|
|
597
689
|
let widgetId = fieldWidget ? fieldWidget.id : params.widget.id;
|
|
598
|
-
|
|
690
|
+
// 导出行不进 fieldSchemaMap,不短路会在 fieldSchemaMap[undefined] 上取值直接崩。
|
|
691
|
+
// 同样走惰性克隆而不是直接交模板,理由见 getExportRowWidget。
|
|
692
|
+
if (row._X_EXPORT_ROW) {
|
|
693
|
+
return this.getExportRowWidget(row, fieldWidget || params.widget);
|
|
694
|
+
}
|
|
695
|
+
// 懒建模式下这一行可能还没建过 schema,直接下标取值会 TypeError
|
|
696
|
+
let rowSchema = this.getRowFieldSchema(row);
|
|
697
|
+
let widget = rowSchema ? rowSchema[widgetId] : null;
|
|
599
698
|
return widget;
|
|
600
699
|
},
|
|
601
700
|
/** @param {String} name 组件名。@param {Function} callback 每行回调。 */
|
|
@@ -919,7 +1018,7 @@ modules = {
|
|
|
919
1018
|
if (!row || !templateWidget) {
|
|
920
1019
|
return templateWidget;
|
|
921
1020
|
}
|
|
922
|
-
const schema = this.
|
|
1021
|
+
const schema = this.getRowFieldSchema(row);
|
|
923
1022
|
if (schema && schema[templateWidget.id]) {
|
|
924
1023
|
return schema[templateWidget.id];
|
|
925
1024
|
}
|
|
@@ -1762,6 +1861,11 @@ modules = {
|
|
|
1762
1861
|
t.type || t.widget?.type,
|
|
1763
1862
|
t.widget?.options || t.options
|
|
1764
1863
|
),
|
|
1864
|
+
exportBlank: isBlankExportColumn(
|
|
1865
|
+
t.formatS,
|
|
1866
|
+
t.type || t.widget?.type,
|
|
1867
|
+
t.exportType
|
|
1868
|
+
),
|
|
1765
1869
|
},
|
|
1766
1870
|
visible: this.getColumnVisible(t),
|
|
1767
1871
|
slots: {},
|
|
@@ -1849,6 +1953,12 @@ modules = {
|
|
|
1849
1953
|
"textarea",
|
|
1850
1954
|
"a-link",
|
|
1851
1955
|
"a-text",
|
|
1956
|
+
// 脚本输入框:展示值就是 fieldModel,不做任何转换,走纯函数完全等价。
|
|
1957
|
+
// 不走这里会落到 getCellValue 的 vNode 挂载兜底,而它内部是**异步组件**
|
|
1958
|
+
// code-editor —— 同步挂载后立刻爬 DOM 根本读不到内容(异步组件那一刻还没
|
|
1959
|
+
// 解析完),所以这类列此前导出为空;顺带每个单元格挂一个代码编辑器,是所有
|
|
1960
|
+
// 类型里最贵的一种。
|
|
1961
|
+
"script-input",
|
|
1852
1962
|
];
|
|
1853
1963
|
if (widget && types.includes(widget.type)) {
|
|
1854
1964
|
const func = (obj) => {
|
|
@@ -1867,9 +1977,14 @@ modules = {
|
|
|
1867
1977
|
if (fieldWidget && !fieldWidget.options.hidden) {
|
|
1868
1978
|
let widgetType = fieldWidget.type;
|
|
1869
1979
|
if (
|
|
1870
|
-
[
|
|
1871
|
-
|
|
1872
|
-
|
|
1980
|
+
[
|
|
1981
|
+
"input",
|
|
1982
|
+
"number",
|
|
1983
|
+
"textarea",
|
|
1984
|
+
"a-link",
|
|
1985
|
+
"a-text",
|
|
1986
|
+
"script-input",
|
|
1987
|
+
].includes(widgetType)
|
|
1873
1988
|
) {
|
|
1874
1989
|
return value;
|
|
1875
1990
|
}
|
|
@@ -2526,6 +2641,9 @@ modules = {
|
|
|
2526
2641
|
let customParam = {
|
|
2527
2642
|
config: {
|
|
2528
2643
|
modal: false,
|
|
2644
|
+
// 导出取消时要能掐断在途取数请求。令牌由 excelExport 生成后随导出参数
|
|
2645
|
+
// 带过来,这里塞进 config,formHttp 的 ...opts 会透传给 axios。
|
|
2646
|
+
cancelToken: options?.cancelToken,
|
|
2529
2647
|
},
|
|
2530
2648
|
export: true,
|
|
2531
2649
|
exportParam: options,
|
|
@@ -2642,8 +2760,8 @@ modules = {
|
|
|
2642
2760
|
: [];
|
|
2643
2761
|
// that.handleNullValue(rows);
|
|
2644
2762
|
if (customParam?.export) {
|
|
2645
|
-
|
|
2646
|
-
this.
|
|
2763
|
+
//导出:只补行主键+标记,不建行级 schema(大数据量会 OOM)
|
|
2764
|
+
this.initExportRows(rows);
|
|
2647
2765
|
} else {
|
|
2648
2766
|
// VXE 与表单必须共用同一批标准化行,否则 _X_ROW_KEY 不一致,
|
|
2649
2767
|
// 行虽能进入编辑态,但 editWidget 无法取得对应的行级 schema。
|
|
@@ -2656,7 +2774,7 @@ modules = {
|
|
|
2656
2774
|
}
|
|
2657
2775
|
|
|
2658
2776
|
resolve(res);
|
|
2659
|
-
if (res
|
|
2777
|
+
if (that.shouldEmitQueryLoaded(res, customParam)) {
|
|
2660
2778
|
if (that.widget.options.isTreeTable) {
|
|
2661
2779
|
if (rows.length > 0) {
|
|
2662
2780
|
let fullAllDataRowMap =
|
|
@@ -2722,18 +2840,7 @@ modules = {
|
|
|
2722
2840
|
}
|
|
2723
2841
|
}
|
|
2724
2842
|
}
|
|
2725
|
-
that
|
|
2726
|
-
setTimeout(function () {
|
|
2727
|
-
dataTableConfig.callback &&
|
|
2728
|
-
dataTableConfig.callback(rows);
|
|
2729
|
-
tableOption.callback && tableOption.callback(rows);
|
|
2730
|
-
that.handleCustomEvent(
|
|
2731
|
-
that.widget.options.formScriptCallback,
|
|
2732
|
-
["rows"],
|
|
2733
|
-
[rows]
|
|
2734
|
-
);
|
|
2735
|
-
}, 0);
|
|
2736
|
-
});
|
|
2843
|
+
that.emitTableDataLoaded(rows, tableOption);
|
|
2737
2844
|
}
|
|
2738
2845
|
};
|
|
2739
2846
|
this.loadDefaultQueryList(reqData, done, customParam);
|
|
@@ -3141,6 +3248,53 @@ modules = {
|
|
|
3141
3248
|
let scriptCode = this.widget.options.formScriptCode || defaultScriptCode;
|
|
3142
3249
|
return scriptCode;
|
|
3143
3250
|
},
|
|
3251
|
+
/**
|
|
3252
|
+
* 本次取数要不要跑「屏幕上那张表格」的成功副作用(树表展开、宿主回调、
|
|
3253
|
+
* tableOption.callback 回写表单模型、formScriptCallback)。
|
|
3254
|
+
*
|
|
3255
|
+
* 导出取数复用的是普通查询这条 proxyConfig.ajax.query,此前只在「建不建行级
|
|
3256
|
+
* schema」那一处分了叉,成功副作用整段照跑,而它们对导出**零意义**:数据在
|
|
3257
|
+
* `resolve(res)` 时就已经交给 excelExport 了,回调还都排在 $nextTick +
|
|
3258
|
+
* setTimeout 之后,改什么也影响不到导出内容。跑了反而有害:
|
|
3259
|
+
* 1. `formScriptCallback`(用户配的「数据加载完成」脚本)会按导出页数被连着触发
|
|
3260
|
+
* N 次,`rows` 是屏幕上根本看不见的数据;脚本里发的请求还会跟导出取数抢连接;
|
|
3261
|
+
* 2. `tableOption.callback` 是 `formModel[fieldKeyName] = rows`,会把表单模型覆盖
|
|
3262
|
+
* 成导出的最后一页 —— 导出之后 `getValue()` 返回的不再是当前页,且页面上看不
|
|
3263
|
+
* 出任何异常,直到下次查询才被冲掉;
|
|
3264
|
+
* 3. 树表分支会对没进表格的导出行 `setTreeExpand`、去 `fullAllDataRowMap` 里查它们,
|
|
3265
|
+
* 中途还反复开关 `$grid.treeConfig.lazy`,并发几页时互相打架。
|
|
3266
|
+
*
|
|
3267
|
+
* `customParam.export` 由 exportAjax 统一置位,覆盖条件导出与明细的选择/条件导出
|
|
3268
|
+
* 三条会发请求的通道(勾选导出/当前页导出不走这里)。
|
|
3269
|
+
* @param {Object} res 取数响应。
|
|
3270
|
+
* @param {Object} [customParam] 调用方附加参数。
|
|
3271
|
+
* @returns {Boolean}
|
|
3272
|
+
*/
|
|
3273
|
+
shouldEmitQueryLoaded(res, customParam) {
|
|
3274
|
+
if (res?.type !== "success") return false;
|
|
3275
|
+
return !customParam?.export;
|
|
3276
|
+
},
|
|
3277
|
+
/**
|
|
3278
|
+
* 派发「表格数据加载完成」的三个回调:宿主注入的 callback、tableOption.callback
|
|
3279
|
+
* (回写表单模型),以及用户配的 formScriptCallback。
|
|
3280
|
+
* 是否该派发由 shouldEmitQueryLoaded 判定,这里只负责发。
|
|
3281
|
+
* @param {Array} rows 本次加载的行。
|
|
3282
|
+
* @param {Object} tableOption 表格配置(callback 挂在它上面)。
|
|
3283
|
+
*/
|
|
3284
|
+
emitTableDataLoaded(rows, tableOption) {
|
|
3285
|
+
this.$nextTick(() => {
|
|
3286
|
+
setTimeout(() => {
|
|
3287
|
+
let dataTableConfig = this.dataTableConfig || {};
|
|
3288
|
+
dataTableConfig.callback && dataTableConfig.callback(rows);
|
|
3289
|
+
tableOption && tableOption.callback && tableOption.callback(rows);
|
|
3290
|
+
this.handleCustomEvent(
|
|
3291
|
+
this.widget.options.formScriptCallback,
|
|
3292
|
+
["rows"],
|
|
3293
|
+
[rows]
|
|
3294
|
+
);
|
|
3295
|
+
}, 0);
|
|
3296
|
+
});
|
|
3297
|
+
},
|
|
3144
3298
|
/**
|
|
3145
3299
|
* 执行默认列表查询。
|
|
3146
3300
|
* @param {Object} reqData 查询请求数据。
|
|
@@ -3212,6 +3366,16 @@ modules = {
|
|
|
3212
3366
|
};
|
|
3213
3367
|
requestData = extendDeeply(requestData, accessParam);
|
|
3214
3368
|
|
|
3369
|
+
// 导出时间快照按 xform 协议放在**信封层**(与 formCode/taBm 同级),不能留在
|
|
3370
|
+
// data 里 —— 那一层是业务查询条件的地盘,后端按字段名当条件解析。它由
|
|
3371
|
+
// excelExport 的分页调度器塞进取数参数(mixins.js loopToDo 的 aParam),一路
|
|
3372
|
+
// 并进 requestData,到这里统一提上来。只有导出通道会带它。
|
|
3373
|
+
let nowDate;
|
|
3374
|
+
if (customParam?.export && requestData.nowDate !== undefined) {
|
|
3375
|
+
nowDate = requestData.nowDate;
|
|
3376
|
+
delete requestData.nowDate;
|
|
3377
|
+
}
|
|
3378
|
+
|
|
3215
3379
|
return this.formHttp({
|
|
3216
3380
|
// url: prefix + "/form_ins/getPage",
|
|
3217
3381
|
scriptCode: scriptCode,
|
|
@@ -3219,6 +3383,7 @@ modules = {
|
|
|
3219
3383
|
formCode: formCode,
|
|
3220
3384
|
formVersion: reportTemplate.formVersion,
|
|
3221
3385
|
taBm: this.fieldKeyName,
|
|
3386
|
+
...(nowDate !== undefined ? { nowDate } : {}),
|
|
3222
3387
|
data: requestData,
|
|
3223
3388
|
},
|
|
3224
3389
|
isLoading: false,
|
|
@@ -3379,6 +3544,8 @@ modules = {
|
|
|
3379
3544
|
* 可以挂多个明细导出按钮、各导各自的列、各走各自的脚本),组装成 exportItemConfig 随
|
|
3380
3545
|
* 导出参数下发,下游(字段选择弹框 / 分页取数 / 脱敏剔除)一律优先读它,读不到才回落
|
|
3381
3546
|
* 表格属性那套。
|
|
3547
|
+
* option.exportButtonName 为导出按钮标识,原样透传给字段选择弹框,用于按按钮分组存放
|
|
3548
|
+
* 勾选记忆(见 excelExport/exportColumnMemory.js)。
|
|
3382
3549
|
*/
|
|
3383
3550
|
exportData(option) {
|
|
3384
3551
|
let exportOption = { ...option };
|
|
@@ -3612,11 +3779,13 @@ modules = {
|
|
|
3612
3779
|
const fieldsToValidate = [];
|
|
3613
3780
|
let tableColumns = this.widget.options.tableColumns;
|
|
3614
3781
|
checkRows.forEach((row) => {
|
|
3615
|
-
let fieldSchema = this.
|
|
3782
|
+
let fieldSchema = this.getRowFieldSchema(row) || {};
|
|
3616
3783
|
tableColumns.forEach((column) => {
|
|
3617
3784
|
if (column.widget) {
|
|
3785
|
+
// 列未就绪时 getRowFieldSchema 会给 null,取不到行级组件就按"不必填"跳过,
|
|
3786
|
+
// 而不是在这里抛异常把整个校验打断
|
|
3618
3787
|
let widget = fieldSchema[column.widget.id];
|
|
3619
|
-
let required = widget
|
|
3788
|
+
let required = widget?.options?.required || false;
|
|
3620
3789
|
if (required) {
|
|
3621
3790
|
let propName = this.getColumnWidgetProp(widget, row);
|
|
3622
3791
|
fieldsToValidate.push(propName);
|
|
@@ -3625,7 +3794,7 @@ modules = {
|
|
|
3625
3794
|
if (column.widgetList) {
|
|
3626
3795
|
column.widgetList.forEach((itemWidget) => {
|
|
3627
3796
|
let widget = fieldSchema[itemWidget.id];
|
|
3628
|
-
let required = widget
|
|
3797
|
+
let required = widget?.options?.required || false;
|
|
3629
3798
|
if (required) {
|
|
3630
3799
|
let propName = this.getColumnWidgetProp(widget, row);
|
|
3631
3800
|
fieldsToValidate.push(propName);
|
|
@@ -3666,9 +3835,9 @@ modules = {
|
|
|
3666
3835
|
let sourceWidgetId = isEdit
|
|
3667
3836
|
? obj.column?.params?.editWidget?.id
|
|
3668
3837
|
: obj.column?.params?.widget?.id;
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
let fieldWidget =
|
|
3838
|
+
let rowSchema = this.getRowFieldSchema(obj.row);
|
|
3839
|
+
if (!sourceWidgetId || !rowSchema) return "false";
|
|
3840
|
+
let fieldWidget = rowSchema[sourceWidgetId];
|
|
3672
3841
|
if (!fieldWidget) {
|
|
3673
3842
|
return "false";
|
|
3674
3843
|
}
|
|
@@ -5690,8 +5859,9 @@ modules = {
|
|
|
5690
5859
|
/**
|
|
5691
5860
|
* 为每一行创建独立字段 schema,避免组件状态在不同行之间共享。
|
|
5692
5861
|
* @param {Boolean} initFlag true 时忽略旧 schema 并全部重新创建。
|
|
5862
|
+
* @param {Number} retryCount 列未就绪时已重试的次数,见 MAX_SCHEMA_INIT_RETRY。
|
|
5693
5863
|
*/
|
|
5694
|
-
initFieldSchemaData(initFlag) {
|
|
5864
|
+
initFieldSchemaData(initFlag, retryCount = 0) {
|
|
5695
5865
|
//初始化fieldSchemaData!!!
|
|
5696
5866
|
/*if (this.widget.type !== 'sub-form') {
|
|
5697
5867
|
return
|
|
@@ -5706,6 +5876,14 @@ modules = {
|
|
|
5706
5876
|
if (!this.getTableFullColumns().length) {
|
|
5707
5877
|
return false;
|
|
5708
5878
|
}
|
|
5879
|
+
// 大数据量不再预建:按「行数 × 组件列数」深克隆,万行量级直接把标签页撑爆
|
|
5880
|
+
// (与条件导出那次崩溃同源)。交给 getRowFieldSchema 在渲染/校验时按需建。
|
|
5881
|
+
if (rowLength > this.getLazyRowSchemaThreshold()) {
|
|
5882
|
+
// initFlag 表示"整体重建",此时旧 schema 必须丢弃;否则(addRow /
|
|
5883
|
+
// deleteRow)保留已建的那些,避免把行内脚本写进去的状态一起清掉。
|
|
5884
|
+
if (initFlag) this.fieldSchemaMap = {};
|
|
5885
|
+
return true;
|
|
5886
|
+
}
|
|
5709
5887
|
let fieldSchemaMap = {};
|
|
5710
5888
|
let fieldSchemaMap0 = this.fieldSchemaMap;
|
|
5711
5889
|
for (let i = 0; i < rowLength; i++) {
|
|
@@ -5714,10 +5892,12 @@ modules = {
|
|
|
5714
5892
|
if (initFlag) {
|
|
5715
5893
|
fieldSchemaMap2 = this.createRowFieldSchemaMap();
|
|
5716
5894
|
} else {
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5895
|
+
// 沿用旧行的 schema 对象本身,不再 cloneDeep:该对象本来就是这一行
|
|
5896
|
+
// 独享的(按 rowId 分桶),克隆只会产出语义完全相同的另一份,白占一份
|
|
5897
|
+
// 内存。而本分支的调用方是 addRow / deleteRow —— 每增删一行都把全表深
|
|
5898
|
+
// 克隆一遍是 O(N²),千行树表上每次增删都要停顿数秒并制造等量垃圾。
|
|
5899
|
+
fieldSchemaMap2
|
|
5900
|
+
= fieldSchemaMap0[rowId] || this.createRowFieldSchemaMap();
|
|
5721
5901
|
}
|
|
5722
5902
|
fieldSchemaMap[rowId] = fieldSchemaMap2;
|
|
5723
5903
|
}
|
|
@@ -5725,9 +5905,19 @@ modules = {
|
|
|
5725
5905
|
return true;
|
|
5726
5906
|
};
|
|
5727
5907
|
if (!build()) {
|
|
5908
|
+
// 列未就绪时隔一帧重试。必须有上限:动态列请求失败 / 列配置为空时列永远不会
|
|
5909
|
+
// 出现,而 rowIdData 非空,这条 $nextTick 自递归就成了每帧一次的死循环,
|
|
5910
|
+
// 页面永久卡死(setValue 侧另有 pendingSchemaInit 挡了一条入口,但
|
|
5911
|
+
// initValue / addRow / deleteRow / 动态列重载都能直接进到这里)。
|
|
5912
|
+
if (retryCount >= MAX_SCHEMA_INIT_RETRY) {
|
|
5913
|
+
console.warn(
|
|
5914
|
+
"[data-table] 表格列始终未就绪,已停止行级 schema 重建重试"
|
|
5915
|
+
);
|
|
5916
|
+
return;
|
|
5917
|
+
}
|
|
5728
5918
|
this.$nextTick(() => {
|
|
5729
5919
|
if (this.rowIdData.length) {
|
|
5730
|
-
this.initFieldSchemaData(initFlag);
|
|
5920
|
+
this.initFieldSchemaData(initFlag, retryCount + 1);
|
|
5731
5921
|
}
|
|
5732
5922
|
});
|
|
5733
5923
|
}
|
|
@@ -5824,6 +6014,30 @@ modules = {
|
|
|
5824
6014
|
return newFieldSchema;
|
|
5825
6015
|
},
|
|
5826
6016
|
//end1
|
|
6017
|
+
/**
|
|
6018
|
+
* 导出取数的行初始化:只补行主键并打导出标记,**不建行级 schema**。
|
|
6019
|
+
*
|
|
6020
|
+
* 行级 schema 的意义是让同一列的组件在不同行之间互不干扰(行内脚本改 options、
|
|
6021
|
+
* 编辑态等)。导出行既不进 vxe 表格也不会被编辑,createRowFieldSchemaMap 产出的
|
|
6022
|
+
* 只是列模板的等价深克隆(仅 id 不同)—— 异步选项同步写的是列模板本身
|
|
6023
|
+
* (collectColumnWidgetConfigRequests),行内脚本改的是已挂载的组件实例,都不会让
|
|
6024
|
+
* 导出行的 schema 与列模板产生差异。
|
|
6025
|
+
*
|
|
6026
|
+
* 但代价是按「行数 × 组件列数」做 deepClone 并常驻 fieldSchemaMap,而该 map 在导出
|
|
6027
|
+
* 期间没有任何释放路径(只有删行、或下次正常查询走 initFieldSchemaData 整体重建才清),
|
|
6028
|
+
* 10 万行量级直接把标签页撑爆。取值侧对缺失行级 schema 本就有回退列模板的分支
|
|
6029
|
+
* (列 filterVal、getTableColumnWidget、getRowWidget),故跳过构建不改变导出内容。
|
|
6030
|
+
*
|
|
6031
|
+
* 注意:树表懒加载走的仍是 initExportFieldSchemaData —— 那批行是要进表格的真实行。
|
|
6032
|
+
* @param {Array} rows 导出取回的当页数据。
|
|
6033
|
+
*/
|
|
6034
|
+
initExportRows(rows) {
|
|
6035
|
+
if (!rows) return;
|
|
6036
|
+
for (let row of rows) {
|
|
6037
|
+
if (!row._X_ROW_KEY) row._X_ROW_KEY = "row_" + generateId();
|
|
6038
|
+
row._X_EXPORT_ROW = true;
|
|
6039
|
+
}
|
|
6040
|
+
},
|
|
5827
6041
|
/** @param {Array} rows 导出数据。为无行主键的数据创建临时 schema。 */
|
|
5828
6042
|
initExportFieldSchemaData(rows) {
|
|
5829
6043
|
if (!rows) return;
|