@robot-admin/naive-ui-components 0.4.3 → 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.
Files changed (285) hide show
  1. package/dist/C_ActionBar.cjs +1 -5
  2. package/dist/C_ActionBar.js +1 -4
  3. package/dist/C_ActionBar.js.map +1 -0
  4. package/dist/C_ActionBar2.js +1 -195
  5. package/dist/C_ActionBar2.js.map +1 -1
  6. package/dist/C_AntV.cjs +1 -8
  7. package/dist/C_AntV.js +1 -4
  8. package/dist/C_AntV.js.map +1 -0
  9. package/dist/C_AntV2.js +4 -3149
  10. package/dist/C_AntV2.js.map +1 -1
  11. package/dist/C_Barcode.cjs +1 -4
  12. package/dist/C_Barcode.js +1 -3
  13. package/dist/C_Barcode.js.map +1 -0
  14. package/dist/C_Barcode2.js +1 -67
  15. package/dist/C_Barcode2.js.map +1 -1
  16. package/dist/C_Captcha.cjs +1 -4
  17. package/dist/C_Captcha.js +1 -3
  18. package/dist/C_Captcha.js.map +1 -0
  19. package/dist/C_Captcha2.js +1 -154
  20. package/dist/C_Captcha2.js.map +1 -1
  21. package/dist/C_Cascade.cjs +1 -4
  22. package/dist/C_Cascade.js +1 -3
  23. package/dist/C_Cascade.js.map +1 -0
  24. package/dist/C_Cascade2.js +1 -102
  25. package/dist/C_Cascade2.js.map +1 -1
  26. package/dist/C_City.cjs +1 -4
  27. package/dist/C_City.js +1 -3
  28. package/dist/C_City.js.map +1 -0
  29. package/dist/C_City2.js +1 -840
  30. package/dist/C_City2.js.map +1 -1
  31. package/dist/C_Code.cjs +1 -5
  32. package/dist/C_Code.js +1 -4
  33. package/dist/C_Code.js.map +1 -0
  34. package/dist/C_Code2.js +1 -346
  35. package/dist/C_Code2.js.map +1 -1
  36. package/dist/C_CollapsePanel.cjs +1 -6
  37. package/dist/C_CollapsePanel.js +1 -4
  38. package/dist/C_CollapsePanel.js.map +1 -0
  39. package/dist/C_CollapsePanel2.js +1 -318
  40. package/dist/C_CollapsePanel2.js.map +1 -1
  41. package/dist/C_Cron.cjs +1 -15
  42. package/dist/C_Cron.js +1 -4
  43. package/dist/C_Cron.js.map +1 -0
  44. package/dist/C_Cron2.js +1 -1209
  45. package/dist/C_Cron2.js.map +1 -1
  46. package/dist/C_Date.cjs +1 -4
  47. package/dist/C_Date.js +1 -3
  48. package/dist/C_Date.js.map +1 -0
  49. package/dist/C_Date2.js +1 -218
  50. package/dist/C_Date2.js.map +1 -1
  51. package/dist/C_Draggable.cjs +1 -5
  52. package/dist/C_Draggable.js +1 -3
  53. package/dist/C_Draggable.js.map +1 -0
  54. package/dist/C_Draggable2.js +1 -294
  55. package/dist/C_Draggable2.js.map +1 -1
  56. package/dist/C_Editor.cjs +1 -4
  57. package/dist/C_Editor.js +1 -3
  58. package/dist/C_Editor.js.map +1 -0
  59. package/dist/C_Editor2.js +1 -159
  60. package/dist/C_Editor2.js.map +1 -1
  61. package/dist/C_FilePreview.cjs +1 -7
  62. package/dist/C_FilePreview.js +1 -4
  63. package/dist/C_FilePreview.js.map +1 -0
  64. package/dist/C_FilePreview2.js +1 -1031
  65. package/dist/C_FilePreview2.js.map +1 -1
  66. package/dist/C_Form.cjs +1 -16
  67. package/dist/C_Form.js +1 -5
  68. package/dist/C_Form.js.map +1 -0
  69. package/dist/C_Form2.js +1 -2569
  70. package/dist/C_Form2.js.map +1 -1
  71. package/dist/C_FormSearch.cjs +1 -6
  72. package/dist/C_FormSearch.js +1 -3
  73. package/dist/C_FormSearch.js.map +1 -0
  74. package/dist/C_FormSearch2.js +1 -355
  75. package/dist/C_FormSearch2.js.map +1 -1
  76. package/dist/C_FormulaEditor.cjs +1 -13
  77. package/dist/C_FormulaEditor.js +1 -4
  78. package/dist/C_FormulaEditor.js.map +1 -0
  79. package/dist/C_FormulaEditor2.js +1 -1432
  80. package/dist/C_FormulaEditor2.js.map +1 -1
  81. package/dist/C_FullCalendar.cjs +1 -9
  82. package/dist/C_FullCalendar.js +1 -3
  83. package/dist/C_FullCalendar.js.map +1 -0
  84. package/dist/C_FullCalendar2.js +1 -376
  85. package/dist/C_FullCalendar2.js.map +1 -1
  86. package/dist/C_GlobalSearch.cjs +1 -5
  87. package/dist/C_GlobalSearch.js +1 -3
  88. package/dist/C_GlobalSearch.js.map +1 -0
  89. package/dist/C_GlobalSearch2.js +1 -335
  90. package/dist/C_GlobalSearch2.js.map +1 -1
  91. package/dist/C_Guide.cjs +1 -5
  92. package/dist/C_Guide.js +1 -4
  93. package/dist/C_Guide.js.map +1 -0
  94. package/dist/C_Guide2.js +1 -60
  95. package/dist/C_Guide2.js.map +1 -1
  96. package/dist/C_Icon.cjs +1 -4
  97. package/dist/C_Icon.js +1 -3
  98. package/dist/C_Icon.js.map +1 -0
  99. package/dist/C_Icon2.js +1 -285
  100. package/dist/C_Icon2.js.map +1 -1
  101. package/dist/C_ImageCropper.cjs +1 -6
  102. package/dist/C_ImageCropper.js +1 -4
  103. package/dist/C_ImageCropper.js.map +1 -0
  104. package/dist/C_ImageCropper2.js +1 -722
  105. package/dist/C_ImageCropper2.js.map +1 -1
  106. package/dist/C_Language.cjs +1 -5
  107. package/dist/C_Language.js +1 -4
  108. package/dist/C_Language.js.map +1 -0
  109. package/dist/C_Language2.js +1 -78
  110. package/dist/C_Language2.js.map +1 -1
  111. package/dist/C_Map.cjs +1 -7
  112. package/dist/C_Map.js +1 -3
  113. package/dist/C_Map.js.map +1 -0
  114. package/dist/C_Map2.js +1 -198
  115. package/dist/C_Map2.js.map +1 -1
  116. package/dist/C_Markdown.cjs +1 -4
  117. package/dist/C_Markdown.js +1 -3
  118. package/dist/C_Markdown.js.map +1 -0
  119. package/dist/C_Markdown2.js +1 -185
  120. package/dist/C_Markdown2.js.map +1 -1
  121. package/dist/C_NotificationCenter.cjs +1 -20
  122. package/dist/C_NotificationCenter.js +1 -4
  123. package/dist/C_NotificationCenter.js.map +1 -0
  124. package/dist/C_NotificationCenter2.js +1 -1383
  125. package/dist/C_NotificationCenter2.js.map +1 -1
  126. package/dist/C_Progress.cjs +1 -4
  127. package/dist/C_Progress.js +1 -3
  128. package/dist/C_Progress.js.map +1 -0
  129. package/dist/C_Progress2.js +1 -102
  130. package/dist/C_Progress2.js.map +1 -1
  131. package/dist/C_QRCode.cjs +1 -5
  132. package/dist/C_QRCode.js +1 -3
  133. package/dist/C_QRCode.js.map +1 -0
  134. package/dist/C_QRCode2.js +1 -217
  135. package/dist/C_QRCode2.js.map +1 -1
  136. package/dist/C_Signature.cjs +1 -8
  137. package/dist/C_Signature.js +1 -4
  138. package/dist/C_Signature.js.map +1 -0
  139. package/dist/C_Signature2.js +1 -617
  140. package/dist/C_Signature2.js.map +1 -1
  141. package/dist/C_SplitPane.cjs +1 -6
  142. package/dist/C_SplitPane.js +1 -4
  143. package/dist/C_SplitPane.js.map +1 -0
  144. package/dist/C_SplitPane2.js +1 -355
  145. package/dist/C_SplitPane2.js.map +1 -1
  146. package/dist/C_Steps.cjs +1 -4
  147. package/dist/C_Steps.js +1 -3
  148. package/dist/C_Steps.js.map +1 -0
  149. package/dist/C_Steps2.js +1 -81
  150. package/dist/C_Steps2.js.map +1 -1
  151. package/dist/C_Table.cjs +1 -20
  152. package/dist/C_Table.js +1 -6
  153. package/dist/C_Table.js.map +1 -0
  154. package/dist/C_Table2.js +1 -3023
  155. package/dist/C_Table2.js.map +1 -1
  156. package/dist/C_Theme.cjs +1 -5
  157. package/dist/C_Theme.js +1 -4
  158. package/dist/C_Theme.js.map +1 -0
  159. package/dist/C_Theme2.js +1 -63
  160. package/dist/C_Theme2.js.map +1 -1
  161. package/dist/C_Time.cjs +1 -5
  162. package/dist/C_Time.js +1 -3
  163. package/dist/C_Time.js.map +1 -0
  164. package/dist/C_Time2.js +1 -198
  165. package/dist/C_Time2.js.map +1 -1
  166. package/dist/C_Tree.cjs +1 -7
  167. package/dist/C_Tree.js +1 -4
  168. package/dist/C_Tree.js.map +1 -0
  169. package/dist/C_Tree2.js +1 -440
  170. package/dist/C_Tree2.js.map +1 -1
  171. package/dist/C_Upload.cjs +1 -12
  172. package/dist/C_Upload.js +1 -4
  173. package/dist/C_Upload.js.map +1 -0
  174. package/dist/C_Upload2.js +2 -1365
  175. package/dist/C_Upload2.js.map +1 -1
  176. package/dist/C_VideoPlayer.cjs +1 -23
  177. package/dist/C_VideoPlayer.js +1 -3
  178. package/dist/C_VideoPlayer.js.map +1 -0
  179. package/dist/C_VideoPlayer2.js +3 -1932
  180. package/dist/C_VideoPlayer2.js.map +1 -1
  181. package/dist/C_VtableGantt.cjs +1 -6
  182. package/dist/C_VtableGantt.js +1 -4
  183. package/dist/C_VtableGantt.js.map +1 -0
  184. package/dist/C_VtableGantt2.js +1 -872
  185. package/dist/C_VtableGantt2.js.map +1 -1
  186. package/dist/C_WaterFall.cjs +1 -13
  187. package/dist/C_WaterFall.js +1 -3
  188. package/dist/C_WaterFall.js.map +1 -0
  189. package/dist/C_WaterFall2.js +1 -364
  190. package/dist/C_WaterFall2.js.map +1 -1
  191. package/dist/C_WorkFlow.cjs +1 -8
  192. package/dist/C_WorkFlow.js +1 -4
  193. package/dist/C_WorkFlow.js.map +1 -0
  194. package/dist/C_WorkFlow2.js +1 -1983
  195. package/dist/C_WorkFlow2.js.map +1 -1
  196. package/dist/chunk.js +1 -18
  197. package/dist/city.js +1 -4816
  198. package/dist/constants.d.ts +2 -2
  199. package/dist/constants2.d.ts +3 -3
  200. package/dist/constants3.d.ts +3 -3
  201. package/dist/constants4.d.ts +5 -5
  202. package/dist/constants5.d.ts +2 -2
  203. package/dist/data.d.ts +1 -1
  204. package/dist/export-helper.js +1 -9
  205. package/dist/index.cjs +2 -413
  206. package/dist/index.cjs.map +1 -0
  207. package/dist/index.d.cts +1 -2
  208. package/dist/index.d.ts +1 -2
  209. package/dist/index.js +1 -231
  210. package/dist/index.js.map +1 -1
  211. package/dist/index.vue.d.ts +2 -2
  212. package/dist/index10.vue.d.ts +5 -5
  213. package/dist/index12.vue.d.ts +3 -3
  214. package/dist/index13.vue.d.ts +3 -3
  215. package/dist/index14.vue.d.ts +3 -3
  216. package/dist/index16.vue.d.ts +3 -3
  217. package/dist/index3.vue.d.ts +3 -3
  218. package/dist/index5.vue.d.ts +1 -1
  219. package/dist/index7.vue.d.ts +4 -4
  220. package/dist/index8.vue.d.ts +2 -2
  221. package/dist/resolver.cjs +2 -89
  222. package/dist/resolver.cjs.map +1 -0
  223. package/dist/resolver.js +1 -86
  224. package/dist/resolver.js.map +1 -1
  225. package/dist/storage.js +1 -30
  226. package/dist/storage.js.map +1 -1
  227. package/dist/useCollapsePanel.d.ts +2 -2
  228. package/dist/useCropperCore.d.ts +8 -8
  229. package/dist/useDraggableLayout.d.ts +4 -4
  230. package/dist/useDynamicFormState.d.ts +7 -7
  231. package/dist/useEdgeInteraction.d.ts +1 -1
  232. package/dist/useFullscreen.d.ts +2 -2
  233. package/dist/useInfiniteScroll.d.ts +1 -1
  234. package/dist/useModalEdit.d.ts +1 -1
  235. package/dist/useQRCode.d.ts +3 -3
  236. package/dist/useSearchState.d.ts +2 -2
  237. package/dist/useSignatureHistory.d.ts +1 -1
  238. package/dist/useSplitResize.d.ts +6 -6
  239. package/dist/useTimeSelection.d.ts +2 -2
  240. package/dist/useTreeOperations.d.ts +6 -6
  241. package/dist/useWorkflowValidation.d.ts +4 -4
  242. package/package.json +1 -2
  243. package/dist/constants.d.ts.map +0 -1
  244. package/dist/constants2.d.ts.map +0 -1
  245. package/dist/constants3.d.ts.map +0 -1
  246. package/dist/constants4.d.ts.map +0 -1
  247. package/dist/constants5.d.ts.map +0 -1
  248. package/dist/data.d.ts.map +0 -1
  249. package/dist/index.d.cts.map +0 -1
  250. package/dist/index.d.ts.map +0 -1
  251. package/dist/index.vue.d.ts.map +0 -1
  252. package/dist/index10.vue.d.ts.map +0 -1
  253. package/dist/index11.vue.d.ts.map +0 -1
  254. package/dist/index12.vue.d.ts.map +0 -1
  255. package/dist/index13.vue.d.ts.map +0 -1
  256. package/dist/index14.vue.d.ts.map +0 -1
  257. package/dist/index15.vue.d.ts.map +0 -1
  258. package/dist/index16.vue.d.ts.map +0 -1
  259. package/dist/index2.vue.d.ts.map +0 -1
  260. package/dist/index3.vue.d.ts.map +0 -1
  261. package/dist/index4.vue.d.ts.map +0 -1
  262. package/dist/index5.vue.d.ts.map +0 -1
  263. package/dist/index6.vue.d.ts.map +0 -1
  264. package/dist/index7.vue.d.ts.map +0 -1
  265. package/dist/index8.vue.d.ts.map +0 -1
  266. package/dist/index9.vue.d.ts.map +0 -1
  267. package/dist/resolver.d.cts.map +0 -1
  268. package/dist/resolver.d.ts.map +0 -1
  269. package/dist/useCalendarEvents.d.ts.map +0 -1
  270. package/dist/useCollapsePanel.d.ts.map +0 -1
  271. package/dist/useCropperCore.d.ts.map +0 -1
  272. package/dist/useDraggableLayout.d.ts.map +0 -1
  273. package/dist/useDynamicFormState.d.ts.map +0 -1
  274. package/dist/useEdgeInteraction.d.ts.map +0 -1
  275. package/dist/useFullscreen.d.ts.map +0 -1
  276. package/dist/useGlobalSearch.d.ts.map +0 -1
  277. package/dist/useInfiniteScroll.d.ts.map +0 -1
  278. package/dist/useModalEdit.d.ts.map +0 -1
  279. package/dist/useQRCode.d.ts.map +0 -1
  280. package/dist/useSearchState.d.ts.map +0 -1
  281. package/dist/useSignatureHistory.d.ts.map +0 -1
  282. package/dist/useSplitResize.d.ts.map +0 -1
  283. package/dist/useTimeSelection.d.ts.map +0 -1
  284. package/dist/useTreeOperations.d.ts.map +0 -1
  285. 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