@robot-admin/naive-ui-components 0.4.2 → 0.4.4
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/dist/C_ActionBar.cjs +1 -5
- package/dist/C_ActionBar.js +1 -4
- package/dist/C_ActionBar.js.map +1 -0
- package/dist/C_ActionBar2.js +1 -195
- package/dist/C_ActionBar2.js.map +1 -1
- package/dist/C_AntV.cjs +1 -8
- package/dist/C_AntV.js +1 -4
- package/dist/C_AntV.js.map +1 -0
- package/dist/C_AntV2.js +4 -3149
- package/dist/C_AntV2.js.map +1 -1
- package/dist/C_Barcode.cjs +1 -4
- package/dist/C_Barcode.js +1 -3
- package/dist/C_Barcode.js.map +1 -0
- package/dist/C_Barcode2.js +1 -67
- package/dist/C_Barcode2.js.map +1 -1
- package/dist/C_Captcha.cjs +1 -4
- package/dist/C_Captcha.js +1 -3
- package/dist/C_Captcha.js.map +1 -0
- package/dist/C_Captcha2.js +1 -154
- package/dist/C_Captcha2.js.map +1 -1
- package/dist/C_Cascade.cjs +1 -4
- package/dist/C_Cascade.js +1 -3
- package/dist/C_Cascade.js.map +1 -0
- package/dist/C_Cascade2.js +1 -102
- package/dist/C_Cascade2.js.map +1 -1
- package/dist/C_City.cjs +1 -4
- package/dist/C_City.js +1 -3
- package/dist/C_City.js.map +1 -0
- package/dist/C_City2.js +1 -840
- package/dist/C_City2.js.map +1 -1
- package/dist/C_Code.cjs +1 -5
- package/dist/C_Code.js +1 -4
- package/dist/C_Code.js.map +1 -0
- package/dist/C_Code2.js +1 -346
- package/dist/C_Code2.js.map +1 -1
- package/dist/C_CollapsePanel.cjs +1 -6
- package/dist/C_CollapsePanel.js +1 -4
- package/dist/C_CollapsePanel.js.map +1 -0
- package/dist/C_CollapsePanel2.js +1 -318
- package/dist/C_CollapsePanel2.js.map +1 -1
- package/dist/C_Cron.cjs +1 -15
- package/dist/C_Cron.js +1 -4
- package/dist/C_Cron.js.map +1 -0
- package/dist/C_Cron2.js +1 -1209
- package/dist/C_Cron2.js.map +1 -1
- package/dist/C_Date.cjs +1 -4
- package/dist/C_Date.js +1 -3
- package/dist/C_Date.js.map +1 -0
- package/dist/C_Date2.js +1 -218
- package/dist/C_Date2.js.map +1 -1
- package/dist/C_Draggable.cjs +1 -5
- package/dist/C_Draggable.js +1 -3
- package/dist/C_Draggable.js.map +1 -0
- package/dist/C_Draggable2.js +1 -294
- package/dist/C_Draggable2.js.map +1 -1
- package/dist/C_Editor.cjs +1 -4
- package/dist/C_Editor.js +1 -3
- package/dist/C_Editor.js.map +1 -0
- package/dist/C_Editor2.js +1 -159
- package/dist/C_Editor2.js.map +1 -1
- package/dist/C_FilePreview.cjs +1 -7
- package/dist/C_FilePreview.js +1 -4
- package/dist/C_FilePreview.js.map +1 -0
- package/dist/C_FilePreview2.js +1 -1031
- package/dist/C_FilePreview2.js.map +1 -1
- package/dist/C_Form.cjs +1 -16
- package/dist/C_Form.js +1 -5
- package/dist/C_Form.js.map +1 -0
- package/dist/C_Form2.js +1 -2569
- package/dist/C_Form2.js.map +1 -1
- package/dist/C_FormSearch.cjs +1 -6
- package/dist/C_FormSearch.js +1 -3
- package/dist/C_FormSearch.js.map +1 -0
- package/dist/C_FormSearch2.js +1 -355
- package/dist/C_FormSearch2.js.map +1 -1
- package/dist/C_FormulaEditor.cjs +1 -13
- package/dist/C_FormulaEditor.js +1 -4
- package/dist/C_FormulaEditor.js.map +1 -0
- package/dist/C_FormulaEditor2.js +1 -1432
- package/dist/C_FormulaEditor2.js.map +1 -1
- package/dist/C_FullCalendar.cjs +1 -9
- package/dist/C_FullCalendar.js +1 -3
- package/dist/C_FullCalendar.js.map +1 -0
- package/dist/C_FullCalendar2.js +1 -376
- package/dist/C_FullCalendar2.js.map +1 -1
- package/dist/C_GlobalSearch.cjs +1 -5
- package/dist/C_GlobalSearch.js +1 -3
- package/dist/C_GlobalSearch.js.map +1 -0
- package/dist/C_GlobalSearch2.js +1 -335
- package/dist/C_GlobalSearch2.js.map +1 -1
- package/dist/C_Guide.cjs +1 -4
- package/dist/C_Guide.js +1 -3
- package/dist/C_Guide.js.map +1 -0
- package/dist/C_Guide2.js +1 -57
- package/dist/C_Guide2.js.map +1 -1
- package/dist/C_Icon.cjs +1 -4
- package/dist/C_Icon.js +1 -3
- package/dist/C_Icon.js.map +1 -0
- package/dist/C_Icon2.js +1 -285
- package/dist/C_Icon2.js.map +1 -1
- package/dist/C_ImageCropper.cjs +1 -6
- package/dist/C_ImageCropper.js +1 -4
- package/dist/C_ImageCropper.js.map +1 -0
- package/dist/C_ImageCropper2.js +1 -722
- package/dist/C_ImageCropper2.js.map +1 -1
- package/dist/C_Language.cjs +1 -4
- package/dist/C_Language.js +1 -3
- package/dist/C_Language.js.map +1 -0
- package/dist/C_Language2.js +1 -71
- package/dist/C_Language2.js.map +1 -1
- package/dist/C_Map.cjs +1 -7
- package/dist/C_Map.js +1 -3
- package/dist/C_Map.js.map +1 -0
- package/dist/C_Map2.js +1 -198
- package/dist/C_Map2.js.map +1 -1
- package/dist/C_Markdown.cjs +1 -4
- package/dist/C_Markdown.js +1 -3
- package/dist/C_Markdown.js.map +1 -0
- package/dist/C_Markdown2.js +1 -185
- package/dist/C_Markdown2.js.map +1 -1
- package/dist/C_NotificationCenter.cjs +1 -20
- package/dist/C_NotificationCenter.js +1 -4
- package/dist/C_NotificationCenter.js.map +1 -0
- package/dist/C_NotificationCenter2.js +1 -1383
- package/dist/C_NotificationCenter2.js.map +1 -1
- package/dist/C_Progress.cjs +1 -4
- package/dist/C_Progress.js +1 -3
- package/dist/C_Progress.js.map +1 -0
- package/dist/C_Progress2.js +1 -102
- package/dist/C_Progress2.js.map +1 -1
- package/dist/C_QRCode.cjs +1 -5
- package/dist/C_QRCode.js +1 -3
- package/dist/C_QRCode.js.map +1 -0
- package/dist/C_QRCode2.js +1 -217
- package/dist/C_QRCode2.js.map +1 -1
- package/dist/C_Signature.cjs +1 -8
- package/dist/C_Signature.js +1 -4
- package/dist/C_Signature.js.map +1 -0
- package/dist/C_Signature2.js +1 -617
- package/dist/C_Signature2.js.map +1 -1
- package/dist/C_SplitPane.cjs +1 -6
- package/dist/C_SplitPane.js +1 -4
- package/dist/C_SplitPane.js.map +1 -0
- package/dist/C_SplitPane2.js +1 -355
- package/dist/C_SplitPane2.js.map +1 -1
- package/dist/C_Steps.cjs +1 -4
- package/dist/C_Steps.js +1 -3
- package/dist/C_Steps.js.map +1 -0
- package/dist/C_Steps2.js +1 -81
- package/dist/C_Steps2.js.map +1 -1
- package/dist/C_Table.cjs +1 -20
- package/dist/C_Table.js +1 -6
- package/dist/C_Table.js.map +1 -0
- package/dist/C_Table2.js +1 -3023
- package/dist/C_Table2.js.map +1 -1
- package/dist/C_Theme.cjs +1 -4
- package/dist/C_Theme.js +1 -3
- package/dist/C_Theme.js.map +1 -0
- package/dist/C_Theme2.js +1 -59
- package/dist/C_Theme2.js.map +1 -1
- package/dist/C_Time.cjs +1 -5
- package/dist/C_Time.js +1 -3
- package/dist/C_Time.js.map +1 -0
- package/dist/C_Time2.js +1 -198
- package/dist/C_Time2.js.map +1 -1
- package/dist/C_Tree.cjs +1 -7
- package/dist/C_Tree.js +1 -4
- package/dist/C_Tree.js.map +1 -0
- package/dist/C_Tree2.js +1 -440
- package/dist/C_Tree2.js.map +1 -1
- package/dist/C_Upload.cjs +1 -12
- package/dist/C_Upload.js +1 -4
- package/dist/C_Upload.js.map +1 -0
- package/dist/C_Upload2.js +2 -1365
- package/dist/C_Upload2.js.map +1 -1
- package/dist/C_VideoPlayer.cjs +1 -23
- package/dist/C_VideoPlayer.js +1 -3
- package/dist/C_VideoPlayer.js.map +1 -0
- package/dist/C_VideoPlayer2.js +3 -1932
- package/dist/C_VideoPlayer2.js.map +1 -1
- package/dist/C_VtableGantt.cjs +1 -6
- package/dist/C_VtableGantt.js +1 -4
- package/dist/C_VtableGantt.js.map +1 -0
- package/dist/C_VtableGantt2.js +1 -872
- package/dist/C_VtableGantt2.js.map +1 -1
- package/dist/C_WaterFall.cjs +1 -13
- package/dist/C_WaterFall.js +1 -3
- package/dist/C_WaterFall.js.map +1 -0
- package/dist/C_WaterFall2.js +1 -364
- package/dist/C_WaterFall2.js.map +1 -1
- package/dist/C_WorkFlow.cjs +1 -8
- package/dist/C_WorkFlow.js +1 -4
- package/dist/C_WorkFlow.js.map +1 -0
- package/dist/C_WorkFlow2.js +1 -1983
- package/dist/C_WorkFlow2.js.map +1 -1
- package/dist/chunk.js +1 -18
- package/dist/city.js +1 -4816
- package/dist/constants.d.ts +3 -3
- package/dist/constants2.d.ts +5 -5
- package/dist/constants3.d.ts +2 -2
- package/dist/constants4.d.ts +4 -4
- package/dist/constants5.d.ts +2 -2
- package/dist/data.d.ts +1 -1
- package/dist/export-helper.js +1 -9
- package/dist/index.cjs +2 -441
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2 -19
- package/dist/index.d.ts +2 -19
- package/dist/index.js +1 -258
- package/dist/index.js.map +1 -1
- package/dist/index.vue.d.ts +2 -2
- package/dist/index10.vue.d.ts +6 -6
- package/dist/index11.vue.d.ts +2 -2
- package/dist/index12.vue.d.ts +4 -4
- package/dist/index13.vue.d.ts +3 -3
- package/dist/index14.vue.d.ts +4 -4
- package/dist/index16.vue.d.ts +3 -3
- package/dist/index2.vue.d.ts +5 -5
- package/dist/index3.vue.d.ts +2 -2
- package/dist/index4.vue.d.ts +2 -2
- package/dist/index5.vue.d.ts +3 -3
- package/dist/index6.vue.d.ts +1 -1
- package/dist/index7.vue.d.ts +1 -1
- package/dist/index8.vue.d.ts +2 -2
- package/dist/resolver.cjs +2 -89
- package/dist/resolver.cjs.map +1 -0
- package/dist/resolver.js +1 -86
- package/dist/resolver.js.map +1 -1
- package/dist/storage.js +1 -30
- package/dist/storage.js.map +1 -1
- package/dist/useCollapsePanel.d.ts +2 -2
- package/dist/useCropperCore.d.ts +8 -8
- package/dist/useDraggableLayout.d.ts +3 -3
- package/dist/useDynamicFormState.d.ts +3 -3
- package/dist/useEdgeInteraction.d.ts +2 -2
- package/dist/useInfiniteScroll.d.ts +3 -3
- package/dist/useModalEdit.d.ts +3 -3
- package/dist/useQRCode.d.ts +4 -4
- package/dist/useSignatureHistory.d.ts +2 -2
- package/dist/useSplitResize.d.ts +5 -5
- package/dist/useTimeSelection.d.ts +1 -1
- package/dist/useTreeOperations.d.ts +4 -4
- package/dist/useWorkflowValidation.d.ts +2 -2
- package/package.json +5 -196
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants2.d.ts.map +0 -1
- package/dist/constants3.d.ts.map +0 -1
- package/dist/constants4.d.ts.map +0 -1
- package/dist/constants5.d.ts.map +0 -1
- package/dist/data.d.ts.map +0 -1
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.vue.d.ts.map +0 -1
- package/dist/index10.vue.d.ts.map +0 -1
- package/dist/index11.vue.d.ts.map +0 -1
- package/dist/index12.vue.d.ts.map +0 -1
- package/dist/index13.vue.d.ts.map +0 -1
- package/dist/index14.vue.d.ts.map +0 -1
- package/dist/index15.vue.d.ts.map +0 -1
- package/dist/index16.vue.d.ts.map +0 -1
- package/dist/index2.vue.d.ts.map +0 -1
- package/dist/index3.vue.d.ts.map +0 -1
- package/dist/index4.vue.d.ts.map +0 -1
- package/dist/index5.vue.d.ts.map +0 -1
- package/dist/index6.vue.d.ts.map +0 -1
- package/dist/index7.vue.d.ts.map +0 -1
- package/dist/index8.vue.d.ts.map +0 -1
- package/dist/index9.vue.d.ts.map +0 -1
- package/dist/resolver.d.cts.map +0 -1
- package/dist/resolver.d.ts.map +0 -1
- package/dist/useCalendarEvents.d.ts.map +0 -1
- package/dist/useCollapsePanel.d.ts.map +0 -1
- package/dist/useCropperCore.d.ts.map +0 -1
- package/dist/useDraggableLayout.d.ts.map +0 -1
- package/dist/useDynamicFormState.d.ts.map +0 -1
- package/dist/useEdgeInteraction.d.ts.map +0 -1
- package/dist/useFullscreen.d.ts.map +0 -1
- package/dist/useGlobalSearch.d.ts.map +0 -1
- package/dist/useInfiniteScroll.d.ts.map +0 -1
- package/dist/useModalEdit.d.ts.map +0 -1
- package/dist/useQRCode.d.ts.map +0 -1
- package/dist/useSearchState.d.ts.map +0 -1
- package/dist/useSignatureHistory.d.ts.map +0 -1
- package/dist/useSplitResize.d.ts.map +0 -1
- package/dist/useTimeSelection.d.ts.map +0 -1
- package/dist/useTreeOperations.d.ts.map +0 -1
- package/dist/useWorkflowValidation.d.ts.map +0 -1
package/dist/C_Table2.js
CHANGED
|
@@ -1,3024 +1,2 @@
|
|
|
1
|
-
import { t as C_Icon_default } from "./C_Icon2.js";
|
|
2
|
-
import { t as export_helper_default } from "./export-helper.js";
|
|
3
|
-
import { t as C_Form_default } from "./C_Form2.js";
|
|
4
|
-
import { NButton, NDatePicker, NDropdown, NInput, NInputNumber, NSelect, NSpace, NSwitch, useDialog, useMessage } from "naive-ui";
|
|
5
|
-
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, h, isRef, mergeProps, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, watch, watchEffect, withCtx } from "vue";
|
|
6
|
-
import html2canvas from "html2canvas";
|
|
7
|
-
import { NButton as NButton$1, NButtonGroup as NButtonGroup$1, NCheckbox as NCheckbox$1, NDataTable, NDrawer as NDrawer$1, NDrawerContent as NDrawerContent$1, NDropdown as NDropdown$1, NInput as NInput$1, NModal as NModal$1, NPagination as NPagination$1, NSpace as NSpace$1, NSpin as NSpin$1, NSwitch as NSwitch$1, NTag as NTag$1, NText as NText$1, NTooltip as NTooltip$1, useMessage as useMessage$1 } from "naive-ui/es";
|
|
8
|
-
import printJS from "print-js";
|
|
9
|
-
|
|
10
|
-
//#region src/components/C_Table/composables/useTableConfig.ts
|
|
11
|
-
const EDIT_DISABLED = {
|
|
12
|
-
editable: false,
|
|
13
|
-
editMode: "none",
|
|
14
|
-
showRowActions: false,
|
|
15
|
-
modalTitle: "编辑数据",
|
|
16
|
-
modalWidth: 600
|
|
17
|
-
};
|
|
18
|
-
const resolveEdit = (edit) => {
|
|
19
|
-
if (edit === false || edit === void 0) return EDIT_DISABLED;
|
|
20
|
-
if (edit === true) return {
|
|
21
|
-
editable: true,
|
|
22
|
-
editMode: "modal",
|
|
23
|
-
showRowActions: true,
|
|
24
|
-
modalTitle: "编辑数据",
|
|
25
|
-
modalWidth: 600
|
|
26
|
-
};
|
|
27
|
-
return {
|
|
28
|
-
editable: edit.enabled !== false && edit.mode !== "none",
|
|
29
|
-
editMode: edit.mode || "modal",
|
|
30
|
-
showRowActions: edit.showRowActions !== false && edit.mode !== "none",
|
|
31
|
-
modalTitle: edit.modalTitle || "编辑数据",
|
|
32
|
-
modalWidth: edit.modalWidth || 600
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
const resolveExpand = (expand) => {
|
|
36
|
-
if (!expand) return {
|
|
37
|
-
expandable: false,
|
|
38
|
-
defaultExpandedKeys: void 0,
|
|
39
|
-
onLoadExpandData: void 0,
|
|
40
|
-
renderExpandContent: void 0,
|
|
41
|
-
rowExpandable: void 0
|
|
42
|
-
};
|
|
43
|
-
if (expand === true) return {
|
|
44
|
-
expandable: true,
|
|
45
|
-
defaultExpandedKeys: void 0,
|
|
46
|
-
onLoadExpandData: void 0,
|
|
47
|
-
renderExpandContent: void 0,
|
|
48
|
-
rowExpandable: void 0
|
|
49
|
-
};
|
|
50
|
-
return {
|
|
51
|
-
expandable: expand.enabled !== false,
|
|
52
|
-
defaultExpandedKeys: expand.defaultExpandedKeys,
|
|
53
|
-
onLoadExpandData: expand.onLoadData,
|
|
54
|
-
renderExpandContent: expand.renderContent,
|
|
55
|
-
rowExpandable: expand.rowExpandable
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
-
const resolveSelection = (selection) => {
|
|
59
|
-
if (!selection) return {
|
|
60
|
-
enableSelection: false,
|
|
61
|
-
defaultCheckedKeys: void 0,
|
|
62
|
-
rowCheckable: void 0,
|
|
63
|
-
maxSelection: void 0,
|
|
64
|
-
enableChildSelection: false,
|
|
65
|
-
childRowCheckable: void 0,
|
|
66
|
-
enableParentChildLink: false,
|
|
67
|
-
parentChildLinkMode: "loose"
|
|
68
|
-
};
|
|
69
|
-
if (selection === true) return {
|
|
70
|
-
enableSelection: true,
|
|
71
|
-
defaultCheckedKeys: void 0,
|
|
72
|
-
rowCheckable: void 0,
|
|
73
|
-
maxSelection: void 0,
|
|
74
|
-
enableChildSelection: false,
|
|
75
|
-
childRowCheckable: void 0,
|
|
76
|
-
enableParentChildLink: false,
|
|
77
|
-
parentChildLinkMode: "loose"
|
|
78
|
-
};
|
|
79
|
-
const child = selection.childSelection || {};
|
|
80
|
-
const link = selection.parentChildLink || {};
|
|
81
|
-
return {
|
|
82
|
-
enableSelection: selection.enabled !== false,
|
|
83
|
-
defaultCheckedKeys: selection.defaultCheckedKeys,
|
|
84
|
-
rowCheckable: selection.rowCheckable,
|
|
85
|
-
maxSelection: selection.maxSelection,
|
|
86
|
-
enableChildSelection: child.enabled || false,
|
|
87
|
-
childRowCheckable: child.childRowCheckable,
|
|
88
|
-
enableParentChildLink: link.enabled || false,
|
|
89
|
-
parentChildLinkMode: link.mode || "loose"
|
|
90
|
-
};
|
|
91
|
-
};
|
|
92
|
-
const resolvePagination = (pagination) => {
|
|
93
|
-
const defaults = {
|
|
94
|
-
enabled: true,
|
|
95
|
-
page: 1,
|
|
96
|
-
pageSize: 10,
|
|
97
|
-
showSizePicker: true,
|
|
98
|
-
showQuickJumper: true,
|
|
99
|
-
pageSizes: [
|
|
100
|
-
10,
|
|
101
|
-
20,
|
|
102
|
-
50,
|
|
103
|
-
100
|
|
104
|
-
],
|
|
105
|
-
simple: false,
|
|
106
|
-
size: "medium"
|
|
107
|
-
};
|
|
108
|
-
if (pagination === false) return { pagination: null };
|
|
109
|
-
if (pagination === true || pagination === void 0) return { pagination: defaults };
|
|
110
|
-
return { pagination: {
|
|
111
|
-
...defaults,
|
|
112
|
-
...pagination
|
|
113
|
-
} };
|
|
114
|
-
};
|
|
115
|
-
const resolveDynamicRows = (dynamicRows) => {
|
|
116
|
-
if (!dynamicRows) return { dynamicRows: void 0 };
|
|
117
|
-
if (dynamicRows === true) return { dynamicRows: {
|
|
118
|
-
enableRadioSelection: true,
|
|
119
|
-
enableAdd: true,
|
|
120
|
-
enableInsert: true,
|
|
121
|
-
enableDelete: true,
|
|
122
|
-
enableCopy: true,
|
|
123
|
-
enableMove: true,
|
|
124
|
-
enablePrint: true
|
|
125
|
-
} };
|
|
126
|
-
return { dynamicRows };
|
|
127
|
-
};
|
|
128
|
-
const DISPLAY_DEFAULTS = {
|
|
129
|
-
striped: true,
|
|
130
|
-
bordered: true,
|
|
131
|
-
singleLine: true,
|
|
132
|
-
size: "medium",
|
|
133
|
-
maxHeight: void 0,
|
|
134
|
-
scrollX: void 0,
|
|
135
|
-
columnWidth: 180
|
|
136
|
-
};
|
|
137
|
-
/** 解析 display 配置,合并默认值 */
|
|
138
|
-
function resolveDisplay(display) {
|
|
139
|
-
if (!display) return { ...DISPLAY_DEFAULTS };
|
|
140
|
-
return {
|
|
141
|
-
striped: display.striped ?? DISPLAY_DEFAULTS.striped,
|
|
142
|
-
bordered: display.bordered ?? DISPLAY_DEFAULTS.bordered,
|
|
143
|
-
singleLine: display.singleLine ?? DISPLAY_DEFAULTS.singleLine,
|
|
144
|
-
size: display.size ?? DISPLAY_DEFAULTS.size,
|
|
145
|
-
maxHeight: display.maxHeight,
|
|
146
|
-
scrollX: display.scrollX,
|
|
147
|
-
columnWidth: display.columnWidth ?? DISPLAY_DEFAULTS.columnWidth
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
const resolveToolbar = (toolbar) => ({
|
|
151
|
-
showToolbar: toolbar?.show !== false,
|
|
152
|
-
enableColumnSettings: toolbar?.columnSettings !== false
|
|
153
|
-
});
|
|
154
|
-
/**
|
|
155
|
-
* 将 config 单一对象解析为内部扁平化配置
|
|
156
|
-
*/
|
|
157
|
-
function resolveConfig(config = {}) {
|
|
158
|
-
return {
|
|
159
|
-
...resolveEdit(config.edit),
|
|
160
|
-
...resolveExpand(config.expand),
|
|
161
|
-
...resolveSelection(config.selection),
|
|
162
|
-
...resolvePagination(config.pagination),
|
|
163
|
-
...resolveDynamicRows(config.dynamicRows),
|
|
164
|
-
...resolveDisplay(config.display),
|
|
165
|
-
...resolveToolbar(config.toolbar)
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
const createEditModeChecker = (config) => ({
|
|
169
|
-
isNonEditable: (column) => !config.editable || column.editable === false || config.editMode === "none",
|
|
170
|
-
isRowEditMode: () => ["row", "both"].includes(config.editMode),
|
|
171
|
-
isCellEditMode: () => ["cell", "both"].includes(config.editMode)
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
//#endregion
|
|
175
|
-
//#region src/components/C_Table/composables/useRowEdit.ts
|
|
176
|
-
/**
|
|
177
|
-
* 可编辑行组合函数,提供表格整行的编辑功能
|
|
178
|
-
*/
|
|
179
|
-
function useRowEdit(options) {
|
|
180
|
-
const editingRowKey = ref(null);
|
|
181
|
-
const editingData = ref({});
|
|
182
|
-
/**
|
|
183
|
-
* 检查指定行是否正在编辑状态
|
|
184
|
-
*/
|
|
185
|
-
const isEditingRow = (rowKey) => {
|
|
186
|
-
return editingRowKey.value === rowKey;
|
|
187
|
-
};
|
|
188
|
-
/**
|
|
189
|
-
* 根据rowKey实时查找最新的行数据
|
|
190
|
-
*/
|
|
191
|
-
const findRowData = (rowKey) => {
|
|
192
|
-
const currentData = options.data();
|
|
193
|
-
if (!currentData || !Array.isArray(currentData)) return null;
|
|
194
|
-
return currentData.find((row) => options.rowKey(row) === rowKey);
|
|
195
|
-
};
|
|
196
|
-
/**
|
|
197
|
-
* 开始编辑指定行,将原始数据复制到编辑缓存中
|
|
198
|
-
*/
|
|
199
|
-
const startEditRow = (rowKey) => {
|
|
200
|
-
const rowData = findRowData(rowKey);
|
|
201
|
-
if (!rowData) return;
|
|
202
|
-
editingRowKey.value = rowKey;
|
|
203
|
-
editingData.value[rowKey] = { ...rowData };
|
|
204
|
-
};
|
|
205
|
-
/**
|
|
206
|
-
* 取消当前行编辑,调用取消回调并清理编辑状态
|
|
207
|
-
*/
|
|
208
|
-
const cancelEditRow = async () => {
|
|
209
|
-
if (!editingRowKey.value) return;
|
|
210
|
-
const currentData = options.data();
|
|
211
|
-
if (!currentData || !Array.isArray(currentData)) return;
|
|
212
|
-
const rowIndex = currentData.findIndex((row) => options.rowKey(row) === editingRowKey.value);
|
|
213
|
-
if (rowIndex > -1) await options.onCancel?.(currentData[rowIndex], rowIndex);
|
|
214
|
-
editingRowKey.value = null;
|
|
215
|
-
editingData.value = {};
|
|
216
|
-
};
|
|
217
|
-
/**
|
|
218
|
-
* 保存当前行编辑,调用保存回调并清理编辑状态
|
|
219
|
-
*/
|
|
220
|
-
const saveEditRow = async () => {
|
|
221
|
-
if (!editingRowKey.value) return;
|
|
222
|
-
const rowKey = editingRowKey.value;
|
|
223
|
-
const currentData = options.data();
|
|
224
|
-
if (!currentData || !Array.isArray(currentData)) return;
|
|
225
|
-
const rowIndex = currentData.findIndex((row) => options.rowKey(row) === rowKey);
|
|
226
|
-
if (rowIndex === -1) return;
|
|
227
|
-
const updatedData = editingData.value[rowKey];
|
|
228
|
-
if (!updatedData) return;
|
|
229
|
-
await options.onSave?.(updatedData, rowIndex);
|
|
230
|
-
editingRowKey.value = null;
|
|
231
|
-
editingData.value = {};
|
|
232
|
-
return {
|
|
233
|
-
updatedData,
|
|
234
|
-
rowIndex
|
|
235
|
-
};
|
|
236
|
-
};
|
|
237
|
-
/**
|
|
238
|
-
* 获取指定行的编辑中数据
|
|
239
|
-
*/
|
|
240
|
-
const getEditingRowData = (rowKey) => {
|
|
241
|
-
return editingData.value[rowKey];
|
|
242
|
-
};
|
|
243
|
-
/**
|
|
244
|
-
* 更新指定行编辑中的字段值
|
|
245
|
-
*/
|
|
246
|
-
const updateEditingRowData = (rowKey, field, value) => {
|
|
247
|
-
if (!editingData.value[rowKey]) return;
|
|
248
|
-
editingData.value[rowKey][field] = value;
|
|
249
|
-
};
|
|
250
|
-
return {
|
|
251
|
-
editingRowKey,
|
|
252
|
-
isEditingRow,
|
|
253
|
-
startEditRow,
|
|
254
|
-
cancelEditRow,
|
|
255
|
-
saveEditRow,
|
|
256
|
-
getEditingRowData,
|
|
257
|
-
updateEditingRowData,
|
|
258
|
-
findRowData
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
//#endregion
|
|
263
|
-
//#region src/components/C_Table/composables/useCellEdit.ts
|
|
264
|
-
/**
|
|
265
|
-
* 可编辑单元格组合函数,提供表格单元格的编辑功能
|
|
266
|
-
*/
|
|
267
|
-
function useCellEdit(options) {
|
|
268
|
-
const editingCell = ref({
|
|
269
|
-
rowKey: null,
|
|
270
|
-
columnKey: null
|
|
271
|
-
});
|
|
272
|
-
const editingData = ref({});
|
|
273
|
-
/**
|
|
274
|
-
* 检查指定单元格是否正在编辑状态
|
|
275
|
-
*/
|
|
276
|
-
const isEditingCell = (rowKey, columnKey) => {
|
|
277
|
-
return editingCell.value.rowKey === rowKey && editingCell.value.columnKey === columnKey;
|
|
278
|
-
};
|
|
279
|
-
/**
|
|
280
|
-
* 根据rowKey实时查找最新的行数据
|
|
281
|
-
*/
|
|
282
|
-
const findRowData = (rowKey) => {
|
|
283
|
-
const currentData = options.data();
|
|
284
|
-
if (!currentData || !Array.isArray(currentData)) return null;
|
|
285
|
-
return currentData.find((row) => options.rowKey(row) === rowKey);
|
|
286
|
-
};
|
|
287
|
-
/**
|
|
288
|
-
* 开始编辑指定单元格,将原值存储到编辑缓存中
|
|
289
|
-
*/
|
|
290
|
-
const startEditCell = (rowKey, columnKey) => {
|
|
291
|
-
const rowData = findRowData(rowKey);
|
|
292
|
-
if (!rowData) return;
|
|
293
|
-
editingCell.value = {
|
|
294
|
-
rowKey,
|
|
295
|
-
columnKey
|
|
296
|
-
};
|
|
297
|
-
editingData.value[`${rowKey}-${columnKey}`] = rowData[columnKey];
|
|
298
|
-
};
|
|
299
|
-
/**
|
|
300
|
-
* 保存当前编辑的单元格,调用保存回调并清理编辑状态
|
|
301
|
-
*/
|
|
302
|
-
const saveEditCell = async () => {
|
|
303
|
-
const { rowKey, columnKey } = editingCell.value;
|
|
304
|
-
if (!rowKey || !columnKey) return;
|
|
305
|
-
const currentData = options.data();
|
|
306
|
-
if (!currentData || !Array.isArray(currentData)) return;
|
|
307
|
-
const rowIndex = currentData.findIndex((row) => options.rowKey(row) === rowKey);
|
|
308
|
-
if (rowIndex === -1) return;
|
|
309
|
-
const cellKey = `${rowKey}-${columnKey}`;
|
|
310
|
-
const newValue = editingData.value[cellKey];
|
|
311
|
-
const updatedData = {
|
|
312
|
-
...currentData[rowIndex],
|
|
313
|
-
[columnKey]: newValue
|
|
314
|
-
};
|
|
315
|
-
await options.onSave?.(updatedData, rowIndex, columnKey);
|
|
316
|
-
editingCell.value = {
|
|
317
|
-
rowKey: null,
|
|
318
|
-
columnKey: null
|
|
319
|
-
};
|
|
320
|
-
delete editingData.value[cellKey];
|
|
321
|
-
return {
|
|
322
|
-
updatedData,
|
|
323
|
-
rowIndex,
|
|
324
|
-
columnKey
|
|
325
|
-
};
|
|
326
|
-
};
|
|
327
|
-
/**
|
|
328
|
-
* 取消当前单元格编辑,清理编辑状态和缓存数据
|
|
329
|
-
*/
|
|
330
|
-
const cancelEditCell = () => {
|
|
331
|
-
const { rowKey, columnKey } = editingCell.value;
|
|
332
|
-
if (rowKey && columnKey) delete editingData.value[`${rowKey}-${columnKey}`];
|
|
333
|
-
editingCell.value = {
|
|
334
|
-
rowKey: null,
|
|
335
|
-
columnKey: null
|
|
336
|
-
};
|
|
337
|
-
};
|
|
338
|
-
/**
|
|
339
|
-
* 获取指定单元格的编辑中数值
|
|
340
|
-
*/
|
|
341
|
-
const getEditingCellValue = (rowKey, columnKey) => {
|
|
342
|
-
return editingData.value[`${rowKey}-${columnKey}`];
|
|
343
|
-
};
|
|
344
|
-
/**
|
|
345
|
-
* 更新指定单元格的编辑中数值
|
|
346
|
-
*/
|
|
347
|
-
const updateEditingCellValue = (rowKey, columnKey, value) => {
|
|
348
|
-
editingData.value[`${rowKey}-${columnKey}`] = value;
|
|
349
|
-
};
|
|
350
|
-
return {
|
|
351
|
-
editingCell,
|
|
352
|
-
isEditingCell,
|
|
353
|
-
startEditCell,
|
|
354
|
-
saveEditCell,
|
|
355
|
-
cancelEditCell,
|
|
356
|
-
getEditingCellValue,
|
|
357
|
-
updateEditingCellValue,
|
|
358
|
-
findRowData
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
//#endregion
|
|
363
|
-
//#region src/components/C_Table/composables/useModalEdit.ts
|
|
364
|
-
/**
|
|
365
|
-
* 模态框编辑组合函数,提供弹窗形式的数据编辑功能
|
|
366
|
-
*/
|
|
367
|
-
function useModalEdit(options) {
|
|
368
|
-
const isModalVisible = ref(false);
|
|
369
|
-
const editingRowKey = ref(null);
|
|
370
|
-
const editingData = ref({});
|
|
371
|
-
/**
|
|
372
|
-
* 计算属性:获取当前编辑行的索引
|
|
373
|
-
*/
|
|
374
|
-
const editingRowIndex = computed(() => {
|
|
375
|
-
if (!editingRowKey.value) return -1;
|
|
376
|
-
const currentData = options.data();
|
|
377
|
-
if (!currentData || !Array.isArray(currentData)) return -1;
|
|
378
|
-
return currentData.findIndex((row) => options.rowKey(row) === editingRowKey.value);
|
|
379
|
-
});
|
|
380
|
-
/**
|
|
381
|
-
* 重置编辑状态
|
|
382
|
-
*/
|
|
383
|
-
const resetEditingState = () => {
|
|
384
|
-
editingRowKey.value = null;
|
|
385
|
-
editingData.value = {};
|
|
386
|
-
};
|
|
387
|
-
/**
|
|
388
|
-
* 开始编辑指定行
|
|
389
|
-
*/
|
|
390
|
-
const startEdit = (rowKey) => {
|
|
391
|
-
console.log("🚀 开始编辑:", rowKey);
|
|
392
|
-
const currentData = options.data();
|
|
393
|
-
if (!currentData || !Array.isArray(currentData)) {
|
|
394
|
-
console.warn("数据源为空或不是数组");
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
const rowIndex = currentData.findIndex((row) => options.rowKey(row) === rowKey);
|
|
398
|
-
if (rowIndex === -1) {
|
|
399
|
-
console.warn("未找到对应的行数据:", rowKey);
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
402
|
-
const rowData = currentData[rowIndex];
|
|
403
|
-
console.log("找到行数据:", rowData);
|
|
404
|
-
editingRowKey.value = rowKey;
|
|
405
|
-
editingData.value = JSON.parse(JSON.stringify(rowData));
|
|
406
|
-
console.log("编辑数据已准备:", editingData.value);
|
|
407
|
-
isModalVisible.value = true;
|
|
408
|
-
};
|
|
409
|
-
/**
|
|
410
|
-
* 保存编辑
|
|
411
|
-
*/
|
|
412
|
-
const saveEdit = async (formData) => {
|
|
413
|
-
const dataToSave = formData || editingData.value;
|
|
414
|
-
const currentIndex = editingRowIndex.value;
|
|
415
|
-
console.log("💾 保存编辑:", {
|
|
416
|
-
rowKey: editingRowKey.value,
|
|
417
|
-
index: currentIndex,
|
|
418
|
-
data: dataToSave
|
|
419
|
-
});
|
|
420
|
-
if (currentIndex === -1) {
|
|
421
|
-
console.warn("无法找到编辑行的索引");
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
try {
|
|
425
|
-
await options.onSave?.(dataToSave, currentIndex);
|
|
426
|
-
isModalVisible.value = false;
|
|
427
|
-
resetEditingState();
|
|
428
|
-
console.log("✅ 保存成功");
|
|
429
|
-
} catch (error) {
|
|
430
|
-
console.error("❌ 保存失败:", error);
|
|
431
|
-
throw error;
|
|
432
|
-
}
|
|
433
|
-
};
|
|
434
|
-
/**
|
|
435
|
-
* 取消编辑
|
|
436
|
-
*/
|
|
437
|
-
const cancelEdit = async () => {
|
|
438
|
-
console.log("🚫 取消编辑");
|
|
439
|
-
try {
|
|
440
|
-
const currentIndex = editingRowIndex.value;
|
|
441
|
-
if (editingRowKey.value && currentIndex > -1) {
|
|
442
|
-
const currentData = options.data();
|
|
443
|
-
if (currentData && currentData[currentIndex]) await options.onCancel?.(currentData[currentIndex], currentIndex);
|
|
444
|
-
}
|
|
445
|
-
} finally {
|
|
446
|
-
isModalVisible.value = false;
|
|
447
|
-
resetEditingState();
|
|
448
|
-
}
|
|
449
|
-
};
|
|
450
|
-
/**
|
|
451
|
-
* 更新编辑数据
|
|
452
|
-
*/
|
|
453
|
-
const updateEditingData = (data) => {
|
|
454
|
-
editingData.value = { ...data };
|
|
455
|
-
};
|
|
456
|
-
/**
|
|
457
|
-
* 获取当前编辑的行数据
|
|
458
|
-
*/
|
|
459
|
-
const getEditingRowData = (rowKey) => {
|
|
460
|
-
if (editingRowKey.value === rowKey) return editingData.value;
|
|
461
|
-
return null;
|
|
462
|
-
};
|
|
463
|
-
/**
|
|
464
|
-
* 检查是否正在编辑指定行
|
|
465
|
-
*/
|
|
466
|
-
const isEditingRow = (rowKey) => {
|
|
467
|
-
return editingRowKey.value === rowKey && isModalVisible.value;
|
|
468
|
-
};
|
|
469
|
-
return {
|
|
470
|
-
isModalVisible,
|
|
471
|
-
editingData,
|
|
472
|
-
editingRowKey,
|
|
473
|
-
editingRowIndex,
|
|
474
|
-
startEdit,
|
|
475
|
-
saveEdit,
|
|
476
|
-
cancelEdit,
|
|
477
|
-
updateEditingData,
|
|
478
|
-
resetEditingState,
|
|
479
|
-
isEditingRow,
|
|
480
|
-
getEditingRowData
|
|
481
|
-
};
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
//#endregion
|
|
485
|
-
//#region src/components/C_Table/composables/useTableExpand.ts
|
|
486
|
-
const useExpandState = (options) => {
|
|
487
|
-
return {
|
|
488
|
-
expandedKeys: ref([...options.defaultExpandedKeys || []]),
|
|
489
|
-
expandDataMap: ref(/* @__PURE__ */ new Map()),
|
|
490
|
-
loadingMap: ref(/* @__PURE__ */ new Map()),
|
|
491
|
-
checkedKeys: options.enableSelection ? ref([...options.defaultCheckedKeys || []]) : ref([]),
|
|
492
|
-
childSelections: options.enableChildSelection ? ref(/* @__PURE__ */ new Map()) : ref(/* @__PURE__ */ new Map())
|
|
493
|
-
};
|
|
494
|
-
};
|
|
495
|
-
const useDataUtils = (options) => {
|
|
496
|
-
const data = computed(() => unref(options.data));
|
|
497
|
-
const getRowKey = options.rowKey;
|
|
498
|
-
const getChildRowKey = options.childRowKey || ((child) => child.id);
|
|
499
|
-
const findRow = (key) => data.value.find((row) => getRowKey(row) === key);
|
|
500
|
-
return {
|
|
501
|
-
data,
|
|
502
|
-
getRowKey,
|
|
503
|
-
getChildRowKey,
|
|
504
|
-
findRow,
|
|
505
|
-
isRowExpandable: options.rowExpandable || (() => true),
|
|
506
|
-
isRowCheckable: options.rowCheckable || (() => true),
|
|
507
|
-
isChildRowCheckable: options.childRowCheckable || (() => true)
|
|
508
|
-
};
|
|
509
|
-
};
|
|
510
|
-
const useExpandLogic = (state, utils, options) => {
|
|
511
|
-
const loadData = async (row) => {
|
|
512
|
-
if (!options.onLoadData) return [];
|
|
513
|
-
const key = utils.getRowKey(row);
|
|
514
|
-
const existingData = state.expandDataMap.value.get(key);
|
|
515
|
-
if (existingData) return existingData;
|
|
516
|
-
state.loadingMap.value.set(key, true);
|
|
517
|
-
try {
|
|
518
|
-
const result = await options.onLoadData(row) || [];
|
|
519
|
-
state.expandDataMap.value.set(key, result);
|
|
520
|
-
if (options.enableChildSelection && !state.childSelections.value.has(key)) state.childSelections.value.set(key, []);
|
|
521
|
-
return result;
|
|
522
|
-
} catch (error) {
|
|
523
|
-
console.error("加载展开数据失败:", error);
|
|
524
|
-
return [];
|
|
525
|
-
} finally {
|
|
526
|
-
state.loadingMap.value.set(key, false);
|
|
527
|
-
}
|
|
528
|
-
};
|
|
529
|
-
const handleRowExpand = async (row, expanded) => {
|
|
530
|
-
const key = utils.getRowKey(row);
|
|
531
|
-
if (expanded) {
|
|
532
|
-
await loadData(row);
|
|
533
|
-
if (!state.expandedKeys.value.includes(key)) state.expandedKeys.value = [...state.expandedKeys.value, key];
|
|
534
|
-
} else state.expandedKeys.value = state.expandedKeys.value.filter((k) => k !== key);
|
|
535
|
-
options.onExpandChange?.(state.expandedKeys.value);
|
|
536
|
-
};
|
|
537
|
-
const expandAll = async () => {
|
|
538
|
-
const expandableRows = utils.data.value.filter(utils.isRowExpandable);
|
|
539
|
-
await Promise.allSettled(expandableRows.map(loadData));
|
|
540
|
-
state.expandedKeys.value = expandableRows.map(utils.getRowKey);
|
|
541
|
-
options.onExpandChange?.(state.expandedKeys.value);
|
|
542
|
-
};
|
|
543
|
-
const collapseAll = () => {
|
|
544
|
-
state.expandedKeys.value = [];
|
|
545
|
-
state.childSelections.value.clear();
|
|
546
|
-
options.onExpandChange?.(state.expandedKeys.value);
|
|
547
|
-
};
|
|
548
|
-
const handleExpandChange = async (keys) => {
|
|
549
|
-
const newExpandedKeys = keys.filter((key) => !state.expandedKeys.value.includes(key));
|
|
550
|
-
const collapsedKeys = state.expandedKeys.value.filter((key) => !keys.includes(key));
|
|
551
|
-
await Promise.all(newExpandedKeys.map(async (key) => {
|
|
552
|
-
const row = utils.findRow(key);
|
|
553
|
-
if (row) await loadData(row);
|
|
554
|
-
}));
|
|
555
|
-
for (const key of collapsedKeys) state.childSelections.value.delete(key);
|
|
556
|
-
state.expandedKeys.value = keys;
|
|
557
|
-
options.onExpandChange?.(keys);
|
|
558
|
-
};
|
|
559
|
-
return {
|
|
560
|
-
loadData,
|
|
561
|
-
handleRowExpand,
|
|
562
|
-
expandAll,
|
|
563
|
-
collapseAll,
|
|
564
|
-
handleExpandChange
|
|
565
|
-
};
|
|
566
|
-
};
|
|
567
|
-
const useSelectionLogic = (state, utils, options) => {
|
|
568
|
-
const selectableRows = computed(() => utils.data.value.filter(utils.isRowCheckable));
|
|
569
|
-
const selectedRowsCount = computed(() => state.checkedKeys.value.length);
|
|
570
|
-
const selectAll = () => {
|
|
571
|
-
if (!options.enableSelection) return;
|
|
572
|
-
const keys = selectableRows.value.map(utils.getRowKey);
|
|
573
|
-
const finalKeys = options.maxSelection ? keys.slice(0, options.maxSelection) : keys;
|
|
574
|
-
state.checkedKeys.value = finalKeys;
|
|
575
|
-
const selectedRows = selectableRows.value.filter((row) => finalKeys.includes(utils.getRowKey(row)));
|
|
576
|
-
options.onSelectionChange?.(finalKeys, selectedRows, state.childSelections.value);
|
|
577
|
-
};
|
|
578
|
-
const clearSelection = () => {
|
|
579
|
-
if (!options.enableSelection) return;
|
|
580
|
-
state.checkedKeys.value = [];
|
|
581
|
-
options.onSelectionChange?.([], [], state.childSelections.value);
|
|
582
|
-
};
|
|
583
|
-
const handleSelectionChange = (keys) => {
|
|
584
|
-
if (!options.enableSelection) return;
|
|
585
|
-
state.checkedKeys.value = keys;
|
|
586
|
-
const selectedRows = utils.data.value.filter((row) => keys.includes(utils.getRowKey(row)));
|
|
587
|
-
options.onSelectionChange?.(keys, selectedRows, state.childSelections.value);
|
|
588
|
-
};
|
|
589
|
-
return {
|
|
590
|
-
selectAll,
|
|
591
|
-
clearSelection,
|
|
592
|
-
handleSelectionChange,
|
|
593
|
-
selectedRowsCount,
|
|
594
|
-
selectableRows
|
|
595
|
-
};
|
|
596
|
-
};
|
|
597
|
-
const useParentChildLink = (state, options) => {
|
|
598
|
-
const isLinkEnabled = Boolean(options.enableParentChildLink && options.enableSelection && options.enableChildSelection);
|
|
599
|
-
const handleParentChildLink = (parentKey, selectedChildKeys, totalChildren) => {
|
|
600
|
-
if (!isLinkEnabled) return;
|
|
601
|
-
const shouldSelectParent = options.parentChildLinkMode === "strict" ? selectedChildKeys.length === totalChildren && totalChildren > 0 : selectedChildKeys.length > 0;
|
|
602
|
-
const currentKeys = [...state.checkedKeys.value];
|
|
603
|
-
const isParentSelected = currentKeys.includes(parentKey);
|
|
604
|
-
if (shouldSelectParent && !isParentSelected) state.checkedKeys.value = [...currentKeys, parentKey];
|
|
605
|
-
else if (!shouldSelectParent && isParentSelected) state.checkedKeys.value = currentKeys.filter((k) => k !== parentKey);
|
|
606
|
-
};
|
|
607
|
-
return {
|
|
608
|
-
handleParentChildLink,
|
|
609
|
-
isLinkEnabled
|
|
610
|
-
};
|
|
611
|
-
};
|
|
612
|
-
const useChildSelectionLogic = (state, utils, parentChildLink, options) => {
|
|
613
|
-
const totalChildSelections = computed(() => {
|
|
614
|
-
if (!options.enableChildSelection) return 0;
|
|
615
|
-
return Array.from(state.childSelections.value.values()).reduce((total, keys) => total + keys.length, 0);
|
|
616
|
-
});
|
|
617
|
-
const clearAllSelections = () => {
|
|
618
|
-
state.checkedKeys.value = [];
|
|
619
|
-
state.childSelections.value.clear();
|
|
620
|
-
options.onSelectionChange?.([], [], state.childSelections.value);
|
|
621
|
-
};
|
|
622
|
-
const handleChildSelectionChange = (parentKey, childKeys) => {
|
|
623
|
-
if (!options.enableChildSelection) return;
|
|
624
|
-
state.childSelections.value.set(parentKey, childKeys);
|
|
625
|
-
const expandData = state.expandDataMap.value.get(parentKey) || [];
|
|
626
|
-
const selectedChildren = expandData.filter((child) => childKeys.includes(utils.getChildRowKey(child)));
|
|
627
|
-
options.onChildSelectionChange?.(parentKey, childKeys, selectedChildren);
|
|
628
|
-
if (parentChildLink.isLinkEnabled) parentChildLink.handleParentChildLink(parentKey, childKeys, expandData.length);
|
|
629
|
-
};
|
|
630
|
-
return {
|
|
631
|
-
totalChildSelections,
|
|
632
|
-
clearAllSelections,
|
|
633
|
-
handleChildSelectionChange
|
|
634
|
-
};
|
|
635
|
-
};
|
|
636
|
-
const createChildSelectionState = (parentKey, state, utils, childLogic, options) => {
|
|
637
|
-
if (!options.enableChildSelection) return void 0;
|
|
638
|
-
const selectedKeys = state.childSelections.value.get(parentKey) || [];
|
|
639
|
-
const expandData = state.expandDataMap.value.get(parentKey) || [];
|
|
640
|
-
const parent = utils.findRow(parentKey);
|
|
641
|
-
if (!parent) return void 0;
|
|
642
|
-
const checkableChildren = expandData.filter((child) => utils.isChildRowCheckable(child, parent));
|
|
643
|
-
return {
|
|
644
|
-
selectedKeys,
|
|
645
|
-
isAllChecked: checkableChildren.length > 0 && checkableChildren.every((child) => selectedKeys.includes(utils.getChildRowKey(child))),
|
|
646
|
-
selectAll: () => {
|
|
647
|
-
const allKeys = checkableChildren.map((child) => utils.getChildRowKey(child));
|
|
648
|
-
childLogic.handleChildSelectionChange(parentKey, allKeys);
|
|
649
|
-
},
|
|
650
|
-
clearAll: () => {
|
|
651
|
-
childLogic.handleChildSelectionChange(parentKey, []);
|
|
652
|
-
}
|
|
653
|
-
};
|
|
654
|
-
};
|
|
655
|
-
const createLoadingView = () => {
|
|
656
|
-
return h("div", { class: "flex justify-center items-center py-8" }, [h(NSpin$1, { size: "small" }), h("span", { class: "ml-2 text-gray-500" }, "加载中...")]);
|
|
657
|
-
};
|
|
658
|
-
const createEmptyView = () => {
|
|
659
|
-
return h("div", { class: "text-center py-8 text-gray-400" }, "暂无数据");
|
|
660
|
-
};
|
|
661
|
-
const createDefaultColumns = (expandData) => {
|
|
662
|
-
if (!expandData.length) return [];
|
|
663
|
-
const firstItem = expandData[0];
|
|
664
|
-
if (!firstItem || typeof firstItem !== "object") return [];
|
|
665
|
-
return [{
|
|
666
|
-
title: "序号",
|
|
667
|
-
key: "_index",
|
|
668
|
-
width: 60,
|
|
669
|
-
render: (_, index) => index + 1
|
|
670
|
-
}, ...Object.keys(firstItem).filter((key) => !["id", "key"].includes(key)).map((key) => ({
|
|
671
|
-
key,
|
|
672
|
-
title: key.charAt(0).toUpperCase() + key.slice(1),
|
|
673
|
-
width: 120,
|
|
674
|
-
ellipsis: { tooltip: true }
|
|
675
|
-
}))];
|
|
676
|
-
};
|
|
677
|
-
const createDefaultTable = (key, expandData, childSelection, utils, childLogic, options) => {
|
|
678
|
-
const columns = [];
|
|
679
|
-
if (options.enableChildSelection) columns.push({
|
|
680
|
-
type: "selection",
|
|
681
|
-
multiple: true
|
|
682
|
-
});
|
|
683
|
-
columns.push(...createDefaultColumns(expandData));
|
|
684
|
-
return h("div", { class: "p-4 bg-gray-50" }, [h("div", { class: "mb-2 text-sm text-gray-600" }, `详细信息 (${expandData.length} 条)`), h(NDataTable, {
|
|
685
|
-
data: expandData,
|
|
686
|
-
columns,
|
|
687
|
-
size: "small",
|
|
688
|
-
striped: true,
|
|
689
|
-
checkedRowKeys: childSelection?.selectedKeys || [],
|
|
690
|
-
rowKey: (row) => utils.getChildRowKey(row),
|
|
691
|
-
onUpdateCheckedRowKeys: options.enableChildSelection ? (keys) => {
|
|
692
|
-
childLogic.handleChildSelectionChange(key, keys);
|
|
693
|
-
} : void 0
|
|
694
|
-
})]);
|
|
695
|
-
};
|
|
696
|
-
const useRenderer = (state, utils, childLogic, expandLogic, options) => {
|
|
697
|
-
const renderExpandContent = (row) => {
|
|
698
|
-
const key = utils.getRowKey(row);
|
|
699
|
-
const expandData = state.expandDataMap.value.get(key) || [];
|
|
700
|
-
const loading = state.loadingMap.value.get(key) || false;
|
|
701
|
-
if (!expandData.length && !loading && state.expandedKeys.value.includes(key)) nextTick(() => {
|
|
702
|
-
expandLogic.loadData(row);
|
|
703
|
-
});
|
|
704
|
-
const childSelection = createChildSelectionState(key, state, utils, childLogic, options);
|
|
705
|
-
if (options.renderContent) return options.renderContent(row, expandData, loading, childSelection);
|
|
706
|
-
if (loading) return createLoadingView();
|
|
707
|
-
if (!expandData.length) return createEmptyView();
|
|
708
|
-
return createDefaultTable(key, expandData, childSelection, utils, childLogic, options);
|
|
709
|
-
};
|
|
710
|
-
const getTableColumns = (originalColumns) => {
|
|
711
|
-
return originalColumns.map((column) => {
|
|
712
|
-
if (column.type === "selection" && options.enableSelection) return {
|
|
713
|
-
type: "selection",
|
|
714
|
-
disabled: (row) => !utils.isRowCheckable(row),
|
|
715
|
-
multiple: !options.maxSelection || options.maxSelection > 1
|
|
716
|
-
};
|
|
717
|
-
if (column.type === "expand" && (options.onLoadData || options.renderContent)) return {
|
|
718
|
-
type: "expand",
|
|
719
|
-
expandable: utils.isRowExpandable,
|
|
720
|
-
renderExpand: renderExpandContent
|
|
721
|
-
};
|
|
722
|
-
return column;
|
|
723
|
-
});
|
|
724
|
-
};
|
|
725
|
-
return { getTableColumns };
|
|
726
|
-
};
|
|
727
|
-
function useTableExpand(options) {
|
|
728
|
-
const state = useExpandState(options);
|
|
729
|
-
const utils = useDataUtils(options);
|
|
730
|
-
const expandLogic = useExpandLogic(state, utils, options);
|
|
731
|
-
const selectionLogic = useSelectionLogic(state, utils, options);
|
|
732
|
-
const childLogic = useChildSelectionLogic(state, utils, useParentChildLink(state, options), options);
|
|
733
|
-
const renderer = useRenderer(state, utils, childLogic, expandLogic, options);
|
|
734
|
-
if (options.onSelectionChange && options.enableSelection) watchEffect(() => {
|
|
735
|
-
if (!options.onSelectionChange) return;
|
|
736
|
-
const selectedRows = utils.data.value.filter((row) => state.checkedKeys.value.includes(utils.getRowKey(row)));
|
|
737
|
-
const hasSelection = state.checkedKeys.value.length > 0;
|
|
738
|
-
const hasData = utils.data.value.length > 0;
|
|
739
|
-
if (hasSelection || !hasData) options.onSelectionChange(state.checkedKeys.value, selectedRows, state.childSelections.value);
|
|
740
|
-
});
|
|
741
|
-
const expandRow = async (key) => {
|
|
742
|
-
if (state.expandedKeys.value.includes(key)) return;
|
|
743
|
-
const row = utils.findRow(key);
|
|
744
|
-
if (!row) return;
|
|
745
|
-
await expandLogic.loadData(row);
|
|
746
|
-
state.expandedKeys.value = [...state.expandedKeys.value, key];
|
|
747
|
-
options.onExpandChange?.(state.expandedKeys.value, row, true);
|
|
748
|
-
};
|
|
749
|
-
const initializeData = async () => {
|
|
750
|
-
const keysToLoad = options.defaultExpandedKeys || [];
|
|
751
|
-
if (keysToLoad.length === 0) return;
|
|
752
|
-
const loadPromises = keysToLoad.map(async (key) => {
|
|
753
|
-
const row = utils.findRow(key);
|
|
754
|
-
if (row && !state.expandDataMap.value.has(key)) await expandLogic.loadData(row);
|
|
755
|
-
});
|
|
756
|
-
await Promise.allSettled(loadPromises);
|
|
757
|
-
};
|
|
758
|
-
if (options.defaultExpandedKeys?.length) nextTick(initializeData);
|
|
759
|
-
return {
|
|
760
|
-
expandedKeys: state.expandedKeys,
|
|
761
|
-
checkedKeys: state.checkedKeys,
|
|
762
|
-
childSelections: state.childSelections,
|
|
763
|
-
selectedRowsCount: selectionLogic.selectedRowsCount,
|
|
764
|
-
totalChildSelections: childLogic.totalChildSelections,
|
|
765
|
-
expandAll: expandLogic.expandAll,
|
|
766
|
-
collapseAll: expandLogic.collapseAll,
|
|
767
|
-
expandRow,
|
|
768
|
-
handleExpandChange: expandLogic.handleExpandChange,
|
|
769
|
-
selectAll: selectionLogic.selectAll,
|
|
770
|
-
clearSelection: selectionLogic.clearSelection,
|
|
771
|
-
clearAllSelections: childLogic.clearAllSelections,
|
|
772
|
-
handleSelectionChange: selectionLogic.handleSelectionChange,
|
|
773
|
-
getTableColumns: renderer.getTableColumns,
|
|
774
|
-
expandDataMap: state.expandDataMap,
|
|
775
|
-
loadingMap: state.loadingMap
|
|
776
|
-
};
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
//#endregion
|
|
780
|
-
//#region src/components/C_Table/composables/usePrintWatermark.ts
|
|
781
|
-
const DEFAULT_WATERMARK = {
|
|
782
|
-
text: "Robot Admin",
|
|
783
|
-
textSize: 16,
|
|
784
|
-
textColor: "rgba(128, 128, 128, 0.3)",
|
|
785
|
-
font: "Microsoft JhengHei",
|
|
786
|
-
opacity: .3,
|
|
787
|
-
rotate: -20,
|
|
788
|
-
position: "repeat",
|
|
789
|
-
xGap: 200,
|
|
790
|
-
yGap: 120
|
|
791
|
-
};
|
|
792
|
-
const DEFAULT_CAPTURE = {
|
|
793
|
-
scale: 1,
|
|
794
|
-
quality: .92,
|
|
795
|
-
format: "png",
|
|
796
|
-
backgroundColor: "#ffffff",
|
|
797
|
-
logging: false,
|
|
798
|
-
allowTaint: true,
|
|
799
|
-
useCORS: true
|
|
800
|
-
};
|
|
801
|
-
const DEFAULT_PRINT = {
|
|
802
|
-
orientation: "portrait",
|
|
803
|
-
paperSize: "A4",
|
|
804
|
-
margin: "10mm 10mm 0 10mm",
|
|
805
|
-
style: "@page { margin: 10mm 10mm 0 10mm; } @media print { body { margin: 0; } }",
|
|
806
|
-
header: "",
|
|
807
|
-
footer: "",
|
|
808
|
-
showModal: false,
|
|
809
|
-
modalMessage: "正在准备打印...",
|
|
810
|
-
onLoadingStart: () => {},
|
|
811
|
-
onLoadingEnd: () => {},
|
|
812
|
-
onPrintDialogClose: () => {}
|
|
813
|
-
};
|
|
814
|
-
function drawCenterWatermark(ctx, width, height, config) {
|
|
815
|
-
ctx.save();
|
|
816
|
-
ctx.translate(width / 2, height / 2);
|
|
817
|
-
ctx.rotate(config.rotate * Math.PI / 180);
|
|
818
|
-
ctx.fillText(config.text, 0, 0);
|
|
819
|
-
ctx.restore();
|
|
820
|
-
}
|
|
821
|
-
function drawCornerWatermark(ctx, width, height, config) {
|
|
822
|
-
const offset = 50;
|
|
823
|
-
[
|
|
824
|
-
[offset, offset],
|
|
825
|
-
[width - offset, offset],
|
|
826
|
-
[offset, height - offset],
|
|
827
|
-
[width - offset, height - offset]
|
|
828
|
-
].forEach(([x, y]) => {
|
|
829
|
-
ctx.save();
|
|
830
|
-
ctx.translate(x, y);
|
|
831
|
-
ctx.rotate(config.rotate * Math.PI / 180);
|
|
832
|
-
ctx.fillText(config.text, 0, 0);
|
|
833
|
-
ctx.restore();
|
|
834
|
-
});
|
|
835
|
-
}
|
|
836
|
-
function drawDiagonalWatermark(ctx, width, height, config) {
|
|
837
|
-
const diagonal = Math.sqrt(width * width + height * height);
|
|
838
|
-
const centerX = width / 2;
|
|
839
|
-
const centerY = height / 2;
|
|
840
|
-
ctx.save();
|
|
841
|
-
ctx.translate(centerX, centerY);
|
|
842
|
-
ctx.rotate(Math.atan2(height, width));
|
|
843
|
-
const count = Math.floor(diagonal / config.xGap);
|
|
844
|
-
const start = -diagonal / 2;
|
|
845
|
-
for (let i = 0; i <= count; i++) {
|
|
846
|
-
const x = start + i * config.xGap;
|
|
847
|
-
ctx.fillText(config.text, x, 0);
|
|
848
|
-
}
|
|
849
|
-
ctx.restore();
|
|
850
|
-
}
|
|
851
|
-
function drawRepeatWatermark(ctx, width, height, config) {
|
|
852
|
-
const cols = Math.ceil(width / config.xGap) + 1;
|
|
853
|
-
const rows = Math.ceil(height / config.yGap) + 1;
|
|
854
|
-
for (let row = 0; row < rows; row++) for (let col = 0; col < cols; col++) {
|
|
855
|
-
const x = col * config.xGap + config.xGap / 2;
|
|
856
|
-
const y = row * config.yGap + config.yGap / 2;
|
|
857
|
-
ctx.save();
|
|
858
|
-
ctx.translate(x, y);
|
|
859
|
-
ctx.rotate(config.rotate * Math.PI / 180);
|
|
860
|
-
ctx.fillText(config.text, 0, 0);
|
|
861
|
-
ctx.restore();
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
function drawWatermark(canvas, config) {
|
|
865
|
-
const ctx = canvas.getContext("2d");
|
|
866
|
-
if (!ctx) return canvas;
|
|
867
|
-
const finalConfig = {
|
|
868
|
-
...DEFAULT_WATERMARK,
|
|
869
|
-
...config
|
|
870
|
-
};
|
|
871
|
-
const { width, height } = canvas;
|
|
872
|
-
ctx.save();
|
|
873
|
-
ctx.globalAlpha = finalConfig.opacity;
|
|
874
|
-
ctx.font = `${finalConfig.textSize}px ${finalConfig.font}`;
|
|
875
|
-
ctx.fillStyle = finalConfig.textColor;
|
|
876
|
-
ctx.textAlign = "center";
|
|
877
|
-
ctx.textBaseline = "middle";
|
|
878
|
-
const drawFunctions = {
|
|
879
|
-
center: drawCenterWatermark,
|
|
880
|
-
corner: drawCornerWatermark,
|
|
881
|
-
diagonal: drawDiagonalWatermark,
|
|
882
|
-
repeat: drawRepeatWatermark
|
|
883
|
-
};
|
|
884
|
-
(drawFunctions[finalConfig.position] || drawFunctions.repeat)(ctx, width, height, finalConfig);
|
|
885
|
-
ctx.restore();
|
|
886
|
-
return canvas;
|
|
887
|
-
}
|
|
888
|
-
async function captureElement(element, config = {}) {
|
|
889
|
-
const finalConfig = {
|
|
890
|
-
...DEFAULT_CAPTURE,
|
|
891
|
-
...config
|
|
892
|
-
};
|
|
893
|
-
return await html2canvas(element, {
|
|
894
|
-
logging: finalConfig.logging,
|
|
895
|
-
scale: finalConfig.scale,
|
|
896
|
-
allowTaint: finalConfig.allowTaint,
|
|
897
|
-
useCORS: finalConfig.useCORS,
|
|
898
|
-
backgroundColor: finalConfig.backgroundColor,
|
|
899
|
-
onclone: (clonedDoc) => {
|
|
900
|
-
const clonedElement = clonedDoc.body;
|
|
901
|
-
clonedElement.style.transform = "scale(1)";
|
|
902
|
-
}
|
|
903
|
-
});
|
|
904
|
-
}
|
|
905
|
-
function canvasToDataURL(canvas, format = "png", quality = .92) {
|
|
906
|
-
const mimeType = `image/${format}`;
|
|
907
|
-
return format === "png" ? canvas.toDataURL(mimeType) : canvas.toDataURL(mimeType, quality);
|
|
908
|
-
}
|
|
909
|
-
function downloadCanvas(canvas, filename = `screenshot-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.png`, format = "png") {
|
|
910
|
-
const dataURL = canvasToDataURL(canvas, format);
|
|
911
|
-
const link = document.createElement("a");
|
|
912
|
-
link.download = filename;
|
|
913
|
-
link.href = dataURL;
|
|
914
|
-
document.body.appendChild(link);
|
|
915
|
-
link.click();
|
|
916
|
-
document.body.removeChild(link);
|
|
917
|
-
}
|
|
918
|
-
let focusInterval = null;
|
|
919
|
-
function startFocusKeep() {
|
|
920
|
-
focusInterval = setInterval(() => {
|
|
921
|
-
window.dispatchEvent(new Event("focus"));
|
|
922
|
-
}, 500);
|
|
923
|
-
}
|
|
924
|
-
function stopFocusKeep() {
|
|
925
|
-
if (focusInterval) {
|
|
926
|
-
clearInterval(focusInterval);
|
|
927
|
-
focusInterval = null;
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
function printImage(imageDataURL, config = {}) {
|
|
931
|
-
const finalConfig = {
|
|
932
|
-
...DEFAULT_PRINT,
|
|
933
|
-
...config
|
|
934
|
-
};
|
|
935
|
-
return new Promise((resolve, reject) => {
|
|
936
|
-
try {
|
|
937
|
-
startFocusKeep();
|
|
938
|
-
finalConfig.onLoadingStart?.();
|
|
939
|
-
printJS({
|
|
940
|
-
printable: imageDataURL,
|
|
941
|
-
type: "image",
|
|
942
|
-
style: finalConfig.style,
|
|
943
|
-
showModal: finalConfig.showModal,
|
|
944
|
-
modalMessage: finalConfig.modalMessage,
|
|
945
|
-
onLoadingEnd: finalConfig.onLoadingEnd,
|
|
946
|
-
onPrintDialogClose: () => {
|
|
947
|
-
stopFocusKeep();
|
|
948
|
-
finalConfig.onPrintDialogClose?.();
|
|
949
|
-
resolve();
|
|
950
|
-
}
|
|
951
|
-
});
|
|
952
|
-
} catch (error) {
|
|
953
|
-
stopFocusKeep();
|
|
954
|
-
reject(error);
|
|
955
|
-
}
|
|
956
|
-
});
|
|
957
|
-
}
|
|
958
|
-
function calculateMergedCanvasSize(canvases, orientation, spacing) {
|
|
959
|
-
let totalWidth = 0;
|
|
960
|
-
let totalHeight = 0;
|
|
961
|
-
canvases.forEach((canvas) => {
|
|
962
|
-
const { width, height } = canvas;
|
|
963
|
-
if (orientation === "horizontal") {
|
|
964
|
-
totalWidth += width;
|
|
965
|
-
totalHeight = Math.max(totalHeight, height);
|
|
966
|
-
} else {
|
|
967
|
-
totalWidth = Math.max(totalWidth, width);
|
|
968
|
-
totalHeight += height;
|
|
969
|
-
}
|
|
970
|
-
});
|
|
971
|
-
const spacingTotal = (canvases.length - 1) * spacing;
|
|
972
|
-
if (orientation === "horizontal") totalWidth += spacingTotal;
|
|
973
|
-
else totalHeight += spacingTotal;
|
|
974
|
-
return {
|
|
975
|
-
totalWidth,
|
|
976
|
-
totalHeight
|
|
977
|
-
};
|
|
978
|
-
}
|
|
979
|
-
function createMergedCanvas(canvases, options) {
|
|
980
|
-
const { orientation, spacing, backgroundColor, totalWidth, totalHeight } = options;
|
|
981
|
-
const mergedCanvas = document.createElement("canvas");
|
|
982
|
-
mergedCanvas.width = totalWidth;
|
|
983
|
-
mergedCanvas.height = totalHeight;
|
|
984
|
-
const ctx = mergedCanvas.getContext("2d");
|
|
985
|
-
if (!ctx) throw new Error("无法创建画布上下文");
|
|
986
|
-
ctx.fillStyle = backgroundColor;
|
|
987
|
-
ctx.fillRect(0, 0, totalWidth, totalHeight);
|
|
988
|
-
let currentX = 0;
|
|
989
|
-
let currentY = 0;
|
|
990
|
-
canvases.forEach((canvas) => {
|
|
991
|
-
ctx.drawImage(canvas, currentX, currentY);
|
|
992
|
-
if (orientation === "horizontal") currentX += canvas.width + spacing;
|
|
993
|
-
else currentY += canvas.height + spacing;
|
|
994
|
-
});
|
|
995
|
-
return mergedCanvas;
|
|
996
|
-
}
|
|
997
|
-
function validateAndGetMergeOptions(elements, mergeOptions, message) {
|
|
998
|
-
if (!elements.length) {
|
|
999
|
-
message.warning("没有要打印的元素");
|
|
1000
|
-
return null;
|
|
1001
|
-
}
|
|
1002
|
-
return {
|
|
1003
|
-
orientation: mergeOptions.orientation || "vertical",
|
|
1004
|
-
spacing: mergeOptions.spacing || 20,
|
|
1005
|
-
backgroundColor: mergeOptions.backgroundColor || "#ffffff"
|
|
1006
|
-
};
|
|
1007
|
-
}
|
|
1008
|
-
async function captureAndMergeCanvas(elements, options, validatedOptions, updateProgress) {
|
|
1009
|
-
const { orientation, spacing, backgroundColor } = validatedOptions;
|
|
1010
|
-
updateProgress(10);
|
|
1011
|
-
const canvases = await Promise.all(elements.map((element) => captureElement(element, options.capture)));
|
|
1012
|
-
updateProgress(50);
|
|
1013
|
-
const { totalWidth, totalHeight } = calculateMergedCanvasSize(canvases, orientation, spacing);
|
|
1014
|
-
updateProgress(60);
|
|
1015
|
-
return createMergedCanvas(canvases, {
|
|
1016
|
-
orientation,
|
|
1017
|
-
spacing,
|
|
1018
|
-
backgroundColor,
|
|
1019
|
-
totalWidth,
|
|
1020
|
-
totalHeight
|
|
1021
|
-
});
|
|
1022
|
-
}
|
|
1023
|
-
async function addWatermarkAndPrint(mergedCanvas, options, elementsCount, updateProgress, message) {
|
|
1024
|
-
updateProgress(70);
|
|
1025
|
-
if (options.watermark) drawWatermark(mergedCanvas, options.watermark);
|
|
1026
|
-
updateProgress(90);
|
|
1027
|
-
await printImage(canvasToDataURL(mergedCanvas, options.capture?.format, options.capture?.quality), options.print);
|
|
1028
|
-
updateProgress(100);
|
|
1029
|
-
message.success(`合并打印完成,共合并 ${elementsCount} 个元素`);
|
|
1030
|
-
}
|
|
1031
|
-
function usePrintWatermark() {
|
|
1032
|
-
let message;
|
|
1033
|
-
try {
|
|
1034
|
-
message = useMessage();
|
|
1035
|
-
} catch {
|
|
1036
|
-
message = {
|
|
1037
|
-
success: (msg) => console.log("[PrintWatermark]", msg),
|
|
1038
|
-
error: (msg) => console.error("[PrintWatermark]", msg),
|
|
1039
|
-
warning: (msg) => console.warn("[PrintWatermark]", msg)
|
|
1040
|
-
};
|
|
1041
|
-
}
|
|
1042
|
-
const loading = ref(false);
|
|
1043
|
-
const progress = ref(0);
|
|
1044
|
-
const updateProgress = (value) => {
|
|
1045
|
-
progress.value = Math.max(0, Math.min(100, value));
|
|
1046
|
-
};
|
|
1047
|
-
const captureWithWatermark = async (element, options = {}) => {
|
|
1048
|
-
try {
|
|
1049
|
-
updateProgress(0);
|
|
1050
|
-
updateProgress(30);
|
|
1051
|
-
const canvas = await captureElement(element, options.capture);
|
|
1052
|
-
updateProgress(60);
|
|
1053
|
-
if (options.watermark) drawWatermark(canvas, options.watermark);
|
|
1054
|
-
updateProgress(90);
|
|
1055
|
-
const dataURL = canvasToDataURL(canvas, options.capture?.format || "png", options.capture?.quality || .92);
|
|
1056
|
-
updateProgress(100);
|
|
1057
|
-
return dataURL;
|
|
1058
|
-
} catch (error) {
|
|
1059
|
-
console.error("截图失败:", error);
|
|
1060
|
-
throw new Error(`截图失败: ${error instanceof Error ? error.message : "未知错误"}`);
|
|
1061
|
-
}
|
|
1062
|
-
};
|
|
1063
|
-
const printWithWatermark = async (element, options = {}) => {
|
|
1064
|
-
loading.value = true;
|
|
1065
|
-
updateProgress(0);
|
|
1066
|
-
try {
|
|
1067
|
-
await nextTick();
|
|
1068
|
-
const imageDataURL = await captureWithWatermark(element, options);
|
|
1069
|
-
updateProgress(95);
|
|
1070
|
-
await printImage(imageDataURL, options.print);
|
|
1071
|
-
updateProgress(100);
|
|
1072
|
-
message.success("打印完成");
|
|
1073
|
-
} catch (error) {
|
|
1074
|
-
console.error("打印失败:", error);
|
|
1075
|
-
message.error(`打印失败: ${error instanceof Error ? error.message : "未知错误"}`);
|
|
1076
|
-
throw error;
|
|
1077
|
-
} finally {
|
|
1078
|
-
loading.value = false;
|
|
1079
|
-
updateProgress(0);
|
|
1080
|
-
}
|
|
1081
|
-
};
|
|
1082
|
-
const downloadScreenshot = async (element, filename, options = {}) => {
|
|
1083
|
-
loading.value = true;
|
|
1084
|
-
try {
|
|
1085
|
-
await nextTick();
|
|
1086
|
-
const canvas = await captureElement(element, options.capture);
|
|
1087
|
-
if (options.watermark) drawWatermark(canvas, options.watermark);
|
|
1088
|
-
const format = options.capture?.format || "png";
|
|
1089
|
-
const defaultFilename = `screenshot-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 19).replace(/:/g, "-")}.${format}`;
|
|
1090
|
-
downloadCanvas(canvas, filename || defaultFilename, format);
|
|
1091
|
-
message.success("下载完成");
|
|
1092
|
-
} catch (error) {
|
|
1093
|
-
console.error("下载失败:", error);
|
|
1094
|
-
message.error("下载失败");
|
|
1095
|
-
throw error;
|
|
1096
|
-
} finally {
|
|
1097
|
-
loading.value = false;
|
|
1098
|
-
}
|
|
1099
|
-
};
|
|
1100
|
-
const quickPrint = async (element, watermarkText = "Robot Admin") => {
|
|
1101
|
-
return printWithWatermark(element, { watermark: {
|
|
1102
|
-
text: watermarkText,
|
|
1103
|
-
position: "repeat",
|
|
1104
|
-
textColor: "rgba(128, 128, 128, 0.3)"
|
|
1105
|
-
} });
|
|
1106
|
-
};
|
|
1107
|
-
const batchCapture = async (elements, options = {}) => {
|
|
1108
|
-
const total = elements.length;
|
|
1109
|
-
updateProgress(10);
|
|
1110
|
-
const capturePromises = elements.map(async (element, index) => {
|
|
1111
|
-
const url = await captureWithWatermark(element, options);
|
|
1112
|
-
updateProgress(10 + (index + 1) / total * 70);
|
|
1113
|
-
return url;
|
|
1114
|
-
});
|
|
1115
|
-
return Promise.all(capturePromises);
|
|
1116
|
-
};
|
|
1117
|
-
const serialPrint = async (imageUrls, printConfig = {}) => {
|
|
1118
|
-
await imageUrls.reduce(async (prevPromise, imageUrl, index) => {
|
|
1119
|
-
await prevPromise;
|
|
1120
|
-
await printImage(imageUrl, printConfig);
|
|
1121
|
-
if (index < imageUrls.length - 1) await new Promise((resolve) => {
|
|
1122
|
-
setTimeout(() => resolve(), 1e3);
|
|
1123
|
-
});
|
|
1124
|
-
}, Promise.resolve());
|
|
1125
|
-
};
|
|
1126
|
-
const batchPrint = async (elements, options = {}) => {
|
|
1127
|
-
if (!elements.length) {
|
|
1128
|
-
message.warning("没有要打印的元素");
|
|
1129
|
-
return;
|
|
1130
|
-
}
|
|
1131
|
-
loading.value = true;
|
|
1132
|
-
try {
|
|
1133
|
-
updateProgress(0);
|
|
1134
|
-
const imageUrls = await batchCapture(elements, options);
|
|
1135
|
-
updateProgress(80);
|
|
1136
|
-
await serialPrint(imageUrls, options.print);
|
|
1137
|
-
updateProgress(100);
|
|
1138
|
-
message.success(`批量打印完成,共 ${elements.length} 个元素`);
|
|
1139
|
-
} catch (error) {
|
|
1140
|
-
console.error("批量打印失败:", error);
|
|
1141
|
-
message.error("批量打印失败");
|
|
1142
|
-
throw error;
|
|
1143
|
-
} finally {
|
|
1144
|
-
loading.value = false;
|
|
1145
|
-
updateProgress(0);
|
|
1146
|
-
}
|
|
1147
|
-
};
|
|
1148
|
-
const mergePrint = async (elements, options = {}, mergeOptions = {}) => {
|
|
1149
|
-
const validatedOptions = validateAndGetMergeOptions(elements, mergeOptions, message);
|
|
1150
|
-
if (!validatedOptions) return;
|
|
1151
|
-
loading.value = true;
|
|
1152
|
-
try {
|
|
1153
|
-
await addWatermarkAndPrint(await captureAndMergeCanvas(elements, options, validatedOptions, updateProgress), options, elements.length, updateProgress, message);
|
|
1154
|
-
} catch (error) {
|
|
1155
|
-
console.error("合并打印失败:", error);
|
|
1156
|
-
message.error("合并打印失败");
|
|
1157
|
-
throw error;
|
|
1158
|
-
} finally {
|
|
1159
|
-
loading.value = false;
|
|
1160
|
-
updateProgress(0);
|
|
1161
|
-
}
|
|
1162
|
-
};
|
|
1163
|
-
const createPreset = (name, options) => {
|
|
1164
|
-
return {
|
|
1165
|
-
use: (element) => printWithWatermark(element, options),
|
|
1166
|
-
download: (element, filename) => downloadScreenshot(element, filename, options)
|
|
1167
|
-
};
|
|
1168
|
-
};
|
|
1169
|
-
return {
|
|
1170
|
-
loading,
|
|
1171
|
-
progress,
|
|
1172
|
-
captureWithWatermark,
|
|
1173
|
-
printWithWatermark,
|
|
1174
|
-
downloadScreenshot,
|
|
1175
|
-
quickPrint,
|
|
1176
|
-
batchCapture,
|
|
1177
|
-
batchPrint,
|
|
1178
|
-
mergePrint,
|
|
1179
|
-
createPreset,
|
|
1180
|
-
updateProgress,
|
|
1181
|
-
utils: {
|
|
1182
|
-
captureElement,
|
|
1183
|
-
drawWatermark,
|
|
1184
|
-
canvasToDataURL,
|
|
1185
|
-
downloadCanvas,
|
|
1186
|
-
printImage
|
|
1187
|
-
}
|
|
1188
|
-
};
|
|
1189
|
-
}
|
|
1190
|
-
const printPresets = {
|
|
1191
|
-
table: {
|
|
1192
|
-
watermark: {
|
|
1193
|
-
text: "Robot Admin - 数据表格",
|
|
1194
|
-
position: "repeat",
|
|
1195
|
-
textColor: "rgba(100, 100, 100, 0.25)",
|
|
1196
|
-
textSize: 14,
|
|
1197
|
-
xGap: 250,
|
|
1198
|
-
yGap: 120
|
|
1199
|
-
},
|
|
1200
|
-
capture: { scale: 1.2 },
|
|
1201
|
-
print: {
|
|
1202
|
-
orientation: "landscape",
|
|
1203
|
-
style: "@page { margin: 8mm; } body { font-family: Arial, sans-serif; }"
|
|
1204
|
-
}
|
|
1205
|
-
},
|
|
1206
|
-
form: {
|
|
1207
|
-
watermark: {
|
|
1208
|
-
text: "Robot Admin - 表单数据",
|
|
1209
|
-
position: "diagonal",
|
|
1210
|
-
textColor: "rgba(150, 150, 150, 0.2)",
|
|
1211
|
-
textSize: 16
|
|
1212
|
-
},
|
|
1213
|
-
print: { orientation: "portrait" }
|
|
1214
|
-
},
|
|
1215
|
-
report: {
|
|
1216
|
-
watermark: {
|
|
1217
|
-
text: "Robot Admin - 机密报告",
|
|
1218
|
-
position: "center",
|
|
1219
|
-
textColor: "rgba(200, 50, 50, 0.15)",
|
|
1220
|
-
textSize: 24
|
|
1221
|
-
},
|
|
1222
|
-
capture: {
|
|
1223
|
-
quality: .95,
|
|
1224
|
-
format: "png"
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
};
|
|
1228
|
-
|
|
1229
|
-
//#endregion
|
|
1230
|
-
//#region src/components/C_Table/composables/useDynamicRow.ts
|
|
1231
|
-
/** 生成唯一ID */
|
|
1232
|
-
function generateUniqueId() {
|
|
1233
|
-
return `row_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
1234
|
-
}
|
|
1235
|
-
/** 获取行键值 */
|
|
1236
|
-
function getRowKey(row, rowKey) {
|
|
1237
|
-
return typeof rowKey === "function" ? rowKey(row) : row[rowKey];
|
|
1238
|
-
}
|
|
1239
|
-
/** 创建新行数据 */
|
|
1240
|
-
function createNewRow(defaultRowData, rowKey) {
|
|
1241
|
-
const newRow = defaultRowData?.() || {};
|
|
1242
|
-
const keyField = typeof rowKey === "string" ? rowKey : "id";
|
|
1243
|
-
return {
|
|
1244
|
-
...newRow,
|
|
1245
|
-
[keyField]: generateUniqueId()
|
|
1246
|
-
};
|
|
1247
|
-
}
|
|
1248
|
-
/**
|
|
1249
|
-
* 表格动态行操作功能组合
|
|
1250
|
-
*/
|
|
1251
|
-
function useDynamicRows(data, options = {}) {
|
|
1252
|
-
const message = useMessage$1();
|
|
1253
|
-
const finalOptions = {
|
|
1254
|
-
rowKey: "id",
|
|
1255
|
-
enableRadioSelection: true,
|
|
1256
|
-
enableAdd: true,
|
|
1257
|
-
enableInsert: true,
|
|
1258
|
-
enableDelete: true,
|
|
1259
|
-
enableCopy: true,
|
|
1260
|
-
enableMove: true,
|
|
1261
|
-
enablePrint: true,
|
|
1262
|
-
confirmDelete: true,
|
|
1263
|
-
deleteConfirmText: "确定要删除选中的行吗?此操作不可撤销。",
|
|
1264
|
-
printPreset: "table",
|
|
1265
|
-
printTargetSelector: ".c-table-wrapper",
|
|
1266
|
-
defaultRowData: () => ({}),
|
|
1267
|
-
...options
|
|
1268
|
-
};
|
|
1269
|
-
const selectedRowKey = ref(null);
|
|
1270
|
-
const deleteConfirmVisible = ref(false);
|
|
1271
|
-
const selectedRowData = computed(() => {
|
|
1272
|
-
if (selectedRowKey.value === null) return null;
|
|
1273
|
-
return data.value.find((row) => getRowKey(row, finalOptions.rowKey) === selectedRowKey.value) || null;
|
|
1274
|
-
});
|
|
1275
|
-
const selectedRowIndex = computed(() => {
|
|
1276
|
-
if (!selectedRowData.value) return -1;
|
|
1277
|
-
return data.value.findIndex((row) => row === selectedRowData.value);
|
|
1278
|
-
});
|
|
1279
|
-
const canMoveUp = computed(() => selectedRowIndex.value > 0);
|
|
1280
|
-
const canMoveDown = computed(() => selectedRowIndex.value >= 0 && selectedRowIndex.value < data.value.length - 1);
|
|
1281
|
-
const { loading: printLoading, progress: printProgress, printWithWatermark, downloadScreenshot, quickPrint } = usePrintWatermark();
|
|
1282
|
-
/** 获取打印配置选项 */
|
|
1283
|
-
const getPrintOptions = () => {
|
|
1284
|
-
if (finalOptions.printOptions) return finalOptions.printOptions;
|
|
1285
|
-
const baseConfig = printPresets[finalOptions.printPreset || "table"];
|
|
1286
|
-
if (finalOptions.printWatermarkText && baseConfig.watermark) return {
|
|
1287
|
-
...baseConfig,
|
|
1288
|
-
watermark: {
|
|
1289
|
-
...baseConfig.watermark,
|
|
1290
|
-
text: finalOptions.printWatermarkText
|
|
1291
|
-
}
|
|
1292
|
-
};
|
|
1293
|
-
return baseConfig;
|
|
1294
|
-
};
|
|
1295
|
-
/** 更新表格数据 */
|
|
1296
|
-
const updateData = (newData) => {
|
|
1297
|
-
data.value = newData;
|
|
1298
|
-
finalOptions.onRowChange?.(newData);
|
|
1299
|
-
};
|
|
1300
|
-
/** 添加新行到表格末尾 */
|
|
1301
|
-
const addRow = () => {
|
|
1302
|
-
if (!finalOptions.enableAdd) return;
|
|
1303
|
-
const newRow = createNewRow(finalOptions.defaultRowData, finalOptions.rowKey);
|
|
1304
|
-
updateData([...data.value, newRow]);
|
|
1305
|
-
finalOptions.onRowAdd?.(newRow);
|
|
1306
|
-
message.success("添加行成功");
|
|
1307
|
-
};
|
|
1308
|
-
/** 在选中行后插入新行 */
|
|
1309
|
-
const insertRow = () => {
|
|
1310
|
-
if (!finalOptions.enableInsert || !selectedRowData.value) {
|
|
1311
|
-
message.warning("请先选择一行数据");
|
|
1312
|
-
return;
|
|
1313
|
-
}
|
|
1314
|
-
const newRow = createNewRow(finalOptions.defaultRowData, finalOptions.rowKey);
|
|
1315
|
-
const newData = [...data.value];
|
|
1316
|
-
newData.splice(selectedRowIndex.value + 1, 0, newRow);
|
|
1317
|
-
updateData(newData);
|
|
1318
|
-
finalOptions.onRowAdd?.(newRow);
|
|
1319
|
-
message.success("插入行成功");
|
|
1320
|
-
};
|
|
1321
|
-
/** 删除选中的行 */
|
|
1322
|
-
const deleteRow = () => {
|
|
1323
|
-
if (!finalOptions.enableDelete || !selectedRowData.value) {
|
|
1324
|
-
message.warning("请先选择要删除的行");
|
|
1325
|
-
return;
|
|
1326
|
-
}
|
|
1327
|
-
if (finalOptions.confirmDelete) deleteConfirmVisible.value = true;
|
|
1328
|
-
else confirmDeleteFn();
|
|
1329
|
-
};
|
|
1330
|
-
/** 确认删除操作 */
|
|
1331
|
-
const confirmDeleteFn = () => {
|
|
1332
|
-
if (!selectedRowData.value) return;
|
|
1333
|
-
const deletedRow = selectedRowData.value;
|
|
1334
|
-
const deletedIndex = selectedRowIndex.value;
|
|
1335
|
-
updateData(data.value.filter((_, index) => index !== deletedIndex));
|
|
1336
|
-
selectedRowKey.value = null;
|
|
1337
|
-
finalOptions.onSelectionChange?.(null, null);
|
|
1338
|
-
finalOptions.onRowDelete?.(deletedRow, deletedIndex);
|
|
1339
|
-
message.success("删除行成功");
|
|
1340
|
-
deleteConfirmVisible.value = false;
|
|
1341
|
-
};
|
|
1342
|
-
/** 复制选中的行 */
|
|
1343
|
-
const copyRow = () => {
|
|
1344
|
-
if (!finalOptions.enableCopy || !selectedRowData.value) {
|
|
1345
|
-
message.warning("请先选择要复制的行");
|
|
1346
|
-
return;
|
|
1347
|
-
}
|
|
1348
|
-
const originalRow = selectedRowData.value;
|
|
1349
|
-
const keyField = typeof finalOptions.rowKey === "string" ? finalOptions.rowKey : "id";
|
|
1350
|
-
const { [keyField]: _originalKey, ...rowData } = originalRow;
|
|
1351
|
-
const newRow = {
|
|
1352
|
-
...rowData,
|
|
1353
|
-
[keyField]: generateUniqueId()
|
|
1354
|
-
};
|
|
1355
|
-
updateData([...data.value, newRow]);
|
|
1356
|
-
finalOptions.onRowCopy?.(originalRow, newRow);
|
|
1357
|
-
message.success("复制行成功");
|
|
1358
|
-
};
|
|
1359
|
-
/** 将选中行向上移动 */
|
|
1360
|
-
const moveRowUp = () => {
|
|
1361
|
-
if (!finalOptions.enableMove || !canMoveUp.value) return;
|
|
1362
|
-
const currentIndex = selectedRowIndex.value;
|
|
1363
|
-
const newData = [...data.value];
|
|
1364
|
-
const movingRow = newData[currentIndex];
|
|
1365
|
-
[newData[currentIndex], newData[currentIndex - 1]] = [newData[currentIndex - 1], newData[currentIndex]];
|
|
1366
|
-
updateData(newData);
|
|
1367
|
-
finalOptions.onRowMove?.(movingRow, currentIndex, currentIndex - 1);
|
|
1368
|
-
message.success("行已上移");
|
|
1369
|
-
};
|
|
1370
|
-
/** 将选中行向下移动 */
|
|
1371
|
-
const moveRowDown = () => {
|
|
1372
|
-
if (!finalOptions.enableMove || !canMoveDown.value) return;
|
|
1373
|
-
const currentIndex = selectedRowIndex.value;
|
|
1374
|
-
const newData = [...data.value];
|
|
1375
|
-
const movingRow = newData[currentIndex];
|
|
1376
|
-
[newData[currentIndex], newData[currentIndex + 1]] = [newData[currentIndex + 1], newData[currentIndex]];
|
|
1377
|
-
updateData(newData);
|
|
1378
|
-
finalOptions.onRowMove?.(movingRow, currentIndex, currentIndex + 1);
|
|
1379
|
-
message.success("行已下移");
|
|
1380
|
-
};
|
|
1381
|
-
/** 选中指定行 */
|
|
1382
|
-
const selectRow = (key) => {
|
|
1383
|
-
const row = data.value.find((row) => getRowKey(row, finalOptions.rowKey) === key);
|
|
1384
|
-
if (row) {
|
|
1385
|
-
selectedRowKey.value = key;
|
|
1386
|
-
finalOptions.onSelectionChange?.(key, row);
|
|
1387
|
-
}
|
|
1388
|
-
};
|
|
1389
|
-
/** 清空选择状态 */
|
|
1390
|
-
const clearSelection = () => {
|
|
1391
|
-
selectedRowKey.value = null;
|
|
1392
|
-
finalOptions.onSelectionChange?.(null, null);
|
|
1393
|
-
};
|
|
1394
|
-
/** 处理打印操作 */
|
|
1395
|
-
const handlePrint = async (elementRef) => {
|
|
1396
|
-
if (!elementRef.value) {
|
|
1397
|
-
message.error("打印元素未找到");
|
|
1398
|
-
return;
|
|
1399
|
-
}
|
|
1400
|
-
const printOptions = getPrintOptions();
|
|
1401
|
-
await printWithWatermark(elementRef.value, printOptions);
|
|
1402
|
-
};
|
|
1403
|
-
/** 处理下载操作 */
|
|
1404
|
-
const handleDownload = async (elementRef, filename) => {
|
|
1405
|
-
if (!elementRef.value) {
|
|
1406
|
-
message.error("下载元素未找到");
|
|
1407
|
-
return;
|
|
1408
|
-
}
|
|
1409
|
-
const printOptions = getPrintOptions();
|
|
1410
|
-
await downloadScreenshot(elementRef.value, filename, printOptions);
|
|
1411
|
-
};
|
|
1412
|
-
/** 处理快速打印操作 */
|
|
1413
|
-
const handleQuickPrint = async (elementRef) => {
|
|
1414
|
-
if (!elementRef.value) {
|
|
1415
|
-
message.error("打印元素未找到");
|
|
1416
|
-
return;
|
|
1417
|
-
}
|
|
1418
|
-
const watermarkText = finalOptions.printWatermarkText || "Robot Admin";
|
|
1419
|
-
await quickPrint(elementRef.value, watermarkText);
|
|
1420
|
-
};
|
|
1421
|
-
/** 增强表格列配置,添加单选列 */
|
|
1422
|
-
const enhanceColumns = (columns) => {
|
|
1423
|
-
const enhancedColumns = [...columns];
|
|
1424
|
-
if (finalOptions.enableRadioSelection) enhancedColumns.unshift({
|
|
1425
|
-
key: "_radio_selection",
|
|
1426
|
-
title: "选择",
|
|
1427
|
-
width: 80,
|
|
1428
|
-
align: "center",
|
|
1429
|
-
editable: false,
|
|
1430
|
-
render: (rowData) => {
|
|
1431
|
-
const rowKeyVal = getRowKey(rowData, finalOptions.rowKey);
|
|
1432
|
-
return h("div", { class: "flex justify-center" }, [h("input", {
|
|
1433
|
-
type: "radio",
|
|
1434
|
-
name: "table-radio-selection",
|
|
1435
|
-
checked: selectedRowKey.value === rowKeyVal,
|
|
1436
|
-
class: "cursor-pointer accent-blue-500 scale-110",
|
|
1437
|
-
onChange: (e) => {
|
|
1438
|
-
if (e.target.checked) selectRow(rowKeyVal);
|
|
1439
|
-
}
|
|
1440
|
-
})]);
|
|
1441
|
-
}
|
|
1442
|
-
});
|
|
1443
|
-
return enhancedColumns;
|
|
1444
|
-
};
|
|
1445
|
-
/** 渲染工具栏 */
|
|
1446
|
-
const renderToolbar = () => {
|
|
1447
|
-
const buttons = [];
|
|
1448
|
-
if (finalOptions.enablePrint) buttons.push(h(NButton$1, {
|
|
1449
|
-
loading: printLoading.value,
|
|
1450
|
-
type: "primary",
|
|
1451
|
-
ghost: true,
|
|
1452
|
-
onClick: async () => {
|
|
1453
|
-
try {
|
|
1454
|
-
const tableElement = document.querySelector(finalOptions.printTargetSelector);
|
|
1455
|
-
if (tableElement) await handlePrint(ref(tableElement));
|
|
1456
|
-
else console.warn("未找到表格容器元素");
|
|
1457
|
-
} catch (error) {
|
|
1458
|
-
console.error("打印失败:", error);
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
|
-
}, {
|
|
1462
|
-
icon: () => h(C_Icon_default, {
|
|
1463
|
-
name: "mdi:printer",
|
|
1464
|
-
title: "打印"
|
|
1465
|
-
}),
|
|
1466
|
-
default: () => "打印"
|
|
1467
|
-
}));
|
|
1468
|
-
const rowButtons = [];
|
|
1469
|
-
if (finalOptions.enableAdd) rowButtons.push(h(NButton$1, {
|
|
1470
|
-
onClick: addRow,
|
|
1471
|
-
type: "primary"
|
|
1472
|
-
}, {
|
|
1473
|
-
icon: () => h(C_Icon_default, {
|
|
1474
|
-
name: "mdi:plus",
|
|
1475
|
-
title: "增行"
|
|
1476
|
-
}),
|
|
1477
|
-
default: () => "增行"
|
|
1478
|
-
}));
|
|
1479
|
-
if (finalOptions.enableInsert) rowButtons.push(h(NTooltip$1, { disabled: !!selectedRowData.value }, {
|
|
1480
|
-
trigger: () => h(NButton$1, {
|
|
1481
|
-
onClick: insertRow,
|
|
1482
|
-
disabled: !selectedRowData.value,
|
|
1483
|
-
type: "primary",
|
|
1484
|
-
ghost: true
|
|
1485
|
-
}, {
|
|
1486
|
-
icon: () => h(C_Icon_default, {
|
|
1487
|
-
name: "mdi:table-row-plus-after",
|
|
1488
|
-
title: "插行"
|
|
1489
|
-
}),
|
|
1490
|
-
default: () => "插行"
|
|
1491
|
-
}),
|
|
1492
|
-
default: () => "请先选择一行数据"
|
|
1493
|
-
}));
|
|
1494
|
-
if (finalOptions.enableDelete) rowButtons.push(h(NTooltip$1, { disabled: !!selectedRowData.value }, {
|
|
1495
|
-
trigger: () => h(NButton$1, {
|
|
1496
|
-
onClick: deleteRow,
|
|
1497
|
-
disabled: !selectedRowData.value,
|
|
1498
|
-
type: "error",
|
|
1499
|
-
ghost: true
|
|
1500
|
-
}, {
|
|
1501
|
-
icon: () => h(C_Icon_default, {
|
|
1502
|
-
name: "mdi:delete",
|
|
1503
|
-
title: "删除行"
|
|
1504
|
-
}),
|
|
1505
|
-
default: () => "删除行"
|
|
1506
|
-
}),
|
|
1507
|
-
default: () => "请先选择要删除的行"
|
|
1508
|
-
}));
|
|
1509
|
-
if (finalOptions.enableCopy) rowButtons.push(h(NTooltip$1, { disabled: !!selectedRowData.value }, {
|
|
1510
|
-
trigger: () => h(NButton$1, {
|
|
1511
|
-
onClick: copyRow,
|
|
1512
|
-
disabled: !selectedRowData.value,
|
|
1513
|
-
type: "info",
|
|
1514
|
-
ghost: true
|
|
1515
|
-
}, {
|
|
1516
|
-
icon: () => h(C_Icon_default, {
|
|
1517
|
-
name: "mdi:content-copy",
|
|
1518
|
-
title: "复制行"
|
|
1519
|
-
}),
|
|
1520
|
-
default: () => "复制行"
|
|
1521
|
-
}),
|
|
1522
|
-
default: () => "请先选择要复制的行"
|
|
1523
|
-
}));
|
|
1524
|
-
if (finalOptions.enableMove) rowButtons.push(h(NTooltip$1, { disabled: canMoveUp.value }, {
|
|
1525
|
-
trigger: () => h(NButton$1, {
|
|
1526
|
-
onClick: moveRowUp,
|
|
1527
|
-
disabled: !canMoveUp.value,
|
|
1528
|
-
type: "warning",
|
|
1529
|
-
ghost: true
|
|
1530
|
-
}, {
|
|
1531
|
-
icon: () => h(C_Icon_default, {
|
|
1532
|
-
name: "mdi:arrow-up",
|
|
1533
|
-
title: "上移"
|
|
1534
|
-
}),
|
|
1535
|
-
default: () => "上移"
|
|
1536
|
-
}),
|
|
1537
|
-
default: () => !selectedRowData.value ? "请先选择数据" : "已经是第一行"
|
|
1538
|
-
}), h(NTooltip$1, { disabled: canMoveDown.value }, {
|
|
1539
|
-
trigger: () => h(NButton$1, {
|
|
1540
|
-
onClick: moveRowDown,
|
|
1541
|
-
disabled: !canMoveDown.value,
|
|
1542
|
-
type: "warning",
|
|
1543
|
-
ghost: true
|
|
1544
|
-
}, {
|
|
1545
|
-
icon: () => h(C_Icon_default, {
|
|
1546
|
-
name: "mdi:arrow-down",
|
|
1547
|
-
title: "下移"
|
|
1548
|
-
}),
|
|
1549
|
-
default: () => "下移"
|
|
1550
|
-
}),
|
|
1551
|
-
default: () => !selectedRowData.value ? "请先选择数据" : "已经是最后一行"
|
|
1552
|
-
}));
|
|
1553
|
-
if (rowButtons.length > 0) buttons.push(h(NButtonGroup$1, {}, () => rowButtons));
|
|
1554
|
-
return h("div", { class: "dynamic-rows-toolbar mb-4 flex justify-end" }, [h(NSpace$1, {}, () => buttons)]);
|
|
1555
|
-
};
|
|
1556
|
-
/** 渲染删除确认模态框 */
|
|
1557
|
-
const renderConfirmModal = () => {
|
|
1558
|
-
return h(NModal$1, {
|
|
1559
|
-
show: deleteConfirmVisible.value,
|
|
1560
|
-
"onUpdate:show": (show) => {
|
|
1561
|
-
deleteConfirmVisible.value = show;
|
|
1562
|
-
},
|
|
1563
|
-
preset: "dialog",
|
|
1564
|
-
title: "确认删除",
|
|
1565
|
-
content: finalOptions.deleteConfirmText,
|
|
1566
|
-
positiveText: "确认删除",
|
|
1567
|
-
negativeText: "取消",
|
|
1568
|
-
onPositiveClick: confirmDeleteFn
|
|
1569
|
-
});
|
|
1570
|
-
};
|
|
1571
|
-
onBeforeUnmount(() => {
|
|
1572
|
-
selectedRowKey.value = null;
|
|
1573
|
-
deleteConfirmVisible.value = false;
|
|
1574
|
-
});
|
|
1575
|
-
return {
|
|
1576
|
-
selectedRowKey,
|
|
1577
|
-
selectedRowData,
|
|
1578
|
-
selectedRowIndex,
|
|
1579
|
-
canMoveUp,
|
|
1580
|
-
canMoveDown,
|
|
1581
|
-
deleteConfirmVisible,
|
|
1582
|
-
printLoading,
|
|
1583
|
-
printProgress,
|
|
1584
|
-
addRow,
|
|
1585
|
-
insertRow,
|
|
1586
|
-
deleteRow,
|
|
1587
|
-
confirmDelete: confirmDeleteFn,
|
|
1588
|
-
copyRow,
|
|
1589
|
-
moveRowUp,
|
|
1590
|
-
moveRowDown,
|
|
1591
|
-
selectRow,
|
|
1592
|
-
clearSelection,
|
|
1593
|
-
handlePrint,
|
|
1594
|
-
handleDownload,
|
|
1595
|
-
handleQuickPrint,
|
|
1596
|
-
enhanceColumns,
|
|
1597
|
-
renderToolbar,
|
|
1598
|
-
renderConfirmModal
|
|
1599
|
-
};
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
|
-
//#endregion
|
|
1603
|
-
//#region src/components/C_Table/composables/useTableManager.ts
|
|
1604
|
-
/**
|
|
1605
|
-
* 表格统一状态管理器
|
|
1606
|
-
*/
|
|
1607
|
-
function useTableManager(params) {
|
|
1608
|
-
const { config, data, rowKey, emit } = params;
|
|
1609
|
-
/** 创建事件处理器集合 */
|
|
1610
|
-
const createEventHandlers = () => ({
|
|
1611
|
-
onSave: async (rowData, rowIndex, columnKey) => {
|
|
1612
|
-
if (!rowData || rowIndex < 0 || rowIndex >= data().length) return;
|
|
1613
|
-
const newData = [...data()];
|
|
1614
|
-
newData[rowIndex] = {
|
|
1615
|
-
...newData[rowIndex],
|
|
1616
|
-
...rowData
|
|
1617
|
-
};
|
|
1618
|
-
emit("update:data", newData);
|
|
1619
|
-
await nextTick();
|
|
1620
|
-
emit("save", newData[rowIndex], rowIndex, columnKey);
|
|
1621
|
-
},
|
|
1622
|
-
onCancel: (rowData, rowIndex) => {
|
|
1623
|
-
emit("cancel", rowData, rowIndex);
|
|
1624
|
-
},
|
|
1625
|
-
onExpandChange: (keys, row, expanded) => {
|
|
1626
|
-
emit("expand-change", keys, row, expanded);
|
|
1627
|
-
},
|
|
1628
|
-
onSelectionChange: (checkedKeys, checkedRows, childSelections) => {
|
|
1629
|
-
emit("selection-change", checkedKeys, checkedRows, childSelections);
|
|
1630
|
-
},
|
|
1631
|
-
onChildSelectionChange: (parentKey, childKeys, childRows) => {
|
|
1632
|
-
emit("child-selection-change", parentKey, childKeys, childRows);
|
|
1633
|
-
},
|
|
1634
|
-
onRowChange: (data) => {
|
|
1635
|
-
emit("update:data", data);
|
|
1636
|
-
config.dynamicRows?.onRowChange?.(data);
|
|
1637
|
-
},
|
|
1638
|
-
onRowSelectionChange: (selectedKey, selectedRow) => {
|
|
1639
|
-
emit("row-selection-change", selectedKey, selectedRow);
|
|
1640
|
-
config.dynamicRows?.onSelectionChange?.(selectedKey, selectedRow);
|
|
1641
|
-
},
|
|
1642
|
-
onRowAdd: (newRow) => {
|
|
1643
|
-
emit("row-add", newRow);
|
|
1644
|
-
config.dynamicRows?.onRowAdd?.(newRow);
|
|
1645
|
-
},
|
|
1646
|
-
onRowDelete: (deletedRow, index) => {
|
|
1647
|
-
emit("row-delete", deletedRow, index);
|
|
1648
|
-
config.dynamicRows?.onRowDelete?.(deletedRow, index);
|
|
1649
|
-
},
|
|
1650
|
-
onRowCopy: (originalRow, newRow) => {
|
|
1651
|
-
emit("row-copy", originalRow, newRow);
|
|
1652
|
-
config.dynamicRows?.onRowCopy?.(originalRow, newRow);
|
|
1653
|
-
},
|
|
1654
|
-
onRowMove: (row, fromIndex, toIndex) => {
|
|
1655
|
-
emit("row-move", row, fromIndex, toIndex);
|
|
1656
|
-
config.dynamicRows?.onRowMove?.(row, fromIndex, toIndex);
|
|
1657
|
-
}
|
|
1658
|
-
});
|
|
1659
|
-
const eventHandlers = createEventHandlers();
|
|
1660
|
-
/** 初始化编辑功能状态 */
|
|
1661
|
-
const initEditStates = () => {
|
|
1662
|
-
return {
|
|
1663
|
-
rowEdit: useRowEdit({
|
|
1664
|
-
data,
|
|
1665
|
-
rowKey,
|
|
1666
|
-
onSave: eventHandlers.onSave,
|
|
1667
|
-
onCancel: eventHandlers.onCancel
|
|
1668
|
-
}),
|
|
1669
|
-
cellEdit: useCellEdit({
|
|
1670
|
-
data,
|
|
1671
|
-
rowKey,
|
|
1672
|
-
onSave: eventHandlers.onSave
|
|
1673
|
-
}),
|
|
1674
|
-
modalEdit: useModalEdit({
|
|
1675
|
-
data,
|
|
1676
|
-
rowKey,
|
|
1677
|
-
onSave: eventHandlers.onSave,
|
|
1678
|
-
onCancel: eventHandlers.onCancel
|
|
1679
|
-
})
|
|
1680
|
-
};
|
|
1681
|
-
};
|
|
1682
|
-
/** 初始化展开功能状态 */
|
|
1683
|
-
const initExpandState = () => {
|
|
1684
|
-
if (!(config.expandable || config.enableSelection || config.enableChildSelection)) return null;
|
|
1685
|
-
return useTableExpand({
|
|
1686
|
-
data: computed(() => data()),
|
|
1687
|
-
rowKey,
|
|
1688
|
-
childRowKey: (child) => child.id,
|
|
1689
|
-
defaultExpandedKeys: config.defaultExpandedKeys,
|
|
1690
|
-
onLoadData: config.onLoadExpandData,
|
|
1691
|
-
renderContent: config.renderExpandContent,
|
|
1692
|
-
rowExpandable: config.rowExpandable,
|
|
1693
|
-
enableSelection: config.enableSelection,
|
|
1694
|
-
defaultCheckedKeys: config.defaultCheckedKeys,
|
|
1695
|
-
rowCheckable: config.rowCheckable,
|
|
1696
|
-
maxSelection: config.maxSelection,
|
|
1697
|
-
enableChildSelection: config.enableChildSelection,
|
|
1698
|
-
childRowCheckable: config.childRowCheckable,
|
|
1699
|
-
enableParentChildLink: config.enableParentChildLink,
|
|
1700
|
-
parentChildLinkMode: config.parentChildLinkMode,
|
|
1701
|
-
onExpandChange: eventHandlers.onExpandChange,
|
|
1702
|
-
onSelectionChange: eventHandlers.onSelectionChange,
|
|
1703
|
-
onChildSelectionChange: eventHandlers.onChildSelectionChange
|
|
1704
|
-
});
|
|
1705
|
-
};
|
|
1706
|
-
/** 初始化动态行功能状态 */
|
|
1707
|
-
const initDynamicRowsState = () => {
|
|
1708
|
-
if (!config.dynamicRows) return null;
|
|
1709
|
-
const dynamicOptions = {
|
|
1710
|
-
...config.dynamicRows,
|
|
1711
|
-
onRowChange: eventHandlers.onRowChange,
|
|
1712
|
-
onSelectionChange: eventHandlers.onRowSelectionChange,
|
|
1713
|
-
onRowAdd: eventHandlers.onRowAdd,
|
|
1714
|
-
onRowDelete: eventHandlers.onRowDelete,
|
|
1715
|
-
onRowCopy: eventHandlers.onRowCopy,
|
|
1716
|
-
onRowMove: eventHandlers.onRowMove
|
|
1717
|
-
};
|
|
1718
|
-
return useDynamicRows(computed(() => data()), dynamicOptions);
|
|
1719
|
-
};
|
|
1720
|
-
const editStates = initEditStates();
|
|
1721
|
-
const expandState = initExpandState();
|
|
1722
|
-
const dynamicRowsState = initDynamicRowsState();
|
|
1723
|
-
/** 创建统一的状态管理器 */
|
|
1724
|
-
const createStateManager = () => {
|
|
1725
|
-
return {
|
|
1726
|
-
edit: {
|
|
1727
|
-
start(rowKey, columnKey) {
|
|
1728
|
-
const mode = config.editMode;
|
|
1729
|
-
if (mode === "modal") editStates.modalEdit.startEdit(rowKey);
|
|
1730
|
-
else if (mode === "cell" && columnKey) editStates.cellEdit.startEditCell(rowKey, columnKey);
|
|
1731
|
-
else if (mode === "row" || mode === "both") editStates.rowEdit.startEditRow(rowKey);
|
|
1732
|
-
},
|
|
1733
|
-
cancel() {
|
|
1734
|
-
if (editStates.modalEdit.isModalVisible.value) editStates.modalEdit.cancelEdit();
|
|
1735
|
-
else if (editStates.cellEdit.editingCell.value.rowKey) editStates.cellEdit.cancelEditCell();
|
|
1736
|
-
else if (editStates.rowEdit.editingRowKey.value) editStates.rowEdit.cancelEditRow();
|
|
1737
|
-
},
|
|
1738
|
-
async save() {
|
|
1739
|
-
if (editStates.modalEdit.isModalVisible.value) await editStates.modalEdit.saveEdit();
|
|
1740
|
-
else if (editStates.cellEdit.editingCell.value.rowKey) await editStates.cellEdit.saveEditCell();
|
|
1741
|
-
else if (editStates.rowEdit.editingRowKey.value) await editStates.rowEdit.saveEditRow();
|
|
1742
|
-
},
|
|
1743
|
-
isEditing(rowKey, columnKey) {
|
|
1744
|
-
if (config.editMode === "modal") return editStates.modalEdit.isEditingRow(rowKey);
|
|
1745
|
-
if (columnKey) return editStates.cellEdit.isEditingCell(rowKey, columnKey);
|
|
1746
|
-
return editStates.rowEdit.isEditingRow(rowKey);
|
|
1747
|
-
},
|
|
1748
|
-
getEditingData() {
|
|
1749
|
-
if (editStates.modalEdit.isModalVisible.value) return editStates.modalEdit.editingData;
|
|
1750
|
-
if (editStates.rowEdit.editingRowKey.value) return editStates.rowEdit.getEditingRowData(editStates.rowEdit.editingRowKey.value);
|
|
1751
|
-
return null;
|
|
1752
|
-
}
|
|
1753
|
-
},
|
|
1754
|
-
expand: {
|
|
1755
|
-
async row(rowKey) {
|
|
1756
|
-
if (expandState) {
|
|
1757
|
-
const currentKeys = [...expandState.expandedKeys.value];
|
|
1758
|
-
if (!currentKeys.includes(rowKey)) {
|
|
1759
|
-
currentKeys.push(rowKey);
|
|
1760
|
-
expandState.handleExpandChange(currentKeys);
|
|
1761
|
-
}
|
|
1762
|
-
}
|
|
1763
|
-
},
|
|
1764
|
-
collapse(rowKey) {
|
|
1765
|
-
if (expandState) {
|
|
1766
|
-
const currentKeys = expandState.expandedKeys.value.filter((key) => key !== rowKey);
|
|
1767
|
-
expandState.handleExpandChange(currentKeys);
|
|
1768
|
-
}
|
|
1769
|
-
},
|
|
1770
|
-
async toggle(rowKey) {
|
|
1771
|
-
if (expandState?.expandedKeys.value.includes(rowKey)) this.collapse(rowKey);
|
|
1772
|
-
else await this.row(rowKey);
|
|
1773
|
-
},
|
|
1774
|
-
async all() {
|
|
1775
|
-
await expandState?.expandAll();
|
|
1776
|
-
},
|
|
1777
|
-
collapseAll() {
|
|
1778
|
-
expandState?.collapseAll();
|
|
1779
|
-
},
|
|
1780
|
-
isExpanded(rowKey) {
|
|
1781
|
-
return expandState?.expandedKeys.value.includes(rowKey) ?? false;
|
|
1782
|
-
}
|
|
1783
|
-
},
|
|
1784
|
-
selection: {
|
|
1785
|
-
select(rowKey) {
|
|
1786
|
-
if (expandState?.checkedKeys.value && !expandState.checkedKeys.value.includes(rowKey)) {
|
|
1787
|
-
const newKeys = [...expandState.checkedKeys.value, rowKey];
|
|
1788
|
-
expandState.handleSelectionChange(newKeys);
|
|
1789
|
-
}
|
|
1790
|
-
},
|
|
1791
|
-
unselect(rowKey) {
|
|
1792
|
-
if (expandState?.checkedKeys.value) {
|
|
1793
|
-
const newKeys = expandState.checkedKeys.value.filter((key) => key !== rowKey);
|
|
1794
|
-
expandState.handleSelectionChange(newKeys);
|
|
1795
|
-
}
|
|
1796
|
-
},
|
|
1797
|
-
all() {
|
|
1798
|
-
expandState?.selectAll();
|
|
1799
|
-
},
|
|
1800
|
-
clear() {
|
|
1801
|
-
expandState?.clearSelection();
|
|
1802
|
-
},
|
|
1803
|
-
isSelected(rowKey) {
|
|
1804
|
-
return expandState?.checkedKeys.value.includes(rowKey) ?? false;
|
|
1805
|
-
},
|
|
1806
|
-
getSelected() {
|
|
1807
|
-
if (!expandState?.checkedKeys.value) return [];
|
|
1808
|
-
return data().filter((row) => expandState.checkedKeys.value.includes(rowKey(row)));
|
|
1809
|
-
}
|
|
1810
|
-
},
|
|
1811
|
-
childSelection: {
|
|
1812
|
-
select(parentKey, childKey) {
|
|
1813
|
-
if (expandState?.childSelections.value) {
|
|
1814
|
-
const current = expandState.childSelections.value.get(parentKey) || [];
|
|
1815
|
-
if (!current.includes(childKey)) {
|
|
1816
|
-
const newSelection = [...current, childKey];
|
|
1817
|
-
expandState.childSelections.value.set(parentKey, newSelection);
|
|
1818
|
-
emit("child-selection-change", parentKey, newSelection, []);
|
|
1819
|
-
}
|
|
1820
|
-
}
|
|
1821
|
-
},
|
|
1822
|
-
unselect(parentKey, childKey) {
|
|
1823
|
-
if (expandState?.childSelections.value) {
|
|
1824
|
-
const newSelection = (expandState.childSelections.value.get(parentKey) || []).filter((k) => k !== childKey);
|
|
1825
|
-
expandState.childSelections.value.set(parentKey, newSelection);
|
|
1826
|
-
emit("child-selection-change", parentKey, newSelection, []);
|
|
1827
|
-
}
|
|
1828
|
-
},
|
|
1829
|
-
selectAll(parentKey) {
|
|
1830
|
-
if (expandState?.childSelections.value && expandState.expandDataMap?.value) {
|
|
1831
|
-
const expandData = expandState.expandDataMap.value.get(parentKey) || [];
|
|
1832
|
-
const allChildKeys = expandData.map((child) => child.id);
|
|
1833
|
-
expandState.childSelections.value.set(parentKey, allChildKeys);
|
|
1834
|
-
emit("child-selection-change", parentKey, allChildKeys, expandData);
|
|
1835
|
-
}
|
|
1836
|
-
},
|
|
1837
|
-
clear(parentKey) {
|
|
1838
|
-
if (expandState?.childSelections.value) {
|
|
1839
|
-
expandState.childSelections.value.set(parentKey, []);
|
|
1840
|
-
emit("child-selection-change", parentKey, [], []);
|
|
1841
|
-
}
|
|
1842
|
-
},
|
|
1843
|
-
getSelected(parentKey) {
|
|
1844
|
-
if (!expandState?.childSelections.value || !expandState.expandDataMap?.value) return [];
|
|
1845
|
-
const selectedKeys = expandState.childSelections.value.get(parentKey) || [];
|
|
1846
|
-
return (expandState.expandDataMap.value.get(parentKey) || []).filter((child) => selectedKeys.includes(child.id));
|
|
1847
|
-
}
|
|
1848
|
-
},
|
|
1849
|
-
dynamicRows: {
|
|
1850
|
-
add() {
|
|
1851
|
-
dynamicRowsState?.addRow();
|
|
1852
|
-
},
|
|
1853
|
-
insert() {
|
|
1854
|
-
dynamicRowsState?.insertRow();
|
|
1855
|
-
},
|
|
1856
|
-
delete() {
|
|
1857
|
-
dynamicRowsState?.deleteRow();
|
|
1858
|
-
},
|
|
1859
|
-
copy() {
|
|
1860
|
-
dynamicRowsState?.copyRow();
|
|
1861
|
-
},
|
|
1862
|
-
moveUp() {
|
|
1863
|
-
dynamicRowsState?.moveRowUp();
|
|
1864
|
-
},
|
|
1865
|
-
moveDown() {
|
|
1866
|
-
dynamicRowsState?.moveRowDown();
|
|
1867
|
-
},
|
|
1868
|
-
clearSelection() {
|
|
1869
|
-
dynamicRowsState?.clearSelection();
|
|
1870
|
-
},
|
|
1871
|
-
getSelected() {
|
|
1872
|
-
return dynamicRowsState?.selectedRowData.value || null;
|
|
1873
|
-
},
|
|
1874
|
-
async print(elementRef) {
|
|
1875
|
-
if (dynamicRowsState && elementRef) await dynamicRowsState.handlePrint(ref(elementRef));
|
|
1876
|
-
},
|
|
1877
|
-
async download(elementRef, filename) {
|
|
1878
|
-
if (dynamicRowsState && elementRef) await dynamicRowsState.handleDownload(ref(elementRef), filename);
|
|
1879
|
-
}
|
|
1880
|
-
},
|
|
1881
|
-
clearAllSelections() {
|
|
1882
|
-
expandState?.clearAllSelections();
|
|
1883
|
-
}
|
|
1884
|
-
};
|
|
1885
|
-
};
|
|
1886
|
-
return {
|
|
1887
|
-
editStates,
|
|
1888
|
-
expandState,
|
|
1889
|
-
dynamicRowsState,
|
|
1890
|
-
stateManager: createStateManager(),
|
|
1891
|
-
expandedKeys: computed(() => expandState?.expandedKeys.value ?? []),
|
|
1892
|
-
checkedKeys: computed(() => expandState?.checkedKeys.value ?? []),
|
|
1893
|
-
eventHandlers
|
|
1894
|
-
};
|
|
1895
|
-
}
|
|
1896
|
-
|
|
1897
|
-
//#endregion
|
|
1898
|
-
//#region src/components/C_Table/composables/usePagination.ts
|
|
1899
|
-
const DEFAULT_PAGINATION_CONFIG = {
|
|
1900
|
-
enabled: true,
|
|
1901
|
-
page: 1,
|
|
1902
|
-
pageSize: 10,
|
|
1903
|
-
showSizePicker: true,
|
|
1904
|
-
showQuickJumper: true,
|
|
1905
|
-
pageSizes: [
|
|
1906
|
-
10,
|
|
1907
|
-
20,
|
|
1908
|
-
50,
|
|
1909
|
-
100
|
|
1910
|
-
],
|
|
1911
|
-
simple: false,
|
|
1912
|
-
size: "medium"
|
|
1913
|
-
};
|
|
1914
|
-
function usePagination(options) {
|
|
1915
|
-
const { data, config, emit } = options;
|
|
1916
|
-
const currentPage = ref(1);
|
|
1917
|
-
const currentPageSize = ref(10);
|
|
1918
|
-
const dataSource = computed(() => {
|
|
1919
|
-
if (typeof data === "function") return data() || [];
|
|
1920
|
-
return unref(data) || [];
|
|
1921
|
-
});
|
|
1922
|
-
/** 分页后的数据 */
|
|
1923
|
-
const paginatedData = computed(() => {
|
|
1924
|
-
if (!config.value?.enabled) return dataSource.value;
|
|
1925
|
-
const start = (currentPage.value - 1) * currentPageSize.value;
|
|
1926
|
-
const end = start + currentPageSize.value;
|
|
1927
|
-
return dataSource.value.slice(start, end);
|
|
1928
|
-
});
|
|
1929
|
-
/** 分页配置对象 */
|
|
1930
|
-
const paginationConfig = computed(() => {
|
|
1931
|
-
if (!config.value?.enabled) return null;
|
|
1932
|
-
return {
|
|
1933
|
-
page: currentPage.value,
|
|
1934
|
-
pageSize: currentPageSize.value,
|
|
1935
|
-
itemCount: dataSource.value.length,
|
|
1936
|
-
showSizePicker: config.value.showSizePicker ?? DEFAULT_PAGINATION_CONFIG.showSizePicker,
|
|
1937
|
-
showQuickJumper: config.value.showQuickJumper ?? DEFAULT_PAGINATION_CONFIG.showQuickJumper,
|
|
1938
|
-
pageSizes: config.value.pageSizes ?? DEFAULT_PAGINATION_CONFIG.pageSizes,
|
|
1939
|
-
simple: config.value.simple ?? DEFAULT_PAGINATION_CONFIG.simple,
|
|
1940
|
-
size: config.value.size ?? DEFAULT_PAGINATION_CONFIG.size,
|
|
1941
|
-
prefix: (info) => `共 ${info.itemCount} 条`,
|
|
1942
|
-
suffix: (info) => `第 ${info.startIndex + 1}-${info.endIndex} 条`,
|
|
1943
|
-
"onUpdate:page": handlePageChange,
|
|
1944
|
-
"onUpdate:pageSize": handlePageSizeChange
|
|
1945
|
-
};
|
|
1946
|
-
});
|
|
1947
|
-
/** 页码变化处理 */
|
|
1948
|
-
const handlePageChange = (page) => {
|
|
1949
|
-
currentPage.value = page;
|
|
1950
|
-
emit?.("pagination-change", page, currentPageSize.value);
|
|
1951
|
-
};
|
|
1952
|
-
/** 页面大小变化处理 */
|
|
1953
|
-
const handlePageSizeChange = (pageSize) => {
|
|
1954
|
-
currentPageSize.value = pageSize;
|
|
1955
|
-
currentPage.value = 1;
|
|
1956
|
-
emit?.("pagination-change", 1, pageSize);
|
|
1957
|
-
};
|
|
1958
|
-
/** 重置到第一页 */
|
|
1959
|
-
const resetToFirstPage = () => {
|
|
1960
|
-
if (currentPage.value !== 1) handlePageChange(1);
|
|
1961
|
-
};
|
|
1962
|
-
/** 获取总页数 */
|
|
1963
|
-
const getTotalPages = () => {
|
|
1964
|
-
if (!config.value?.enabled || currentPageSize.value === 0) return 1;
|
|
1965
|
-
return Math.ceil(dataSource.value.length / currentPageSize.value);
|
|
1966
|
-
};
|
|
1967
|
-
/** 初始化分页配置 */
|
|
1968
|
-
watchEffect(() => {
|
|
1969
|
-
if (config.value?.enabled) {
|
|
1970
|
-
currentPage.value = config.value.page ?? DEFAULT_PAGINATION_CONFIG.page;
|
|
1971
|
-
currentPageSize.value = config.value.pageSize ?? DEFAULT_PAGINATION_CONFIG.pageSize;
|
|
1972
|
-
}
|
|
1973
|
-
});
|
|
1974
|
-
/** 监听数据变化,确保分页状态正确 */
|
|
1975
|
-
watch(() => dataSource.value.length, (newLength) => {
|
|
1976
|
-
if (config.value?.enabled && currentPage.value > 1) {
|
|
1977
|
-
const maxPage = Math.ceil(newLength / currentPageSize.value);
|
|
1978
|
-
if (currentPage.value > maxPage) currentPage.value = Math.max(1, maxPage);
|
|
1979
|
-
}
|
|
1980
|
-
});
|
|
1981
|
-
return {
|
|
1982
|
-
currentPage,
|
|
1983
|
-
currentPageSize,
|
|
1984
|
-
paginatedData,
|
|
1985
|
-
paginationConfig,
|
|
1986
|
-
handlePageChange,
|
|
1987
|
-
handlePageSizeChange,
|
|
1988
|
-
resetToFirstPage,
|
|
1989
|
-
getTotalPages
|
|
1990
|
-
};
|
|
1991
|
-
}
|
|
1992
|
-
|
|
1993
|
-
//#endregion
|
|
1994
|
-
//#region src/components/C_Table/composables/useTableActions.ts
|
|
1995
|
-
/**
|
|
1996
|
-
* 表格操作Hook
|
|
1997
|
-
*/
|
|
1998
|
-
function useTableActions(options) {
|
|
1999
|
-
const { actions, config, tableManager, rowKey, emit, onViewDetail } = options;
|
|
2000
|
-
const message = useMessage();
|
|
2001
|
-
const dialog = useDialog();
|
|
2002
|
-
const isActionEnabled = (key) => actions.value?.[key] !== false;
|
|
2003
|
-
const isValidApiFunction = (action) => {
|
|
2004
|
-
return action !== false && typeof action === "function";
|
|
2005
|
-
};
|
|
2006
|
-
const extractApiResponseData = (response) => {
|
|
2007
|
-
if (response && typeof response === "object" && "data" in response) return response.data;
|
|
2008
|
-
return response;
|
|
2009
|
-
};
|
|
2010
|
-
const createButton = (icon, title, type = "primary", onClick) => h(NButton, {
|
|
2011
|
-
size: "small",
|
|
2012
|
-
type,
|
|
2013
|
-
quaternary: true,
|
|
2014
|
-
onClick
|
|
2015
|
-
}, () => [h(C_Icon_default, {
|
|
2016
|
-
name: icon,
|
|
2017
|
-
size: 14,
|
|
2018
|
-
title
|
|
2019
|
-
})]);
|
|
2020
|
-
const handleEdit = (row, _index) => {
|
|
2021
|
-
const rowKeyValue = rowKey(row);
|
|
2022
|
-
const editAction = actions.value?.edit;
|
|
2023
|
-
if (config.value.editMode === "modal") tableManager.editStates.modalEdit.startEdit(rowKeyValue, { ...row }, editAction);
|
|
2024
|
-
else tableManager.editStates.rowEdit.startEditRow(rowKeyValue, editAction);
|
|
2025
|
-
};
|
|
2026
|
-
const executeDelete = async (deleteAction, row, index) => {
|
|
2027
|
-
try {
|
|
2028
|
-
await deleteAction(row, index);
|
|
2029
|
-
message.success("删除成功");
|
|
2030
|
-
emit("row-delete", row, index);
|
|
2031
|
-
} catch (error) {
|
|
2032
|
-
console.error("删除失败:", error);
|
|
2033
|
-
message.error("删除失败");
|
|
2034
|
-
throw error;
|
|
2035
|
-
}
|
|
2036
|
-
};
|
|
2037
|
-
const handleDelete = (row, index) => {
|
|
2038
|
-
const deleteAction = actions.value?.delete;
|
|
2039
|
-
if (!isValidApiFunction(deleteAction)) return;
|
|
2040
|
-
dialog.warning({
|
|
2041
|
-
title: "确认删除",
|
|
2042
|
-
content: "确定要删除这条记录吗?",
|
|
2043
|
-
positiveText: "确定",
|
|
2044
|
-
negativeText: "取消",
|
|
2045
|
-
onPositiveClick: () => executeDelete(deleteAction, row, index)
|
|
2046
|
-
});
|
|
2047
|
-
};
|
|
2048
|
-
const handleDetail = async (row, index) => {
|
|
2049
|
-
const detailAction = actions.value?.detail;
|
|
2050
|
-
if (!isValidApiFunction(detailAction)) {
|
|
2051
|
-
onViewDetail?.(row);
|
|
2052
|
-
return;
|
|
2053
|
-
}
|
|
2054
|
-
try {
|
|
2055
|
-
const detailData = extractApiResponseData(await detailAction(row, index));
|
|
2056
|
-
onViewDetail?.(detailData || row);
|
|
2057
|
-
} catch (error) {
|
|
2058
|
-
console.error("获取详情失败:", error);
|
|
2059
|
-
message.error("获取详情失败");
|
|
2060
|
-
onViewDetail?.(row);
|
|
2061
|
-
}
|
|
2062
|
-
};
|
|
2063
|
-
const renderRowEditButtons = (rowKeyValue) => {
|
|
2064
|
-
if (tableManager.editStates.rowEdit.isEditingRow(rowKeyValue)) return [createButton("mdi:check", "保存", "primary", () => tableManager.editStates.rowEdit.saveEditRow()), createButton("mdi:close", "取消", "default", () => tableManager.editStates.rowEdit.cancelEditRow())];
|
|
2065
|
-
return [createButton("mdi:pencil", "编辑", "warning", () => tableManager.editStates.rowEdit.startEditRow(rowKeyValue))];
|
|
2066
|
-
};
|
|
2067
|
-
const renderBasicActions = (row, index) => {
|
|
2068
|
-
const buttons = [];
|
|
2069
|
-
if (isActionEnabled("detail")) buttons.push(createButton("mdi:eye", "详情", "info", () => handleDetail(row, index)));
|
|
2070
|
-
if (config.value.editMode === "modal" && (isActionEnabled("edit") || config.value.editable)) buttons.push(createButton("mdi:pencil", "编辑", "warning", () => handleEdit(row, index)));
|
|
2071
|
-
if (isActionEnabled("delete")) buttons.push(createButton("mdi:delete", "删除", "error", () => handleDelete(row, index)));
|
|
2072
|
-
return buttons;
|
|
2073
|
-
};
|
|
2074
|
-
const renderCustomDropdown = (row, index) => {
|
|
2075
|
-
const customActions = actions.value?.custom;
|
|
2076
|
-
if (!customActions?.length) return null;
|
|
2077
|
-
const visibleActions = customActions.filter((action) => action.show ? action.show(row, index) : true);
|
|
2078
|
-
if (!visibleActions.length) return null;
|
|
2079
|
-
return h(NDropdown, {
|
|
2080
|
-
options: visibleActions.map((action) => {
|
|
2081
|
-
const label = typeof action.label === "function" ? action.label(row, index) : action.label;
|
|
2082
|
-
const icon = typeof action.icon === "function" ? action.icon(row, index) : action.icon;
|
|
2083
|
-
return {
|
|
2084
|
-
label,
|
|
2085
|
-
key: action.key,
|
|
2086
|
-
icon: () => h(C_Icon_default, {
|
|
2087
|
-
name: icon,
|
|
2088
|
-
size: 14
|
|
2089
|
-
}),
|
|
2090
|
-
disabled: action.disabled?.(row, index) || false
|
|
2091
|
-
};
|
|
2092
|
-
}),
|
|
2093
|
-
onSelect: (key) => {
|
|
2094
|
-
const action = visibleActions.find((a) => a.key === key);
|
|
2095
|
-
if (action) try {
|
|
2096
|
-
action.onClick(row, index);
|
|
2097
|
-
} catch (error) {
|
|
2098
|
-
console.error(`操作"${action.label}"执行失败:`, error);
|
|
2099
|
-
message.error(`${action.label}失败`);
|
|
2100
|
-
}
|
|
2101
|
-
}
|
|
2102
|
-
}, () => createButton("mdi:dots-horizontal", "更多操作", "default", () => {}));
|
|
2103
|
-
};
|
|
2104
|
-
const renderActions = (row, index) => {
|
|
2105
|
-
if (actions.value?.render) return actions.value.render(row, index);
|
|
2106
|
-
const rowKeyValue = rowKey(row);
|
|
2107
|
-
const isRowEditMode = ["row", "both"].includes(config.value.editMode);
|
|
2108
|
-
if (isRowEditMode && tableManager.editStates.rowEdit.isEditingRow(rowKeyValue)) return h(NSpace, {
|
|
2109
|
-
size: 2,
|
|
2110
|
-
wrap: false
|
|
2111
|
-
}, () => renderRowEditButtons(rowKeyValue));
|
|
2112
|
-
const allButtons = [...isRowEditMode ? renderRowEditButtons(rowKeyValue) : [], ...renderBasicActions(row, index)];
|
|
2113
|
-
const dropdown = renderCustomDropdown(row, index);
|
|
2114
|
-
if (dropdown) allButtons.push(dropdown);
|
|
2115
|
-
return h(NSpace, {
|
|
2116
|
-
size: 2,
|
|
2117
|
-
wrap: false
|
|
2118
|
-
}, () => allButtons);
|
|
2119
|
-
};
|
|
2120
|
-
return {
|
|
2121
|
-
renderActions,
|
|
2122
|
-
isActionEnabled
|
|
2123
|
-
};
|
|
2124
|
-
}
|
|
2125
|
-
|
|
2126
|
-
//#endregion
|
|
2127
|
-
//#region src/components/C_Table/data.ts
|
|
2128
|
-
const EDIT_COMPONENTS = {
|
|
2129
|
-
number: NInputNumber,
|
|
2130
|
-
switch: NSwitch,
|
|
2131
|
-
input: NInput,
|
|
2132
|
-
email: NInput,
|
|
2133
|
-
mobile: NInput,
|
|
2134
|
-
date: (props) => h(NDatePicker, {
|
|
2135
|
-
...props,
|
|
2136
|
-
type: "date",
|
|
2137
|
-
format: "yyyy-MM-dd"
|
|
2138
|
-
}),
|
|
2139
|
-
select: (props) => h(NSelect, {
|
|
2140
|
-
...props,
|
|
2141
|
-
options: props.options || []
|
|
2142
|
-
}),
|
|
2143
|
-
textarea: (props) => h(NInput, {
|
|
2144
|
-
...props,
|
|
2145
|
-
type: "textarea",
|
|
2146
|
-
rows: 3
|
|
2147
|
-
})
|
|
2148
|
-
};
|
|
2149
|
-
const EDIT_TO_FORM_TYPE = {
|
|
2150
|
-
number: "inputNumber",
|
|
2151
|
-
date: "datePicker",
|
|
2152
|
-
textarea: "textarea",
|
|
2153
|
-
select: "select",
|
|
2154
|
-
switch: "switch"
|
|
2155
|
-
};
|
|
2156
|
-
/**
|
|
2157
|
-
* 根据可编辑列配置自动生成表单选项(用于编辑弹窗)
|
|
2158
|
-
*/
|
|
2159
|
-
const generateFormOptions = (columns) => columns.map((column) => {
|
|
2160
|
-
const rules = column.required ? [{
|
|
2161
|
-
required: true,
|
|
2162
|
-
message: `请输入${column.title}`,
|
|
2163
|
-
trigger: ["blur", "input"],
|
|
2164
|
-
validator: async (_, value) => {
|
|
2165
|
-
if (!value && value !== 0 && value !== false) throw new Error(`请输入${column.title}`);
|
|
2166
|
-
}
|
|
2167
|
-
}] : [];
|
|
2168
|
-
return {
|
|
2169
|
-
prop: column.key,
|
|
2170
|
-
label: column.title || column.key,
|
|
2171
|
-
type: EDIT_TO_FORM_TYPE[column.editType || "input"] || "input",
|
|
2172
|
-
placeholder: `请输入${column.title}`,
|
|
2173
|
-
rules,
|
|
2174
|
-
attrs: column.editProps || {},
|
|
2175
|
-
layout: { span: 1 },
|
|
2176
|
-
show: true
|
|
2177
|
-
};
|
|
2178
|
-
});
|
|
2179
|
-
|
|
2180
|
-
//#endregion
|
|
2181
|
-
//#region src/components/C_Table/composables/useTableColumns.ts
|
|
2182
|
-
/**
|
|
2183
|
-
* 渲染编辑组件(行编辑/单元格编辑通用)
|
|
2184
|
-
*/
|
|
2185
|
-
function renderEditComponent(column, value, onUpdate) {
|
|
2186
|
-
if (column.editRender) return column.editRender(value, {}, 0);
|
|
2187
|
-
const col = column;
|
|
2188
|
-
const componentProps = {
|
|
2189
|
-
value,
|
|
2190
|
-
"onUpdate:value": onUpdate,
|
|
2191
|
-
placeholder: `请输入${col.title ?? ""}`,
|
|
2192
|
-
style: { width: "100%" },
|
|
2193
|
-
...column.editProps
|
|
2194
|
-
};
|
|
2195
|
-
return h(EDIT_COMPONENTS[column.editType || "input"] || EDIT_COMPONENTS.input, componentProps);
|
|
2196
|
-
}
|
|
2197
|
-
/**
|
|
2198
|
-
* 渲染只读单元格
|
|
2199
|
-
*/
|
|
2200
|
-
function renderDisplayCell(column, rowData, rowIndex, value) {
|
|
2201
|
-
return column.render ? column.render(rowData, rowIndex) ?? String(value ?? "") : String(value ?? "");
|
|
2202
|
-
}
|
|
2203
|
-
/**
|
|
2204
|
-
* 渲染编辑中的单元格(带保存/取消按钮)
|
|
2205
|
-
*/
|
|
2206
|
-
function renderEditingCell(column, value, onUpdate, onSave, onCancel) {
|
|
2207
|
-
const actionBtn = (name, title, onClick) => h("button", {
|
|
2208
|
-
class: `cell-action-btn cell-action-${name}`,
|
|
2209
|
-
title,
|
|
2210
|
-
type: "button",
|
|
2211
|
-
onClick: (e) => {
|
|
2212
|
-
e.stopPropagation();
|
|
2213
|
-
e.preventDefault();
|
|
2214
|
-
onClick(e);
|
|
2215
|
-
}
|
|
2216
|
-
}, [h(C_Icon_default, {
|
|
2217
|
-
name: `mdi:${name === "save" ? "check" : "close"}`,
|
|
2218
|
-
title: name === "save" ? "保存" : "取消",
|
|
2219
|
-
size: 12
|
|
2220
|
-
})]);
|
|
2221
|
-
return h("div", { class: "cell-editing-container" }, [h("div", { class: "cell-editing-input" }, [renderEditComponent(column, value, onUpdate)]), h("div", { class: "cell-editing-actions" }, [actionBtn("save", "保存", onSave), actionBtn("cancel", "取消", onCancel)])]);
|
|
2222
|
-
}
|
|
2223
|
-
/**
|
|
2224
|
-
* 渲染可编辑单元格(显示值 + 编辑图标)
|
|
2225
|
-
*/
|
|
2226
|
-
function renderEditableCell(column, rowData, rowIndex, value, onStartEdit) {
|
|
2227
|
-
return h("div", { class: "cell-edit-wrapper" }, [h("span", { class: "cell-value" }, column.render ? column.render(rowData, rowIndex) ?? String(value ?? "") : String(value ?? "")), h(C_Icon_default, {
|
|
2228
|
-
name: "mdi:square-edit-outline",
|
|
2229
|
-
title: "编辑",
|
|
2230
|
-
class: "cell-edit-icon",
|
|
2231
|
-
size: 14,
|
|
2232
|
-
clickable: true,
|
|
2233
|
-
onClick: (e) => {
|
|
2234
|
-
e.stopPropagation();
|
|
2235
|
-
onStartEdit();
|
|
2236
|
-
}
|
|
2237
|
-
})]);
|
|
2238
|
-
}
|
|
2239
|
-
/**
|
|
2240
|
-
* 表格列处理引擎
|
|
2241
|
-
*/
|
|
2242
|
-
function useTableColumns(options) {
|
|
2243
|
-
const { rawColumns, config, columnWidth, rowKey, tableManager, actionsRenderer, editModeChecker } = options;
|
|
2244
|
-
const reactiveColumns = ref([]);
|
|
2245
|
-
const showSettingsPanel = ref(false);
|
|
2246
|
-
/** 同步外部列配置到响应式状态 */
|
|
2247
|
-
const syncColumns = (newColumns) => {
|
|
2248
|
-
const existingActions = reactiveColumns.value.find((col) => col.key === "_actions");
|
|
2249
|
-
reactiveColumns.value = [...newColumns, existingActions || {
|
|
2250
|
-
key: "_actions",
|
|
2251
|
-
title: "操作",
|
|
2252
|
-
width: 180,
|
|
2253
|
-
editable: false,
|
|
2254
|
-
visible: true,
|
|
2255
|
-
fixed: "right"
|
|
2256
|
-
}];
|
|
2257
|
-
};
|
|
2258
|
-
watch(rawColumns, (cols) => {
|
|
2259
|
-
if (cols?.length) syncColumns(cols);
|
|
2260
|
-
}, {
|
|
2261
|
-
deep: true,
|
|
2262
|
-
immediate: true
|
|
2263
|
-
});
|
|
2264
|
-
/** 单元格编辑模式渲染 */
|
|
2265
|
-
const renderCellEdit = (column, rowData, rowIndex, rowKeyVal) => {
|
|
2266
|
-
const colKey = column.key ?? "";
|
|
2267
|
-
const value = rowData[colKey];
|
|
2268
|
-
const { isEditingCell, getEditingCellValue, updateEditingCellValue, saveEditCell, cancelEditCell, startEditCell } = tableManager.editStates.cellEdit;
|
|
2269
|
-
if (isEditingCell(rowKeyVal, colKey)) return renderEditingCell(column, getEditingCellValue(rowKeyVal, colKey) ?? value, (val) => updateEditingCellValue(rowKeyVal, colKey, val), () => saveEditCell(), () => cancelEditCell());
|
|
2270
|
-
return renderEditableCell(column, rowData, rowIndex, value, () => startEditCell(rowKeyVal, colKey));
|
|
2271
|
-
};
|
|
2272
|
-
/** 统一单元格渲染入口 */
|
|
2273
|
-
const renderCell = (column, rowData, rowIndex) => {
|
|
2274
|
-
const colKey = column.key ?? "";
|
|
2275
|
-
const value = rowData[colKey];
|
|
2276
|
-
const key = rowKey(rowData);
|
|
2277
|
-
const checker = editModeChecker.value;
|
|
2278
|
-
if (checker.isNonEditable(column)) return renderDisplayCell(column, rowData, rowIndex, value);
|
|
2279
|
-
if (checker.isRowEditMode() && tableManager.editStates.rowEdit.isEditingRow(key)) return renderEditComponent(column, tableManager.editStates.rowEdit.getEditingRowData(key)?.[colKey] ?? value, (val) => tableManager.editStates.rowEdit.updateEditingRowData(key, colKey, val));
|
|
2280
|
-
if (checker.isCellEditMode()) return renderCellEdit(column, rowData, rowIndex, key);
|
|
2281
|
-
return renderDisplayCell(column, rowData, rowIndex, value);
|
|
2282
|
-
};
|
|
2283
|
-
const getColWidth = (col) => {
|
|
2284
|
-
const w = col.width || columnWidth || 180;
|
|
2285
|
-
return typeof w === "number" ? w : 180;
|
|
2286
|
-
};
|
|
2287
|
-
/** 序号列 */
|
|
2288
|
-
const mapIndexColumn = (column) => {
|
|
2289
|
-
const col = column;
|
|
2290
|
-
return {
|
|
2291
|
-
key: "_index",
|
|
2292
|
-
title: col.title || "序号",
|
|
2293
|
-
width: typeof (col.width || 50) === "number" ? col.width || 50 : 50,
|
|
2294
|
-
titleAlign: "center",
|
|
2295
|
-
align: "center",
|
|
2296
|
-
render: (_, index) => index + 1,
|
|
2297
|
-
fixed: column.fixed
|
|
2298
|
-
};
|
|
2299
|
-
};
|
|
2300
|
-
/** 普通数据列 */
|
|
2301
|
-
const mapRegularColumn = (column) => {
|
|
2302
|
-
const col = column;
|
|
2303
|
-
const base = {
|
|
2304
|
-
...col,
|
|
2305
|
-
width: getColWidth(column),
|
|
2306
|
-
titleAlign: col.titleAlign || "center",
|
|
2307
|
-
align: col.align || "center",
|
|
2308
|
-
render: column.render || ((rowData, rowIndex) => renderCell(column, rowData, rowIndex))
|
|
2309
|
-
};
|
|
2310
|
-
if (column.fixed) base.fixed = column.fixed;
|
|
2311
|
-
if (column.resizable && typeof base.width === "number") {
|
|
2312
|
-
base.resizable = true;
|
|
2313
|
-
base.minWidth = column.minWidth || 80;
|
|
2314
|
-
base.maxWidth = column.maxWidth || 500;
|
|
2315
|
-
}
|
|
2316
|
-
return base;
|
|
2317
|
-
};
|
|
2318
|
-
const computedColumns = computed(() => {
|
|
2319
|
-
let cols = reactiveColumns.value.filter((c) => {
|
|
2320
|
-
const col = c;
|
|
2321
|
-
return col.visible !== false && col.key !== "_actions";
|
|
2322
|
-
}).map((c) => {
|
|
2323
|
-
return c.type === "index" ? mapIndexColumn(c) : mapRegularColumn(c);
|
|
2324
|
-
});
|
|
2325
|
-
if (tableManager.dynamicRowsState) cols = tableManager.dynamicRowsState.enhanceColumns(cols);
|
|
2326
|
-
if (tableManager.expandState && (config.value.expandable || config.value.enableSelection)) cols = tableManager.expandState.getTableColumns(cols);
|
|
2327
|
-
const actionsMeta = reactiveColumns.value.find((c) => c.key === "_actions");
|
|
2328
|
-
cols.push({
|
|
2329
|
-
key: "_actions",
|
|
2330
|
-
title: "操作",
|
|
2331
|
-
align: "center",
|
|
2332
|
-
titleAlign: "center",
|
|
2333
|
-
render: actionsRenderer,
|
|
2334
|
-
fixed: actionsMeta?.fixed
|
|
2335
|
-
});
|
|
2336
|
-
return cols;
|
|
2337
|
-
});
|
|
2338
|
-
const computedScrollX = computed(() => {
|
|
2339
|
-
if (options.scrollX !== void 0) return options.scrollX;
|
|
2340
|
-
if (!reactiveColumns.value.some((c) => {
|
|
2341
|
-
const col = c;
|
|
2342
|
-
return col.fixed && col.visible !== false;
|
|
2343
|
-
})) return void 0;
|
|
2344
|
-
return reactiveColumns.value.filter((c) => c.visible !== false).reduce((sum, c) => sum + getColWidth(c), 0) + 200;
|
|
2345
|
-
});
|
|
2346
|
-
const handleColumnChange = (columns) => {
|
|
2347
|
-
reactiveColumns.value = columns.map((col) => {
|
|
2348
|
-
const c = col;
|
|
2349
|
-
return {
|
|
2350
|
-
...col,
|
|
2351
|
-
visible: c.visible !== false,
|
|
2352
|
-
fixed: col.fixed,
|
|
2353
|
-
width: c.width || columnWidth,
|
|
2354
|
-
align: c.align || "center",
|
|
2355
|
-
titleAlign: c.titleAlign || "center"
|
|
2356
|
-
};
|
|
2357
|
-
});
|
|
2358
|
-
};
|
|
2359
|
-
return {
|
|
2360
|
-
reactiveColumns,
|
|
2361
|
-
showSettingsPanel,
|
|
2362
|
-
computedColumns,
|
|
2363
|
-
computedScrollX,
|
|
2364
|
-
handleColumnChange
|
|
2365
|
-
};
|
|
2366
|
-
}
|
|
2367
|
-
|
|
2368
|
-
//#endregion
|
|
2369
|
-
//#region src/components/C_Table/components/ColumnSettings/data.ts
|
|
2370
|
-
/** 固定列下拉选项 */
|
|
2371
|
-
const getFixedOptions = (column) => [
|
|
2372
|
-
{
|
|
2373
|
-
label: column.fixed ? "✓ 取消固定" : "不固定",
|
|
2374
|
-
key: "none",
|
|
2375
|
-
disabled: !column.fixed
|
|
2376
|
-
},
|
|
2377
|
-
{
|
|
2378
|
-
label: column.fixed === "left" ? "✓ 固定左侧" : "固定左侧",
|
|
2379
|
-
key: "left",
|
|
2380
|
-
disabled: false
|
|
2381
|
-
},
|
|
2382
|
-
{
|
|
2383
|
-
label: column.fixed === "right" ? "✓ 固定右侧" : "固定右侧",
|
|
2384
|
-
key: "right",
|
|
2385
|
-
disabled: false
|
|
2386
|
-
}
|
|
2387
|
-
];
|
|
2388
|
-
/** 不可操作的特殊列 key */
|
|
2389
|
-
const SPECIAL_COLUMN_KEYS = ["_actions"];
|
|
2390
|
-
/** 不可拖拽的列 type */
|
|
2391
|
-
const SPECIAL_COLUMN_TYPES = ["selection", "expand"];
|
|
2392
|
-
/** 判断是否为特殊列(不可调宽、不可拖拽) */
|
|
2393
|
-
const isSpecialColumn = (column) => SPECIAL_COLUMN_KEYS.includes(column.key) || SPECIAL_COLUMN_TYPES.includes(column.type);
|
|
2394
|
-
|
|
2395
|
-
//#endregion
|
|
2396
|
-
//#region src/components/C_Table/components/ColumnSettings/index.vue?vue&type=script&setup=true&lang.ts
|
|
2397
|
-
const _hoisted_1$1 = { class: "column-management-tab" };
|
|
2398
|
-
const _hoisted_2$1 = { class: "search-row" };
|
|
2399
|
-
const _hoisted_3$1 = { class: "resizable-control" };
|
|
2400
|
-
const _hoisted_4$1 = { class: "top-actions-bar" };
|
|
2401
|
-
const _hoisted_5 = { class: "stats-info" };
|
|
2402
|
-
const _hoisted_6 = { class: "quick-actions" };
|
|
2403
|
-
const _hoisted_7 = [
|
|
2404
|
-
"draggable",
|
|
2405
|
-
"onDragstart",
|
|
2406
|
-
"onDragover",
|
|
2407
|
-
"onDrop"
|
|
2408
|
-
];
|
|
2409
|
-
const _hoisted_8 = { class: "column-info" };
|
|
2410
|
-
const _hoisted_9 = { class: "column-controls" };
|
|
2411
|
-
const _hoisted_10 = { class: "column-details" };
|
|
2412
|
-
const _hoisted_11 = { class: "column-actions" };
|
|
2413
|
-
const _hoisted_12 = { class: "drag-controls" };
|
|
2414
|
-
var index_vue_vue_type_script_setup_true_lang_default$1 = /* @__PURE__ */ defineComponent({
|
|
2415
|
-
name: "ColumnSettings",
|
|
2416
|
-
__name: "index",
|
|
2417
|
-
props: { columns: {} },
|
|
2418
|
-
emits: ["change"],
|
|
2419
|
-
setup(__props, { emit: __emit }) {
|
|
2420
|
-
const props = __props;
|
|
2421
|
-
const emit = __emit;
|
|
2422
|
-
const localColumns = ref([...props.columns]);
|
|
2423
|
-
const searchText = ref("");
|
|
2424
|
-
const listRef = ref();
|
|
2425
|
-
const draggedIndex = ref(null);
|
|
2426
|
-
const dragOverIndex = ref(null);
|
|
2427
|
-
const enableResizable = ref(false);
|
|
2428
|
-
onMounted(() => {
|
|
2429
|
-
enableResizable.value = localColumns.value.some((col) => col.resizable === true);
|
|
2430
|
-
});
|
|
2431
|
-
const filteredColumns = computed(() => {
|
|
2432
|
-
if (!searchText.value) return localColumns.value;
|
|
2433
|
-
const search = searchText.value.toLowerCase();
|
|
2434
|
-
return localColumns.value.filter((col) => col.title?.toLowerCase().includes(search) || col.key.toLowerCase().includes(search));
|
|
2435
|
-
});
|
|
2436
|
-
const visibleCount = computed(() => localColumns.value.filter((col) => col.visible !== false).length);
|
|
2437
|
-
const totalCount = computed(() => localColumns.value.length);
|
|
2438
|
-
const setAllColumnsVisible = (visible) => {
|
|
2439
|
-
localColumns.value.forEach((col) => {
|
|
2440
|
-
if (col.key !== "_actions") col.visible = visible;
|
|
2441
|
-
});
|
|
2442
|
-
applyChanges();
|
|
2443
|
-
};
|
|
2444
|
-
const selectAll = () => setAllColumnsVisible(true);
|
|
2445
|
-
const selectNone = () => setAllColumnsVisible(false);
|
|
2446
|
-
const findOriginalIndex = (filteredIndex) => {
|
|
2447
|
-
const column = filteredColumns.value[filteredIndex];
|
|
2448
|
-
return localColumns.value.findIndex((col) => col.key === column.key);
|
|
2449
|
-
};
|
|
2450
|
-
const updateColumnProperty = (index, updater) => {
|
|
2451
|
-
const originalIndex = findOriginalIndex(index);
|
|
2452
|
-
if (originalIndex !== -1) {
|
|
2453
|
-
updater(localColumns.value[originalIndex]);
|
|
2454
|
-
applyChanges();
|
|
2455
|
-
}
|
|
2456
|
-
};
|
|
2457
|
-
const toggleColumnVisibility = (index, visible) => {
|
|
2458
|
-
updateColumnProperty(index, (col) => {
|
|
2459
|
-
col.visible = visible;
|
|
2460
|
-
});
|
|
2461
|
-
};
|
|
2462
|
-
const handleFixedSelect = (index, value) => {
|
|
2463
|
-
updateColumnProperty(index, (col) => {
|
|
2464
|
-
col.fixed = value === "none" ? void 0 : value;
|
|
2465
|
-
});
|
|
2466
|
-
};
|
|
2467
|
-
const applyChanges = () => emit("change", [...localColumns.value]);
|
|
2468
|
-
const resetColumns = () => {
|
|
2469
|
-
localColumns.value = [...props.columns];
|
|
2470
|
-
applyChanges();
|
|
2471
|
-
};
|
|
2472
|
-
const handleResizableChange = (value) => {
|
|
2473
|
-
localColumns.value.forEach((col) => {
|
|
2474
|
-
if (!isSpecialColumn(col)) {
|
|
2475
|
-
col.resizable = value;
|
|
2476
|
-
if (value) {
|
|
2477
|
-
col.minWidth = col.minWidth || 80;
|
|
2478
|
-
col.maxWidth = col.maxWidth || 500;
|
|
2479
|
-
}
|
|
2480
|
-
}
|
|
2481
|
-
});
|
|
2482
|
-
applyChanges();
|
|
2483
|
-
};
|
|
2484
|
-
const moveColumn = (fromIndex, toIndex) => {
|
|
2485
|
-
const originalFromIndex = findOriginalIndex(fromIndex);
|
|
2486
|
-
const originalToIndex = findOriginalIndex(toIndex);
|
|
2487
|
-
if (originalFromIndex !== -1 && originalToIndex !== -1) {
|
|
2488
|
-
const [movedColumn] = localColumns.value.splice(originalFromIndex, 1);
|
|
2489
|
-
localColumns.value.splice(originalToIndex, 0, movedColumn);
|
|
2490
|
-
applyChanges();
|
|
2491
|
-
}
|
|
2492
|
-
};
|
|
2493
|
-
const handleDragStart = (index, event) => {
|
|
2494
|
-
if (filteredColumns.value[index].key === "_actions") {
|
|
2495
|
-
event.preventDefault();
|
|
2496
|
-
return;
|
|
2497
|
-
}
|
|
2498
|
-
draggedIndex.value = index;
|
|
2499
|
-
if (event.dataTransfer) event.dataTransfer.effectAllowed = "move";
|
|
2500
|
-
};
|
|
2501
|
-
const handleDragOver = (index, event) => {
|
|
2502
|
-
event.preventDefault();
|
|
2503
|
-
if (draggedIndex.value === null || filteredColumns.value[index].key === "_actions") return;
|
|
2504
|
-
dragOverIndex.value = index;
|
|
2505
|
-
if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
|
|
2506
|
-
};
|
|
2507
|
-
const handleDrop = (toIndex) => {
|
|
2508
|
-
if (draggedIndex.value === null || filteredColumns.value[toIndex].key === "_actions") return;
|
|
2509
|
-
moveColumn(draggedIndex.value, toIndex);
|
|
2510
|
-
draggedIndex.value = null;
|
|
2511
|
-
dragOverIndex.value = null;
|
|
2512
|
-
};
|
|
2513
|
-
const handleDragEnd = () => {
|
|
2514
|
-
draggedIndex.value = null;
|
|
2515
|
-
dragOverIndex.value = null;
|
|
2516
|
-
};
|
|
2517
|
-
return (_ctx, _cache) => {
|
|
2518
|
-
return openBlock(), createElementBlock("div", _hoisted_1$1, [
|
|
2519
|
-
createCommentVNode(" 搜索框和列宽调整开关 "),
|
|
2520
|
-
createElementVNode("div", _hoisted_2$1, [createVNode(unref(NInput$1), {
|
|
2521
|
-
value: searchText.value,
|
|
2522
|
-
"onUpdate:value": _cache[0] || (_cache[0] = ($event) => searchText.value = $event),
|
|
2523
|
-
placeholder: "搜索列名...",
|
|
2524
|
-
clearable: "",
|
|
2525
|
-
class: "search-input"
|
|
2526
|
-
}, {
|
|
2527
|
-
prefix: withCtx(() => [createVNode(C_Icon_default, { name: "mdi:magnify" })]),
|
|
2528
|
-
_: 1
|
|
2529
|
-
}, 8, ["value"]), createElementVNode("div", _hoisted_3$1, [
|
|
2530
|
-
createVNode(C_Icon_default, {
|
|
2531
|
-
name: "mdi:arrow-split-vertical",
|
|
2532
|
-
size: "14",
|
|
2533
|
-
title: enableResizable.value ? "开启后可拖拽列边界调整宽度" : "允许调整列宽"
|
|
2534
|
-
}, null, 8, ["title"]),
|
|
2535
|
-
createVNode(unref(NText$1), { style: {
|
|
2536
|
-
fontSize: "12px",
|
|
2537
|
-
marginLeft: "4px"
|
|
2538
|
-
} }, {
|
|
2539
|
-
default: withCtx(() => _cache[2] || (_cache[2] = [createTextVNode(" 列宽调整 ", -1)])),
|
|
2540
|
-
_: 1,
|
|
2541
|
-
__: [2]
|
|
2542
|
-
}),
|
|
2543
|
-
createVNode(unref(NSwitch$1), {
|
|
2544
|
-
value: enableResizable.value,
|
|
2545
|
-
"onUpdate:value": [_cache[1] || (_cache[1] = ($event) => enableResizable.value = $event), handleResizableChange],
|
|
2546
|
-
size: "small",
|
|
2547
|
-
style: { "margin-left": "6px" }
|
|
2548
|
-
}, null, 8, ["value"])
|
|
2549
|
-
])]),
|
|
2550
|
-
createCommentVNode(" 顶部操作栏:统计信息和快捷操作按钮 "),
|
|
2551
|
-
createElementVNode("div", _hoisted_4$1, [createElementVNode("div", _hoisted_5, [createVNode(unref(NText$1), {
|
|
2552
|
-
depth: "3",
|
|
2553
|
-
style: { fontSize: "13px" }
|
|
2554
|
-
}, {
|
|
2555
|
-
default: withCtx(() => [createTextVNode(" 已选 " + toDisplayString(visibleCount.value) + " / 总共 " + toDisplayString(totalCount.value) + " 列 ", 1)]),
|
|
2556
|
-
_: 1
|
|
2557
|
-
})]), createElementVNode("div", _hoisted_6, [createVNode(unref(NSpace$1), { size: 6 }, {
|
|
2558
|
-
default: withCtx(() => [
|
|
2559
|
-
createVNode(unref(NButton$1), {
|
|
2560
|
-
size: "tiny",
|
|
2561
|
-
onClick: selectAll
|
|
2562
|
-
}, {
|
|
2563
|
-
default: withCtx(() => _cache[3] || (_cache[3] = [createTextVNode(" 全选 ", -1)])),
|
|
2564
|
-
_: 1,
|
|
2565
|
-
__: [3]
|
|
2566
|
-
}),
|
|
2567
|
-
createVNode(unref(NButton$1), {
|
|
2568
|
-
size: "tiny",
|
|
2569
|
-
onClick: selectNone
|
|
2570
|
-
}, {
|
|
2571
|
-
default: withCtx(() => _cache[4] || (_cache[4] = [createTextVNode(" 全不选 ", -1)])),
|
|
2572
|
-
_: 1,
|
|
2573
|
-
__: [4]
|
|
2574
|
-
}),
|
|
2575
|
-
createVNode(unref(NButton$1), {
|
|
2576
|
-
size: "tiny",
|
|
2577
|
-
onClick: resetColumns
|
|
2578
|
-
}, {
|
|
2579
|
-
default: withCtx(() => _cache[5] || (_cache[5] = [createTextVNode(" 重置 ", -1)])),
|
|
2580
|
-
_: 1,
|
|
2581
|
-
__: [5]
|
|
2582
|
-
})
|
|
2583
|
-
]),
|
|
2584
|
-
_: 1
|
|
2585
|
-
})])]),
|
|
2586
|
-
createCommentVNode(" 列列表 "),
|
|
2587
|
-
createElementVNode("div", {
|
|
2588
|
-
ref_key: "listRef",
|
|
2589
|
-
ref: listRef,
|
|
2590
|
-
class: "column-list"
|
|
2591
|
-
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(filteredColumns.value, (column, index) => {
|
|
2592
|
-
return openBlock(), createElementBlock("div", {
|
|
2593
|
-
key: column.key,
|
|
2594
|
-
class: normalizeClass(["column-item", {
|
|
2595
|
-
disabled: column.key === "_actions",
|
|
2596
|
-
"fixed-left": column.fixed === "left",
|
|
2597
|
-
"fixed-right": column.fixed === "right"
|
|
2598
|
-
}]),
|
|
2599
|
-
draggable: column.key !== "_actions",
|
|
2600
|
-
onDragstart: ($event) => handleDragStart(index, $event),
|
|
2601
|
-
onDragover: ($event) => handleDragOver(index, $event),
|
|
2602
|
-
onDragend: handleDragEnd,
|
|
2603
|
-
onDrop: ($event) => handleDrop(index)
|
|
2604
|
-
}, [createElementVNode("div", _hoisted_8, [createElementVNode("div", _hoisted_9, [createVNode(C_Icon_default, {
|
|
2605
|
-
name: "mdi:drag",
|
|
2606
|
-
size: "16",
|
|
2607
|
-
class: normalizeClass(["drag-handle", { disabled: column.key === "_actions" }])
|
|
2608
|
-
}, null, 8, ["class"]), createVNode(unref(NCheckbox$1), {
|
|
2609
|
-
checked: column.visible !== false,
|
|
2610
|
-
disabled: column.key === "_actions",
|
|
2611
|
-
"onUpdate:checked": (value) => toggleColumnVisibility(index, value)
|
|
2612
|
-
}, null, 8, [
|
|
2613
|
-
"checked",
|
|
2614
|
-
"disabled",
|
|
2615
|
-
"onUpdate:checked"
|
|
2616
|
-
])]), createElementVNode("div", _hoisted_10, [createVNode(unref(NSpace$1), {
|
|
2617
|
-
align: "center",
|
|
2618
|
-
size: 6
|
|
2619
|
-
}, {
|
|
2620
|
-
default: withCtx(() => [
|
|
2621
|
-
createVNode(unref(NText$1), {
|
|
2622
|
-
strong: "",
|
|
2623
|
-
style: { fontSize: "13px" }
|
|
2624
|
-
}, {
|
|
2625
|
-
default: withCtx(() => [createTextVNode(toDisplayString(column.title || column.key), 1)]),
|
|
2626
|
-
_: 2
|
|
2627
|
-
}, 1024),
|
|
2628
|
-
column.fixed === "left" ? (openBlock(), createBlock(unref(NTag$1), {
|
|
2629
|
-
key: 0,
|
|
2630
|
-
size: "tiny",
|
|
2631
|
-
type: "info"
|
|
2632
|
-
}, {
|
|
2633
|
-
default: withCtx(() => _cache[6] || (_cache[6] = [createTextVNode(" 左固定 ", -1)])),
|
|
2634
|
-
_: 1,
|
|
2635
|
-
__: [6]
|
|
2636
|
-
})) : createCommentVNode("v-if", true),
|
|
2637
|
-
column.fixed === "right" ? (openBlock(), createBlock(unref(NTag$1), {
|
|
2638
|
-
key: 1,
|
|
2639
|
-
size: "tiny",
|
|
2640
|
-
type: "warning"
|
|
2641
|
-
}, {
|
|
2642
|
-
default: withCtx(() => _cache[7] || (_cache[7] = [createTextVNode(" 右固定 ", -1)])),
|
|
2643
|
-
_: 1,
|
|
2644
|
-
__: [7]
|
|
2645
|
-
})) : createCommentVNode("v-if", true)
|
|
2646
|
-
]),
|
|
2647
|
-
_: 2
|
|
2648
|
-
}, 1024), createVNode(unref(NText$1), {
|
|
2649
|
-
depth: "3",
|
|
2650
|
-
style: { fontSize: "11px" }
|
|
2651
|
-
}, {
|
|
2652
|
-
default: withCtx(() => [createTextVNode(toDisplayString(column.key), 1)]),
|
|
2653
|
-
_: 2
|
|
2654
|
-
}, 1024)])]), createElementVNode("div", _hoisted_11, [createElementVNode("div", _hoisted_12, [createVNode(C_Icon_default, {
|
|
2655
|
-
name: "mdi:chevron-up",
|
|
2656
|
-
size: "14",
|
|
2657
|
-
title: "上移",
|
|
2658
|
-
clickable: index !== 0,
|
|
2659
|
-
class: normalizeClass({ disabled: index === 0 }),
|
|
2660
|
-
onClick: ($event) => index !== 0 && moveColumn(index, index - 1)
|
|
2661
|
-
}, null, 8, [
|
|
2662
|
-
"clickable",
|
|
2663
|
-
"class",
|
|
2664
|
-
"onClick"
|
|
2665
|
-
]), createVNode(C_Icon_default, {
|
|
2666
|
-
name: "mdi:chevron-down",
|
|
2667
|
-
size: "14",
|
|
2668
|
-
title: "下移",
|
|
2669
|
-
clickable: index !== filteredColumns.value.length - 1,
|
|
2670
|
-
class: normalizeClass({ disabled: index === filteredColumns.value.length - 1 }),
|
|
2671
|
-
onClick: ($event) => index !== filteredColumns.value.length - 1 && moveColumn(index, index + 1)
|
|
2672
|
-
}, null, 8, [
|
|
2673
|
-
"clickable",
|
|
2674
|
-
"class",
|
|
2675
|
-
"onClick"
|
|
2676
|
-
])]), createVNode(unref(NDropdown$1), {
|
|
2677
|
-
options: unref(getFixedOptions)(column),
|
|
2678
|
-
onSelect: (value) => handleFixedSelect(index, value)
|
|
2679
|
-
}, {
|
|
2680
|
-
default: withCtx(() => [createVNode(C_Icon_default, {
|
|
2681
|
-
name: "mdi:pin",
|
|
2682
|
-
size: "14",
|
|
2683
|
-
title: "固定列",
|
|
2684
|
-
clickable: "",
|
|
2685
|
-
style: normalizeStyle({ color: column.fixed ? "var(--n-primary-color)" : void 0 })
|
|
2686
|
-
}, null, 8, ["style"])]),
|
|
2687
|
-
_: 2
|
|
2688
|
-
}, 1032, ["options", "onSelect"])])], 42, _hoisted_7);
|
|
2689
|
-
}), 128))], 512)
|
|
2690
|
-
]);
|
|
2691
|
-
};
|
|
2692
|
-
}
|
|
2693
|
-
});
|
|
2694
|
-
|
|
2695
|
-
//#endregion
|
|
2696
|
-
//#region src/components/C_Table/components/ColumnSettings/index.vue
|
|
2697
|
-
var ColumnSettings_default = /* @__PURE__ */ export_helper_default(index_vue_vue_type_script_setup_true_lang_default$1, [["__scopeId", "data-v-a4d013ea"]]);
|
|
2698
|
-
|
|
2699
|
-
//#endregion
|
|
2700
|
-
//#region src/components/C_Table/index.vue?vue&type=script&setup=true&lang.ts
|
|
2701
|
-
const _hoisted_1 = { class: "c-table-wrapper" };
|
|
2702
|
-
const _hoisted_2 = {
|
|
2703
|
-
key: 1,
|
|
2704
|
-
class: "table-toolbar"
|
|
2705
|
-
};
|
|
2706
|
-
const _hoisted_3 = { class: "toolbar-left" };
|
|
2707
|
-
const _hoisted_4 = { class: "toolbar-right" };
|
|
2708
|
-
var index_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
|
|
2709
|
-
name: "C_Table",
|
|
2710
|
-
inheritAttrs: false,
|
|
2711
|
-
__name: "index",
|
|
2712
|
-
props: {
|
|
2713
|
-
columns: {},
|
|
2714
|
-
data: {},
|
|
2715
|
-
loading: { default: void 0 },
|
|
2716
|
-
rowKey: {
|
|
2717
|
-
type: Function,
|
|
2718
|
-
default: (row) => row.id
|
|
2719
|
-
},
|
|
2720
|
-
config: { default: () => ({}) },
|
|
2721
|
-
crud: {}
|
|
2722
|
-
},
|
|
2723
|
-
emits: [
|
|
2724
|
-
"pagination-change",
|
|
2725
|
-
"row-delete",
|
|
2726
|
-
"expand-change",
|
|
2727
|
-
"selection-change",
|
|
2728
|
-
"child-selection-change",
|
|
2729
|
-
"parent-child-link-change",
|
|
2730
|
-
"update:data",
|
|
2731
|
-
"save",
|
|
2732
|
-
"cancel",
|
|
2733
|
-
"row-add",
|
|
2734
|
-
"row-copy",
|
|
2735
|
-
"row-move",
|
|
2736
|
-
"row-selection-change",
|
|
2737
|
-
"view-detail",
|
|
2738
|
-
"column-change"
|
|
2739
|
-
],
|
|
2740
|
-
setup(__props, { expose: __expose, emit: __emit }) {
|
|
2741
|
-
const props = __props;
|
|
2742
|
-
const emit = __emit;
|
|
2743
|
-
/** 包装 emit:在触发事件的同时自动调用 crud 对应的方法 */
|
|
2744
|
-
const bridgedEmit = (event, ...args) => {
|
|
2745
|
-
emit(event, ...args);
|
|
2746
|
-
if (!props.crud) return;
|
|
2747
|
-
({
|
|
2748
|
-
save: props.crud.save,
|
|
2749
|
-
cancel: props.crud.handleCancel,
|
|
2750
|
-
"pagination-change": props.crud.handlePaginationChange,
|
|
2751
|
-
"row-delete": props.crud.handleRowDelete,
|
|
2752
|
-
"view-detail": props.crud.detail?.show
|
|
2753
|
-
})[event]?.(...args);
|
|
2754
|
-
};
|
|
2755
|
-
/** 合并 crud 返回的 actions/pagination 到用户 config */
|
|
2756
|
-
const effectiveConfig = computed(() => {
|
|
2757
|
-
if (!props.crud) return props.config || {};
|
|
2758
|
-
const fromCrud = {};
|
|
2759
|
-
if (props.crud.actions) fromCrud.actions = props.crud.actions.value;
|
|
2760
|
-
if (props.crud.pagination) fromCrud.pagination = props.crud.pagination.value;
|
|
2761
|
-
return {
|
|
2762
|
-
...fromCrud,
|
|
2763
|
-
...props.config
|
|
2764
|
-
};
|
|
2765
|
-
});
|
|
2766
|
-
const effectiveColumns = computed(() => props.columns ?? props.crud?.columns.value ?? []);
|
|
2767
|
-
const resolved = computed(() => resolveConfig(effectiveConfig.value));
|
|
2768
|
-
const editModeChecker = computed(() => createEditModeChecker(resolved.value));
|
|
2769
|
-
const unwrapMaybeRef = (val) => val && typeof val === "object" && "value" in val ? val.value : val;
|
|
2770
|
-
const normalizedData = computed(() => unwrapMaybeRef(props.data) ?? props.crud?.data.value ?? []);
|
|
2771
|
-
/**
|
|
2772
|
-
* Loading 状态:使用 watchEffect 主动追踪 props.loading / crud.loading
|
|
2773
|
-
* 解决跨 npm 包时 computed 对 props.crud.loading.value 依赖追踪不稳定的问题
|
|
2774
|
-
*/
|
|
2775
|
-
const normalizedLoading = ref(false);
|
|
2776
|
-
watchEffect(() => {
|
|
2777
|
-
const propVal = props.loading;
|
|
2778
|
-
if (propVal !== void 0) {
|
|
2779
|
-
normalizedLoading.value = propVal && typeof propVal === "object" && "value" in propVal ? !!propVal.value : !!propVal;
|
|
2780
|
-
return;
|
|
2781
|
-
}
|
|
2782
|
-
const crudLoading = props.crud?.loading;
|
|
2783
|
-
if (crudLoading !== void 0) {
|
|
2784
|
-
normalizedLoading.value = crudLoading && typeof crudLoading === "object" && "value" in crudLoading ? !!crudLoading.value : !!crudLoading;
|
|
2785
|
-
return;
|
|
2786
|
-
}
|
|
2787
|
-
normalizedLoading.value = false;
|
|
2788
|
-
});
|
|
2789
|
-
const pagination = usePagination({
|
|
2790
|
-
data: normalizedData,
|
|
2791
|
-
config: computed(() => resolved.value.pagination),
|
|
2792
|
-
emit: bridgedEmit
|
|
2793
|
-
});
|
|
2794
|
-
const tableManager = useTableManager({
|
|
2795
|
-
config: resolved.value,
|
|
2796
|
-
data: () => normalizedData.value,
|
|
2797
|
-
rowKey: props.rowKey,
|
|
2798
|
-
emit: bridgedEmit
|
|
2799
|
-
});
|
|
2800
|
-
const tableActions = useTableActions({
|
|
2801
|
-
actions: computed(() => effectiveConfig.value.actions || {}),
|
|
2802
|
-
config: resolved,
|
|
2803
|
-
tableManager,
|
|
2804
|
-
rowKey: props.rowKey,
|
|
2805
|
-
emit: bridgedEmit,
|
|
2806
|
-
onViewDetail: (data) => bridgedEmit("view-detail", data)
|
|
2807
|
-
});
|
|
2808
|
-
const columnState = useTableColumns({
|
|
2809
|
-
rawColumns: effectiveColumns,
|
|
2810
|
-
config: resolved,
|
|
2811
|
-
columnWidth: resolved.value.columnWidth,
|
|
2812
|
-
scrollX: resolved.value.scrollX,
|
|
2813
|
-
rowKey: props.rowKey,
|
|
2814
|
-
tableManager,
|
|
2815
|
-
actionsRenderer: tableActions.renderActions,
|
|
2816
|
-
editModeChecker
|
|
2817
|
-
});
|
|
2818
|
-
const { showSettingsPanel, reactiveColumns, computedColumns, computedScrollX } = columnState;
|
|
2819
|
-
const tableRef = ref();
|
|
2820
|
-
const computedTableProps = computed(() => ({
|
|
2821
|
-
striped: resolved.value.striped,
|
|
2822
|
-
bordered: resolved.value.bordered,
|
|
2823
|
-
singleLine: resolved.value.singleLine,
|
|
2824
|
-
size: resolved.value.size,
|
|
2825
|
-
maxHeight: resolved.value.maxHeight
|
|
2826
|
-
}));
|
|
2827
|
-
const editFormRef = ref();
|
|
2828
|
-
const modalSubmitLoading = ref(false);
|
|
2829
|
-
const localEditingData = ref({});
|
|
2830
|
-
const modalVisible = computed({
|
|
2831
|
-
get: () => tableManager.editStates.modalEdit.isModalVisible.value,
|
|
2832
|
-
set: (val) => {
|
|
2833
|
-
tableManager.editStates.modalEdit.isModalVisible.value = val;
|
|
2834
|
-
}
|
|
2835
|
-
});
|
|
2836
|
-
const editableColumns = computed(() => effectiveColumns.value.filter((col) => col.editable !== false));
|
|
2837
|
-
const formKey = computed(() => `edit-form-${tableManager.editStates.modalEdit.editingRowKey.value || "new"}`);
|
|
2838
|
-
const formOptions = computed(() => generateFormOptions(editableColumns.value));
|
|
2839
|
-
watch(() => tableManager.editStates.modalEdit.editingData.value, (newData) => {
|
|
2840
|
-
if (newData && Object.keys(newData).length > 0) localEditingData.value = JSON.parse(JSON.stringify(newData));
|
|
2841
|
-
}, {
|
|
2842
|
-
immediate: true,
|
|
2843
|
-
deep: true
|
|
2844
|
-
});
|
|
2845
|
-
let modalCloseTimer = null;
|
|
2846
|
-
watch(modalVisible, (visible) => {
|
|
2847
|
-
if (!visible) modalCloseTimer = setTimeout(() => {
|
|
2848
|
-
localEditingData.value = {};
|
|
2849
|
-
modalCloseTimer = null;
|
|
2850
|
-
}, 300);
|
|
2851
|
-
});
|
|
2852
|
-
const handleModalSave = async () => {
|
|
2853
|
-
if (!editFormRef.value) return;
|
|
2854
|
-
modalSubmitLoading.value = true;
|
|
2855
|
-
try {
|
|
2856
|
-
await editFormRef.value.validate();
|
|
2857
|
-
await tableManager.editStates.modalEdit.saveEdit(localEditingData.value);
|
|
2858
|
-
} catch {} finally {
|
|
2859
|
-
modalSubmitLoading.value = false;
|
|
2860
|
-
}
|
|
2861
|
-
};
|
|
2862
|
-
const handleModalCancel = () => {
|
|
2863
|
-
localEditingData.value = {};
|
|
2864
|
-
tableManager.editStates.modalEdit.cancelEdit();
|
|
2865
|
-
};
|
|
2866
|
-
const onColumnSettingsChange = (columns) => {
|
|
2867
|
-
columnState.handleColumnChange(columns);
|
|
2868
|
-
emit("column-change", columnState.reactiveColumns.value);
|
|
2869
|
-
};
|
|
2870
|
-
const { edit, expand, selection, dynamicRows } = tableManager.stateManager;
|
|
2871
|
-
const exposedApi = {
|
|
2872
|
-
startEdit: edit.start,
|
|
2873
|
-
expandAll: expand.all,
|
|
2874
|
-
collapseAll: expand.collapseAll,
|
|
2875
|
-
selectAll: selection.all,
|
|
2876
|
-
clearSelection: selection.clear,
|
|
2877
|
-
clearAllSelections: tableManager.stateManager.clearAllSelections,
|
|
2878
|
-
clearRowSelection: dynamicRows?.clearSelection,
|
|
2879
|
-
resetToFirstPage: pagination.resetToFirstPage,
|
|
2880
|
-
getSelectedRows: selection.getSelected,
|
|
2881
|
-
getEditingData: edit.getEditingData,
|
|
2882
|
-
isEditing: edit.isEditing,
|
|
2883
|
-
isExpanded: expand.isExpanded,
|
|
2884
|
-
getManager: () => tableManager.stateManager
|
|
2885
|
-
};
|
|
2886
|
-
__expose(exposedApi);
|
|
2887
|
-
onMounted(() => {
|
|
2888
|
-
const crudRef = props.crud?.tableRef;
|
|
2889
|
-
if (crudRef) crudRef.value = exposedApi;
|
|
2890
|
-
});
|
|
2891
|
-
onBeforeUnmount(() => {
|
|
2892
|
-
if (modalCloseTimer) clearTimeout(modalCloseTimer);
|
|
2893
|
-
});
|
|
2894
|
-
return (_ctx, _cache) => {
|
|
2895
|
-
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
2896
|
-
createCommentVNode(" 动态行工具栏 "),
|
|
2897
|
-
unref(tableManager).dynamicRowsState ? (openBlock(), createBlock(resolveDynamicComponent(unref(tableManager).dynamicRowsState.renderToolbar()), { key: 0 })) : createCommentVNode("v-if", true),
|
|
2898
|
-
createCommentVNode(" 表格工具栏 "),
|
|
2899
|
-
resolved.value.showToolbar ? (openBlock(), createElementBlock("div", _hoisted_2, [createElementVNode("div", _hoisted_3, [renderSlot(_ctx.$slots, "toolbar-left", {}, void 0, true)]), createElementVNode("div", _hoisted_4, [renderSlot(_ctx.$slots, "toolbar-right", {}, void 0, true), resolved.value.enableColumnSettings ? (openBlock(), createBlock(C_Icon_default, {
|
|
2900
|
-
key: 0,
|
|
2901
|
-
name: "mdi:cog",
|
|
2902
|
-
size: "18",
|
|
2903
|
-
title: "表格设置",
|
|
2904
|
-
clickable: "",
|
|
2905
|
-
class: "column-settings-btn",
|
|
2906
|
-
onClick: _cache[0] || (_cache[0] = ($event) => showSettingsPanel.value = true)
|
|
2907
|
-
})) : createCommentVNode("v-if", true)])])) : createCommentVNode("v-if", true),
|
|
2908
|
-
createCommentVNode(" 表格主体 "),
|
|
2909
|
-
createVNode(unref(NDataTable), mergeProps({
|
|
2910
|
-
ref_key: "tableRef",
|
|
2911
|
-
ref: tableRef
|
|
2912
|
-
}, {
|
|
2913
|
-
...computedTableProps.value,
|
|
2914
|
-
..._ctx.$attrs
|
|
2915
|
-
}, {
|
|
2916
|
-
columns: unref(computedColumns),
|
|
2917
|
-
data: normalizedData.value,
|
|
2918
|
-
loading: normalizedLoading.value,
|
|
2919
|
-
"row-key": _ctx.rowKey,
|
|
2920
|
-
"expanded-row-keys": unref(tableManager).expandedKeys.value,
|
|
2921
|
-
"checked-row-keys": unref(tableManager).checkedKeys.value,
|
|
2922
|
-
"onUpdate:expandedRowKeys": unref(tableManager).expandState?.handleExpandChange,
|
|
2923
|
-
"onUpdate:checkedRowKeys": unref(tableManager).expandState?.handleSelectionChange,
|
|
2924
|
-
"scroll-x": unref(computedScrollX),
|
|
2925
|
-
style: { "width": "100%" }
|
|
2926
|
-
}), null, 16, [
|
|
2927
|
-
"columns",
|
|
2928
|
-
"data",
|
|
2929
|
-
"loading",
|
|
2930
|
-
"row-key",
|
|
2931
|
-
"expanded-row-keys",
|
|
2932
|
-
"checked-row-keys",
|
|
2933
|
-
"onUpdate:expandedRowKeys",
|
|
2934
|
-
"onUpdate:checkedRowKeys",
|
|
2935
|
-
"scroll-x"
|
|
2936
|
-
]),
|
|
2937
|
-
createCommentVNode(" 分页 "),
|
|
2938
|
-
unref(pagination).paginationConfig.value ? (openBlock(), createBlock(unref(NPagination$1), mergeProps({ key: 2 }, unref(pagination).paginationConfig.value, { class: "pagination-wrapper" }), null, 16)) : createCommentVNode("v-if", true),
|
|
2939
|
-
createCommentVNode(" 编辑弹窗 "),
|
|
2940
|
-
resolved.value.editMode === "modal" || resolved.value.editMode === "both" ? (openBlock(), createBlock(unref(NModal$1), {
|
|
2941
|
-
key: 3,
|
|
2942
|
-
show: modalVisible.value,
|
|
2943
|
-
"onUpdate:show": _cache[2] || (_cache[2] = ($event) => modalVisible.value = $event),
|
|
2944
|
-
title: resolved.value.modalTitle,
|
|
2945
|
-
width: resolved.value.modalWidth,
|
|
2946
|
-
preset: "card",
|
|
2947
|
-
"mask-closable": false,
|
|
2948
|
-
"close-on-esc": false,
|
|
2949
|
-
class: "w60%",
|
|
2950
|
-
closable: false
|
|
2951
|
-
}, {
|
|
2952
|
-
action: withCtx(() => [createVNode(unref(NSpace$1), { justify: "end" }, {
|
|
2953
|
-
default: withCtx(() => [createVNode(unref(NButton$1), { onClick: handleModalCancel }, {
|
|
2954
|
-
default: withCtx(() => _cache[4] || (_cache[4] = [createTextVNode("取消", -1)])),
|
|
2955
|
-
_: 1,
|
|
2956
|
-
__: [4]
|
|
2957
|
-
}), createVNode(unref(NButton$1), {
|
|
2958
|
-
type: "primary",
|
|
2959
|
-
loading: modalSubmitLoading.value,
|
|
2960
|
-
onClick: handleModalSave
|
|
2961
|
-
}, {
|
|
2962
|
-
default: withCtx(() => _cache[5] || (_cache[5] = [createTextVNode(" 保存 ", -1)])),
|
|
2963
|
-
_: 1,
|
|
2964
|
-
__: [5]
|
|
2965
|
-
}, 8, ["loading"])]),
|
|
2966
|
-
_: 1
|
|
2967
|
-
})]),
|
|
2968
|
-
default: withCtx(() => [modalVisible.value && formOptions.value.length ? (openBlock(), createBlock(C_Form_default, {
|
|
2969
|
-
ref_key: "editFormRef",
|
|
2970
|
-
ref: editFormRef,
|
|
2971
|
-
key: formKey.value,
|
|
2972
|
-
modelValue: localEditingData.value,
|
|
2973
|
-
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => localEditingData.value = $event),
|
|
2974
|
-
options: formOptions.value,
|
|
2975
|
-
config: {
|
|
2976
|
-
layout: "grid",
|
|
2977
|
-
grid: {
|
|
2978
|
-
cols: 2,
|
|
2979
|
-
xGap: 16,
|
|
2980
|
-
yGap: 16
|
|
2981
|
-
},
|
|
2982
|
-
showActions: false
|
|
2983
|
-
}
|
|
2984
|
-
}, null, 8, ["modelValue", "options"])) : createCommentVNode("v-if", true)]),
|
|
2985
|
-
_: 1
|
|
2986
|
-
}, 8, [
|
|
2987
|
-
"show",
|
|
2988
|
-
"title",
|
|
2989
|
-
"width"
|
|
2990
|
-
])) : createCommentVNode("v-if", true),
|
|
2991
|
-
createCommentVNode(" 动态行确认删除弹窗 "),
|
|
2992
|
-
unref(tableManager).dynamicRowsState ? (openBlock(), createBlock(resolveDynamicComponent(unref(tableManager).dynamicRowsState.renderConfirmModal()), { key: 4 })) : createCommentVNode("v-if", true),
|
|
2993
|
-
createCommentVNode(" 列设置抽屉 "),
|
|
2994
|
-
createVNode(unref(NDrawer$1), {
|
|
2995
|
-
show: unref(showSettingsPanel),
|
|
2996
|
-
"onUpdate:show": _cache[3] || (_cache[3] = ($event) => isRef(showSettingsPanel) ? showSettingsPanel.value = $event : null),
|
|
2997
|
-
width: 420,
|
|
2998
|
-
placement: "right",
|
|
2999
|
-
"mask-closable": true
|
|
3000
|
-
}, {
|
|
3001
|
-
default: withCtx(() => [createVNode(unref(NDrawerContent$1), {
|
|
3002
|
-
title: "列设置",
|
|
3003
|
-
closable: ""
|
|
3004
|
-
}, {
|
|
3005
|
-
default: withCtx(() => [createVNode(ColumnSettings_default, {
|
|
3006
|
-
columns: unref(reactiveColumns),
|
|
3007
|
-
onChange: onColumnSettingsChange
|
|
3008
|
-
}, null, 8, ["columns"])]),
|
|
3009
|
-
_: 1
|
|
3010
|
-
})]),
|
|
3011
|
-
_: 1
|
|
3012
|
-
}, 8, ["show"])
|
|
3013
|
-
]);
|
|
3014
|
-
};
|
|
3015
|
-
}
|
|
3016
|
-
});
|
|
3017
|
-
|
|
3018
|
-
//#endregion
|
|
3019
|
-
//#region src/components/C_Table/index.vue
|
|
3020
|
-
var C_Table_default = /* @__PURE__ */ export_helper_default(index_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-767c7393"]]);
|
|
3021
|
-
|
|
3022
|
-
//#endregion
|
|
3023
|
-
export { useTableManager as a, usePrintWatermark as c, useCellEdit as d, useRowEdit as f, usePagination as i, useTableExpand as l, resolveConfig as m, useTableColumns as n, useDynamicRows as o, createEditModeChecker as p, useTableActions as r, printPresets as s, C_Table_default as t, useModalEdit as u };
|
|
1
|
+
import{t as e}from"./C_Icon2.js";import{t}from"./export-helper.js";import{t as n}from"./C_Form2.js";import{NButton as r,NDatePicker as i,NDropdown as a,NInput as o,NInputNumber as s,NSelect as c,NSpace as l,NSwitch as u,useDialog as d,useMessage as f}from"naive-ui";import{Fragment as p,computed as m,createBlock as h,createCommentVNode as g,createElementBlock as _,createElementVNode as v,createTextVNode as y,createVNode as b,defineComponent as x,h as S,isRef as C,mergeProps as w,nextTick as T,normalizeClass as E,normalizeStyle as D,onBeforeUnmount as O,onMounted as ee,openBlock as k,ref as A,renderList as j,renderSlot as te,resolveDynamicComponent as ne,toDisplayString as M,unref as N,watch as P,watchEffect as F,withCtx as I}from"vue";import re from"html2canvas";import{NButton as L,NButtonGroup as R,NCheckbox as ie,NDataTable as ae,NDrawer as oe,NDrawerContent as se,NDropdown as ce,NInput as z,NModal as le,NPagination as ue,NSpace as de,NSpin as fe,NSwitch as B,NTag as V,NText as H,NTooltip as U,useMessage as pe}from"naive-ui/es";import W from"print-js";const me={editable:!1,editMode:`none`,showRowActions:!1,modalTitle:`编辑数据`,modalWidth:600},he=e=>e===!1||e===void 0?me:e===!0?{editable:!0,editMode:`modal`,showRowActions:!0,modalTitle:`编辑数据`,modalWidth:600}:{editable:e.enabled!==!1&&e.mode!==`none`,editMode:e.mode||`modal`,showRowActions:e.showRowActions!==!1&&e.mode!==`none`,modalTitle:e.modalTitle||`编辑数据`,modalWidth:e.modalWidth||600},ge=e=>e?e===!0?{expandable:!0,defaultExpandedKeys:void 0,onLoadExpandData:void 0,renderExpandContent:void 0,rowExpandable:void 0}:{expandable:e.enabled!==!1,defaultExpandedKeys:e.defaultExpandedKeys,onLoadExpandData:e.onLoadData,renderExpandContent:e.renderContent,rowExpandable:e.rowExpandable}:{expandable:!1,defaultExpandedKeys:void 0,onLoadExpandData:void 0,renderExpandContent:void 0,rowExpandable:void 0},G=e=>{if(!e)return{enableSelection:!1,defaultCheckedKeys:void 0,rowCheckable:void 0,maxSelection:void 0,enableChildSelection:!1,childRowCheckable:void 0,enableParentChildLink:!1,parentChildLinkMode:`loose`};if(e===!0)return{enableSelection:!0,defaultCheckedKeys:void 0,rowCheckable:void 0,maxSelection:void 0,enableChildSelection:!1,childRowCheckable:void 0,enableParentChildLink:!1,parentChildLinkMode:`loose`};let t=e.childSelection||{},n=e.parentChildLink||{};return{enableSelection:e.enabled!==!1,defaultCheckedKeys:e.defaultCheckedKeys,rowCheckable:e.rowCheckable,maxSelection:e.maxSelection,enableChildSelection:t.enabled||!1,childRowCheckable:t.childRowCheckable,enableParentChildLink:n.enabled||!1,parentChildLinkMode:n.mode||`loose`}},K=e=>{let t={enabled:!0,page:1,pageSize:10,showSizePicker:!0,showQuickJumper:!0,pageSizes:[10,20,50,100],simple:!1,size:`medium`};return e===!1?{pagination:null}:e===!0||e===void 0?{pagination:t}:{pagination:{...t,...e}}},q=e=>e?e===!0?{dynamicRows:{enableRadioSelection:!0,enableAdd:!0,enableInsert:!0,enableDelete:!0,enableCopy:!0,enableMove:!0,enablePrint:!0}}:{dynamicRows:e}:{dynamicRows:void 0},J={striped:!0,bordered:!0,singleLine:!0,size:`medium`,maxHeight:void 0,scrollX:void 0,columnWidth:180};function _e(e){return e?{striped:e.striped??J.striped,bordered:e.bordered??J.bordered,singleLine:e.singleLine??J.singleLine,size:e.size??J.size,maxHeight:e.maxHeight,scrollX:e.scrollX,columnWidth:e.columnWidth??J.columnWidth}:{...J}}const ve=e=>({showToolbar:e?.show!==!1,enableColumnSettings:e?.columnSettings!==!1});function ye(e={}){return{...he(e.edit),...ge(e.expand),...G(e.selection),...K(e.pagination),...q(e.dynamicRows),..._e(e.display),...ve(e.toolbar)}}const be=e=>({isNonEditable:t=>!e.editable||t.editable===!1||e.editMode===`none`,isRowEditMode:()=>[`row`,`both`].includes(e.editMode),isCellEditMode:()=>[`cell`,`both`].includes(e.editMode)});function xe(e){let t=A(null),n=A({}),r=e=>t.value===e,i=t=>{let n=e.data();return!n||!Array.isArray(n)?null:n.find(n=>e.rowKey(n)===t)};return{editingRowKey:t,isEditingRow:r,startEditRow:e=>{let r=i(e);r&&(t.value=e,n.value[e]={...r})},cancelEditRow:async()=>{if(!t.value)return;let r=e.data();if(!r||!Array.isArray(r))return;let i=r.findIndex(n=>e.rowKey(n)===t.value);i>-1&&await e.onCancel?.(r[i],i),t.value=null,n.value={}},saveEditRow:async()=>{if(!t.value)return;let r=t.value,i=e.data();if(!i||!Array.isArray(i))return;let a=i.findIndex(t=>e.rowKey(t)===r);if(a===-1)return;let o=n.value[r];if(o)return await e.onSave?.(o,a),t.value=null,n.value={},{updatedData:o,rowIndex:a}},getEditingRowData:e=>n.value[e],updateEditingRowData:(e,t,r)=>{n.value[e]&&(n.value[e][t]=r)},findRowData:i}}function Se(e){let t=A({rowKey:null,columnKey:null}),n=A({}),r=(e,n)=>t.value.rowKey===e&&t.value.columnKey===n,i=t=>{let n=e.data();return!n||!Array.isArray(n)?null:n.find(n=>e.rowKey(n)===t)};return{editingCell:t,isEditingCell:r,startEditCell:(e,r)=>{let a=i(e);a&&(t.value={rowKey:e,columnKey:r},n.value[`${e}-${r}`]=a[r])},saveEditCell:async()=>{let{rowKey:r,columnKey:i}=t.value;if(!r||!i)return;let a=e.data();if(!a||!Array.isArray(a))return;let o=a.findIndex(t=>e.rowKey(t)===r);if(o===-1)return;let s=`${r}-${i}`,c=n.value[s],l={...a[o],[i]:c};return await e.onSave?.(l,o,i),t.value={rowKey:null,columnKey:null},delete n.value[s],{updatedData:l,rowIndex:o,columnKey:i}},cancelEditCell:()=>{let{rowKey:e,columnKey:r}=t.value;e&&r&&delete n.value[`${e}-${r}`],t.value={rowKey:null,columnKey:null}},getEditingCellValue:(e,t)=>n.value[`${e}-${t}`],updateEditingCellValue:(e,t,r)=>{n.value[`${e}-${t}`]=r},findRowData:i}}function Ce(e){let t=A(!1),n=A(null),r=A({}),i=m(()=>{if(!n.value)return-1;let t=e.data();return!t||!Array.isArray(t)?-1:t.findIndex(t=>e.rowKey(t)===n.value)}),a=()=>{n.value=null,r.value={}};return{isModalVisible:t,editingData:r,editingRowKey:n,editingRowIndex:i,startEdit:i=>{console.log(`🚀 开始编辑:`,i);let a=e.data();if(!a||!Array.isArray(a)){console.warn(`数据源为空或不是数组`);return}let o=a.findIndex(t=>e.rowKey(t)===i);if(o===-1){console.warn(`未找到对应的行数据:`,i);return}let s=a[o];console.log(`找到行数据:`,s),n.value=i,r.value=JSON.parse(JSON.stringify(s)),console.log(`编辑数据已准备:`,r.value),t.value=!0},saveEdit:async o=>{let s=o||r.value,c=i.value;if(console.log(`💾 保存编辑:`,{rowKey:n.value,index:c,data:s}),c===-1){console.warn(`无法找到编辑行的索引`);return}try{await e.onSave?.(s,c),t.value=!1,a(),console.log(`✅ 保存成功`)}catch(e){throw console.error(`❌ 保存失败:`,e),e}},cancelEdit:async()=>{console.log(`🚫 取消编辑`);try{let t=i.value;if(n.value&&t>-1){let n=e.data();n&&n[t]&&await e.onCancel?.(n[t],t)}}finally{t.value=!1,a()}},updateEditingData:e=>{r.value={...e}},resetEditingState:a,isEditingRow:e=>n.value===e&&t.value,getEditingRowData:e=>n.value===e?r.value:null}}const we=e=>({expandedKeys:A([...e.defaultExpandedKeys||[]]),expandDataMap:A(new Map),loadingMap:A(new Map),checkedKeys:e.enableSelection?A([...e.defaultCheckedKeys||[]]):A([]),childSelections:(e.enableChildSelection,A(new Map))}),Te=e=>{let t=m(()=>N(e.data)),n=e.rowKey;return{data:t,getRowKey:n,getChildRowKey:e.childRowKey||(e=>e.id),findRow:e=>t.value.find(t=>n(t)===e),isRowExpandable:e.rowExpandable||(()=>!0),isRowCheckable:e.rowCheckable||(()=>!0),isChildRowCheckable:e.childRowCheckable||(()=>!0)}},Ee=(e,t,n)=>{let r=async r=>{if(!n.onLoadData)return[];let i=t.getRowKey(r),a=e.expandDataMap.value.get(i);if(a)return a;e.loadingMap.value.set(i,!0);try{let t=await n.onLoadData(r)||[];return e.expandDataMap.value.set(i,t),n.enableChildSelection&&!e.childSelections.value.has(i)&&e.childSelections.value.set(i,[]),t}catch(e){return console.error(`加载展开数据失败:`,e),[]}finally{e.loadingMap.value.set(i,!1)}};return{loadData:r,handleRowExpand:async(i,a)=>{let o=t.getRowKey(i);a?(await r(i),e.expandedKeys.value.includes(o)||(e.expandedKeys.value=[...e.expandedKeys.value,o])):e.expandedKeys.value=e.expandedKeys.value.filter(e=>e!==o),n.onExpandChange?.(e.expandedKeys.value)},expandAll:async()=>{let i=t.data.value.filter(t.isRowExpandable);await Promise.allSettled(i.map(r)),e.expandedKeys.value=i.map(t.getRowKey),n.onExpandChange?.(e.expandedKeys.value)},collapseAll:()=>{e.expandedKeys.value=[],e.childSelections.value.clear(),n.onExpandChange?.(e.expandedKeys.value)},handleExpandChange:async i=>{let a=i.filter(t=>!e.expandedKeys.value.includes(t)),o=e.expandedKeys.value.filter(e=>!i.includes(e));await Promise.all(a.map(async e=>{let n=t.findRow(e);n&&await r(n)}));for(let t of o)e.childSelections.value.delete(t);e.expandedKeys.value=i,n.onExpandChange?.(i)}}},De=(e,t,n)=>{let r=m(()=>t.data.value.filter(t.isRowCheckable));return{selectAll:()=>{if(!n.enableSelection)return;let i=r.value.map(t.getRowKey),a=n.maxSelection?i.slice(0,n.maxSelection):i;e.checkedKeys.value=a;let o=r.value.filter(e=>a.includes(t.getRowKey(e)));n.onSelectionChange?.(a,o,e.childSelections.value)},clearSelection:()=>{n.enableSelection&&(e.checkedKeys.value=[],n.onSelectionChange?.([],[],e.childSelections.value))},handleSelectionChange:r=>{if(!n.enableSelection)return;e.checkedKeys.value=r;let i=t.data.value.filter(e=>r.includes(t.getRowKey(e)));n.onSelectionChange?.(r,i,e.childSelections.value)},selectedRowsCount:m(()=>e.checkedKeys.value.length),selectableRows:r}},Oe=(e,t)=>{let n=!!(t.enableParentChildLink&&t.enableSelection&&t.enableChildSelection);return{handleParentChildLink:(r,i,a)=>{if(!n)return;let o=t.parentChildLinkMode===`strict`?i.length===a&&a>0:i.length>0,s=[...e.checkedKeys.value],c=s.includes(r);o&&!c?e.checkedKeys.value=[...s,r]:!o&&c&&(e.checkedKeys.value=s.filter(e=>e!==r))},isLinkEnabled:n}},ke=(e,t,n,r)=>({totalChildSelections:m(()=>r.enableChildSelection?Array.from(e.childSelections.value.values()).reduce((e,t)=>e+t.length,0):0),clearAllSelections:()=>{e.checkedKeys.value=[],e.childSelections.value.clear(),r.onSelectionChange?.([],[],e.childSelections.value)},handleChildSelectionChange:(i,a)=>{if(!r.enableChildSelection)return;e.childSelections.value.set(i,a);let o=e.expandDataMap.value.get(i)||[],s=o.filter(e=>a.includes(t.getChildRowKey(e)));r.onChildSelectionChange?.(i,a,s),n.isLinkEnabled&&n.handleParentChildLink(i,a,o.length)}}),Ae=(e,t,n,r,i)=>{if(!i.enableChildSelection)return;let a=t.childSelections.value.get(e)||[],o=t.expandDataMap.value.get(e)||[],s=n.findRow(e);if(!s)return;let c=o.filter(e=>n.isChildRowCheckable(e,s));return{selectedKeys:a,isAllChecked:c.length>0&&c.every(e=>a.includes(n.getChildRowKey(e))),selectAll:()=>{let t=c.map(e=>n.getChildRowKey(e));r.handleChildSelectionChange(e,t)},clearAll:()=>{r.handleChildSelectionChange(e,[])}}},je=()=>S(`div`,{class:`flex justify-center items-center py-8`},[S(fe,{size:`small`}),S(`span`,{class:`ml-2 text-gray-500`},`加载中...`)]),Me=()=>S(`div`,{class:`text-center py-8 text-gray-400`},`暂无数据`),Ne=e=>{if(!e.length)return[];let t=e[0];return!t||typeof t!=`object`?[]:[{title:`序号`,key:`_index`,width:60,render:(e,t)=>t+1},...Object.keys(t).filter(e=>![`id`,`key`].includes(e)).map(e=>({key:e,title:e.charAt(0).toUpperCase()+e.slice(1),width:120,ellipsis:{tooltip:!0}}))]},Pe=(e,t,n,r,i,a)=>{let o=[];return a.enableChildSelection&&o.push({type:`selection`,multiple:!0}),o.push(...Ne(t)),S(`div`,{class:`p-4 bg-gray-50`},[S(`div`,{class:`mb-2 text-sm text-gray-600`},`详细信息 (${t.length} 条)`),S(ae,{data:t,columns:o,size:`small`,striped:!0,checkedRowKeys:n?.selectedKeys||[],rowKey:e=>r.getChildRowKey(e),onUpdateCheckedRowKeys:a.enableChildSelection?t=>{i.handleChildSelectionChange(e,t)}:void 0})])},Fe=(e,t,n,r,i)=>{let a=a=>{let o=t.getRowKey(a),s=e.expandDataMap.value.get(o)||[],c=e.loadingMap.value.get(o)||!1;!s.length&&!c&&e.expandedKeys.value.includes(o)&&T(()=>{r.loadData(a)});let l=Ae(o,e,t,n,i);return i.renderContent?i.renderContent(a,s,c,l):c?je():s.length?Pe(o,s,l,t,n,i):Me()};return{getTableColumns:e=>e.map(e=>e.type===`selection`&&i.enableSelection?{type:`selection`,disabled:e=>!t.isRowCheckable(e),multiple:!i.maxSelection||i.maxSelection>1}:e.type===`expand`&&(i.onLoadData||i.renderContent)?{type:`expand`,expandable:t.isRowExpandable,renderExpand:a}:e)}};function Ie(e){let t=we(e),n=Te(e),r=Ee(t,n,e),i=De(t,n,e),a=ke(t,n,Oe(t,e),e),o=Fe(t,n,a,r,e);return e.onSelectionChange&&e.enableSelection&&F(()=>{if(!e.onSelectionChange)return;let r=n.data.value.filter(e=>t.checkedKeys.value.includes(n.getRowKey(e))),i=t.checkedKeys.value.length>0,a=n.data.value.length>0;(i||!a)&&e.onSelectionChange(t.checkedKeys.value,r,t.childSelections.value)}),e.defaultExpandedKeys?.length&&T(async()=>{let i=e.defaultExpandedKeys||[];if(i.length===0)return;let a=i.map(async e=>{let i=n.findRow(e);i&&!t.expandDataMap.value.has(e)&&await r.loadData(i)});await Promise.allSettled(a)}),{expandedKeys:t.expandedKeys,checkedKeys:t.checkedKeys,childSelections:t.childSelections,selectedRowsCount:i.selectedRowsCount,totalChildSelections:a.totalChildSelections,expandAll:r.expandAll,collapseAll:r.collapseAll,expandRow:async i=>{if(t.expandedKeys.value.includes(i))return;let a=n.findRow(i);a&&(await r.loadData(a),t.expandedKeys.value=[...t.expandedKeys.value,i],e.onExpandChange?.(t.expandedKeys.value,a,!0))},handleExpandChange:r.handleExpandChange,selectAll:i.selectAll,clearSelection:i.clearSelection,clearAllSelections:a.clearAllSelections,handleSelectionChange:i.handleSelectionChange,getTableColumns:o.getTableColumns,expandDataMap:t.expandDataMap,loadingMap:t.loadingMap}}const Le={text:`Robot Admin`,textSize:16,textColor:`rgba(128, 128, 128, 0.3)`,font:`Microsoft JhengHei`,opacity:.3,rotate:-20,position:`repeat`,xGap:200,yGap:120},Re={scale:1,quality:.92,format:`png`,backgroundColor:`#ffffff`,logging:!1,allowTaint:!0,useCORS:!0},ze={orientation:`portrait`,paperSize:`A4`,margin:`10mm 10mm 0 10mm`,style:`@page { margin: 10mm 10mm 0 10mm; } @media print { body { margin: 0; } }`,header:``,footer:``,showModal:!1,modalMessage:`正在准备打印...`,onLoadingStart:()=>{},onLoadingEnd:()=>{},onPrintDialogClose:()=>{}};function Be(e,t,n,r){e.save(),e.translate(t/2,n/2),e.rotate(r.rotate*Math.PI/180),e.fillText(r.text,0,0),e.restore()}function Ve(e,t,n,r){[[50,50],[t-50,50],[50,n-50],[t-50,n-50]].forEach(([t,n])=>{e.save(),e.translate(t,n),e.rotate(r.rotate*Math.PI/180),e.fillText(r.text,0,0),e.restore()})}function He(e,t,n,r){let i=Math.sqrt(t*t+n*n),a=t/2,o=n/2;e.save(),e.translate(a,o),e.rotate(Math.atan2(n,t));let s=Math.floor(i/r.xGap),c=-i/2;for(let t=0;t<=s;t++){let n=c+t*r.xGap;e.fillText(r.text,n,0)}e.restore()}function Ue(e,t,n,r){let i=Math.ceil(t/r.xGap)+1,a=Math.ceil(n/r.yGap)+1;for(let t=0;t<a;t++)for(let n=0;n<i;n++){let i=n*r.xGap+r.xGap/2,a=t*r.yGap+r.yGap/2;e.save(),e.translate(i,a),e.rotate(r.rotate*Math.PI/180),e.fillText(r.text,0,0),e.restore()}}function Y(e,t){let n=e.getContext(`2d`);if(!n)return e;let r={...Le,...t},{width:i,height:a}=e;n.save(),n.globalAlpha=r.opacity,n.font=`${r.textSize}px ${r.font}`,n.fillStyle=r.textColor,n.textAlign=`center`,n.textBaseline=`middle`;let o={center:Be,corner:Ve,diagonal:He,repeat:Ue};return(o[r.position]||o.repeat)(n,i,a,r),n.restore(),e}async function X(e,t={}){let n={...Re,...t};return await re(e,{logging:n.logging,scale:n.scale,allowTaint:n.allowTaint,useCORS:n.useCORS,backgroundColor:n.backgroundColor,onclone:e=>{let t=e.body;t.style.transform=`scale(1)`}})}function Z(e,t=`png`,n=.92){let r=`image/${t}`;return t===`png`?e.toDataURL(r):e.toDataURL(r,n)}function We(e,t=`screenshot-${new Date().toISOString().slice(0,10)}.png`,n=`png`){let r=Z(e,n),i=document.createElement(`a`);i.download=t,i.href=r,document.body.appendChild(i),i.click(),document.body.removeChild(i)}let Ge=null;function Ke(){Ge=setInterval(()=>{window.dispatchEvent(new Event(`focus`))},500)}function qe(){Ge&&=(clearInterval(Ge),null)}function Q(e,t={}){let n={...ze,...t};return new Promise((t,r)=>{try{Ke(),n.onLoadingStart?.(),W({printable:e,type:`image`,style:n.style,showModal:n.showModal,modalMessage:n.modalMessage,onLoadingEnd:n.onLoadingEnd,onPrintDialogClose:()=>{qe(),n.onPrintDialogClose?.(),t()}})}catch(e){qe(),r(e)}})}function Je(e,t,n){let r=0,i=0;e.forEach(e=>{let{width:n,height:a}=e;t===`horizontal`?(r+=n,i=Math.max(i,a)):(r=Math.max(r,n),i+=a)});let a=(e.length-1)*n;return t===`horizontal`?r+=a:i+=a,{totalWidth:r,totalHeight:i}}function Ye(e,t){let{orientation:n,spacing:r,backgroundColor:i,totalWidth:a,totalHeight:o}=t,s=document.createElement(`canvas`);s.width=a,s.height=o;let c=s.getContext(`2d`);if(!c)throw Error(`无法创建画布上下文`);c.fillStyle=i,c.fillRect(0,0,a,o);let l=0,u=0;return e.forEach(e=>{c.drawImage(e,l,u),n===`horizontal`?l+=e.width+r:u+=e.height+r}),s}function Xe(e,t,n){return e.length?{orientation:t.orientation||`vertical`,spacing:t.spacing||20,backgroundColor:t.backgroundColor||`#ffffff`}:(n.warning(`没有要打印的元素`),null)}async function Ze(e,t,n,r){let{orientation:i,spacing:a,backgroundColor:o}=n;r(10);let s=await Promise.all(e.map(e=>X(e,t.capture)));r(50);let{totalWidth:c,totalHeight:l}=Je(s,i,a);return r(60),Ye(s,{orientation:i,spacing:a,backgroundColor:o,totalWidth:c,totalHeight:l})}async function Qe(e,t,n,r,i){r(70),t.watermark&&Y(e,t.watermark),r(90),await Q(Z(e,t.capture?.format,t.capture?.quality),t.print),r(100),i.success(`合并打印完成,共合并 ${n} 个元素`)}function $e(){let e;try{e=f()}catch{e={success:e=>console.log(`[PrintWatermark]`,e),error:e=>console.error(`[PrintWatermark]`,e),warning:e=>console.warn(`[PrintWatermark]`,e)}}let t=A(!1),n=A(0),r=e=>{n.value=Math.max(0,Math.min(100,e))},i=async(e,t={})=>{try{r(0),r(30);let n=await X(e,t.capture);r(60),t.watermark&&Y(n,t.watermark),r(90);let i=Z(n,t.capture?.format||`png`,t.capture?.quality||.92);return r(100),i}catch(e){throw console.error(`截图失败:`,e),Error(`截图失败: ${e instanceof Error?e.message:`未知错误`}`)}},a=async(n,a={})=>{t.value=!0,r(0);try{await T();let t=await i(n,a);r(95),await Q(t,a.print),r(100),e.success(`打印完成`)}catch(t){throw console.error(`打印失败:`,t),e.error(`打印失败: ${t instanceof Error?t.message:`未知错误`}`),t}finally{t.value=!1,r(0)}},o=async(n,r,i={})=>{t.value=!0;try{await T();let t=await X(n,i.capture);i.watermark&&Y(t,i.watermark);let a=i.capture?.format||`png`,o=`screenshot-${new Date().toISOString().slice(0,19).replace(/:/g,`-`)}.${a}`;We(t,r||o,a),e.success(`下载完成`)}catch(t){throw console.error(`下载失败:`,t),e.error(`下载失败`),t}finally{t.value=!1}},s=async(e,t=`Robot Admin`)=>a(e,{watermark:{text:t,position:`repeat`,textColor:`rgba(128, 128, 128, 0.3)`}}),c=async(e,t={})=>{let n=e.length;r(10);let a=e.map(async(e,a)=>{let o=await i(e,t);return r(10+(a+1)/n*70),o});return Promise.all(a)},l=async(e,t={})=>{await e.reduce(async(n,r,i)=>{await n,await Q(r,t),i<e.length-1&&await new Promise(e=>{setTimeout(()=>e(),1e3)})},Promise.resolve())};return{loading:t,progress:n,captureWithWatermark:i,printWithWatermark:a,downloadScreenshot:o,quickPrint:s,batchCapture:c,batchPrint:async(n,i={})=>{if(!n.length){e.warning(`没有要打印的元素`);return}t.value=!0;try{r(0);let t=await c(n,i);r(80),await l(t,i.print),r(100),e.success(`批量打印完成,共 ${n.length} 个元素`)}catch(t){throw console.error(`批量打印失败:`,t),e.error(`批量打印失败`),t}finally{t.value=!1,r(0)}},mergePrint:async(n,i={},a={})=>{let o=Xe(n,a,e);if(o){t.value=!0;try{await Qe(await Ze(n,i,o,r),i,n.length,r,e)}catch(t){throw console.error(`合并打印失败:`,t),e.error(`合并打印失败`),t}finally{t.value=!1,r(0)}}},createPreset:(e,t)=>({use:e=>a(e,t),download:(e,n)=>o(e,n,t)}),updateProgress:r,utils:{captureElement:X,drawWatermark:Y,canvasToDataURL:Z,downloadCanvas:We,printImage:Q}}}const et={table:{watermark:{text:`Robot Admin - 数据表格`,position:`repeat`,textColor:`rgba(100, 100, 100, 0.25)`,textSize:14,xGap:250,yGap:120},capture:{scale:1.2},print:{orientation:`landscape`,style:`@page { margin: 8mm; } body { font-family: Arial, sans-serif; }`}},form:{watermark:{text:`Robot Admin - 表单数据`,position:`diagonal`,textColor:`rgba(150, 150, 150, 0.2)`,textSize:16},print:{orientation:`portrait`}},report:{watermark:{text:`Robot Admin - 机密报告`,position:`center`,textColor:`rgba(200, 50, 50, 0.15)`,textSize:24},capture:{quality:.95,format:`png`}}};function tt(){return`row_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}function nt(e,t){return typeof t==`function`?t(e):e[t]}function rt(e,t){let n=e?.()||{},r=typeof t==`string`?t:`id`;return{...n,[r]:tt()}}function it(t,n={}){let r=pe(),i={rowKey:`id`,enableRadioSelection:!0,enableAdd:!0,enableInsert:!0,enableDelete:!0,enableCopy:!0,enableMove:!0,enablePrint:!0,confirmDelete:!0,deleteConfirmText:`确定要删除选中的行吗?此操作不可撤销。`,printPreset:`table`,printTargetSelector:`.c-table-wrapper`,defaultRowData:()=>({}),...n},a=A(null),o=A(!1),s=m(()=>a.value===null?null:t.value.find(e=>nt(e,i.rowKey)===a.value)||null),c=m(()=>s.value?t.value.findIndex(e=>e===s.value):-1),l=m(()=>c.value>0),u=m(()=>c.value>=0&&c.value<t.value.length-1),{loading:d,progress:f,printWithWatermark:p,downloadScreenshot:h,quickPrint:g}=$e(),_=()=>{if(i.printOptions)return i.printOptions;let e=et[i.printPreset||`table`];return i.printWatermarkText&&e.watermark?{...e,watermark:{...e.watermark,text:i.printWatermarkText}}:e},v=e=>{t.value=e,i.onRowChange?.(e)},y=()=>{if(!i.enableAdd)return;let e=rt(i.defaultRowData,i.rowKey);v([...t.value,e]),i.onRowAdd?.(e),r.success(`添加行成功`)},b=()=>{if(!i.enableInsert||!s.value){r.warning(`请先选择一行数据`);return}let e=rt(i.defaultRowData,i.rowKey),n=[...t.value];n.splice(c.value+1,0,e),v(n),i.onRowAdd?.(e),r.success(`插入行成功`)},x=()=>{if(!i.enableDelete||!s.value){r.warning(`请先选择要删除的行`);return}i.confirmDelete?o.value=!0:C()},C=()=>{if(!s.value)return;let e=s.value,n=c.value;v(t.value.filter((e,t)=>t!==n)),a.value=null,i.onSelectionChange?.(null,null),i.onRowDelete?.(e,n),r.success(`删除行成功`),o.value=!1},w=()=>{if(!i.enableCopy||!s.value){r.warning(`请先选择要复制的行`);return}let e=s.value,n=typeof i.rowKey==`string`?i.rowKey:`id`,{[n]:a,...o}=e,c={...o,[n]:tt()};v([...t.value,c]),i.onRowCopy?.(e,c),r.success(`复制行成功`)},T=()=>{if(!i.enableMove||!l.value)return;let e=c.value,n=[...t.value],a=n[e];[n[e],n[e-1]]=[n[e-1],n[e]],v(n),i.onRowMove?.(a,e,e-1),r.success(`行已上移`)},E=()=>{if(!i.enableMove||!u.value)return;let e=c.value,n=[...t.value],a=n[e];[n[e],n[e+1]]=[n[e+1],n[e]],v(n),i.onRowMove?.(a,e,e+1),r.success(`行已下移`)},D=e=>{let n=t.value.find(t=>nt(t,i.rowKey)===e);n&&(a.value=e,i.onSelectionChange?.(e,n))},ee=()=>{a.value=null,i.onSelectionChange?.(null,null)},k=async e=>{if(!e.value){r.error(`打印元素未找到`);return}let t=_();await p(e.value,t)};return O(()=>{a.value=null,o.value=!1}),{selectedRowKey:a,selectedRowData:s,selectedRowIndex:c,canMoveUp:l,canMoveDown:u,deleteConfirmVisible:o,printLoading:d,printProgress:f,addRow:y,insertRow:b,deleteRow:x,confirmDelete:C,copyRow:w,moveRowUp:T,moveRowDown:E,selectRow:D,clearSelection:ee,handlePrint:k,handleDownload:async(e,t)=>{if(!e.value){r.error(`下载元素未找到`);return}let n=_();await h(e.value,t,n)},handleQuickPrint:async e=>{if(!e.value){r.error(`打印元素未找到`);return}let t=i.printWatermarkText||`Robot Admin`;await g(e.value,t)},enhanceColumns:e=>{let t=[...e];return i.enableRadioSelection&&t.unshift({key:`_radio_selection`,title:`选择`,width:80,align:`center`,editable:!1,render:e=>{let t=nt(e,i.rowKey);return S(`div`,{class:`flex justify-center`},[S(`input`,{type:`radio`,name:`table-radio-selection`,checked:a.value===t,class:`cursor-pointer accent-blue-500 scale-110`,onChange:e=>{e.target.checked&&D(t)}})])}}),t},renderToolbar:()=>{let t=[];i.enablePrint&&t.push(S(L,{loading:d.value,type:`primary`,ghost:!0,onClick:async()=>{try{let e=document.querySelector(i.printTargetSelector);e?await k(A(e)):console.warn(`未找到表格容器元素`)}catch(e){console.error(`打印失败:`,e)}}},{icon:()=>S(e,{name:`mdi:printer`,title:`打印`}),default:()=>`打印`}));let n=[];return i.enableAdd&&n.push(S(L,{onClick:y,type:`primary`},{icon:()=>S(e,{name:`mdi:plus`,title:`增行`}),default:()=>`增行`})),i.enableInsert&&n.push(S(U,{disabled:!!s.value},{trigger:()=>S(L,{onClick:b,disabled:!s.value,type:`primary`,ghost:!0},{icon:()=>S(e,{name:`mdi:table-row-plus-after`,title:`插行`}),default:()=>`插行`}),default:()=>`请先选择一行数据`})),i.enableDelete&&n.push(S(U,{disabled:!!s.value},{trigger:()=>S(L,{onClick:x,disabled:!s.value,type:`error`,ghost:!0},{icon:()=>S(e,{name:`mdi:delete`,title:`删除行`}),default:()=>`删除行`}),default:()=>`请先选择要删除的行`})),i.enableCopy&&n.push(S(U,{disabled:!!s.value},{trigger:()=>S(L,{onClick:w,disabled:!s.value,type:`info`,ghost:!0},{icon:()=>S(e,{name:`mdi:content-copy`,title:`复制行`}),default:()=>`复制行`}),default:()=>`请先选择要复制的行`})),i.enableMove&&n.push(S(U,{disabled:l.value},{trigger:()=>S(L,{onClick:T,disabled:!l.value,type:`warning`,ghost:!0},{icon:()=>S(e,{name:`mdi:arrow-up`,title:`上移`}),default:()=>`上移`}),default:()=>s.value?`已经是第一行`:`请先选择数据`}),S(U,{disabled:u.value},{trigger:()=>S(L,{onClick:E,disabled:!u.value,type:`warning`,ghost:!0},{icon:()=>S(e,{name:`mdi:arrow-down`,title:`下移`}),default:()=>`下移`}),default:()=>s.value?`已经是最后一行`:`请先选择数据`})),n.length>0&&t.push(S(R,{},()=>n)),S(`div`,{class:`dynamic-rows-toolbar mb-4 flex justify-end`},[S(de,{},()=>t)])},renderConfirmModal:()=>S(le,{show:o.value,"onUpdate:show":e=>{o.value=e},preset:`dialog`,title:`确认删除`,content:i.deleteConfirmText,positiveText:`确认删除`,negativeText:`取消`,onPositiveClick:C})}}function at(e){let{config:t,data:n,rowKey:r,emit:i}=e,a={onSave:async(e,t,r)=>{if(!e||t<0||t>=n().length)return;let a=[...n()];a[t]={...a[t],...e},i(`update:data`,a),await T(),i(`save`,a[t],t,r)},onCancel:(e,t)=>{i(`cancel`,e,t)},onExpandChange:(e,t,n)=>{i(`expand-change`,e,t,n)},onSelectionChange:(e,t,n)=>{i(`selection-change`,e,t,n)},onChildSelectionChange:(e,t,n)=>{i(`child-selection-change`,e,t,n)},onRowChange:e=>{i(`update:data`,e),t.dynamicRows?.onRowChange?.(e)},onRowSelectionChange:(e,n)=>{i(`row-selection-change`,e,n),t.dynamicRows?.onSelectionChange?.(e,n)},onRowAdd:e=>{i(`row-add`,e),t.dynamicRows?.onRowAdd?.(e)},onRowDelete:(e,n)=>{i(`row-delete`,e,n),t.dynamicRows?.onRowDelete?.(e,n)},onRowCopy:(e,n)=>{i(`row-copy`,e,n),t.dynamicRows?.onRowCopy?.(e,n)},onRowMove:(e,n,r)=>{i(`row-move`,e,n,r),t.dynamicRows?.onRowMove?.(e,n,r)}},o=()=>({rowEdit:xe({data:n,rowKey:r,onSave:a.onSave,onCancel:a.onCancel}),cellEdit:Se({data:n,rowKey:r,onSave:a.onSave}),modalEdit:Ce({data:n,rowKey:r,onSave:a.onSave,onCancel:a.onCancel})}),s=()=>t.expandable||t.enableSelection||t.enableChildSelection?Ie({data:m(()=>n()),rowKey:r,childRowKey:e=>e.id,defaultExpandedKeys:t.defaultExpandedKeys,onLoadData:t.onLoadExpandData,renderContent:t.renderExpandContent,rowExpandable:t.rowExpandable,enableSelection:t.enableSelection,defaultCheckedKeys:t.defaultCheckedKeys,rowCheckable:t.rowCheckable,maxSelection:t.maxSelection,enableChildSelection:t.enableChildSelection,childRowCheckable:t.childRowCheckable,enableParentChildLink:t.enableParentChildLink,parentChildLinkMode:t.parentChildLinkMode,onExpandChange:a.onExpandChange,onSelectionChange:a.onSelectionChange,onChildSelectionChange:a.onChildSelectionChange}):null,c=()=>{if(!t.dynamicRows)return null;let e={...t.dynamicRows,onRowChange:a.onRowChange,onSelectionChange:a.onRowSelectionChange,onRowAdd:a.onRowAdd,onRowDelete:a.onRowDelete,onRowCopy:a.onRowCopy,onRowMove:a.onRowMove};return it(m(()=>n()),e)},l=o(),u=s(),d=c();return{editStates:l,expandState:u,dynamicRowsState:d,stateManager:{edit:{start(e,n){let r=t.editMode;r===`modal`?l.modalEdit.startEdit(e):r===`cell`&&n?l.cellEdit.startEditCell(e,n):(r===`row`||r===`both`)&&l.rowEdit.startEditRow(e)},cancel(){l.modalEdit.isModalVisible.value?l.modalEdit.cancelEdit():l.cellEdit.editingCell.value.rowKey?l.cellEdit.cancelEditCell():l.rowEdit.editingRowKey.value&&l.rowEdit.cancelEditRow()},async save(){l.modalEdit.isModalVisible.value?await l.modalEdit.saveEdit():l.cellEdit.editingCell.value.rowKey?await l.cellEdit.saveEditCell():l.rowEdit.editingRowKey.value&&await l.rowEdit.saveEditRow()},isEditing(e,n){return t.editMode===`modal`?l.modalEdit.isEditingRow(e):n?l.cellEdit.isEditingCell(e,n):l.rowEdit.isEditingRow(e)},getEditingData(){return l.modalEdit.isModalVisible.value?l.modalEdit.editingData:l.rowEdit.editingRowKey.value?l.rowEdit.getEditingRowData(l.rowEdit.editingRowKey.value):null}},expand:{async row(e){if(u){let t=[...u.expandedKeys.value];t.includes(e)||(t.push(e),u.handleExpandChange(t))}},collapse(e){if(u){let t=u.expandedKeys.value.filter(t=>t!==e);u.handleExpandChange(t)}},async toggle(e){u?.expandedKeys.value.includes(e)?this.collapse(e):await this.row(e)},async all(){await u?.expandAll()},collapseAll(){u?.collapseAll()},isExpanded(e){return u?.expandedKeys.value.includes(e)??!1}},selection:{select(e){if(u?.checkedKeys.value&&!u.checkedKeys.value.includes(e)){let t=[...u.checkedKeys.value,e];u.handleSelectionChange(t)}},unselect(e){if(u?.checkedKeys.value){let t=u.checkedKeys.value.filter(t=>t!==e);u.handleSelectionChange(t)}},all(){u?.selectAll()},clear(){u?.clearSelection()},isSelected(e){return u?.checkedKeys.value.includes(e)??!1},getSelected(){return u?.checkedKeys.value?n().filter(e=>u.checkedKeys.value.includes(r(e))):[]}},childSelection:{select(e,t){if(u?.childSelections.value){let n=u.childSelections.value.get(e)||[];if(!n.includes(t)){let r=[...n,t];u.childSelections.value.set(e,r),i(`child-selection-change`,e,r,[])}}},unselect(e,t){if(u?.childSelections.value){let n=(u.childSelections.value.get(e)||[]).filter(e=>e!==t);u.childSelections.value.set(e,n),i(`child-selection-change`,e,n,[])}},selectAll(e){if(u?.childSelections.value&&u.expandDataMap?.value){let t=u.expandDataMap.value.get(e)||[],n=t.map(e=>e.id);u.childSelections.value.set(e,n),i(`child-selection-change`,e,n,t)}},clear(e){u?.childSelections.value&&(u.childSelections.value.set(e,[]),i(`child-selection-change`,e,[],[]))},getSelected(e){if(!u?.childSelections.value||!u.expandDataMap?.value)return[];let t=u.childSelections.value.get(e)||[];return(u.expandDataMap.value.get(e)||[]).filter(e=>t.includes(e.id))}},dynamicRows:{add(){d?.addRow()},insert(){d?.insertRow()},delete(){d?.deleteRow()},copy(){d?.copyRow()},moveUp(){d?.moveRowUp()},moveDown(){d?.moveRowDown()},clearSelection(){d?.clearSelection()},getSelected(){return d?.selectedRowData.value||null},async print(e){d&&e&&await d.handlePrint(A(e))},async download(e,t){d&&e&&await d.handleDownload(A(e),t)}},clearAllSelections(){u?.clearAllSelections()}},expandedKeys:m(()=>u?.expandedKeys.value??[]),checkedKeys:m(()=>u?.checkedKeys.value??[]),eventHandlers:a}}const $={enabled:!0,page:1,pageSize:10,showSizePicker:!0,showQuickJumper:!0,pageSizes:[10,20,50,100],simple:!1,size:`medium`};function ot(e){let{data:t,config:n,emit:r}=e,i=A(1),a=A(10),o=m(()=>typeof t==`function`?t()||[]:N(t)||[]),s=m(()=>{if(!n.value?.enabled)return o.value;let e=(i.value-1)*a.value,t=e+a.value;return o.value.slice(e,t)}),c=m(()=>n.value?.enabled?{page:i.value,pageSize:a.value,itemCount:o.value.length,showSizePicker:n.value.showSizePicker??$.showSizePicker,showQuickJumper:n.value.showQuickJumper??$.showQuickJumper,pageSizes:n.value.pageSizes??$.pageSizes,simple:n.value.simple??$.simple,size:n.value.size??$.size,prefix:e=>`共 ${e.itemCount} 条`,suffix:e=>`第 ${e.startIndex+1}-${e.endIndex} 条`,"onUpdate:page":l,"onUpdate:pageSize":u}:null),l=e=>{i.value=e,r?.(`pagination-change`,e,a.value)},u=e=>{a.value=e,i.value=1,r?.(`pagination-change`,1,e)};return F(()=>{n.value?.enabled&&(i.value=n.value.page??$.page,a.value=n.value.pageSize??$.pageSize)}),P(()=>o.value.length,e=>{if(n.value?.enabled&&i.value>1){let t=Math.ceil(e/a.value);i.value>t&&(i.value=Math.max(1,t))}}),{currentPage:i,currentPageSize:a,paginatedData:s,paginationConfig:c,handlePageChange:l,handlePageSizeChange:u,resetToFirstPage:()=>{i.value!==1&&l(1)},getTotalPages:()=>!n.value?.enabled||a.value===0?1:Math.ceil(o.value.length/a.value)}}function st(t){let{actions:n,config:i,tableManager:o,rowKey:s,emit:c,onViewDetail:u}=t,p=f(),m=d(),h=e=>n.value?.[e]!==!1,g=e=>e!==!1&&typeof e==`function`,_=e=>e&&typeof e==`object`&&`data`in e?e.data:e,v=(t,n,i=`primary`,a)=>S(r,{size:`small`,type:i,quaternary:!0,onClick:a},()=>[S(e,{name:t,size:14,title:n})]),y=(e,t)=>{let r=s(e),a=n.value?.edit;i.value.editMode===`modal`?o.editStates.modalEdit.startEdit(r,{...e},a):o.editStates.rowEdit.startEditRow(r,a)},b=async(e,t,n)=>{try{await e(t,n),p.success(`删除成功`),c(`row-delete`,t,n)}catch(e){throw console.error(`删除失败:`,e),p.error(`删除失败`),e}},x=(e,t)=>{let r=n.value?.delete;g(r)&&m.warning({title:`确认删除`,content:`确定要删除这条记录吗?`,positiveText:`确定`,negativeText:`取消`,onPositiveClick:()=>b(r,e,t)})},C=async(e,t)=>{let r=n.value?.detail;if(!g(r)){u?.(e);return}try{let n=_(await r(e,t));u?.(n||e)}catch(t){console.error(`获取详情失败:`,t),p.error(`获取详情失败`),u?.(e)}},w=e=>o.editStates.rowEdit.isEditingRow(e)?[v(`mdi:check`,`保存`,`primary`,()=>o.editStates.rowEdit.saveEditRow()),v(`mdi:close`,`取消`,`default`,()=>o.editStates.rowEdit.cancelEditRow())]:[v(`mdi:pencil`,`编辑`,`warning`,()=>o.editStates.rowEdit.startEditRow(e))],T=(e,t)=>{let n=[];return h(`detail`)&&n.push(v(`mdi:eye`,`详情`,`info`,()=>C(e,t))),i.value.editMode===`modal`&&(h(`edit`)||i.value.editable)&&n.push(v(`mdi:pencil`,`编辑`,`warning`,()=>y(e,t))),h(`delete`)&&n.push(v(`mdi:delete`,`删除`,`error`,()=>x(e,t))),n},E=(t,r)=>{let i=n.value?.custom;if(!i?.length)return null;let o=i.filter(e=>e.show?e.show(t,r):!0);return o.length?S(a,{options:o.map(n=>{let i=typeof n.label==`function`?n.label(t,r):n.label,a=typeof n.icon==`function`?n.icon(t,r):n.icon;return{label:i,key:n.key,icon:()=>S(e,{name:a,size:14}),disabled:n.disabled?.(t,r)||!1}}),onSelect:e=>{let n=o.find(t=>t.key===e);if(n)try{n.onClick(t,r)}catch(e){console.error(`操作"${n.label}"执行失败:`,e),p.error(`${n.label}失败`)}}},()=>v(`mdi:dots-horizontal`,`更多操作`,`default`,()=>{})):null};return{renderActions:(e,t)=>{if(n.value?.render)return n.value.render(e,t);let r=s(e),a=[`row`,`both`].includes(i.value.editMode);if(a&&o.editStates.rowEdit.isEditingRow(r))return S(l,{size:2,wrap:!1},()=>w(r));let c=[...a?w(r):[],...T(e,t)],u=E(e,t);return u&&c.push(u),S(l,{size:2,wrap:!1},()=>c)},isActionEnabled:h}}const ct={number:s,switch:u,input:o,email:o,mobile:o,date:e=>S(i,{...e,type:`date`,format:`yyyy-MM-dd`}),select:e=>S(c,{...e,options:e.options||[]}),textarea:e=>S(o,{...e,type:`textarea`,rows:3})},lt={number:`inputNumber`,date:`datePicker`,textarea:`textarea`,select:`select`,switch:`switch`},ut=e=>e.map(e=>{let t=e.required?[{required:!0,message:`请输入${e.title}`,trigger:[`blur`,`input`],validator:async(t,n)=>{if(!n&&n!==0&&n!==!1)throw Error(`请输入${e.title}`)}}]:[];return{prop:e.key,label:e.title||e.key,type:lt[e.editType||`input`]||`input`,placeholder:`请输入${e.title}`,rules:t,attrs:e.editProps||{},layout:{span:1},show:!0}});function dt(e,t,n){if(e.editRender)return e.editRender(t,{},0);let r=e,i={value:t,"onUpdate:value":n,placeholder:`请输入${r.title??``}`,style:{width:`100%`},...e.editProps};return S(ct[e.editType||`input`]||ct.input,i)}function ft(e,t,n,r){return e.render?e.render(t,n)??String(r??``):String(r??``)}function pt(t,n,r,i,a){let o=(t,n,r)=>S(`button`,{class:`cell-action-btn cell-action-${t}`,title:n,type:`button`,onClick:e=>{e.stopPropagation(),e.preventDefault(),r(e)}},[S(e,{name:`mdi:${t===`save`?`check`:`close`}`,title:t===`save`?`保存`:`取消`,size:12})]);return S(`div`,{class:`cell-editing-container`},[S(`div`,{class:`cell-editing-input`},[dt(t,n,r)]),S(`div`,{class:`cell-editing-actions`},[o(`save`,`保存`,i),o(`cancel`,`取消`,a)])])}function mt(t,n,r,i,a){return S(`div`,{class:`cell-edit-wrapper`},[S(`span`,{class:`cell-value`},t.render?t.render(n,r)??String(i??``):String(i??``)),S(e,{name:`mdi:square-edit-outline`,title:`编辑`,class:`cell-edit-icon`,size:14,clickable:!0,onClick:e=>{e.stopPropagation(),a()}})])}function ht(e){let{rawColumns:t,config:n,columnWidth:r,rowKey:i,tableManager:a,actionsRenderer:o,editModeChecker:s}=e,c=A([]),l=A(!1),u=e=>{let t=c.value.find(e=>e.key===`_actions`);c.value=[...e,t||{key:`_actions`,title:`操作`,width:180,editable:!1,visible:!0,fixed:`right`}]};P(t,e=>{e?.length&&u(e)},{deep:!0,immediate:!0});let d=(e,t,n,r)=>{let i=e.key??``,o=t[i],{isEditingCell:s,getEditingCellValue:c,updateEditingCellValue:l,saveEditCell:u,cancelEditCell:d,startEditCell:f}=a.editStates.cellEdit;return s(r,i)?pt(e,c(r,i)??o,e=>l(r,i,e),()=>u(),()=>d()):mt(e,t,n,o,()=>f(r,i))},f=(e,t,n)=>{let r=e.key??``,o=t[r],c=i(t),l=s.value;return l.isNonEditable(e)?ft(e,t,n,o):l.isRowEditMode()&&a.editStates.rowEdit.isEditingRow(c)?dt(e,a.editStates.rowEdit.getEditingRowData(c)?.[r]??o,e=>a.editStates.rowEdit.updateEditingRowData(c,r,e)):l.isCellEditMode()?d(e,t,n,c):ft(e,t,n,o)},p=e=>{let t=e.width||r||180;return typeof t==`number`?t:180},h=e=>{let t=e;return{key:`_index`,title:t.title||`序号`,width:typeof(t.width||50)==`number`&&t.width||50,titleAlign:`center`,align:`center`,render:(e,t)=>t+1,fixed:e.fixed}},g=e=>{let t=e,n={...t,width:p(e),titleAlign:t.titleAlign||`center`,align:t.align||`center`,render:e.render||((t,n)=>f(e,t,n))};return e.fixed&&(n.fixed=e.fixed),e.resizable&&typeof n.width==`number`&&(n.resizable=!0,n.minWidth=e.minWidth||80,n.maxWidth=e.maxWidth||500),n};return{reactiveColumns:c,showSettingsPanel:l,computedColumns:m(()=>{let e=c.value.filter(e=>{let t=e;return t.visible!==!1&&t.key!==`_actions`}).map(e=>e.type===`index`?h(e):g(e));a.dynamicRowsState&&(e=a.dynamicRowsState.enhanceColumns(e)),a.expandState&&(n.value.expandable||n.value.enableSelection)&&(e=a.expandState.getTableColumns(e));let t=c.value.find(e=>e.key===`_actions`);return e.push({key:`_actions`,title:`操作`,align:`center`,titleAlign:`center`,render:o,fixed:t?.fixed}),e}),computedScrollX:m(()=>{if(e.scrollX!==void 0)return e.scrollX;if(c.value.some(e=>{let t=e;return t.fixed&&t.visible!==!1}))return c.value.filter(e=>e.visible!==!1).reduce((e,t)=>e+p(t),0)+200}),handleColumnChange:e=>{c.value=e.map(e=>{let t=e;return{...e,visible:t.visible!==!1,fixed:e.fixed,width:t.width||r,align:t.align||`center`,titleAlign:t.titleAlign||`center`}})}}}const gt=e=>[{label:e.fixed?`✓ 取消固定`:`不固定`,key:`none`,disabled:!e.fixed},{label:e.fixed===`left`?`✓ 固定左侧`:`固定左侧`,key:`left`,disabled:!1},{label:e.fixed===`right`?`✓ 固定右侧`:`固定右侧`,key:`right`,disabled:!1}],_t=[`_actions`],vt=[`selection`,`expand`],yt=e=>_t.includes(e.key)||vt.includes(e.type),bt={class:`column-management-tab`},xt={class:`search-row`},St={class:`resizable-control`},Ct={class:`top-actions-bar`},wt={class:`stats-info`},Tt={class:`quick-actions`},Et=[`draggable`,`onDragstart`,`onDragover`,`onDrop`],Dt={class:`column-info`},Ot={class:`column-controls`},kt={class:`column-details`},At={class:`column-actions`},jt={class:`drag-controls`};var Mt=t(x({name:`ColumnSettings`,__name:`index`,props:{columns:{}},emits:[`change`],setup(t,{emit:n}){let r=t,i=n,a=A([...r.columns]),o=A(``),s=A(),c=A(null),l=A(null),u=A(!1);ee(()=>{u.value=a.value.some(e=>e.resizable===!0)});let d=m(()=>{if(!o.value)return a.value;let e=o.value.toLowerCase();return a.value.filter(t=>t.title?.toLowerCase().includes(e)||t.key.toLowerCase().includes(e))}),f=m(()=>a.value.filter(e=>e.visible!==!1).length),x=m(()=>a.value.length),S=e=>{a.value.forEach(t=>{t.key!==`_actions`&&(t.visible=e)}),P()},C=()=>S(!0),w=()=>S(!1),T=e=>{let t=d.value[e];return a.value.findIndex(e=>e.key===t.key)},O=(e,t)=>{let n=T(e);n!==-1&&(t(a.value[n]),P())},te=(e,t)=>{O(e,e=>{e.visible=t})},ne=(e,t)=>{O(e,e=>{e.fixed=t===`none`?void 0:t})},P=()=>i(`change`,[...a.value]),F=()=>{a.value=[...r.columns],P()},re=e=>{a.value.forEach(t=>{yt(t)||(t.resizable=e,e&&(t.minWidth=t.minWidth||80,t.maxWidth=t.maxWidth||500))}),P()},R=(e,t)=>{let n=T(e),r=T(t);if(n!==-1&&r!==-1){let[e]=a.value.splice(n,1);a.value.splice(r,0,e),P()}},ae=(e,t)=>{if(d.value[e].key===`_actions`){t.preventDefault();return}c.value=e,t.dataTransfer&&(t.dataTransfer.effectAllowed=`move`)},oe=(e,t)=>{t.preventDefault(),!(c.value===null||d.value[e].key===`_actions`)&&(l.value=e,t.dataTransfer&&(t.dataTransfer.dropEffect=`move`))},se=e=>{c.value===null||d.value[e].key===`_actions`||(R(c.value,e),c.value=null,l.value=null)},le=()=>{c.value=null,l.value=null};return(t,n)=>(k(),_(`div`,bt,[g(` 搜索框和列宽调整开关 `),v(`div`,xt,[b(N(z),{value:o.value,"onUpdate:value":n[0]||=e=>o.value=e,placeholder:`搜索列名...`,clearable:``,class:`search-input`},{prefix:I(()=>[b(e,{name:`mdi:magnify`})]),_:1},8,[`value`]),v(`div`,St,[b(e,{name:`mdi:arrow-split-vertical`,size:`14`,title:u.value?`开启后可拖拽列边界调整宽度`:`允许调整列宽`},null,8,[`title`]),b(N(H),{style:{fontSize:`12px`,marginLeft:`4px`}},{default:I(()=>n[2]||=[y(` 列宽调整 `,-1)]),_:1,__:[2]}),b(N(B),{value:u.value,"onUpdate:value":[n[1]||=e=>u.value=e,re],size:`small`,style:{"margin-left":`6px`}},null,8,[`value`])])]),g(` 顶部操作栏:统计信息和快捷操作按钮 `),v(`div`,Ct,[v(`div`,wt,[b(N(H),{depth:`3`,style:{fontSize:`13px`}},{default:I(()=>[y(` 已选 `+M(f.value)+` / 总共 `+M(x.value)+` 列 `,1)]),_:1})]),v(`div`,Tt,[b(N(de),{size:6},{default:I(()=>[b(N(L),{size:`tiny`,onClick:C},{default:I(()=>n[3]||=[y(` 全选 `,-1)]),_:1,__:[3]}),b(N(L),{size:`tiny`,onClick:w},{default:I(()=>n[4]||=[y(` 全不选 `,-1)]),_:1,__:[4]}),b(N(L),{size:`tiny`,onClick:F},{default:I(()=>n[5]||=[y(` 重置 `,-1)]),_:1,__:[5]})]),_:1})])]),g(` 列列表 `),v(`div`,{ref_key:`listRef`,ref:s,class:`column-list`},[(k(!0),_(p,null,j(d.value,(t,r)=>(k(),_(`div`,{key:t.key,class:E([`column-item`,{disabled:t.key===`_actions`,"fixed-left":t.fixed===`left`,"fixed-right":t.fixed===`right`}]),draggable:t.key!==`_actions`,onDragstart:e=>ae(r,e),onDragover:e=>oe(r,e),onDragend:le,onDrop:e=>se(r)},[v(`div`,Dt,[v(`div`,Ot,[b(e,{name:`mdi:drag`,size:`16`,class:E([`drag-handle`,{disabled:t.key===`_actions`}])},null,8,[`class`]),b(N(ie),{checked:t.visible!==!1,disabled:t.key===`_actions`,"onUpdate:checked":e=>te(r,e)},null,8,[`checked`,`disabled`,`onUpdate:checked`])]),v(`div`,kt,[b(N(de),{align:`center`,size:6},{default:I(()=>[b(N(H),{strong:``,style:{fontSize:`13px`}},{default:I(()=>[y(M(t.title||t.key),1)]),_:2},1024),t.fixed===`left`?(k(),h(N(V),{key:0,size:`tiny`,type:`info`},{default:I(()=>n[6]||=[y(` 左固定 `,-1)]),_:1,__:[6]})):g(`v-if`,!0),t.fixed===`right`?(k(),h(N(V),{key:1,size:`tiny`,type:`warning`},{default:I(()=>n[7]||=[y(` 右固定 `,-1)]),_:1,__:[7]})):g(`v-if`,!0)]),_:2},1024),b(N(H),{depth:`3`,style:{fontSize:`11px`}},{default:I(()=>[y(M(t.key),1)]),_:2},1024)])]),v(`div`,At,[v(`div`,jt,[b(e,{name:`mdi:chevron-up`,size:`14`,title:`上移`,clickable:r!==0,class:E({disabled:r===0}),onClick:e=>r!==0&&R(r,r-1)},null,8,[`clickable`,`class`,`onClick`]),b(e,{name:`mdi:chevron-down`,size:`14`,title:`下移`,clickable:r!==d.value.length-1,class:E({disabled:r===d.value.length-1}),onClick:e=>r!==d.value.length-1&&R(r,r+1)},null,8,[`clickable`,`class`,`onClick`])]),b(N(ce),{options:N(gt)(t),onSelect:e=>ne(r,e)},{default:I(()=>[b(e,{name:`mdi:pin`,size:`14`,title:`固定列`,clickable:``,style:D({color:t.fixed?`var(--n-primary-color)`:void 0})},null,8,[`style`])]),_:2},1032,[`options`,`onSelect`])])],42,Et))),128))],512)]))}}),[[`__scopeId`,`data-v-a4d013ea`]]);const Nt={class:`c-table-wrapper`},Pt={key:1,class:`table-toolbar`},Ft={class:`toolbar-left`},It={class:`toolbar-right`};var Lt=t(x({name:`C_Table`,inheritAttrs:!1,__name:`index`,props:{columns:{},data:{},loading:{default:void 0},rowKey:{type:Function,default:e=>e.id},config:{default:()=>({})},crud:{}},emits:[`pagination-change`,`row-delete`,`expand-change`,`selection-change`,`child-selection-change`,`parent-child-link-change`,`update:data`,`save`,`cancel`,`row-add`,`row-copy`,`row-move`,`row-selection-change`,`view-detail`,`column-change`],setup(t,{expose:r,emit:i}){let a=t,o=i,s=(e,...t)=>{o(e,...t),a.crud&&{save:a.crud.save,cancel:a.crud.handleCancel,"pagination-change":a.crud.handlePaginationChange,"row-delete":a.crud.handleRowDelete,"view-detail":a.crud.detail?.show}[e]?.(...t)},c=m(()=>{if(!a.crud)return a.config||{};let e={};return a.crud.actions&&(e.actions=a.crud.actions.value),a.crud.pagination&&(e.pagination=a.crud.pagination.value),{...e,...a.config}}),l=m(()=>a.columns??a.crud?.columns.value??[]),u=m(()=>ye(c.value)),d=m(()=>be(u.value)),f=e=>e&&typeof e==`object`&&`value`in e?e.value:e,p=m(()=>f(a.data)??a.crud?.data.value??[]),x=A(!1);F(()=>{let e=a.loading;if(e!==void 0){x.value=e&&typeof e==`object`&&`value`in e?!!e.value:!!e;return}let t=a.crud?.loading;if(t!==void 0){x.value=t&&typeof t==`object`&&`value`in t?!!t.value:!!t;return}x.value=!1});let S=ot({data:p,config:m(()=>u.value.pagination),emit:s}),T=at({config:u.value,data:()=>p.value,rowKey:a.rowKey,emit:s}),E=st({actions:m(()=>c.value.actions||{}),config:u,tableManager:T,rowKey:a.rowKey,emit:s,onViewDetail:e=>s(`view-detail`,e)}),D=ht({rawColumns:l,config:u,columnWidth:u.value.columnWidth,scrollX:u.value.scrollX,rowKey:a.rowKey,tableManager:T,actionsRenderer:E.renderActions,editModeChecker:d}),{showSettingsPanel:j,reactiveColumns:M,computedColumns:re,computedScrollX:R}=D,ie=A(),ce=m(()=>({striped:u.value.striped,bordered:u.value.bordered,singleLine:u.value.singleLine,size:u.value.size,maxHeight:u.value.maxHeight})),z=A(),fe=A(!1),B=A({}),V=m({get:()=>T.editStates.modalEdit.isModalVisible.value,set:e=>{T.editStates.modalEdit.isModalVisible.value=e}}),H=m(()=>l.value.filter(e=>e.editable!==!1)),U=m(()=>`edit-form-${T.editStates.modalEdit.editingRowKey.value||`new`}`),pe=m(()=>ut(H.value));P(()=>T.editStates.modalEdit.editingData.value,e=>{e&&Object.keys(e).length>0&&(B.value=JSON.parse(JSON.stringify(e)))},{immediate:!0,deep:!0});let W=null;P(V,e=>{e||(W=setTimeout(()=>{B.value={},W=null},300))});let me=async()=>{if(z.value){fe.value=!0;try{await z.value.validate(),await T.editStates.modalEdit.saveEdit(B.value)}catch{}finally{fe.value=!1}}},he=()=>{B.value={},T.editStates.modalEdit.cancelEdit()},ge=e=>{D.handleColumnChange(e),o(`column-change`,D.reactiveColumns.value)},{edit:G,expand:K,selection:q,dynamicRows:J}=T.stateManager,_e={startEdit:G.start,expandAll:K.all,collapseAll:K.collapseAll,selectAll:q.all,clearSelection:q.clear,clearAllSelections:T.stateManager.clearAllSelections,clearRowSelection:J?.clearSelection,resetToFirstPage:S.resetToFirstPage,getSelectedRows:q.getSelected,getEditingData:G.getEditingData,isEditing:G.isEditing,isExpanded:K.isExpanded,getManager:()=>T.stateManager};return r(_e),ee(()=>{let e=a.crud?.tableRef;e&&(e.value=_e)}),O(()=>{W&&clearTimeout(W)}),(t,r)=>(k(),_(`div`,Nt,[g(` 动态行工具栏 `),N(T).dynamicRowsState?(k(),h(ne(N(T).dynamicRowsState.renderToolbar()),{key:0})):g(`v-if`,!0),g(` 表格工具栏 `),u.value.showToolbar?(k(),_(`div`,Pt,[v(`div`,Ft,[te(t.$slots,`toolbar-left`,{},void 0,!0)]),v(`div`,It,[te(t.$slots,`toolbar-right`,{},void 0,!0),u.value.enableColumnSettings?(k(),h(e,{key:0,name:`mdi:cog`,size:`18`,title:`表格设置`,clickable:``,class:`column-settings-btn`,onClick:r[0]||=e=>j.value=!0})):g(`v-if`,!0)])])):g(`v-if`,!0),g(` 表格主体 `),b(N(ae),w({ref_key:`tableRef`,ref:ie},{...ce.value,...t.$attrs},{columns:N(re),data:p.value,loading:x.value,"row-key":t.rowKey,"expanded-row-keys":N(T).expandedKeys.value,"checked-row-keys":N(T).checkedKeys.value,"onUpdate:expandedRowKeys":N(T).expandState?.handleExpandChange,"onUpdate:checkedRowKeys":N(T).expandState?.handleSelectionChange,"scroll-x":N(R),style:{width:`100%`}}),null,16,[`columns`,`data`,`loading`,`row-key`,`expanded-row-keys`,`checked-row-keys`,`onUpdate:expandedRowKeys`,`onUpdate:checkedRowKeys`,`scroll-x`]),g(` 分页 `),N(S).paginationConfig.value?(k(),h(N(ue),w({key:2},N(S).paginationConfig.value,{class:`pagination-wrapper`}),null,16)):g(`v-if`,!0),g(` 编辑弹窗 `),u.value.editMode===`modal`||u.value.editMode===`both`?(k(),h(N(le),{key:3,show:V.value,"onUpdate:show":r[2]||=e=>V.value=e,title:u.value.modalTitle,width:u.value.modalWidth,preset:`card`,"mask-closable":!1,"close-on-esc":!1,class:`w60%`,closable:!1},{action:I(()=>[b(N(de),{justify:`end`},{default:I(()=>[b(N(L),{onClick:he},{default:I(()=>r[4]||=[y(`取消`,-1)]),_:1,__:[4]}),b(N(L),{type:`primary`,loading:fe.value,onClick:me},{default:I(()=>r[5]||=[y(` 保存 `,-1)]),_:1,__:[5]},8,[`loading`])]),_:1})]),default:I(()=>[V.value&&pe.value.length?(k(),h(n,{ref_key:`editFormRef`,ref:z,key:U.value,modelValue:B.value,"onUpdate:modelValue":r[1]||=e=>B.value=e,options:pe.value,config:{layout:`grid`,grid:{cols:2,xGap:16,yGap:16},showActions:!1}},null,8,[`modelValue`,`options`])):g(`v-if`,!0)]),_:1},8,[`show`,`title`,`width`])):g(`v-if`,!0),g(` 动态行确认删除弹窗 `),N(T).dynamicRowsState?(k(),h(ne(N(T).dynamicRowsState.renderConfirmModal()),{key:4})):g(`v-if`,!0),g(` 列设置抽屉 `),b(N(oe),{show:N(j),"onUpdate:show":r[3]||=e=>C(j)?j.value=e:null,width:420,placement:`right`,"mask-closable":!0},{default:I(()=>[b(N(se),{title:`列设置`,closable:``},{default:I(()=>[b(Mt,{columns:N(M),onChange:ge},null,8,[`columns`])]),_:1})]),_:1},8,[`show`])]))}}),[[`__scopeId`,`data-v-767c7393`]]);export{at as a,$e as c,Se as d,xe as f,ot as i,Ie as l,ye as m,ht as n,it as o,be as p,st as r,et as s,Lt as t,Ce as u};
|
|
3024
2
|
//# sourceMappingURL=C_Table2.js.map
|