@robot-admin/naive-ui-components 0.3.0

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 (352) hide show
  1. package/README.md +257 -0
  2. package/dist/C_ActionBar-DWN-woTc.css.map +1 -0
  3. package/dist/C_ActionBar.cjs +5 -0
  4. package/dist/C_ActionBar.d.cts +2 -0
  5. package/dist/C_ActionBar.d.ts +2 -0
  6. package/dist/C_ActionBar.js +4 -0
  7. package/dist/C_ActionBar2.js +196 -0
  8. package/dist/C_ActionBar2.js.map +1 -0
  9. package/dist/C_AntV-AFKyK6hH.css.map +1 -0
  10. package/dist/C_AntV.cjs +8 -0
  11. package/dist/C_AntV.d.cts +2 -0
  12. package/dist/C_AntV.d.ts +2 -0
  13. package/dist/C_AntV.js +4 -0
  14. package/dist/C_AntV2.js +3150 -0
  15. package/dist/C_AntV2.js.map +1 -0
  16. package/dist/C_Barcode-P_EFj8dC.css.map +1 -0
  17. package/dist/C_Barcode.cjs +4 -0
  18. package/dist/C_Barcode.d.cts +2 -0
  19. package/dist/C_Barcode.d.ts +2 -0
  20. package/dist/C_Barcode.js +3 -0
  21. package/dist/C_Barcode2.js +68 -0
  22. package/dist/C_Barcode2.js.map +1 -0
  23. package/dist/C_Captcha-C-ef41xw.css.map +1 -0
  24. package/dist/C_Captcha.cjs +4 -0
  25. package/dist/C_Captcha.d.cts +2 -0
  26. package/dist/C_Captcha.d.ts +2 -0
  27. package/dist/C_Captcha.js +3 -0
  28. package/dist/C_Captcha2.js +155 -0
  29. package/dist/C_Captcha2.js.map +1 -0
  30. package/dist/C_Cascade-D9kNsjsV.css.map +1 -0
  31. package/dist/C_Cascade.cjs +4 -0
  32. package/dist/C_Cascade.d.cts +2 -0
  33. package/dist/C_Cascade.d.ts +2 -0
  34. package/dist/C_Cascade.js +3 -0
  35. package/dist/C_Cascade2.js +103 -0
  36. package/dist/C_Cascade2.js.map +1 -0
  37. package/dist/C_City-BCQ4ipiK.css.map +1 -0
  38. package/dist/C_City.cjs +4 -0
  39. package/dist/C_City.d.cts +2 -0
  40. package/dist/C_City.d.ts +2 -0
  41. package/dist/C_City.js +3 -0
  42. package/dist/C_City2.js +841 -0
  43. package/dist/C_City2.js.map +1 -0
  44. package/dist/C_Code-C9kvvEmO.css.map +1 -0
  45. package/dist/C_Code.cjs +5 -0
  46. package/dist/C_Code.d.cts +2 -0
  47. package/dist/C_Code.d.ts +2 -0
  48. package/dist/C_Code.js +4 -0
  49. package/dist/C_Code2.js +346 -0
  50. package/dist/C_Code2.js.map +1 -0
  51. package/dist/C_CollapsePanel-BUJHuYcU.css.map +1 -0
  52. package/dist/C_CollapsePanel.cjs +6 -0
  53. package/dist/C_CollapsePanel.d.cts +2 -0
  54. package/dist/C_CollapsePanel.d.ts +2 -0
  55. package/dist/C_CollapsePanel.js +4 -0
  56. package/dist/C_CollapsePanel2.js +319 -0
  57. package/dist/C_CollapsePanel2.js.map +1 -0
  58. package/dist/C_Cron-yx2Ob4Jl.css.map +1 -0
  59. package/dist/C_Cron.cjs +15 -0
  60. package/dist/C_Cron.d.cts +2 -0
  61. package/dist/C_Cron.d.ts +2 -0
  62. package/dist/C_Cron.js +4 -0
  63. package/dist/C_Cron2.js +1209 -0
  64. package/dist/C_Cron2.js.map +1 -0
  65. package/dist/C_Date.cjs +4 -0
  66. package/dist/C_Date.d.cts +2 -0
  67. package/dist/C_Date.d.ts +2 -0
  68. package/dist/C_Date.js +3 -0
  69. package/dist/C_Date2.js +219 -0
  70. package/dist/C_Date2.js.map +1 -0
  71. package/dist/C_Draggable-C483syRC.css.map +1 -0
  72. package/dist/C_Draggable.cjs +5 -0
  73. package/dist/C_Draggable.d.cts +2 -0
  74. package/dist/C_Draggable.d.ts +2 -0
  75. package/dist/C_Draggable.js +3 -0
  76. package/dist/C_Draggable2.js +295 -0
  77. package/dist/C_Draggable2.js.map +1 -0
  78. package/dist/C_Editor-Bp0SyIEw.css.map +1 -0
  79. package/dist/C_Editor.cjs +4 -0
  80. package/dist/C_Editor.d.cts +2 -0
  81. package/dist/C_Editor.d.ts +2 -0
  82. package/dist/C_Editor.js +3 -0
  83. package/dist/C_Editor2.js +160 -0
  84. package/dist/C_Editor2.js.map +1 -0
  85. package/dist/C_FilePreview-CPqvhoCy.css.map +1 -0
  86. package/dist/C_FilePreview.cjs +6 -0
  87. package/dist/C_FilePreview.d.cts +2 -0
  88. package/dist/C_FilePreview.d.ts +2 -0
  89. package/dist/C_FilePreview.js +3 -0
  90. package/dist/C_FilePreview2.js +1031 -0
  91. package/dist/C_FilePreview2.js.map +1 -0
  92. package/dist/C_Form-Jx7PY3sT.css.map +1 -0
  93. package/dist/C_Form.cjs +15 -0
  94. package/dist/C_Form.d.cts +2 -0
  95. package/dist/C_Form.d.ts +2 -0
  96. package/dist/C_Form.js +4 -0
  97. package/dist/C_Form2.js +2510 -0
  98. package/dist/C_Form2.js.map +1 -0
  99. package/dist/C_FormSearch-DvRgxlRn.css.map +1 -0
  100. package/dist/C_FormSearch.cjs +6 -0
  101. package/dist/C_FormSearch.d.cts +2 -0
  102. package/dist/C_FormSearch.d.ts +2 -0
  103. package/dist/C_FormSearch.js +3 -0
  104. package/dist/C_FormSearch2.js +356 -0
  105. package/dist/C_FormSearch2.js.map +1 -0
  106. package/dist/C_FormulaEditor-DtGkt4T_.css.map +1 -0
  107. package/dist/C_FormulaEditor.cjs +13 -0
  108. package/dist/C_FormulaEditor.d.cts +2 -0
  109. package/dist/C_FormulaEditor.d.ts +2 -0
  110. package/dist/C_FormulaEditor.js +4 -0
  111. package/dist/C_FormulaEditor2.js +1433 -0
  112. package/dist/C_FormulaEditor2.js.map +1 -0
  113. package/dist/C_FullCalendar-BF7H0YIx.css.map +1 -0
  114. package/dist/C_FullCalendar.cjs +9 -0
  115. package/dist/C_FullCalendar.d.cts +2 -0
  116. package/dist/C_FullCalendar.d.ts +2 -0
  117. package/dist/C_FullCalendar.js +3 -0
  118. package/dist/C_FullCalendar2.js +377 -0
  119. package/dist/C_FullCalendar2.js.map +1 -0
  120. package/dist/C_Guide.cjs +4 -0
  121. package/dist/C_Guide.d.cts +2 -0
  122. package/dist/C_Guide.d.ts +2 -0
  123. package/dist/C_Guide.js +3 -0
  124. package/dist/C_Guide2.js +58 -0
  125. package/dist/C_Guide2.js.map +1 -0
  126. package/dist/C_Icon.cjs +4 -0
  127. package/dist/C_Icon.d.cts +2 -0
  128. package/dist/C_Icon.d.ts +2 -0
  129. package/dist/C_Icon.js +3 -0
  130. package/dist/C_Icon2.js +286 -0
  131. package/dist/C_Icon2.js.map +1 -0
  132. package/dist/C_ImageCropper-BVJfUufl.css.map +1 -0
  133. package/dist/C_ImageCropper.cjs +6 -0
  134. package/dist/C_ImageCropper.d.cts +2 -0
  135. package/dist/C_ImageCropper.d.ts +2 -0
  136. package/dist/C_ImageCropper.js +4 -0
  137. package/dist/C_ImageCropper2.js +723 -0
  138. package/dist/C_ImageCropper2.js.map +1 -0
  139. package/dist/C_Language.cjs +4 -0
  140. package/dist/C_Language.d.cts +2 -0
  141. package/dist/C_Language.d.ts +2 -0
  142. package/dist/C_Language.js +3 -0
  143. package/dist/C_Language2.js +72 -0
  144. package/dist/C_Language2.js.map +1 -0
  145. package/dist/C_Map-DpzeuWdX.css.map +1 -0
  146. package/dist/C_Map.cjs +7 -0
  147. package/dist/C_Map.d.cts +2 -0
  148. package/dist/C_Map.d.ts +2 -0
  149. package/dist/C_Map.js +3 -0
  150. package/dist/C_Map2.js +199 -0
  151. package/dist/C_Map2.js.map +1 -0
  152. package/dist/C_Markdown-BEjxknqd.css.map +1 -0
  153. package/dist/C_Markdown.cjs +4 -0
  154. package/dist/C_Markdown.d.cts +2 -0
  155. package/dist/C_Markdown.d.ts +2 -0
  156. package/dist/C_Markdown.js +3 -0
  157. package/dist/C_Markdown2.js +186 -0
  158. package/dist/C_Markdown2.js.map +1 -0
  159. package/dist/C_NotificationCenter-0l3TY2Gn.css.map +1 -0
  160. package/dist/C_NotificationCenter.cjs +20 -0
  161. package/dist/C_NotificationCenter.d.cts +2 -0
  162. package/dist/C_NotificationCenter.d.ts +2 -0
  163. package/dist/C_NotificationCenter.js +4 -0
  164. package/dist/C_NotificationCenter2.js +1383 -0
  165. package/dist/C_NotificationCenter2.js.map +1 -0
  166. package/dist/C_Progress.cjs +4 -0
  167. package/dist/C_Progress.d.cts +2 -0
  168. package/dist/C_Progress.d.ts +2 -0
  169. package/dist/C_Progress.js +3 -0
  170. package/dist/C_Progress2.js +103 -0
  171. package/dist/C_Progress2.js.map +1 -0
  172. package/dist/C_QRCode-DbdiAIPg.css.map +1 -0
  173. package/dist/C_QRCode.cjs +5 -0
  174. package/dist/C_QRCode.d.cts +2 -0
  175. package/dist/C_QRCode.d.ts +2 -0
  176. package/dist/C_QRCode.js +3 -0
  177. package/dist/C_QRCode2.js +218 -0
  178. package/dist/C_QRCode2.js.map +1 -0
  179. package/dist/C_Signature-zhHCbra9.css.map +1 -0
  180. package/dist/C_Signature.cjs +8 -0
  181. package/dist/C_Signature.d.cts +2 -0
  182. package/dist/C_Signature.d.ts +2 -0
  183. package/dist/C_Signature.js +4 -0
  184. package/dist/C_Signature2.js +618 -0
  185. package/dist/C_Signature2.js.map +1 -0
  186. package/dist/C_SplitPane-C6sBsfKY.css.map +1 -0
  187. package/dist/C_SplitPane.cjs +6 -0
  188. package/dist/C_SplitPane.d.cts +2 -0
  189. package/dist/C_SplitPane.d.ts +2 -0
  190. package/dist/C_SplitPane.js +4 -0
  191. package/dist/C_SplitPane2.js +356 -0
  192. package/dist/C_SplitPane2.js.map +1 -0
  193. package/dist/C_Steps-CODHN5Hs.css.map +1 -0
  194. package/dist/C_Steps.cjs +4 -0
  195. package/dist/C_Steps.d.cts +2 -0
  196. package/dist/C_Steps.d.ts +2 -0
  197. package/dist/C_Steps.js +3 -0
  198. package/dist/C_Steps2.js +82 -0
  199. package/dist/C_Steps2.js.map +1 -0
  200. package/dist/C_Table-DSNsntmT.css.map +1 -0
  201. package/dist/C_Table.cjs +19 -0
  202. package/dist/C_Table.d.cts +2 -0
  203. package/dist/C_Table.d.ts +2 -0
  204. package/dist/C_Table.js +5 -0
  205. package/dist/C_Table2.js +3009 -0
  206. package/dist/C_Table2.js.map +1 -0
  207. package/dist/C_Theme.cjs +4 -0
  208. package/dist/C_Theme.d.cts +2 -0
  209. package/dist/C_Theme.d.ts +2 -0
  210. package/dist/C_Theme.js +3 -0
  211. package/dist/C_Theme2.js +60 -0
  212. package/dist/C_Theme2.js.map +1 -0
  213. package/dist/C_Time-BvZLYraL.css.map +1 -0
  214. package/dist/C_Time.cjs +5 -0
  215. package/dist/C_Time.d.cts +2 -0
  216. package/dist/C_Time.d.ts +2 -0
  217. package/dist/C_Time.js +3 -0
  218. package/dist/C_Time2.js +199 -0
  219. package/dist/C_Time2.js.map +1 -0
  220. package/dist/C_Tree-0GDv--jX.css.map +1 -0
  221. package/dist/C_Tree.cjs +7 -0
  222. package/dist/C_Tree.d.cts +2 -0
  223. package/dist/C_Tree.d.ts +2 -0
  224. package/dist/C_Tree.js +4 -0
  225. package/dist/C_Tree2.js +441 -0
  226. package/dist/C_Tree2.js.map +1 -0
  227. package/dist/C_Upload-BXd3YYLx.css.map +1 -0
  228. package/dist/C_Upload.cjs +12 -0
  229. package/dist/C_Upload.d.cts +2 -0
  230. package/dist/C_Upload.d.ts +2 -0
  231. package/dist/C_Upload.js +4 -0
  232. package/dist/C_Upload2.js +1388 -0
  233. package/dist/C_Upload2.js.map +1 -0
  234. package/dist/C_VideoPlayer-DYG3RL0Q.css.map +1 -0
  235. package/dist/C_VideoPlayer.cjs +23 -0
  236. package/dist/C_VideoPlayer.d.cts +2 -0
  237. package/dist/C_VideoPlayer.d.ts +2 -0
  238. package/dist/C_VideoPlayer.js +3 -0
  239. package/dist/C_VideoPlayer2.js +1932 -0
  240. package/dist/C_VideoPlayer2.js.map +1 -0
  241. package/dist/C_VtableGantt-fhItIiHE.css.map +1 -0
  242. package/dist/C_VtableGantt.cjs +6 -0
  243. package/dist/C_VtableGantt.d.cts +2 -0
  244. package/dist/C_VtableGantt.d.ts +2 -0
  245. package/dist/C_VtableGantt.js +4 -0
  246. package/dist/C_VtableGantt2.js +873 -0
  247. package/dist/C_VtableGantt2.js.map +1 -0
  248. package/dist/C_WaterFall-8sQDFXKg.css.map +1 -0
  249. package/dist/C_WaterFall.cjs +13 -0
  250. package/dist/C_WaterFall.d.cts +2 -0
  251. package/dist/C_WaterFall.d.ts +2 -0
  252. package/dist/C_WaterFall.js +3 -0
  253. package/dist/C_WaterFall2.js +365 -0
  254. package/dist/C_WaterFall2.js.map +1 -0
  255. package/dist/C_WorkFlow-J-dyIuh9.css.map +1 -0
  256. package/dist/C_WorkFlow.cjs +8 -0
  257. package/dist/C_WorkFlow.d.cts +2 -0
  258. package/dist/C_WorkFlow.d.ts +2 -0
  259. package/dist/C_WorkFlow.js +4 -0
  260. package/dist/C_WorkFlow2.js +1984 -0
  261. package/dist/C_WorkFlow2.js.map +1 -0
  262. package/dist/chunk.js +22 -0
  263. package/dist/city.js +4817 -0
  264. package/dist/city.js.map +1 -0
  265. package/dist/constants.d.ts +273 -0
  266. package/dist/constants.d.ts.map +1 -0
  267. package/dist/constants2.d.ts +178 -0
  268. package/dist/constants2.d.ts.map +1 -0
  269. package/dist/constants3.d.ts +475 -0
  270. package/dist/constants3.d.ts.map +1 -0
  271. package/dist/constants4.d.ts +430 -0
  272. package/dist/constants4.d.ts.map +1 -0
  273. package/dist/constants5.d.ts +4283 -0
  274. package/dist/constants5.d.ts.map +1 -0
  275. package/dist/data.d.ts +67 -0
  276. package/dist/data.d.ts.map +1 -0
  277. package/dist/export-helper.js +9 -0
  278. package/dist/index.cjs +409 -0
  279. package/dist/index.d.cts +96 -0
  280. package/dist/index.d.cts.map +1 -0
  281. package/dist/index.d.ts +103 -0
  282. package/dist/index.d.ts.map +1 -0
  283. package/dist/index.js +230 -0
  284. package/dist/index.js.map +1 -0
  285. package/dist/index.vue.d.ts +80 -0
  286. package/dist/index.vue.d.ts.map +1 -0
  287. package/dist/index10.vue.d.ts +72 -0
  288. package/dist/index10.vue.d.ts.map +1 -0
  289. package/dist/index11.vue.d.ts +26 -0
  290. package/dist/index11.vue.d.ts.map +1 -0
  291. package/dist/index12.vue.d.ts +81 -0
  292. package/dist/index12.vue.d.ts.map +1 -0
  293. package/dist/index13.vue.d.ts +55 -0
  294. package/dist/index13.vue.d.ts.map +1 -0
  295. package/dist/index14.vue.d.ts +33 -0
  296. package/dist/index14.vue.d.ts.map +1 -0
  297. package/dist/index15.vue.d.ts +18 -0
  298. package/dist/index15.vue.d.ts.map +1 -0
  299. package/dist/index16.vue.d.ts +662 -0
  300. package/dist/index16.vue.d.ts.map +1 -0
  301. package/dist/index2.vue.d.ts +38 -0
  302. package/dist/index2.vue.d.ts.map +1 -0
  303. package/dist/index3.vue.d.ts +45 -0
  304. package/dist/index3.vue.d.ts.map +1 -0
  305. package/dist/index4.vue.d.ts +31 -0
  306. package/dist/index4.vue.d.ts.map +1 -0
  307. package/dist/index5.vue.d.ts +35 -0
  308. package/dist/index5.vue.d.ts.map +1 -0
  309. package/dist/index6.vue.d.ts +48 -0
  310. package/dist/index6.vue.d.ts.map +1 -0
  311. package/dist/index7.vue.d.ts +56 -0
  312. package/dist/index7.vue.d.ts.map +1 -0
  313. package/dist/index8.vue.d.ts +41 -0
  314. package/dist/index8.vue.d.ts.map +1 -0
  315. package/dist/index9.vue.d.ts +30 -0
  316. package/dist/index9.vue.d.ts.map +1 -0
  317. package/dist/storage.js +31 -0
  318. package/dist/storage.js.map +1 -0
  319. package/dist/style.css +7725 -0
  320. package/dist/useCalendarEvents.d.ts +148 -0
  321. package/dist/useCalendarEvents.d.ts.map +1 -0
  322. package/dist/useCollapsePanel.d.ts +132 -0
  323. package/dist/useCollapsePanel.d.ts.map +1 -0
  324. package/dist/useCropperCore.d.ts +102 -0
  325. package/dist/useCropperCore.d.ts.map +1 -0
  326. package/dist/useDraggableLayout.d.ts +194 -0
  327. package/dist/useDraggableLayout.d.ts.map +1 -0
  328. package/dist/useDynamicFormState.d.ts +4248 -0
  329. package/dist/useDynamicFormState.d.ts.map +1 -0
  330. package/dist/useEdgeInteraction.d.ts +7614 -0
  331. package/dist/useEdgeInteraction.d.ts.map +1 -0
  332. package/dist/useFullscreen.d.ts +166 -0
  333. package/dist/useFullscreen.d.ts.map +1 -0
  334. package/dist/useInfiniteScroll.d.ts +169 -0
  335. package/dist/useInfiniteScroll.d.ts.map +1 -0
  336. package/dist/useModalEdit.d.ts +960 -0
  337. package/dist/useModalEdit.d.ts.map +1 -0
  338. package/dist/useQRCode.d.ts +87 -0
  339. package/dist/useQRCode.d.ts.map +1 -0
  340. package/dist/useSearchState.d.ts +180 -0
  341. package/dist/useSearchState.d.ts.map +1 -0
  342. package/dist/useSignatureHistory.d.ts +189 -0
  343. package/dist/useSignatureHistory.d.ts.map +1 -0
  344. package/dist/useSplitResize.d.ts +158 -0
  345. package/dist/useSplitResize.d.ts.map +1 -0
  346. package/dist/useTimeSelection.d.ts +105 -0
  347. package/dist/useTimeSelection.d.ts.map +1 -0
  348. package/dist/useTreeOperations.d.ts +183 -0
  349. package/dist/useTreeOperations.d.ts.map +1 -0
  350. package/dist/useWorkflowValidation.d.ts +1052 -0
  351. package/dist/useWorkflowValidation.d.ts.map +1 -0
  352. package/package.json +342 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"C_Table2.js","names":["NSpin","useMessage","NButton","C_Icon","NTooltip","NButtonGroup","NSpace","NModal","C_Icon","C_Icon","$attrs","rowKey"],"sources":["../src/components/C_Table/composables/useTableConfig.ts","../src/components/C_Table/composables/useRowEdit.ts","../src/components/C_Table/composables/useCellEdit.ts","../src/components/C_Table/composables/useModalEdit.ts","../src/components/C_Table/composables/useTableExpand.ts","../src/components/C_Table/composables/usePrintWatermark.ts","../src/components/C_Table/composables/useDynamicRow.ts","../src/components/C_Table/composables/useTableManager.ts","../src/components/C_Table/composables/usePagination.ts","../src/components/C_Table/composables/useTableActions.ts","../src/components/C_Table/data.ts","../src/components/C_Table/composables/useTableColumns.ts","../src/components/C_Table/components/ColumnSettings/data.ts","../src/components/C_Table/components/ColumnSettings/index.vue","../src/components/C_Table/components/ColumnSettings/index.vue","../src/components/C_Table/components/ColumnSettings/index.vue","../src/components/C_Table/index.vue","../src/components/C_Table/index.vue","../src/components/C_Table/index.vue"],"sourcesContent":["/*\r\n * @Description: 表格配置构建 — 从 config 单一入口合并为内部统一配置对象\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport type { VNodeChild, Ref, ComputedRef } from \"vue\";\r\nimport type { DataTableRowKey } from \"naive-ui/es\";\r\nimport type {\r\n DataRecord,\r\n PaginationConfig,\r\n ParentChildLinkMode,\r\n SimpleTableActions,\r\n TableColumn,\r\n} from \"../types\";\r\nimport type { DynamicRowsOptions } from \"./useDynamicRow\";\r\n\r\n/* ================= CRUD 绑定类型 ================= */\r\n\r\n/** 可绑定到 C_Table 的 CRUD 对象接口 */\r\nexport interface CrudBinding {\r\n data: Ref<DataRecord[]>;\r\n loading: Ref<boolean>;\r\n columns: ComputedRef<TableColumn[]>;\r\n actions?: ComputedRef<SimpleTableActions>;\r\n pagination?: ComputedRef<PaginationConfig | null>;\r\n tableRef?: Ref<unknown>;\r\n save?: (...args: unknown[]) => unknown;\r\n handleCancel?: () => void;\r\n handlePaginationChange?: (page: number, pageSize: number) => void;\r\n handleRowDelete?: (...args: unknown[]) => void;\r\n detail?: { show: (...args: unknown[]) => void };\r\n}\r\n\r\n/* ================= 使用侧配置类型(对外 API) ================= */\r\n\r\n/** C_Table :config prop 的类型 — 所有功能配置收拢在此 */\r\nexport interface TableConfig<T extends DataRecord = DataRecord> {\r\n /** 编辑配置 */\r\n edit?: EditConfig | boolean;\r\n /** 操作按钮 */\r\n actions?: SimpleTableActions<T>;\r\n /** 分页配置 */\r\n pagination?: PaginationConfig | boolean;\r\n /** 展开行配置 */\r\n expand?: ExpandConfig<T> | boolean;\r\n /** 选择配置 */\r\n selection?: SelectionConfig<T> | boolean;\r\n /** 动态行配置 */\r\n dynamicRows?: DynamicRowsOptions<T> | boolean;\r\n /** 工具栏 */\r\n toolbar?: ToolbarConfig;\r\n /** 表格显示属性 */\r\n display?: DisplayConfig;\r\n}\r\n\r\nexport interface EditConfig {\r\n enabled?: boolean;\r\n mode?: \"row\" | \"cell\" | \"modal\" | \"both\" | \"none\";\r\n showRowActions?: boolean;\r\n modalTitle?: string;\r\n modalWidth?: number;\r\n}\r\n\r\nexport interface ExpandConfig<T extends DataRecord = DataRecord> {\r\n enabled?: boolean;\r\n defaultExpandedKeys?: DataTableRowKey[];\r\n onLoadData?: (row: T) => Promise<unknown[]> | unknown[];\r\n renderContent?: (\r\n row: T,\r\n expandData: unknown[],\r\n loading: boolean,\r\n childSelection?: unknown,\r\n ) => VNodeChild;\r\n rowExpandable?: (row: T) => boolean;\r\n}\r\n\r\nexport interface SelectionConfig<T extends DataRecord = DataRecord> {\r\n enabled?: boolean;\r\n defaultCheckedKeys?: import(\"naive-ui/es\").DataTableRowKey[];\r\n rowCheckable?: (row: T) => boolean;\r\n maxSelection?: number;\r\n childSelection?: {\r\n enabled?: boolean;\r\n childRowCheckable?: (childRow: unknown, parentRow: T) => boolean;\r\n };\r\n parentChildLink?: {\r\n enabled?: boolean;\r\n mode?: ParentChildLinkMode;\r\n };\r\n}\r\n\r\nexport interface ToolbarConfig {\r\n /** 是否显示工具栏 */\r\n show?: boolean;\r\n /** 是否启用列设置 */\r\n columnSettings?: boolean;\r\n}\r\n\r\nexport interface DisplayConfig {\r\n striped?: boolean;\r\n bordered?: boolean;\r\n singleLine?: boolean;\r\n size?: \"small\" | \"medium\" | \"large\";\r\n maxHeight?: number | string;\r\n scrollX?: number | string;\r\n columnWidth?: number;\r\n}\r\n\r\n/* ================= 内部解析后的扁平配置 ================= */\r\n\r\nexport interface ResolvedConfig {\r\n editable: boolean;\r\n editMode: string;\r\n showRowActions: boolean;\r\n modalTitle: string;\r\n modalWidth: number;\r\n expandable: boolean;\r\n defaultExpandedKeys: DataTableRowKey[] | undefined;\r\n onLoadExpandData:\r\n | ((row: DataRecord) => Promise<unknown[]> | unknown[])\r\n | undefined;\r\n renderExpandContent:\r\n | ((\r\n row: DataRecord,\r\n expandData: unknown[],\r\n loading: boolean,\r\n childSelection?: unknown,\r\n ) => VNodeChild)\r\n | undefined;\r\n rowExpandable: ((row: DataRecord) => boolean) | undefined;\r\n enableSelection: boolean;\r\n defaultCheckedKeys: DataTableRowKey[] | undefined;\r\n rowCheckable: ((row: DataRecord) => boolean) | undefined;\r\n maxSelection: number | undefined;\r\n enableChildSelection: boolean;\r\n childRowCheckable:\r\n | ((childRow: unknown, parentRow: DataRecord) => boolean)\r\n | undefined;\r\n enableParentChildLink: boolean;\r\n parentChildLinkMode: ParentChildLinkMode;\r\n pagination: PaginationConfig | null;\r\n dynamicRows: DynamicRowsOptions<DataRecord> | undefined;\r\n striped: boolean;\r\n bordered: boolean;\r\n singleLine: boolean;\r\n size: string;\r\n maxHeight: number | string | undefined;\r\n scrollX: number | string | undefined;\r\n columnWidth: number;\r\n showToolbar: boolean;\r\n enableColumnSettings: boolean;\r\n}\r\n\r\n/* ================= 解析逻辑 ================= */\r\n\r\nconst EDIT_DISABLED: Pick<\r\n ResolvedConfig,\r\n \"editable\" | \"editMode\" | \"showRowActions\" | \"modalTitle\" | \"modalWidth\"\r\n> = {\r\n editable: false,\r\n editMode: \"none\",\r\n showRowActions: false,\r\n modalTitle: \"编辑数据\",\r\n modalWidth: 600,\r\n};\r\n\r\nconst resolveEdit = (\r\n edit: EditConfig | boolean | undefined,\r\n): Pick<\r\n ResolvedConfig,\r\n \"editable\" | \"editMode\" | \"showRowActions\" | \"modalTitle\" | \"modalWidth\"\r\n> => {\r\n if (edit === false || edit === undefined) return EDIT_DISABLED;\r\n if (edit === true)\r\n return {\r\n editable: true,\r\n editMode: \"modal\",\r\n showRowActions: true,\r\n modalTitle: \"编辑数据\",\r\n modalWidth: 600,\r\n };\r\n return {\r\n editable: edit.enabled !== false && edit.mode !== \"none\",\r\n editMode: edit.mode || \"modal\",\r\n showRowActions: edit.showRowActions !== false && edit.mode !== \"none\",\r\n modalTitle: edit.modalTitle || \"编辑数据\",\r\n modalWidth: edit.modalWidth || 600,\r\n };\r\n};\r\n\r\nconst resolveExpand = (expand: ExpandConfig | boolean | undefined) => {\r\n if (!expand)\r\n return {\r\n expandable: false,\r\n defaultExpandedKeys: undefined,\r\n onLoadExpandData: undefined,\r\n renderExpandContent: undefined,\r\n rowExpandable: undefined,\r\n };\r\n if (expand === true)\r\n return {\r\n expandable: true,\r\n defaultExpandedKeys: undefined,\r\n onLoadExpandData: undefined,\r\n renderExpandContent: undefined,\r\n rowExpandable: undefined,\r\n };\r\n return {\r\n expandable: expand.enabled !== false,\r\n defaultExpandedKeys: expand.defaultExpandedKeys,\r\n onLoadExpandData: expand.onLoadData,\r\n renderExpandContent: expand.renderContent,\r\n rowExpandable: expand.rowExpandable,\r\n };\r\n};\r\n\r\nconst resolveSelection = (selection: SelectionConfig | boolean | undefined) => {\r\n if (!selection)\r\n return {\r\n enableSelection: false,\r\n defaultCheckedKeys: undefined,\r\n rowCheckable: undefined,\r\n maxSelection: undefined,\r\n enableChildSelection: false,\r\n childRowCheckable: undefined,\r\n enableParentChildLink: false,\r\n parentChildLinkMode: \"loose\" as ParentChildLinkMode,\r\n };\r\n if (selection === true)\r\n return {\r\n enableSelection: true,\r\n defaultCheckedKeys: undefined,\r\n rowCheckable: undefined,\r\n maxSelection: undefined,\r\n enableChildSelection: false,\r\n childRowCheckable: undefined,\r\n enableParentChildLink: false,\r\n parentChildLinkMode: \"loose\" as ParentChildLinkMode,\r\n };\r\n const child = selection.childSelection || {};\r\n const link = selection.parentChildLink || {};\r\n return {\r\n enableSelection: selection.enabled !== false,\r\n defaultCheckedKeys: selection.defaultCheckedKeys,\r\n rowCheckable: selection.rowCheckable,\r\n maxSelection: selection.maxSelection,\r\n enableChildSelection: child.enabled || false,\r\n childRowCheckable: child.childRowCheckable,\r\n enableParentChildLink: link.enabled || false,\r\n parentChildLinkMode: (link.mode || \"loose\") as ParentChildLinkMode,\r\n };\r\n};\r\n\r\nconst resolvePagination = (\r\n pagination: PaginationConfig | boolean | undefined,\r\n): { pagination: PaginationConfig | null } => {\r\n const defaults: PaginationConfig = {\r\n enabled: true,\r\n page: 1,\r\n pageSize: 10,\r\n showSizePicker: true,\r\n showQuickJumper: true,\r\n pageSizes: [10, 20, 50, 100],\r\n simple: false,\r\n size: \"medium\",\r\n };\r\n\r\n if (pagination === false) return { pagination: null };\r\n if (pagination === true || pagination === undefined)\r\n return { pagination: defaults };\r\n return { pagination: { ...defaults, ...pagination } };\r\n};\r\n\r\nconst resolveDynamicRows = (\r\n dynamicRows: DynamicRowsOptions | boolean | undefined,\r\n) => {\r\n if (!dynamicRows) return { dynamicRows: undefined };\r\n if (dynamicRows === true) {\r\n return {\r\n dynamicRows: {\r\n enableRadioSelection: true,\r\n enableAdd: true,\r\n enableInsert: true,\r\n enableDelete: true,\r\n enableCopy: true,\r\n enableMove: true,\r\n enablePrint: true,\r\n },\r\n };\r\n }\r\n return { dynamicRows };\r\n};\r\n\r\nconst DISPLAY_DEFAULTS: Pick<\r\n ResolvedConfig,\r\n | \"striped\"\r\n | \"bordered\"\r\n | \"singleLine\"\r\n | \"size\"\r\n | \"maxHeight\"\r\n | \"scrollX\"\r\n | \"columnWidth\"\r\n> = {\r\n striped: true,\r\n bordered: true,\r\n singleLine: true,\r\n size: \"medium\",\r\n maxHeight: undefined,\r\n scrollX: undefined,\r\n columnWidth: 180,\r\n};\r\n\r\n/** 解析 display 配置,合并默认值 */\r\nfunction resolveDisplay(display: DisplayConfig | undefined) {\r\n if (!display) return { ...DISPLAY_DEFAULTS };\r\n return {\r\n striped: display.striped ?? DISPLAY_DEFAULTS.striped,\r\n bordered: display.bordered ?? DISPLAY_DEFAULTS.bordered,\r\n singleLine: display.singleLine ?? DISPLAY_DEFAULTS.singleLine,\r\n size: display.size ?? DISPLAY_DEFAULTS.size,\r\n maxHeight: display.maxHeight,\r\n scrollX: display.scrollX,\r\n columnWidth: display.columnWidth ?? DISPLAY_DEFAULTS.columnWidth,\r\n };\r\n}\r\n\r\nconst resolveToolbar = (toolbar: ToolbarConfig | undefined) => ({\r\n showToolbar: toolbar?.show !== false,\r\n enableColumnSettings: toolbar?.columnSettings !== false,\r\n});\r\n\r\n/* ================= 主配置函数 ================= */\r\n\r\n/**\r\n * 将 config 单一对象解析为内部扁平化配置\r\n */\r\nexport function resolveConfig(config: TableConfig = {}): ResolvedConfig {\r\n return {\r\n ...resolveEdit(config.edit),\r\n ...resolveExpand(config.expand),\r\n ...resolveSelection(config.selection),\r\n ...resolvePagination(config.pagination),\r\n ...resolveDynamicRows(config.dynamicRows),\r\n ...resolveDisplay(config.display),\r\n ...resolveToolbar(config.toolbar),\r\n };\r\n}\r\n\r\n/* ================= 编辑模式检查器 ================= */\r\n\r\nexport const createEditModeChecker = (config: ResolvedConfig) => ({\r\n isNonEditable: (column: TableColumn) =>\r\n !config.editable || column.editable === false || config.editMode === \"none\",\r\n isRowEditMode: () => [\"row\", \"both\"].includes(config.editMode),\r\n isCellEditMode: () => [\"cell\", \"both\"].includes(config.editMode),\r\n});\r\n","/*\r\n * @Description: 可编辑行组合函数,提供表格整行的编辑功能\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { ref } from \"vue\";\r\nimport type { DataTableRowKey } from \"naive-ui/es\";\r\nimport type { DataRecord } from \"../types\";\r\n\r\n/**\r\n * 行编辑配置选项\r\n */\r\nexport interface RowEditOptions {\r\n data: () => DataRecord[];\r\n rowKey: (row: DataRecord) => DataTableRowKey;\r\n onSave?: (rowData: DataRecord, rowIndex: number) => void | Promise<void>;\r\n onCancel?: (rowData: DataRecord, rowIndex: number) => void;\r\n}\r\n\r\n/**\r\n * 可编辑行组合函数,提供表格整行的编辑功能\r\n */\r\nexport function useRowEdit(options: RowEditOptions) {\r\n const editingRowKey = ref<DataTableRowKey | null>(null);\r\n const editingData = ref<Record<string, DataRecord>>({});\r\n\r\n /**\r\n * 检查指定行是否正在编辑状态\r\n */\r\n const isEditingRow = (rowKey: DataTableRowKey) => {\r\n return editingRowKey.value === rowKey;\r\n };\r\n\r\n /**\r\n * 根据rowKey实时查找最新的行数据\r\n */\r\n const findRowData = (rowKey: DataTableRowKey) => {\r\n const currentData = options.data();\r\n if (!currentData || !Array.isArray(currentData)) {\r\n return null;\r\n }\r\n return currentData.find((row) => options.rowKey(row) === rowKey);\r\n };\r\n\r\n /**\r\n * 开始编辑指定行,将原始数据复制到编辑缓存中\r\n */\r\n const startEditRow = (rowKey: DataTableRowKey) => {\r\n const rowData = findRowData(rowKey);\r\n if (!rowData) return;\r\n\r\n editingRowKey.value = rowKey;\r\n editingData.value[rowKey as string] = { ...rowData };\r\n };\r\n\r\n /**\r\n * 取消当前行编辑,调用取消回调并清理编辑状态\r\n */\r\n const cancelEditRow = async () => {\r\n if (!editingRowKey.value) return;\r\n\r\n const currentData = options.data();\r\n if (!currentData || !Array.isArray(currentData)) return;\r\n\r\n const rowIndex = currentData.findIndex(\r\n (row) => options.rowKey(row) === editingRowKey.value,\r\n );\r\n\r\n if (rowIndex > -1) {\r\n await options.onCancel?.(currentData[rowIndex], rowIndex);\r\n }\r\n\r\n editingRowKey.value = null;\r\n editingData.value = {};\r\n };\r\n\r\n /**\r\n * 保存当前行编辑,调用保存回调并清理编辑状态\r\n */\r\n const saveEditRow = async () => {\r\n if (!editingRowKey.value) return;\r\n\r\n const rowKey = editingRowKey.value;\r\n const currentData = options.data();\r\n if (!currentData || !Array.isArray(currentData)) return;\r\n\r\n const rowIndex = currentData.findIndex(\r\n (row) => options.rowKey(row) === rowKey,\r\n );\r\n\r\n if (rowIndex === -1) return;\r\n\r\n const updatedData = editingData.value[rowKey as string];\r\n if (!updatedData) return;\r\n\r\n await options.onSave?.(updatedData, rowIndex);\r\n\r\n editingRowKey.value = null;\r\n editingData.value = {};\r\n\r\n return { updatedData, rowIndex };\r\n };\r\n\r\n /**\r\n * 获取指定行的编辑中数据\r\n */\r\n const getEditingRowData = (rowKey: DataTableRowKey) => {\r\n return editingData.value[rowKey as string];\r\n };\r\n\r\n /**\r\n * 更新指定行编辑中的字段值\r\n */\r\n const updateEditingRowData = (\r\n rowKey: DataTableRowKey,\r\n field: string,\r\n value: unknown,\r\n ) => {\r\n if (!editingData.value[rowKey as string]) return;\r\n editingData.value[rowKey as string][field] = value;\r\n };\r\n\r\n return {\r\n editingRowKey,\r\n isEditingRow,\r\n startEditRow,\r\n cancelEditRow,\r\n saveEditRow,\r\n getEditingRowData,\r\n updateEditingRowData,\r\n findRowData,\r\n };\r\n}\r\n","/*\r\n * @Description: 可编辑单元格组合函数\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { ref } from \"vue\";\r\nimport type { DataTableRowKey } from \"naive-ui/es\";\r\nimport type { DataRecord } from \"../types\";\r\n\r\n/**\r\n * 单元格编辑配置选项\r\n */\r\nexport interface CellEditOptions {\r\n data: () => DataRecord[];\r\n rowKey: (row: DataRecord) => DataTableRowKey;\r\n onSave?: (\r\n rowData: DataRecord,\r\n rowIndex: number,\r\n columnKey: string,\r\n ) => void | Promise<void>;\r\n}\r\n\r\n/**\r\n * 可编辑单元格组合函数,提供表格单元格的编辑功能\r\n */\r\nexport function useCellEdit(options: CellEditOptions) {\r\n const editingCell = ref<{\r\n rowKey: DataTableRowKey | null;\r\n columnKey: string | null;\r\n }>({\r\n rowKey: null,\r\n columnKey: null,\r\n });\r\n const editingData = ref<Record<string, unknown>>({});\r\n\r\n /**\r\n * 检查指定单元格是否正在编辑状态\r\n */\r\n const isEditingCell = (rowKey: DataTableRowKey, columnKey: string) => {\r\n return (\r\n editingCell.value.rowKey === rowKey &&\r\n editingCell.value.columnKey === columnKey\r\n );\r\n };\r\n\r\n /**\r\n * 根据rowKey实时查找最新的行数据\r\n */\r\n const findRowData = (rowKey: DataTableRowKey) => {\r\n const currentData = options.data();\r\n if (!currentData || !Array.isArray(currentData)) {\r\n return null;\r\n }\r\n return currentData.find((row) => options.rowKey(row) === rowKey);\r\n };\r\n\r\n /**\r\n * 开始编辑指定单元格,将原值存储到编辑缓存中\r\n */\r\n const startEditCell = (rowKey: DataTableRowKey, columnKey: string) => {\r\n const rowData = findRowData(rowKey);\r\n if (!rowData) return;\r\n\r\n editingCell.value = { rowKey, columnKey };\r\n editingData.value[`${rowKey}-${columnKey}`] = rowData[columnKey];\r\n };\r\n\r\n /**\r\n * 保存当前编辑的单元格,调用保存回调并清理编辑状态\r\n */\r\n const saveEditCell = async () => {\r\n const { rowKey, columnKey } = editingCell.value;\r\n if (!rowKey || !columnKey) return;\r\n\r\n const currentData = options.data();\r\n if (!currentData || !Array.isArray(currentData)) return;\r\n\r\n const rowIndex = currentData.findIndex(\r\n (row) => options.rowKey(row) === rowKey,\r\n );\r\n if (rowIndex === -1) return;\r\n\r\n const cellKey = `${rowKey}-${columnKey}`;\r\n const newValue = editingData.value[cellKey];\r\n\r\n const updatedData = {\r\n ...currentData[rowIndex],\r\n [columnKey]: newValue,\r\n };\r\n\r\n await options.onSave?.(updatedData, rowIndex, columnKey);\r\n\r\n editingCell.value = { rowKey: null, columnKey: null };\r\n delete editingData.value[cellKey];\r\n\r\n return { updatedData, rowIndex, columnKey };\r\n };\r\n\r\n /**\r\n * 取消当前单元格编辑,清理编辑状态和缓存数据\r\n */\r\n const cancelEditCell = () => {\r\n const { rowKey, columnKey } = editingCell.value;\r\n if (rowKey && columnKey) {\r\n delete editingData.value[`${rowKey}-${columnKey}`];\r\n }\r\n editingCell.value = { rowKey: null, columnKey: null };\r\n };\r\n\r\n /**\r\n * 获取指定单元格的编辑中数值\r\n */\r\n const getEditingCellValue = (rowKey: DataTableRowKey, columnKey: string) => {\r\n return editingData.value[`${rowKey}-${columnKey}`];\r\n };\r\n\r\n /**\r\n * 更新指定单元格的编辑中数值\r\n */\r\n const updateEditingCellValue = (\r\n rowKey: DataTableRowKey,\r\n columnKey: string,\r\n value: unknown,\r\n ) => {\r\n editingData.value[`${rowKey}-${columnKey}`] = value;\r\n };\r\n\r\n return {\r\n editingCell,\r\n isEditingCell,\r\n startEditCell,\r\n saveEditCell,\r\n cancelEditCell,\r\n getEditingCellValue,\r\n updateEditingCellValue,\r\n findRowData,\r\n };\r\n}\r\n","/*\r\n * @Description: 模态框编辑组合函数\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { ref, computed } from \"vue\";\r\nimport type { DataTableRowKey } from \"naive-ui/es\";\r\n\r\n/**\r\n * 模态框编辑配置选项\r\n */\r\nexport interface ModalEditOptions<T = Record<string, any>> {\r\n data: () => T[];\r\n rowKey: (row: T) => DataTableRowKey;\r\n onSave?: (\r\n editingData: Record<string, any>,\r\n rowIndex: number,\r\n ) => void | Promise<void>;\r\n onCancel?: (originalData: T, rowIndex: number) => void | Promise<void>;\r\n}\r\n\r\n/**\r\n * 模态框编辑组合函数,提供弹窗形式的数据编辑功能\r\n */\r\nexport function useModalEdit<T = Record<string, any>>(\r\n options: ModalEditOptions<T>,\r\n) {\r\n const isModalVisible = ref(false);\r\n const editingRowKey = ref<DataTableRowKey | null>(null);\r\n const editingData = ref<Record<string, any>>({});\r\n\r\n /**\r\n * 计算属性:获取当前编辑行的索引\r\n */\r\n const editingRowIndex = computed(() => {\r\n if (!editingRowKey.value) return -1;\r\n const currentData = options.data();\r\n if (!currentData || !Array.isArray(currentData)) return -1;\r\n\r\n return currentData.findIndex(\r\n (row) => options.rowKey(row) === editingRowKey.value,\r\n );\r\n });\r\n\r\n /**\r\n * 重置编辑状态\r\n */\r\n const resetEditingState = () => {\r\n editingRowKey.value = null;\r\n editingData.value = {};\r\n };\r\n\r\n /**\r\n * 开始编辑指定行\r\n */\r\n const startEdit = (rowKey: DataTableRowKey) => {\r\n console.log(\"🚀 开始编辑:\", rowKey);\r\n\r\n const currentData = options.data();\r\n if (!currentData || !Array.isArray(currentData)) {\r\n console.warn(\"数据源为空或不是数组\");\r\n return;\r\n }\r\n\r\n const rowIndex = currentData.findIndex(\r\n (row) => options.rowKey(row) === rowKey,\r\n );\r\n\r\n if (rowIndex === -1) {\r\n console.warn(\"未找到对应的行数据:\", rowKey);\r\n return;\r\n }\r\n\r\n const rowData = currentData[rowIndex];\r\n console.log(\"找到行数据:\", rowData);\r\n\r\n editingRowKey.value = rowKey;\r\n editingData.value = JSON.parse(JSON.stringify(rowData));\r\n\r\n console.log(\"编辑数据已准备:\", editingData.value);\r\n\r\n isModalVisible.value = true;\r\n };\r\n\r\n /**\r\n * 保存编辑\r\n */\r\n const saveEdit = async (formData?: Record<string, any>) => {\r\n const dataToSave = formData || editingData.value;\r\n const currentIndex = editingRowIndex.value;\r\n\r\n console.log(\"💾 保存编辑:\", {\r\n rowKey: editingRowKey.value,\r\n index: currentIndex,\r\n data: dataToSave,\r\n });\r\n\r\n if (currentIndex === -1) {\r\n console.warn(\"无法找到编辑行的索引\");\r\n return;\r\n }\r\n\r\n try {\r\n await options.onSave?.(dataToSave, currentIndex);\r\n\r\n isModalVisible.value = false;\r\n resetEditingState();\r\n\r\n console.log(\"✅ 保存成功\");\r\n } catch (error) {\r\n console.error(\"❌ 保存失败:\", error);\r\n throw error;\r\n }\r\n };\r\n\r\n /**\r\n * 取消编辑\r\n */\r\n const cancelEdit = async () => {\r\n console.log(\"🚫 取消编辑\");\r\n\r\n try {\r\n const currentIndex = editingRowIndex.value;\r\n if (editingRowKey.value && currentIndex > -1) {\r\n const currentData = options.data();\r\n if (currentData && currentData[currentIndex]) {\r\n await options.onCancel?.(currentData[currentIndex], currentIndex);\r\n }\r\n }\r\n } finally {\r\n isModalVisible.value = false;\r\n resetEditingState();\r\n }\r\n };\r\n\r\n /**\r\n * 更新编辑数据\r\n */\r\n const updateEditingData = (data: Record<string, any>) => {\r\n editingData.value = { ...data };\r\n };\r\n\r\n /**\r\n * 获取当前编辑的行数据\r\n */\r\n const getEditingRowData = (rowKey: DataTableRowKey) => {\r\n if (editingRowKey.value === rowKey) {\r\n return editingData.value;\r\n }\r\n return null;\r\n };\r\n\r\n /**\r\n * 检查是否正在编辑指定行\r\n */\r\n const isEditingRow = (rowKey: DataTableRowKey) => {\r\n return editingRowKey.value === rowKey && isModalVisible.value;\r\n };\r\n\r\n return {\r\n isModalVisible,\r\n editingData,\r\n editingRowKey,\r\n editingRowIndex,\r\n\r\n startEdit,\r\n saveEdit,\r\n cancelEdit,\r\n updateEditingData,\r\n resetEditingState,\r\n\r\n isEditingRow,\r\n getEditingRowData,\r\n };\r\n}\r\n","/*\r\n * @Description: 表格展开功能\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { h, ref, computed, unref, watchEffect, nextTick } from \"vue\";\r\nimport type { VNodeChild, Ref } from \"vue\";\r\nimport { type DataTableRowKey, NSpin, NDataTable } from \"naive-ui/es\";\r\nimport type {\r\n TableColumn,\r\n UseTableExpandOptions,\r\n UseTableExpandReturn,\r\n ChildSelectionState,\r\n DataRecord,\r\n} from \"../types\";\r\n\r\n/* ================= 核心状态管理 ================= */\r\nconst useExpandState = <T extends DataRecord, C>(\r\n options: UseTableExpandOptions<T, C>,\r\n) => {\r\n const expandedKeys = ref<DataTableRowKey[]>([\r\n ...(options.defaultExpandedKeys || []),\r\n ]);\r\n const expandDataMap = ref(new Map<DataTableRowKey, any>()) as Ref<\r\n Map<DataTableRowKey, C[]>\r\n >;\r\n const loadingMap = ref(new Map<DataTableRowKey, boolean>());\r\n\r\n const checkedKeys = options.enableSelection\r\n ? ref<DataTableRowKey[]>([...(options.defaultCheckedKeys || [])])\r\n : ref<DataTableRowKey[]>([]);\r\n\r\n const childSelections = options.enableChildSelection\r\n ? ref(new Map<DataTableRowKey, DataTableRowKey[]>())\r\n : ref(new Map<DataTableRowKey, DataTableRowKey[]>());\r\n\r\n return {\r\n expandedKeys,\r\n expandDataMap,\r\n loadingMap,\r\n checkedKeys,\r\n childSelections,\r\n } as const;\r\n};\r\n\r\n/* ================= 数据工具函数 ================= */\r\nconst useDataUtils = <T extends DataRecord, C>(\r\n options: UseTableExpandOptions<T, C>,\r\n) => {\r\n const data = computed(() => unref(options.data));\r\n\r\n const getRowKey = options.rowKey;\r\n const getChildRowKey =\r\n options.childRowKey || ((child: C): DataTableRowKey => (child as any).id);\r\n\r\n const findRow = (key: DataTableRowKey): T | undefined =>\r\n data.value.find((row) => getRowKey(row) === key);\r\n\r\n const isRowExpandable = options.rowExpandable || ((): boolean => true);\r\n const isRowCheckable = options.rowCheckable || ((): boolean => true);\r\n const isChildRowCheckable =\r\n options.childRowCheckable || ((): boolean => true);\r\n\r\n return {\r\n data,\r\n getRowKey,\r\n getChildRowKey,\r\n findRow,\r\n isRowExpandable,\r\n isRowCheckable,\r\n isChildRowCheckable,\r\n } as const;\r\n};\r\n\r\n/* ================= 展开逻辑 ================= */\r\nconst useExpandLogic = <T extends DataRecord, C>(\r\n state: ReturnType<typeof useExpandState<T, C>>,\r\n utils: ReturnType<typeof useDataUtils<T, C>>,\r\n options: UseTableExpandOptions<T, C>,\r\n) => {\r\n const loadData = async (row: T): Promise<C[]> => {\r\n if (!options.onLoadData) return [];\r\n\r\n const key = utils.getRowKey(row);\r\n const existingData = state.expandDataMap.value.get(key);\r\n if (existingData) return existingData;\r\n\r\n state.loadingMap.value.set(key, true);\r\n\r\n try {\r\n const data = await options.onLoadData(row);\r\n const result = data || [];\r\n state.expandDataMap.value.set(key, result as any);\r\n\r\n if (\r\n options.enableChildSelection &&\r\n !state.childSelections.value.has(key)\r\n ) {\r\n state.childSelections.value.set(key, []);\r\n }\r\n\r\n return result;\r\n } catch (error) {\r\n console.error(\"加载展开数据失败:\", error);\r\n return [];\r\n } finally {\r\n state.loadingMap.value.set(key, false);\r\n }\r\n };\r\n\r\n const handleRowExpand = async (row: T, expanded: boolean): Promise<void> => {\r\n const key = utils.getRowKey(row);\r\n\r\n if (expanded) {\r\n await loadData(row);\r\n if (!state.expandedKeys.value.includes(key)) {\r\n state.expandedKeys.value = [...state.expandedKeys.value, key];\r\n }\r\n } else {\r\n state.expandedKeys.value = state.expandedKeys.value.filter(\r\n (k) => k !== key,\r\n );\r\n }\r\n\r\n options.onExpandChange?.(state.expandedKeys.value);\r\n };\r\n\r\n const expandAll = async (): Promise<void> => {\r\n const expandableRows = utils.data.value.filter(utils.isRowExpandable);\r\n await Promise.allSettled(expandableRows.map(loadData));\r\n state.expandedKeys.value = expandableRows.map(utils.getRowKey);\r\n options.onExpandChange?.(state.expandedKeys.value);\r\n };\r\n\r\n const collapseAll = (): void => {\r\n state.expandedKeys.value = [];\r\n state.childSelections.value.clear();\r\n options.onExpandChange?.(state.expandedKeys.value);\r\n };\r\n\r\n const handleExpandChange = async (keys: DataTableRowKey[]): Promise<void> => {\r\n const newExpandedKeys = keys.filter(\r\n (key) => !state.expandedKeys.value.includes(key),\r\n );\r\n const collapsedKeys = state.expandedKeys.value.filter(\r\n (key) => !keys.includes(key),\r\n );\r\n\r\n await Promise.all(\r\n newExpandedKeys.map(async (key) => {\r\n const row = utils.findRow(key);\r\n if (row) {\r\n await loadData(row);\r\n }\r\n }),\r\n );\r\n\r\n for (const key of collapsedKeys) {\r\n state.childSelections.value.delete(key);\r\n }\r\n\r\n state.expandedKeys.value = keys;\r\n options.onExpandChange?.(keys);\r\n };\r\n\r\n return {\r\n loadData,\r\n handleRowExpand,\r\n expandAll,\r\n collapseAll,\r\n handleExpandChange,\r\n } as const;\r\n};\r\n\r\n/* ================= 选择逻辑 ================= */\r\nconst useSelectionLogic = <T extends DataRecord, C>(\r\n state: ReturnType<typeof useExpandState<T, C>>,\r\n utils: ReturnType<typeof useDataUtils<T, C>>,\r\n options: UseTableExpandOptions<T, C>,\r\n) => {\r\n const selectableRows = computed(() =>\r\n utils.data.value.filter(utils.isRowCheckable),\r\n );\r\n\r\n const selectedRowsCount = computed(() => state.checkedKeys.value.length);\r\n\r\n const selectAll = (): void => {\r\n if (!options.enableSelection) return;\r\n\r\n const keys = selectableRows.value.map(utils.getRowKey);\r\n const finalKeys = options.maxSelection\r\n ? keys.slice(0, options.maxSelection)\r\n : keys;\r\n\r\n state.checkedKeys.value = finalKeys;\r\n\r\n const selectedRows = selectableRows.value.filter((row) =>\r\n finalKeys.includes(utils.getRowKey(row)),\r\n );\r\n\r\n options.onSelectionChange?.(\r\n finalKeys,\r\n selectedRows,\r\n state.childSelections.value,\r\n );\r\n };\r\n\r\n const clearSelection = (): void => {\r\n if (!options.enableSelection) return;\r\n\r\n state.checkedKeys.value = [];\r\n options.onSelectionChange?.([], [], state.childSelections.value);\r\n };\r\n\r\n const handleSelectionChange = (keys: DataTableRowKey[]): void => {\r\n if (!options.enableSelection) return;\r\n\r\n state.checkedKeys.value = keys;\r\n const selectedRows = utils.data.value.filter((row) =>\r\n keys.includes(utils.getRowKey(row)),\r\n );\r\n options.onSelectionChange?.(\r\n keys,\r\n selectedRows,\r\n state.childSelections.value,\r\n );\r\n };\r\n\r\n return {\r\n selectAll,\r\n clearSelection,\r\n handleSelectionChange,\r\n selectedRowsCount,\r\n selectableRows,\r\n } as const;\r\n};\r\n\r\n/* ================= 父子联动逻辑 ================= */\r\nconst useParentChildLink = <T extends DataRecord, C>(\r\n state: ReturnType<typeof useExpandState<T, C>>,\r\n options: UseTableExpandOptions<T, C>,\r\n) => {\r\n const isLinkEnabled = Boolean(\r\n options.enableParentChildLink &&\r\n options.enableSelection &&\r\n options.enableChildSelection,\r\n );\r\n\r\n const handleParentChildLink = (\r\n parentKey: DataTableRowKey,\r\n selectedChildKeys: DataTableRowKey[],\r\n totalChildren: number,\r\n ): void => {\r\n if (!isLinkEnabled) return;\r\n\r\n const shouldSelectParent =\r\n options.parentChildLinkMode === \"strict\"\r\n ? selectedChildKeys.length === totalChildren && totalChildren > 0\r\n : selectedChildKeys.length > 0;\r\n\r\n const currentKeys = [...state.checkedKeys.value];\r\n const isParentSelected = currentKeys.includes(parentKey);\r\n\r\n if (shouldSelectParent && !isParentSelected) {\r\n state.checkedKeys.value = [...currentKeys, parentKey];\r\n } else if (!shouldSelectParent && isParentSelected) {\r\n state.checkedKeys.value = currentKeys.filter((k) => k !== parentKey);\r\n }\r\n };\r\n\r\n return {\r\n handleParentChildLink,\r\n isLinkEnabled,\r\n } as const;\r\n};\r\n\r\n/* ================= 子选择逻辑 ================= */\r\nconst useChildSelectionLogic = <T extends DataRecord, C>(\r\n state: ReturnType<typeof useExpandState<T, C>>,\r\n utils: ReturnType<typeof useDataUtils<T, C>>,\r\n parentChildLink: ReturnType<typeof useParentChildLink<T, C>>,\r\n options: UseTableExpandOptions<T, C>,\r\n) => {\r\n const totalChildSelections = computed(() => {\r\n if (!options.enableChildSelection) return 0;\r\n return Array.from(state.childSelections.value.values()).reduce(\r\n (total, keys) => total + keys.length,\r\n 0,\r\n );\r\n });\r\n\r\n const clearAllSelections = (): void => {\r\n state.checkedKeys.value = [];\r\n state.childSelections.value.clear();\r\n options.onSelectionChange?.([], [], state.childSelections.value);\r\n };\r\n\r\n const handleChildSelectionChange = (\r\n parentKey: DataTableRowKey,\r\n childKeys: DataTableRowKey[],\r\n ): void => {\r\n if (!options.enableChildSelection) return;\r\n\r\n state.childSelections.value.set(parentKey, childKeys);\r\n\r\n const expandData = state.expandDataMap.value.get(parentKey) || [];\r\n const selectedChildren = expandData.filter((child: DataRecord) =>\r\n childKeys.includes(utils.getChildRowKey(child as C)),\r\n ) as C[];\r\n\r\n options.onChildSelectionChange?.(parentKey, childKeys, selectedChildren);\r\n\r\n if (parentChildLink.isLinkEnabled) {\r\n parentChildLink.handleParentChildLink(\r\n parentKey,\r\n childKeys,\r\n expandData.length,\r\n );\r\n }\r\n };\r\n\r\n return {\r\n totalChildSelections,\r\n clearAllSelections,\r\n handleChildSelectionChange,\r\n } as const;\r\n};\r\n\r\n/* ================= 渲染辅助函数 ================= */\r\nconst createChildSelectionState = <T extends DataRecord, C>(\r\n parentKey: DataTableRowKey,\r\n state: ReturnType<typeof useExpandState<T, C>>,\r\n utils: ReturnType<typeof useDataUtils<T, C>>,\r\n childLogic: ReturnType<typeof useChildSelectionLogic<T, C>>,\r\n options: UseTableExpandOptions<T, C>,\r\n): ChildSelectionState | undefined => {\r\n if (!options.enableChildSelection) return undefined;\r\n\r\n const selectedKeys = state.childSelections.value.get(parentKey) || [];\r\n const expandData = state.expandDataMap.value.get(parentKey) || [];\r\n const parent = utils.findRow(parentKey);\r\n\r\n if (!parent) return undefined;\r\n\r\n const checkableChildren = expandData.filter((child: DataRecord) =>\r\n utils.isChildRowCheckable(child as C, parent),\r\n );\r\n\r\n const isAllChecked =\r\n checkableChildren.length > 0 &&\r\n checkableChildren.every((child: DataRecord) =>\r\n selectedKeys.includes(utils.getChildRowKey(child as C)),\r\n );\r\n\r\n return {\r\n selectedKeys,\r\n isAllChecked,\r\n selectAll: () => {\r\n const allKeys = checkableChildren.map((child: DataRecord) =>\r\n utils.getChildRowKey(child as C),\r\n );\r\n childLogic.handleChildSelectionChange(parentKey, allKeys);\r\n },\r\n clearAll: () => {\r\n childLogic.handleChildSelectionChange(parentKey, []);\r\n },\r\n };\r\n};\r\n\r\nconst createLoadingView = (): VNodeChild => {\r\n return h(\"div\", { class: \"flex justify-center items-center py-8\" }, [\r\n h(NSpin, { size: \"small\" }),\r\n h(\"span\", { class: \"ml-2 text-gray-500\" }, \"加载中...\"),\r\n ]);\r\n};\r\n\r\nconst createEmptyView = (): VNodeChild => {\r\n return h(\"div\", { class: \"text-center py-8 text-gray-400\" }, \"暂无数据\");\r\n};\r\n\r\nconst createDefaultColumns = (expandData: DataRecord[]): DataRecord[] => {\r\n if (!expandData.length) return [];\r\n\r\n const firstItem = expandData[0];\r\n if (!firstItem || typeof firstItem !== \"object\") return [];\r\n\r\n const dataKeys = Object.keys(firstItem).filter(\r\n (key) => ![\"id\", \"key\"].includes(key),\r\n );\r\n\r\n return [\r\n {\r\n title: \"序号\",\r\n key: \"_index\",\r\n width: 60,\r\n render: (_: unknown, index: number) => index + 1,\r\n },\r\n ...dataKeys.map((key) => ({\r\n key,\r\n title: key.charAt(0).toUpperCase() + key.slice(1),\r\n width: 120,\r\n ellipsis: { tooltip: true },\r\n })),\r\n ];\r\n};\r\n\r\nconst createDefaultTable = <T extends DataRecord, C>(\r\n key: DataTableRowKey,\r\n expandData: DataRecord[],\r\n childSelection: ChildSelectionState | undefined,\r\n utils: ReturnType<typeof useDataUtils<T, C>>,\r\n childLogic: ReturnType<typeof useChildSelectionLogic<T, C>>,\r\n options: UseTableExpandOptions<T, C>,\r\n): VNodeChild => {\r\n const columns: Array<Record<string, unknown>> = [];\r\n\r\n if (options.enableChildSelection) {\r\n columns.push({ type: \"selection\", multiple: true });\r\n }\r\n\r\n columns.push(...createDefaultColumns(expandData));\r\n\r\n return h(\"div\", { class: \"p-4 bg-gray-50\" }, [\r\n h(\r\n \"div\",\r\n { class: \"mb-2 text-sm text-gray-600\" },\r\n `详细信息 (${expandData.length} 条)`,\r\n ),\r\n h(NDataTable, {\r\n data: expandData,\r\n columns,\r\n size: \"small\",\r\n striped: true,\r\n checkedRowKeys: childSelection?.selectedKeys || [],\r\n rowKey: (row: DataRecord) => utils.getChildRowKey(row as C),\r\n onUpdateCheckedRowKeys: options.enableChildSelection\r\n ? (keys: DataTableRowKey[]) => {\r\n childLogic.handleChildSelectionChange(key, keys);\r\n }\r\n : undefined,\r\n }),\r\n ]);\r\n};\r\n\r\n/* ================= 渲染逻辑 ================= */\r\nconst useRenderer = <T extends DataRecord, C>(\r\n state: ReturnType<typeof useExpandState<T, C>>,\r\n utils: ReturnType<typeof useDataUtils<T, C>>,\r\n childLogic: ReturnType<typeof useChildSelectionLogic<T, C>>,\r\n expandLogic: ReturnType<typeof useExpandLogic<T, C>>,\r\n options: UseTableExpandOptions<T, C>,\r\n) => {\r\n const renderExpandContent = (row: T): VNodeChild => {\r\n const key = utils.getRowKey(row);\r\n const expandData = state.expandDataMap.value.get(key) || [];\r\n const loading = state.loadingMap.value.get(key) || false;\r\n\r\n if (\r\n !expandData.length &&\r\n !loading &&\r\n state.expandedKeys.value.includes(key)\r\n ) {\r\n nextTick(() => {\r\n expandLogic.loadData(row);\r\n });\r\n }\r\n\r\n const childSelection = createChildSelectionState(\r\n key,\r\n state,\r\n utils,\r\n childLogic,\r\n options,\r\n );\r\n\r\n if (options.renderContent) {\r\n return options.renderContent(\r\n row,\r\n expandData as C[],\r\n loading,\r\n childSelection,\r\n );\r\n }\r\n\r\n if (loading) return createLoadingView();\r\n if (!expandData.length) return createEmptyView();\r\n\r\n return createDefaultTable(\r\n key,\r\n expandData,\r\n childSelection,\r\n utils,\r\n childLogic,\r\n options,\r\n );\r\n };\r\n\r\n const getTableColumns = (originalColumns: TableColumn<T>[]): unknown[] => {\r\n return originalColumns.map((column) => {\r\n if ((column as any).type === \"selection\" && options.enableSelection) {\r\n return {\r\n type: \"selection\",\r\n disabled: (row: T) => !utils.isRowCheckable(row),\r\n multiple: !options.maxSelection || options.maxSelection > 1,\r\n };\r\n }\r\n\r\n if (\r\n (column as any).type === \"expand\" &&\r\n (options.onLoadData || options.renderContent)\r\n ) {\r\n return {\r\n type: \"expand\",\r\n expandable: utils.isRowExpandable,\r\n renderExpand: renderExpandContent,\r\n };\r\n }\r\n\r\n return column;\r\n });\r\n };\r\n\r\n return {\r\n getTableColumns,\r\n } as const;\r\n};\r\n\r\n/* ================= 主函数 ================= */\r\nexport function useTableExpand<\r\n T extends DataRecord = Record<string, any>,\r\n C = any,\r\n>(options: UseTableExpandOptions<T, C>): UseTableExpandReturn<T, C> {\r\n const state = useExpandState(options);\r\n const utils = useDataUtils(options);\r\n const expandLogic = useExpandLogic(state, utils, options);\r\n const selectionLogic = useSelectionLogic(state, utils, options);\r\n const parentChildLink = useParentChildLink(state, options);\r\n const childLogic = useChildSelectionLogic(\r\n state,\r\n utils,\r\n parentChildLink,\r\n options,\r\n );\r\n const renderer = useRenderer(state, utils, childLogic, expandLogic, options);\r\n\r\n if (options.onSelectionChange && options.enableSelection) {\r\n watchEffect(() => {\r\n if (!options.onSelectionChange) return;\r\n\r\n const selectedRows = utils.data.value.filter((row) =>\r\n state.checkedKeys.value.includes(utils.getRowKey(row)),\r\n );\r\n\r\n const hasSelection = state.checkedKeys.value.length > 0;\r\n const hasData = utils.data.value.length > 0;\r\n\r\n if (hasSelection || !hasData) {\r\n options.onSelectionChange(\r\n state.checkedKeys.value,\r\n selectedRows,\r\n state.childSelections.value,\r\n );\r\n }\r\n });\r\n }\r\n\r\n const expandRow = async (key: DataTableRowKey): Promise<void> => {\r\n if (state.expandedKeys.value.includes(key)) return;\r\n\r\n const row = utils.findRow(key);\r\n if (!row) return;\r\n\r\n await expandLogic.loadData(row);\r\n state.expandedKeys.value = [...state.expandedKeys.value, key];\r\n options.onExpandChange?.(state.expandedKeys.value, row, true);\r\n };\r\n\r\n const initializeData = async (): Promise<void> => {\r\n const keysToLoad = options.defaultExpandedKeys || [];\r\n if (keysToLoad.length === 0) return;\r\n\r\n const loadPromises = keysToLoad.map(async (key) => {\r\n const row = utils.findRow(key);\r\n if (row && !state.expandDataMap.value.has(key)) {\r\n await expandLogic.loadData(row);\r\n }\r\n });\r\n\r\n await Promise.allSettled(loadPromises);\r\n };\r\n\r\n if (options.defaultExpandedKeys?.length) {\r\n nextTick(initializeData);\r\n }\r\n\r\n return {\r\n expandedKeys: state.expandedKeys,\r\n checkedKeys: state.checkedKeys,\r\n childSelections: state.childSelections,\r\n\r\n selectedRowsCount: selectionLogic.selectedRowsCount,\r\n totalChildSelections: childLogic.totalChildSelections,\r\n\r\n expandAll: expandLogic.expandAll,\r\n collapseAll: expandLogic.collapseAll,\r\n expandRow,\r\n handleExpandChange: expandLogic.handleExpandChange,\r\n\r\n selectAll: selectionLogic.selectAll,\r\n clearSelection: selectionLogic.clearSelection,\r\n clearAllSelections: childLogic.clearAllSelections,\r\n handleSelectionChange: selectionLogic.handleSelectionChange,\r\n\r\n getTableColumns: renderer.getTableColumns,\r\n\r\n expandDataMap: state.expandDataMap,\r\n loadingMap: state.loadingMap,\r\n };\r\n}\r\n","/*\r\n * @Description: 打印水印组合工具 - 封装 printJS 和 html2canvas\r\n * @Migration: naive-ui-components 组件库迁移版本(从 @/hooks/usePrintWatermark 迁移)\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { ref, nextTick } from \"vue\";\r\nimport html2canvas from \"html2canvas\";\r\nimport printJS from \"print-js\";\r\n\r\n/* ================= 类型定义 ================= */\r\n\r\n/** 消息提示 API 接口 */\r\ninterface MessageApi {\r\n success: (msg: string) => void;\r\n error: (msg: string) => void;\r\n warning: (msg: string) => void;\r\n}\r\n\r\nexport interface WatermarkConfig {\r\n text: string;\r\n textSize?: number;\r\n textColor?: string;\r\n font?: string;\r\n opacity?: number;\r\n rotate?: number;\r\n position?: \"center\" | \"repeat\" | \"corner\" | \"diagonal\";\r\n xGap?: number;\r\n yGap?: number;\r\n}\r\n\r\nexport interface CaptureConfig {\r\n scale?: number;\r\n quality?: number;\r\n format?: \"png\" | \"jpeg\" | \"webp\";\r\n backgroundColor?: string;\r\n logging?: boolean;\r\n allowTaint?: boolean;\r\n useCORS?: boolean;\r\n}\r\n\r\nexport interface PrintConfig {\r\n orientation?: \"portrait\" | \"landscape\";\r\n paperSize?: \"A4\" | \"A3\" | \"Letter\" | string;\r\n margin?: string;\r\n style?: string;\r\n header?: string;\r\n footer?: string;\r\n showModal?: boolean;\r\n modalMessage?: string;\r\n onLoadingStart?: () => void;\r\n onLoadingEnd?: () => void;\r\n onPrintDialogClose?: () => void;\r\n}\r\n\r\nexport interface PrintWatermarkOptions {\r\n watermark?: WatermarkConfig;\r\n capture?: CaptureConfig;\r\n print?: PrintConfig;\r\n}\r\n\r\n/* ================= 默认配置 ================= */\r\nconst DEFAULT_WATERMARK: Required<WatermarkConfig> = {\r\n text: \"Robot Admin\",\r\n textSize: 16,\r\n textColor: \"rgba(128, 128, 128, 0.3)\",\r\n font: \"Microsoft JhengHei\",\r\n opacity: 0.3,\r\n rotate: -20,\r\n position: \"repeat\",\r\n xGap: 200,\r\n yGap: 120,\r\n};\r\n\r\nconst DEFAULT_CAPTURE: Required<Omit<CaptureConfig, \"dpi\">> = {\r\n scale: 1,\r\n quality: 0.92,\r\n format: \"png\",\r\n backgroundColor: \"#ffffff\",\r\n logging: false,\r\n allowTaint: true,\r\n useCORS: true,\r\n};\r\n\r\nconst DEFAULT_PRINT: Required<\r\n Omit<PrintConfig, \"onPrintDialogOpen\" | \"onError\">\r\n> = {\r\n orientation: \"portrait\",\r\n paperSize: \"A4\",\r\n margin: \"10mm 10mm 0 10mm\",\r\n style:\r\n \"@page { margin: 10mm 10mm 0 10mm; } @media print { body { margin: 0; } }\",\r\n header: \"\",\r\n footer: \"\",\r\n showModal: false,\r\n modalMessage: \"正在准备打印...\",\r\n onLoadingStart: () => {},\r\n onLoadingEnd: () => {},\r\n onPrintDialogClose: () => {},\r\n};\r\n\r\n/* ================= 水印绘制函数 ================= */\r\n\r\nfunction drawCenterWatermark(\r\n ctx: CanvasRenderingContext2D,\r\n width: number,\r\n height: number,\r\n config: Required<WatermarkConfig>,\r\n) {\r\n ctx.save();\r\n ctx.translate(width / 2, height / 2);\r\n ctx.rotate((config.rotate * Math.PI) / 180);\r\n ctx.fillText(config.text, 0, 0);\r\n ctx.restore();\r\n}\r\n\r\nfunction drawCornerWatermark(\r\n ctx: CanvasRenderingContext2D,\r\n width: number,\r\n height: number,\r\n config: Required<WatermarkConfig>,\r\n) {\r\n const offset = 50;\r\n const corners = [\r\n [offset, offset],\r\n [width - offset, offset],\r\n [offset, height - offset],\r\n [width - offset, height - offset],\r\n ];\r\n\r\n corners.forEach(([x, y]) => {\r\n ctx.save();\r\n ctx.translate(x, y);\r\n ctx.rotate((config.rotate * Math.PI) / 180);\r\n ctx.fillText(config.text, 0, 0);\r\n ctx.restore();\r\n });\r\n}\r\n\r\nfunction drawDiagonalWatermark(\r\n ctx: CanvasRenderingContext2D,\r\n width: number,\r\n height: number,\r\n config: Required<WatermarkConfig>,\r\n) {\r\n const diagonal = Math.sqrt(width * width + height * height);\r\n const centerX = width / 2;\r\n const centerY = height / 2;\r\n\r\n ctx.save();\r\n ctx.translate(centerX, centerY);\r\n ctx.rotate(Math.atan2(height, width));\r\n\r\n const count = Math.floor(diagonal / config.xGap);\r\n const start = -diagonal / 2;\r\n\r\n for (let i = 0; i <= count; i++) {\r\n const x = start + i * config.xGap;\r\n ctx.fillText(config.text, x, 0);\r\n }\r\n\r\n ctx.restore();\r\n}\r\n\r\nfunction drawRepeatWatermark(\r\n ctx: CanvasRenderingContext2D,\r\n width: number,\r\n height: number,\r\n config: Required<WatermarkConfig>,\r\n) {\r\n const cols = Math.ceil(width / config.xGap) + 1;\r\n const rows = Math.ceil(height / config.yGap) + 1;\r\n\r\n for (let row = 0; row < rows; row++) {\r\n for (let col = 0; col < cols; col++) {\r\n const x = col * config.xGap + config.xGap / 2;\r\n const y = row * config.yGap + config.yGap / 2;\r\n\r\n ctx.save();\r\n ctx.translate(x, y);\r\n ctx.rotate((config.rotate * Math.PI) / 180);\r\n ctx.fillText(config.text, 0, 0);\r\n ctx.restore();\r\n }\r\n }\r\n}\r\n\r\nfunction drawWatermark(\r\n canvas: HTMLCanvasElement,\r\n config: WatermarkConfig,\r\n): HTMLCanvasElement {\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) return canvas;\r\n\r\n const finalConfig = { ...DEFAULT_WATERMARK, ...config };\r\n const { width, height } = canvas;\r\n\r\n ctx.save();\r\n ctx.globalAlpha = finalConfig.opacity;\r\n ctx.font = `${finalConfig.textSize}px ${finalConfig.font}`;\r\n ctx.fillStyle = finalConfig.textColor;\r\n ctx.textAlign = \"center\";\r\n ctx.textBaseline = \"middle\";\r\n\r\n const drawFunctions = {\r\n center: drawCenterWatermark,\r\n corner: drawCornerWatermark,\r\n diagonal: drawDiagonalWatermark,\r\n repeat: drawRepeatWatermark,\r\n };\r\n\r\n const drawFunction =\r\n drawFunctions[finalConfig.position] || drawFunctions.repeat;\r\n drawFunction(ctx, width, height, finalConfig);\r\n\r\n ctx.restore();\r\n return canvas;\r\n}\r\n\r\n/* ================= 截图函数 ================= */\r\n\r\nasync function captureElement(\r\n element: HTMLElement,\r\n config: CaptureConfig = {},\r\n): Promise<HTMLCanvasElement> {\r\n const finalConfig = { ...DEFAULT_CAPTURE, ...config };\r\n\r\n return await html2canvas(element, {\r\n logging: finalConfig.logging,\r\n scale: finalConfig.scale,\r\n allowTaint: finalConfig.allowTaint,\r\n useCORS: finalConfig.useCORS,\r\n backgroundColor: finalConfig.backgroundColor,\r\n onclone: (clonedDoc) => {\r\n const clonedElement = clonedDoc.body;\r\n clonedElement.style.transform = \"scale(1)\";\r\n },\r\n });\r\n}\r\n\r\nfunction canvasToDataURL(\r\n canvas: HTMLCanvasElement,\r\n format: \"png\" | \"jpeg\" | \"webp\" = \"png\",\r\n quality: number = 0.92,\r\n): string {\r\n const mimeType = `image/${format}`;\r\n return format === \"png\"\r\n ? canvas.toDataURL(mimeType)\r\n : canvas.toDataURL(mimeType, quality);\r\n}\r\n\r\nfunction downloadCanvas(\r\n canvas: HTMLCanvasElement,\r\n filename: string = `screenshot-${new Date().toISOString().slice(0, 10)}.png`,\r\n format: \"png\" | \"jpeg\" | \"webp\" = \"png\",\r\n) {\r\n const dataURL = canvasToDataURL(canvas, format);\r\n const link = document.createElement(\"a\");\r\n link.download = filename;\r\n link.href = dataURL;\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n}\r\n\r\n/* ================= 打印函数 ================= */\r\n\r\nlet focusInterval: ReturnType<typeof setInterval> | null = null;\r\n\r\nfunction startFocusKeep() {\r\n focusInterval = setInterval(() => {\r\n window.dispatchEvent(new Event(\"focus\"));\r\n }, 500);\r\n}\r\n\r\nfunction stopFocusKeep() {\r\n if (focusInterval) {\r\n clearInterval(focusInterval);\r\n focusInterval = null;\r\n }\r\n}\r\n\r\nfunction printImage(\r\n imageDataURL: string,\r\n config: PrintConfig = {},\r\n): Promise<void> {\r\n const finalConfig = { ...DEFAULT_PRINT, ...config };\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n try {\r\n startFocusKeep();\r\n finalConfig.onLoadingStart?.();\r\n\r\n printJS({\r\n printable: imageDataURL,\r\n type: \"image\",\r\n style: finalConfig.style,\r\n showModal: finalConfig.showModal,\r\n modalMessage: finalConfig.modalMessage,\r\n onLoadingEnd: finalConfig.onLoadingEnd,\r\n onPrintDialogClose: () => {\r\n stopFocusKeep();\r\n finalConfig.onPrintDialogClose?.();\r\n resolve();\r\n },\r\n });\r\n } catch (error) {\r\n stopFocusKeep();\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\n/* ================= 合并打印辅助函数 ================= */\r\n\r\nfunction calculateMergedCanvasSize(\r\n canvases: HTMLCanvasElement[],\r\n orientation: \"horizontal\" | \"vertical\",\r\n spacing: number,\r\n) {\r\n let totalWidth = 0;\r\n let totalHeight = 0;\r\n\r\n canvases.forEach((canvas) => {\r\n const { width, height } = canvas;\r\n\r\n if (orientation === \"horizontal\") {\r\n totalWidth += width;\r\n totalHeight = Math.max(totalHeight, height);\r\n } else {\r\n totalWidth = Math.max(totalWidth, width);\r\n totalHeight += height;\r\n }\r\n });\r\n\r\n const spacingTotal = (canvases.length - 1) * spacing;\r\n if (orientation === \"horizontal\") {\r\n totalWidth += spacingTotal;\r\n } else {\r\n totalHeight += spacingTotal;\r\n }\r\n\r\n return { totalWidth, totalHeight };\r\n}\r\n\r\nfunction createMergedCanvas(\r\n canvases: HTMLCanvasElement[],\r\n options: {\r\n orientation: \"horizontal\" | \"vertical\";\r\n spacing: number;\r\n backgroundColor: string;\r\n totalWidth: number;\r\n totalHeight: number;\r\n },\r\n): HTMLCanvasElement {\r\n const { orientation, spacing, backgroundColor, totalWidth, totalHeight } =\r\n options;\r\n\r\n const mergedCanvas = document.createElement(\"canvas\");\r\n mergedCanvas.width = totalWidth;\r\n mergedCanvas.height = totalHeight;\r\n\r\n const ctx = mergedCanvas.getContext(\"2d\");\r\n if (!ctx) throw new Error(\"无法创建画布上下文\");\r\n\r\n ctx.fillStyle = backgroundColor;\r\n ctx.fillRect(0, 0, totalWidth, totalHeight);\r\n\r\n let currentX = 0;\r\n let currentY = 0;\r\n\r\n canvases.forEach((canvas) => {\r\n ctx.drawImage(canvas, currentX, currentY);\r\n\r\n if (orientation === \"horizontal\") {\r\n currentX += canvas.width + spacing;\r\n } else {\r\n currentY += canvas.height + spacing;\r\n }\r\n });\r\n\r\n return mergedCanvas;\r\n}\r\n\r\nfunction validateAndGetMergeOptions(\r\n elements: HTMLElement[],\r\n mergeOptions: {\r\n orientation?: \"horizontal\" | \"vertical\";\r\n spacing?: number;\r\n backgroundColor?: string;\r\n },\r\n message: MessageApi,\r\n) {\r\n if (!elements.length) {\r\n message.warning(\"没有要打印的元素\");\r\n return null;\r\n }\r\n\r\n return {\r\n orientation: mergeOptions.orientation || \"vertical\",\r\n spacing: mergeOptions.spacing || 20,\r\n backgroundColor: mergeOptions.backgroundColor || \"#ffffff\",\r\n };\r\n}\r\n\r\nasync function captureAndMergeCanvas(\r\n elements: HTMLElement[],\r\n options: PrintWatermarkOptions,\r\n validatedOptions: {\r\n orientation: \"horizontal\" | \"vertical\";\r\n spacing: number;\r\n backgroundColor: string;\r\n },\r\n updateProgress: (value: number) => void,\r\n): Promise<HTMLCanvasElement> {\r\n const { orientation, spacing, backgroundColor } = validatedOptions;\r\n\r\n updateProgress(10);\r\n const canvases = await Promise.all(\r\n elements.map((element) => captureElement(element, options.capture)),\r\n );\r\n\r\n updateProgress(50);\r\n const { totalWidth, totalHeight } = calculateMergedCanvasSize(\r\n canvases,\r\n orientation,\r\n spacing,\r\n );\r\n\r\n updateProgress(60);\r\n return createMergedCanvas(canvases, {\r\n orientation,\r\n spacing,\r\n backgroundColor,\r\n totalWidth,\r\n totalHeight,\r\n });\r\n}\r\n\r\nasync function addWatermarkAndPrint(\r\n mergedCanvas: HTMLCanvasElement,\r\n options: PrintWatermarkOptions,\r\n elementsCount: number,\r\n updateProgress: (value: number) => void,\r\n message: MessageApi,\r\n): Promise<void> {\r\n updateProgress(70);\r\n\r\n if (options.watermark) {\r\n drawWatermark(mergedCanvas, options.watermark);\r\n }\r\n\r\n updateProgress(90);\r\n const imageUrl = canvasToDataURL(\r\n mergedCanvas,\r\n options.capture?.format,\r\n options.capture?.quality,\r\n );\r\n await printImage(imageUrl, options.print);\r\n\r\n updateProgress(100);\r\n message.success(`合并打印完成,共合并 ${elementsCount} 个元素`);\r\n}\r\n\r\n/* ================= 主要的 Composable ================= */\r\n\r\nexport function usePrintWatermark() {\r\n /* NOTE: useMessage() requires naive-ui provider context; caller must ensure NMessageProvider is present */\r\n let message: MessageApi;\r\n try {\r\n /* dynamic import not possible; rely on naive-ui auto-import or global provider */\r\n const { useMessage: _useMessage } = require(\"naive-ui\");\r\n message = _useMessage();\r\n } catch {\r\n message = {\r\n success: (msg: string) => console.log(\"[PrintWatermark]\", msg),\r\n error: (msg: string) => console.error(\"[PrintWatermark]\", msg),\r\n warning: (msg: string) => console.warn(\"[PrintWatermark]\", msg),\r\n };\r\n }\r\n const loading = ref(false);\r\n const progress = ref(0);\r\n\r\n const updateProgress = (value: number) => {\r\n progress.value = Math.max(0, Math.min(100, value));\r\n };\r\n\r\n const captureWithWatermark = async (\r\n element: HTMLElement,\r\n options: PrintWatermarkOptions = {},\r\n ): Promise<string> => {\r\n try {\r\n updateProgress(0);\r\n updateProgress(30);\r\n const canvas = await captureElement(element, options.capture);\r\n\r\n updateProgress(60);\r\n if (options.watermark) {\r\n drawWatermark(canvas, options.watermark);\r\n }\r\n\r\n updateProgress(90);\r\n const format = options.capture?.format || \"png\";\r\n const quality = options.capture?.quality || 0.92;\r\n const dataURL = canvasToDataURL(canvas, format, quality);\r\n\r\n updateProgress(100);\r\n return dataURL;\r\n } catch (error) {\r\n console.error(\"截图失败:\", error);\r\n throw new Error(\r\n `截图失败: ${error instanceof Error ? error.message : \"未知错误\"}`,\r\n );\r\n }\r\n };\r\n\r\n const printWithWatermark = async (\r\n element: HTMLElement,\r\n options: PrintWatermarkOptions = {},\r\n ): Promise<void> => {\r\n loading.value = true;\r\n updateProgress(0);\r\n\r\n try {\r\n await nextTick();\r\n const imageDataURL = await captureWithWatermark(element, options);\r\n updateProgress(95);\r\n await printImage(imageDataURL, options.print);\r\n updateProgress(100);\r\n message.success(\"打印完成\");\r\n } catch (error) {\r\n console.error(\"打印失败:\", error);\r\n message.error(\r\n `打印失败: ${error instanceof Error ? error.message : \"未知错误\"}`,\r\n );\r\n throw error;\r\n } finally {\r\n loading.value = false;\r\n updateProgress(0);\r\n }\r\n };\r\n\r\n const downloadScreenshot = async (\r\n element: HTMLElement,\r\n filename?: string,\r\n options: PrintWatermarkOptions = {},\r\n ): Promise<void> => {\r\n loading.value = true;\r\n\r\n try {\r\n await nextTick();\r\n const canvas = await captureElement(element, options.capture);\r\n\r\n if (options.watermark) {\r\n drawWatermark(canvas, options.watermark);\r\n }\r\n\r\n const format = options.capture?.format || \"png\";\r\n const defaultFilename = `screenshot-${new Date()\r\n .toISOString()\r\n .slice(0, 19)\r\n .replace(/:/g, \"-\")}.${format}`;\r\n\r\n downloadCanvas(canvas, filename || defaultFilename, format);\r\n message.success(\"下载完成\");\r\n } catch (error) {\r\n console.error(\"下载失败:\", error);\r\n message.error(\"下载失败\");\r\n throw error;\r\n } finally {\r\n loading.value = false;\r\n }\r\n };\r\n\r\n const quickPrint = async (\r\n element: HTMLElement,\r\n watermarkText: string = \"Robot Admin\",\r\n ): Promise<void> => {\r\n return printWithWatermark(element, {\r\n watermark: {\r\n text: watermarkText,\r\n position: \"repeat\",\r\n textColor: \"rgba(128, 128, 128, 0.3)\",\r\n },\r\n });\r\n };\r\n\r\n const batchCapture = async (\r\n elements: HTMLElement[],\r\n options: PrintWatermarkOptions = {},\r\n ): Promise<string[]> => {\r\n const total = elements.length;\r\n updateProgress(10);\r\n\r\n const capturePromises = elements.map(async (element, index) => {\r\n const url = await captureWithWatermark(element, options);\r\n updateProgress(10 + ((index + 1) / total) * 70);\r\n return url;\r\n });\r\n\r\n return Promise.all(capturePromises);\r\n };\r\n\r\n const serialPrint = async (\r\n imageUrls: string[],\r\n printConfig: PrintConfig = {},\r\n ): Promise<void> => {\r\n await imageUrls.reduce(async (prevPromise, imageUrl, index) => {\r\n await prevPromise;\r\n await printImage(imageUrl, printConfig);\r\n\r\n if (index < imageUrls.length - 1) {\r\n await new Promise<void>((resolve) => {\r\n setTimeout(() => resolve(), 1000);\r\n });\r\n }\r\n }, Promise.resolve());\r\n };\r\n\r\n const batchPrint = async (\r\n elements: HTMLElement[],\r\n options: PrintWatermarkOptions = {},\r\n ): Promise<void> => {\r\n if (!elements.length) {\r\n message.warning(\"没有要打印的元素\");\r\n return;\r\n }\r\n\r\n loading.value = true;\r\n\r\n try {\r\n updateProgress(0);\r\n const imageUrls = await batchCapture(elements, options);\r\n updateProgress(80);\r\n await serialPrint(imageUrls, options.print);\r\n updateProgress(100);\r\n message.success(`批量打印完成,共 ${elements.length} 个元素`);\r\n } catch (error) {\r\n console.error(\"批量打印失败:\", error);\r\n message.error(\"批量打印失败\");\r\n throw error;\r\n } finally {\r\n loading.value = false;\r\n updateProgress(0);\r\n }\r\n };\r\n\r\n const mergePrint = async (\r\n elements: HTMLElement[],\r\n options: PrintWatermarkOptions = {},\r\n mergeOptions: {\r\n orientation?: \"horizontal\" | \"vertical\";\r\n spacing?: number;\r\n backgroundColor?: string;\r\n } = {},\r\n ): Promise<void> => {\r\n const validatedOptions = validateAndGetMergeOptions(\r\n elements,\r\n mergeOptions,\r\n message,\r\n );\r\n if (!validatedOptions) return;\r\n\r\n loading.value = true;\r\n\r\n try {\r\n const mergedCanvas = await captureAndMergeCanvas(\r\n elements,\r\n options,\r\n validatedOptions,\r\n updateProgress,\r\n );\r\n await addWatermarkAndPrint(\r\n mergedCanvas,\r\n options,\r\n elements.length,\r\n updateProgress,\r\n message,\r\n );\r\n } catch (error) {\r\n console.error(\"合并打印失败:\", error);\r\n message.error(\"合并打印失败\");\r\n throw error;\r\n } finally {\r\n loading.value = false;\r\n updateProgress(0);\r\n }\r\n };\r\n\r\n const createPreset = (name: string, options: PrintWatermarkOptions) => {\r\n return {\r\n use: (element: HTMLElement) => printWithWatermark(element, options),\r\n download: (element: HTMLElement, filename?: string) =>\r\n downloadScreenshot(element, filename, options),\r\n };\r\n };\r\n\r\n return {\r\n loading,\r\n progress,\r\n\r\n captureWithWatermark,\r\n printWithWatermark,\r\n downloadScreenshot,\r\n quickPrint,\r\n batchCapture,\r\n batchPrint,\r\n mergePrint,\r\n\r\n createPreset,\r\n updateProgress,\r\n\r\n utils: {\r\n captureElement,\r\n drawWatermark,\r\n canvasToDataURL,\r\n downloadCanvas,\r\n printImage,\r\n },\r\n };\r\n}\r\n\r\n/* ================= 预设配置 ================= */\r\nexport const printPresets = {\r\n table: {\r\n watermark: {\r\n text: \"Robot Admin - 数据表格\",\r\n position: \"repeat\" as const,\r\n textColor: \"rgba(100, 100, 100, 0.25)\",\r\n textSize: 14,\r\n xGap: 250,\r\n yGap: 120,\r\n },\r\n capture: {\r\n scale: 1.2,\r\n },\r\n print: {\r\n orientation: \"landscape\" as const,\r\n style: \"@page { margin: 8mm; } body { font-family: Arial, sans-serif; }\",\r\n },\r\n },\r\n\r\n form: {\r\n watermark: {\r\n text: \"Robot Admin - 表单数据\",\r\n position: \"diagonal\" as const,\r\n textColor: \"rgba(150, 150, 150, 0.2)\",\r\n textSize: 16,\r\n },\r\n print: {\r\n orientation: \"portrait\" as const,\r\n },\r\n },\r\n\r\n report: {\r\n watermark: {\r\n text: \"Robot Admin - 机密报告\",\r\n position: \"center\" as const,\r\n textColor: \"rgba(200, 50, 50, 0.15)\",\r\n textSize: 24,\r\n },\r\n capture: {\r\n quality: 0.95,\r\n format: \"png\" as const,\r\n },\r\n },\r\n} as const;\r\n\r\n/* ================= 工具函数导出 ================= */\r\nexport {\r\n drawWatermark,\r\n captureElement,\r\n canvasToDataURL,\r\n downloadCanvas,\r\n printImage,\r\n};\r\n","/*\r\n * @Description: 表格动态行操作 Hooks — 增行、插行、删除行、复制行、调整行、单选功能、打印功能\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport {\r\n h,\r\n ref,\r\n computed,\r\n onBeforeUnmount,\r\n type Ref,\r\n type RendererElement,\r\n type RendererNode,\r\n type VNodeChild,\r\n} from \"vue\";\r\nimport {\r\n type DataTableRowKey,\r\n NButton,\r\n NTooltip,\r\n NModal,\r\n NButtonGroup,\r\n NSpace,\r\n useMessage,\r\n} from \"naive-ui/es\";\r\nimport {\r\n usePrintWatermark,\r\n printPresets,\r\n type PrintWatermarkOptions,\r\n} from \"./usePrintWatermark\";\r\nimport type { TableColumn, DataRecord } from \"../types\";\r\nimport C_Icon from \"../../C_Icon/index.vue\";\r\n\r\n/* ================= 类型定义 ================= */\r\nexport interface DynamicRowsOptions<T extends DataRecord = DataRecord> {\r\n /* 基础配置 */\r\n rowKey?: string | ((row: T) => DataTableRowKey);\r\n defaultRowData?: () => T;\r\n\r\n /* 功能开关 */\r\n enableRadioSelection?: boolean;\r\n enableAdd?: boolean;\r\n enableInsert?: boolean;\r\n enableDelete?: boolean;\r\n enableCopy?: boolean;\r\n enableMove?: boolean;\r\n enablePrint?: boolean;\r\n\r\n /* 打印配置 */\r\n printOptions?: PrintWatermarkOptions;\r\n printPreset?: \"table\" | \"form\" | \"report\";\r\n printWatermarkText?: string;\r\n printTargetSelector?: string;\r\n\r\n /* 交互配置 */\r\n confirmDelete?: boolean;\r\n deleteConfirmText?: string;\r\n\r\n /* 事件回调 */\r\n onRowChange?: (data: T[]) => void;\r\n onSelectionChange?: (\r\n selectedKey: DataTableRowKey | null,\r\n selectedRow: T | null,\r\n ) => void;\r\n onRowAdd?: (newRow: T) => void;\r\n onRowDelete?: (deletedRow: T, index: number) => void;\r\n onRowCopy?: (originalRow: T, newRow: T) => void;\r\n onRowMove?: (row: T, fromIndex: number, toIndex: number) => void;\r\n}\r\n\r\nexport interface DynamicRowsReturn<T extends DataRecord = DataRecord> {\r\n /* 状态 */\r\n selectedRowKey: Ref<DataTableRowKey | null>;\r\n selectedRowData: Ref<T | null>;\r\n selectedRowIndex: Ref<number>;\r\n canMoveUp: Ref<boolean>;\r\n canMoveDown: Ref<boolean>;\r\n deleteConfirmVisible: Ref<boolean>;\r\n printLoading: Ref<boolean>;\r\n printProgress: Ref<number>;\r\n\r\n /* 行操作方法 */\r\n addRow: () => void;\r\n insertRow: () => void;\r\n deleteRow: () => void;\r\n confirmDelete: () => void;\r\n copyRow: () => void;\r\n moveRowUp: () => void;\r\n moveRowDown: () => void;\r\n\r\n /* 选择方法 */\r\n selectRow: (key: DataTableRowKey) => void;\r\n clearSelection: () => void;\r\n\r\n /* 打印方法 */\r\n handlePrint: (elementRef: Ref<HTMLElement | undefined>) => Promise<void>;\r\n handleDownload: (\r\n elementRef: Ref<HTMLElement | undefined>,\r\n filename?: string,\r\n ) => Promise<void>;\r\n handleQuickPrint: (elementRef: Ref<HTMLElement | undefined>) => Promise<void>;\r\n\r\n /* 列增强方法 */\r\n enhanceColumns: (columns: TableColumn<T>[]) => TableColumn<T>[];\r\n\r\n /* 工具栏渲染 */\r\n renderToolbar: () => VNodeChild;\r\n renderConfirmModal: () => VNodeChild;\r\n}\r\n\r\n/* ================= 辅助函数 ================= */\r\n\r\n/** 生成唯一ID */\r\nfunction generateUniqueId(): string {\r\n return `row_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\r\n}\r\n\r\n/** 获取行键值 */\r\nfunction getRowKey<T extends DataRecord>(\r\n row: T,\r\n rowKey: string | ((row: T) => DataTableRowKey),\r\n): DataTableRowKey {\r\n return typeof rowKey === \"function\" ? rowKey(row) : (row as any)[rowKey];\r\n}\r\n\r\n/** 创建新行数据 */\r\nfunction createNewRow<T extends DataRecord>(\r\n defaultRowData: (() => T) | undefined,\r\n rowKey: string | ((row: T) => DataTableRowKey),\r\n): T {\r\n const newRow = defaultRowData?.() || ({} as T);\r\n const keyField = typeof rowKey === \"string\" ? rowKey : \"id\";\r\n return {\r\n ...newRow,\r\n [keyField]: generateUniqueId(),\r\n } as T;\r\n}\r\n\r\n/* ================= 主函数 ================= */\r\n\r\n/**\r\n * 表格动态行操作功能组合\r\n */\r\nexport function useDynamicRows<T extends DataRecord = DataRecord>(\r\n data: Ref<T[]>,\r\n options: DynamicRowsOptions<T> = {},\r\n): DynamicRowsReturn<T> {\r\n const message = useMessage();\r\n\r\n /* 默认配置 */\r\n const finalOptions = {\r\n rowKey: \"id\",\r\n enableRadioSelection: true,\r\n enableAdd: true,\r\n enableInsert: true,\r\n enableDelete: true,\r\n enableCopy: true,\r\n enableMove: true,\r\n enablePrint: true,\r\n confirmDelete: true,\r\n deleteConfirmText: \"确定要删除选中的行吗?此操作不可撤销。\",\r\n printPreset: \"table\" as const,\r\n printTargetSelector: \".c-table-wrapper\",\r\n defaultRowData: () => ({}) as T,\r\n ...options,\r\n };\r\n\r\n /* 状态 */\r\n const selectedRowKey = ref<DataTableRowKey | null>(null);\r\n const deleteConfirmVisible = ref(false);\r\n\r\n const selectedRowData = computed(() => {\r\n if (selectedRowKey.value === null) return null;\r\n return (\r\n data.value.find(\r\n (row) => getRowKey(row, finalOptions.rowKey) === selectedRowKey.value,\r\n ) || null\r\n );\r\n });\r\n\r\n const selectedRowIndex = computed(() => {\r\n if (!selectedRowData.value) return -1;\r\n return data.value.findIndex((row) => row === selectedRowData.value);\r\n });\r\n\r\n const canMoveUp = computed(() => selectedRowIndex.value > 0);\r\n const canMoveDown = computed(\r\n () =>\r\n selectedRowIndex.value >= 0 &&\r\n selectedRowIndex.value < data.value.length - 1,\r\n );\r\n\r\n /* 打印功能 */\r\n const {\r\n loading: printLoading,\r\n progress: printProgress,\r\n printWithWatermark,\r\n downloadScreenshot,\r\n quickPrint,\r\n } = usePrintWatermark();\r\n\r\n /** 获取打印配置选项 */\r\n const getPrintOptions = (): PrintWatermarkOptions => {\r\n if (finalOptions.printOptions) {\r\n return finalOptions.printOptions;\r\n }\r\n\r\n const preset = finalOptions.printPreset || \"table\";\r\n const baseConfig = printPresets[preset];\r\n\r\n if (finalOptions.printWatermarkText && baseConfig.watermark) {\r\n return {\r\n ...baseConfig,\r\n watermark: {\r\n ...baseConfig.watermark,\r\n text: finalOptions.printWatermarkText,\r\n },\r\n };\r\n }\r\n\r\n return baseConfig;\r\n };\r\n\r\n /** 更新表格数据 */\r\n const updateData = (newData: T[]) => {\r\n data.value = newData;\r\n finalOptions.onRowChange?.(newData);\r\n };\r\n\r\n /** 添加新行到表格末尾 */\r\n const addRow = () => {\r\n if (!finalOptions.enableAdd) return;\r\n\r\n const newRow = createNewRow(\r\n finalOptions.defaultRowData,\r\n finalOptions.rowKey,\r\n );\r\n const newData = [...data.value, newRow];\r\n updateData(newData);\r\n finalOptions.onRowAdd?.(newRow);\r\n message.success(\"添加行成功\");\r\n };\r\n\r\n /** 在选中行后插入新行 */\r\n const insertRow = () => {\r\n if (!finalOptions.enableInsert || !selectedRowData.value) {\r\n message.warning(\"请先选择一行数据\");\r\n return;\r\n }\r\n\r\n const newRow = createNewRow(\r\n finalOptions.defaultRowData,\r\n finalOptions.rowKey,\r\n );\r\n const newData = [...data.value];\r\n newData.splice(selectedRowIndex.value + 1, 0, newRow);\r\n updateData(newData);\r\n finalOptions.onRowAdd?.(newRow);\r\n message.success(\"插入行成功\");\r\n };\r\n\r\n /** 删除选中的行 */\r\n const deleteRow = () => {\r\n if (!finalOptions.enableDelete || !selectedRowData.value) {\r\n message.warning(\"请先选择要删除的行\");\r\n return;\r\n }\r\n\r\n if (finalOptions.confirmDelete) {\r\n deleteConfirmVisible.value = true;\r\n } else {\r\n confirmDeleteFn();\r\n }\r\n };\r\n\r\n /** 确认删除操作 */\r\n const confirmDeleteFn = () => {\r\n if (!selectedRowData.value) return;\r\n\r\n const deletedRow = selectedRowData.value;\r\n const deletedIndex = selectedRowIndex.value;\r\n\r\n const newData = data.value.filter((_, index) => index !== deletedIndex);\r\n updateData(newData);\r\n\r\n selectedRowKey.value = null;\r\n finalOptions.onSelectionChange?.(null, null);\r\n finalOptions.onRowDelete?.(deletedRow, deletedIndex);\r\n\r\n message.success(\"删除行成功\");\r\n deleteConfirmVisible.value = false;\r\n };\r\n\r\n /** 复制选中的行 */\r\n const copyRow = () => {\r\n if (!finalOptions.enableCopy || !selectedRowData.value) {\r\n message.warning(\"请先选择要复制的行\");\r\n return;\r\n }\r\n\r\n const originalRow = selectedRowData.value;\r\n const keyField =\r\n typeof finalOptions.rowKey === \"string\" ? finalOptions.rowKey : \"id\";\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n const { [keyField]: _originalKey, ...rowData } = originalRow as Record<\r\n string,\r\n unknown\r\n >;\r\n\r\n const newRow = {\r\n ...rowData,\r\n [keyField]: generateUniqueId(),\r\n } as T;\r\n\r\n const newData = [...data.value, newRow];\r\n updateData(newData);\r\n finalOptions.onRowCopy?.(originalRow, newRow);\r\n message.success(\"复制行成功\");\r\n };\r\n\r\n /** 将选中行向上移动 */\r\n const moveRowUp = () => {\r\n if (!finalOptions.enableMove || !canMoveUp.value) return;\r\n\r\n const currentIndex = selectedRowIndex.value;\r\n const newData = [...data.value];\r\n const movingRow = newData[currentIndex];\r\n\r\n [newData[currentIndex], newData[currentIndex - 1]] = [\r\n newData[currentIndex - 1],\r\n newData[currentIndex],\r\n ];\r\n\r\n updateData(newData);\r\n finalOptions.onRowMove?.(movingRow, currentIndex, currentIndex - 1);\r\n message.success(\"行已上移\");\r\n };\r\n\r\n /** 将选中行向下移动 */\r\n const moveRowDown = () => {\r\n if (!finalOptions.enableMove || !canMoveDown.value) return;\r\n\r\n const currentIndex = selectedRowIndex.value;\r\n const newData = [...data.value];\r\n const movingRow = newData[currentIndex];\r\n\r\n [newData[currentIndex], newData[currentIndex + 1]] = [\r\n newData[currentIndex + 1],\r\n newData[currentIndex],\r\n ];\r\n\r\n updateData(newData);\r\n finalOptions.onRowMove?.(movingRow, currentIndex, currentIndex + 1);\r\n message.success(\"行已下移\");\r\n };\r\n\r\n /** 选中指定行 */\r\n const selectRow = (key: DataTableRowKey) => {\r\n const row = data.value.find(\r\n (row) => getRowKey(row, finalOptions.rowKey) === key,\r\n );\r\n if (row) {\r\n selectedRowKey.value = key;\r\n finalOptions.onSelectionChange?.(key, row);\r\n }\r\n };\r\n\r\n /** 清空选择状态 */\r\n const clearSelection = () => {\r\n selectedRowKey.value = null;\r\n finalOptions.onSelectionChange?.(null, null);\r\n };\r\n\r\n /** 处理打印操作 */\r\n const handlePrint = async (elementRef: Ref<HTMLElement | undefined>) => {\r\n if (!elementRef.value) {\r\n message.error(\"打印元素未找到\");\r\n return;\r\n }\r\n\r\n const printOptions = getPrintOptions();\r\n await printWithWatermark(elementRef.value, printOptions);\r\n };\r\n\r\n /** 处理下载操作 */\r\n const handleDownload = async (\r\n elementRef: Ref<HTMLElement | undefined>,\r\n filename?: string,\r\n ) => {\r\n if (!elementRef.value) {\r\n message.error(\"下载元素未找到\");\r\n return;\r\n }\r\n\r\n const printOptions = getPrintOptions();\r\n await downloadScreenshot(elementRef.value, filename, printOptions);\r\n };\r\n\r\n /** 处理快速打印操作 */\r\n const handleQuickPrint = async (elementRef: Ref<HTMLElement | undefined>) => {\r\n if (!elementRef.value) {\r\n message.error(\"打印元素未找到\");\r\n return;\r\n }\r\n\r\n const watermarkText = finalOptions.printWatermarkText || \"Robot Admin\";\r\n await quickPrint(elementRef.value, watermarkText);\r\n };\r\n\r\n /** 增强表格列配置,添加单选列 */\r\n const enhanceColumns = (columns: TableColumn<T>[]): TableColumn<T>[] => {\r\n const enhancedColumns = [...columns];\r\n\r\n if (finalOptions.enableRadioSelection) {\r\n enhancedColumns.unshift({\r\n key: \"_radio_selection\",\r\n title: \"选择\",\r\n width: 80,\r\n align: \"center\",\r\n editable: false,\r\n render: (rowData: T) => {\r\n const rowKeyVal = getRowKey(rowData, finalOptions.rowKey);\r\n return h(\"div\", { class: \"flex justify-center\" }, [\r\n h(\"input\", {\r\n type: \"radio\",\r\n name: \"table-radio-selection\",\r\n checked: selectedRowKey.value === rowKeyVal,\r\n class: \"cursor-pointer accent-blue-500 scale-110\",\r\n onChange: (e: Event) => {\r\n if ((e.target as HTMLInputElement).checked) {\r\n selectRow(rowKeyVal);\r\n }\r\n },\r\n }),\r\n ]);\r\n },\r\n } as TableColumn<T>);\r\n }\r\n\r\n return enhancedColumns;\r\n };\r\n\r\n /** 渲染工具栏 */\r\n const renderToolbar = (): VNodeChild => {\r\n const buttons: globalThis.VNode<\r\n RendererNode,\r\n RendererElement,\r\n Record<string, unknown>\r\n >[] = [];\r\n\r\n if (finalOptions.enablePrint) {\r\n buttons.push(\r\n h(\r\n NButton,\r\n {\r\n loading: printLoading.value,\r\n type: \"primary\",\r\n ghost: true,\r\n onClick: async () => {\r\n try {\r\n const tableElement = document.querySelector(\r\n finalOptions.printTargetSelector,\r\n );\r\n if (tableElement) {\r\n await handlePrint(ref(tableElement as HTMLElement));\r\n } else {\r\n console.warn(\"未找到表格容器元素\");\r\n }\r\n } catch (error) {\r\n console.error(\"打印失败:\", error);\r\n }\r\n },\r\n },\r\n {\r\n icon: () => h(C_Icon, { name: \"mdi:printer\", title: \"打印\" }),\r\n default: () => \"打印\",\r\n },\r\n ),\r\n );\r\n }\r\n\r\n const rowButtons: globalThis.VNode<\r\n RendererNode,\r\n RendererElement,\r\n Record<string, unknown>\r\n >[] = [];\r\n\r\n if (finalOptions.enableAdd) {\r\n rowButtons.push(\r\n h(\r\n NButton,\r\n {\r\n onClick: addRow,\r\n type: \"primary\",\r\n },\r\n {\r\n icon: () => h(C_Icon, { name: \"mdi:plus\", title: \"增行\" }),\r\n default: () => \"增行\",\r\n },\r\n ),\r\n );\r\n }\r\n\r\n if (finalOptions.enableInsert) {\r\n rowButtons.push(\r\n h(\r\n NTooltip,\r\n {\r\n disabled: !!selectedRowData.value,\r\n },\r\n {\r\n trigger: () =>\r\n h(\r\n NButton,\r\n {\r\n onClick: insertRow,\r\n disabled: !selectedRowData.value,\r\n type: \"primary\",\r\n ghost: true,\r\n },\r\n {\r\n icon: () =>\r\n h(C_Icon, {\r\n name: \"mdi:table-row-plus-after\",\r\n title: \"插行\",\r\n }),\r\n default: () => \"插行\",\r\n },\r\n ),\r\n default: () => \"请先选择一行数据\",\r\n },\r\n ),\r\n );\r\n }\r\n\r\n if (finalOptions.enableDelete) {\r\n rowButtons.push(\r\n h(\r\n NTooltip,\r\n {\r\n disabled: !!selectedRowData.value,\r\n },\r\n {\r\n trigger: () =>\r\n h(\r\n NButton,\r\n {\r\n onClick: deleteRow,\r\n disabled: !selectedRowData.value,\r\n type: \"error\",\r\n ghost: true,\r\n },\r\n {\r\n icon: () =>\r\n h(C_Icon, { name: \"mdi:delete\", title: \"删除行\" }),\r\n default: () => \"删除行\",\r\n },\r\n ),\r\n default: () => \"请先选择要删除的行\",\r\n },\r\n ),\r\n );\r\n }\r\n\r\n if (finalOptions.enableCopy) {\r\n rowButtons.push(\r\n h(\r\n NTooltip,\r\n {\r\n disabled: !!selectedRowData.value,\r\n },\r\n {\r\n trigger: () =>\r\n h(\r\n NButton,\r\n {\r\n onClick: copyRow,\r\n disabled: !selectedRowData.value,\r\n type: \"info\",\r\n ghost: true,\r\n },\r\n {\r\n icon: () =>\r\n h(C_Icon, { name: \"mdi:content-copy\", title: \"复制行\" }),\r\n default: () => \"复制行\",\r\n },\r\n ),\r\n default: () => \"请先选择要复制的行\",\r\n },\r\n ),\r\n );\r\n }\r\n\r\n if (finalOptions.enableMove) {\r\n rowButtons.push(\r\n h(\r\n NTooltip,\r\n {\r\n disabled: canMoveUp.value,\r\n },\r\n {\r\n trigger: () =>\r\n h(\r\n NButton,\r\n {\r\n onClick: moveRowUp,\r\n disabled: !canMoveUp.value,\r\n type: \"warning\",\r\n ghost: true,\r\n },\r\n {\r\n icon: () =>\r\n h(C_Icon, { name: \"mdi:arrow-up\", title: \"上移\" }),\r\n default: () => \"上移\",\r\n },\r\n ),\r\n default: () =>\r\n !selectedRowData.value ? \"请先选择数据\" : \"已经是第一行\",\r\n },\r\n ),\r\n h(\r\n NTooltip,\r\n {\r\n disabled: canMoveDown.value,\r\n },\r\n {\r\n trigger: () =>\r\n h(\r\n NButton,\r\n {\r\n onClick: moveRowDown,\r\n disabled: !canMoveDown.value,\r\n type: \"warning\",\r\n ghost: true,\r\n },\r\n {\r\n icon: () =>\r\n h(C_Icon, { name: \"mdi:arrow-down\", title: \"下移\" }),\r\n default: () => \"下移\",\r\n },\r\n ),\r\n default: () =>\r\n !selectedRowData.value ? \"请先选择数据\" : \"已经是最后一行\",\r\n },\r\n ),\r\n );\r\n }\r\n\r\n if (rowButtons.length > 0) {\r\n buttons.push(h(NButtonGroup, {}, () => rowButtons));\r\n }\r\n\r\n return h(\"div\", { class: \"dynamic-rows-toolbar mb-4 flex justify-end\" }, [\r\n h(NSpace, {}, () => buttons),\r\n ]);\r\n };\r\n\r\n /** 渲染删除确认模态框 */\r\n const renderConfirmModal = (): VNodeChild => {\r\n return h(NModal, {\r\n show: deleteConfirmVisible.value,\r\n \"onUpdate:show\": (show: boolean) => {\r\n deleteConfirmVisible.value = show;\r\n },\r\n preset: \"dialog\",\r\n title: \"确认删除\",\r\n content: finalOptions.deleteConfirmText,\r\n positiveText: \"确认删除\",\r\n negativeText: \"取消\",\r\n onPositiveClick: confirmDeleteFn,\r\n });\r\n };\r\n\r\n /* 组件卸载时清理 */\r\n onBeforeUnmount(() => {\r\n selectedRowKey.value = null;\r\n deleteConfirmVisible.value = false;\r\n });\r\n\r\n return {\r\n /* 状态 */\r\n selectedRowKey,\r\n selectedRowData,\r\n selectedRowIndex,\r\n canMoveUp,\r\n canMoveDown,\r\n deleteConfirmVisible,\r\n printLoading,\r\n printProgress,\r\n\r\n /* 行操作方法 */\r\n addRow,\r\n insertRow,\r\n deleteRow,\r\n confirmDelete: confirmDeleteFn,\r\n copyRow,\r\n moveRowUp,\r\n moveRowDown,\r\n\r\n /* 选择方法 */\r\n selectRow,\r\n clearSelection,\r\n\r\n /* 打印方法 */\r\n handlePrint,\r\n handleDownload,\r\n handleQuickPrint,\r\n\r\n /* 列增强方法 */\r\n enhanceColumns,\r\n\r\n /* 工具栏渲染 */\r\n renderToolbar,\r\n renderConfirmModal,\r\n };\r\n}\r\n","/*\r\n * @Description: 表格统一状态管理器\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { ref, computed, nextTick } from \"vue\";\r\nimport type { DataTableRowKey } from \"naive-ui/es\";\r\nimport type { DataRecord, ParentChildLinkMode } from \"../types\";\r\nimport { useRowEdit } from \"./useRowEdit\";\r\nimport { useCellEdit } from \"./useCellEdit\";\r\nimport { useModalEdit } from \"./useModalEdit\";\r\nimport { useTableExpand } from \"./useTableExpand\";\r\nimport { useDynamicRows, type DynamicRowsOptions } from \"./useDynamicRow\";\r\n\r\n/**\r\n * 表格管理器配置接口\r\n */\r\ninterface TableManagerConfig {\r\n /* 基础配置 */\r\n editable: boolean;\r\n editMode: string;\r\n showRowActions: boolean;\r\n modalTitle: string;\r\n modalWidth: number;\r\n\r\n /* 展开配置 */\r\n expandable: boolean;\r\n defaultExpandedKeys?: DataTableRowKey[];\r\n onLoadExpandData?: (row: DataRecord) => Promise<any[]> | any[];\r\n renderExpandContent?: unknown;\r\n rowExpandable?: (row: DataRecord) => boolean;\r\n\r\n /* 选择配置 */\r\n enableSelection: boolean;\r\n defaultCheckedKeys?: DataTableRowKey[];\r\n rowCheckable?: (row: DataRecord) => boolean;\r\n maxSelection?: number;\r\n enableChildSelection: boolean;\r\n childRowCheckable?: (childRow: DataRecord, parentRow: DataRecord) => boolean;\r\n enableParentChildLink: boolean;\r\n parentChildLinkMode: ParentChildLinkMode;\r\n\r\n /* 动态行配置 */\r\n dynamicRows?: DynamicRowsOptions<DataRecord>;\r\n}\r\n\r\n/**\r\n * 表格管理器参数接口\r\n */\r\ninterface TableManagerParams {\r\n config: TableManagerConfig;\r\n data: () => DataRecord[];\r\n rowKey: (row: DataRecord) => DataTableRowKey;\r\n emit: (...args: unknown[]) => void;\r\n}\r\n\r\n/**\r\n * 事件处理器接口\r\n */\r\ninterface EventHandlers {\r\n onSave: (\r\n rowData: DataRecord,\r\n rowIndex: number,\r\n columnKey?: string,\r\n ) => Promise<void>;\r\n onCancel: (rowData: DataRecord, rowIndex: number) => void;\r\n onExpandChange: (\r\n keys: DataTableRowKey[],\r\n row?: DataRecord,\r\n expanded?: boolean,\r\n ) => void;\r\n onSelectionChange: (\r\n checkedKeys: DataTableRowKey[],\r\n checkedRows: DataRecord[],\r\n childSelections: Map<DataTableRowKey, DataTableRowKey[]>,\r\n ) => void;\r\n onChildSelectionChange: (\r\n parentKey: DataTableRowKey,\r\n childKeys: DataTableRowKey[],\r\n childRows: DataRecord[],\r\n ) => void;\r\n onRowChange: (data: DataRecord[]) => void;\r\n onRowSelectionChange: (\r\n selectedKey: DataTableRowKey | null,\r\n selectedRow: DataRecord | null,\r\n ) => void;\r\n onRowAdd: (newRow: DataRecord) => void;\r\n onRowDelete: (deletedRow: DataRecord, index: number) => void;\r\n onRowCopy: (originalRow: DataRecord, newRow: DataRecord) => void;\r\n onRowMove: (row: DataRecord, fromIndex: number, toIndex: number) => void;\r\n}\r\n\r\n/**\r\n * 表格统一状态管理器\r\n */\r\nexport function useTableManager(params: TableManagerParams) {\r\n const { config, data, rowKey, emit } = params;\r\n\r\n /* ================= 事件处理器工厂 ================= */\r\n\r\n /** 创建事件处理器集合 */\r\n const createEventHandlers = (): EventHandlers => ({\r\n /* 通用事件 */\r\n onSave: async (\r\n rowData: DataRecord,\r\n rowIndex: number,\r\n columnKey?: string,\r\n ) => {\r\n if (!rowData || rowIndex < 0 || rowIndex >= data().length) return;\r\n\r\n const newData = [...data()];\r\n newData[rowIndex] = { ...newData[rowIndex], ...rowData };\r\n\r\n emit(\"update:data\", newData);\r\n await nextTick();\r\n emit(\"save\", newData[rowIndex], rowIndex, columnKey);\r\n },\r\n\r\n onCancel: (rowData: DataRecord, rowIndex: number) => {\r\n emit(\"cancel\", rowData, rowIndex);\r\n },\r\n\r\n /* 展开选择事件 */\r\n onExpandChange: (\r\n keys: DataTableRowKey[],\r\n row?: DataRecord,\r\n expanded?: boolean,\r\n ) => {\r\n emit(\"expand-change\", keys, row, expanded);\r\n },\r\n\r\n onSelectionChange: (\r\n checkedKeys: DataTableRowKey[],\r\n checkedRows: DataRecord[],\r\n childSelections: Map<DataTableRowKey, DataTableRowKey[]>,\r\n ) => {\r\n emit(\"selection-change\", checkedKeys, checkedRows, childSelections);\r\n },\r\n\r\n onChildSelectionChange: (\r\n parentKey: DataTableRowKey,\r\n childKeys: DataTableRowKey[],\r\n childRows: DataRecord[],\r\n ) => {\r\n emit(\"child-selection-change\", parentKey, childKeys, childRows);\r\n },\r\n\r\n /* 动态行事件 */\r\n onRowChange: (data: DataRecord[]) => {\r\n emit(\"update:data\", data);\r\n config.dynamicRows?.onRowChange?.(data);\r\n },\r\n\r\n onRowSelectionChange: (\r\n selectedKey: DataTableRowKey | null,\r\n selectedRow: DataRecord | null,\r\n ) => {\r\n emit(\"row-selection-change\", selectedKey, selectedRow);\r\n config.dynamicRows?.onSelectionChange?.(selectedKey, selectedRow);\r\n },\r\n\r\n onRowAdd: (newRow: DataRecord) => {\r\n emit(\"row-add\", newRow);\r\n config.dynamicRows?.onRowAdd?.(newRow);\r\n },\r\n\r\n onRowDelete: (deletedRow: DataRecord, index: number) => {\r\n emit(\"row-delete\", deletedRow, index);\r\n config.dynamicRows?.onRowDelete?.(deletedRow, index);\r\n },\r\n\r\n onRowCopy: (originalRow: DataRecord, newRow: DataRecord) => {\r\n emit(\"row-copy\", originalRow, newRow);\r\n config.dynamicRows?.onRowCopy?.(originalRow, newRow);\r\n },\r\n\r\n onRowMove: (row: DataRecord, fromIndex: number, toIndex: number) => {\r\n emit(\"row-move\", row, fromIndex, toIndex);\r\n config.dynamicRows?.onRowMove?.(row, fromIndex, toIndex);\r\n },\r\n });\r\n\r\n const eventHandlers = createEventHandlers();\r\n\r\n /* ================= 功能状态初始化 ================= */\r\n\r\n /** 初始化编辑功能状态 */\r\n const initEditStates = () => {\r\n const rowEdit = useRowEdit({\r\n data,\r\n rowKey,\r\n onSave: eventHandlers.onSave,\r\n onCancel: eventHandlers.onCancel,\r\n });\r\n\r\n const cellEdit = useCellEdit({\r\n data,\r\n rowKey,\r\n onSave: eventHandlers.onSave,\r\n });\r\n\r\n const modalEdit = useModalEdit({\r\n data,\r\n rowKey,\r\n onSave: eventHandlers.onSave,\r\n onCancel: eventHandlers.onCancel,\r\n });\r\n\r\n return { rowEdit, cellEdit, modalEdit };\r\n };\r\n\r\n /** 初始化展开功能状态 */\r\n const initExpandState = () => {\r\n const needsExpand =\r\n config.expandable ||\r\n config.enableSelection ||\r\n config.enableChildSelection;\r\n\r\n if (!needsExpand) return null;\r\n\r\n return useTableExpand({\r\n data: computed(() => data()),\r\n rowKey,\r\n childRowKey: (child: DataRecord) => child.id,\r\n\r\n defaultExpandedKeys: config.defaultExpandedKeys,\r\n onLoadData: config.onLoadExpandData,\r\n renderContent: config.renderExpandContent,\r\n rowExpandable: config.rowExpandable,\r\n enableSelection: config.enableSelection,\r\n defaultCheckedKeys: config.defaultCheckedKeys,\r\n rowCheckable: config.rowCheckable,\r\n maxSelection: config.maxSelection,\r\n enableChildSelection: config.enableChildSelection,\r\n childRowCheckable: config.childRowCheckable,\r\n enableParentChildLink: config.enableParentChildLink,\r\n parentChildLinkMode: config.parentChildLinkMode,\r\n\r\n onExpandChange: eventHandlers.onExpandChange,\r\n onSelectionChange: eventHandlers.onSelectionChange,\r\n onChildSelectionChange: eventHandlers.onChildSelectionChange,\r\n });\r\n };\r\n\r\n /** 初始化动态行功能状态 */\r\n const initDynamicRowsState = () => {\r\n if (!config.dynamicRows) return null;\r\n\r\n const dynamicOptions: DynamicRowsOptions<DataRecord> = {\r\n ...config.dynamicRows,\r\n onRowChange: eventHandlers.onRowChange,\r\n onSelectionChange: eventHandlers.onRowSelectionChange,\r\n onRowAdd: eventHandlers.onRowAdd,\r\n onRowDelete: eventHandlers.onRowDelete,\r\n onRowCopy: eventHandlers.onRowCopy,\r\n onRowMove: eventHandlers.onRowMove,\r\n };\r\n\r\n return useDynamicRows(\r\n computed(() => data()),\r\n dynamicOptions,\r\n );\r\n };\r\n\r\n /* 初始化所有功能状态 */\r\n const editStates = initEditStates();\r\n const expandState = initExpandState();\r\n const dynamicRowsState = initDynamicRowsState();\r\n\r\n /* ================= 统一的状态管理器 ================= */\r\n\r\n /** 创建统一的状态管理器 */\r\n const createStateManager = () => {\r\n return {\r\n /* 编辑控制 */\r\n edit: {\r\n /** 开始编辑 */\r\n start(rowKey: DataTableRowKey, columnKey?: string) {\r\n const mode = config.editMode;\r\n if (mode === \"modal\") editStates.modalEdit.startEdit(rowKey);\r\n else if (mode === \"cell\" && columnKey)\r\n editStates.cellEdit.startEditCell(rowKey, columnKey);\r\n else if (mode === \"row\" || mode === \"both\")\r\n editStates.rowEdit.startEditRow(rowKey);\r\n },\r\n\r\n /** 取消编辑 */\r\n cancel() {\r\n if (editStates.modalEdit.isModalVisible.value)\r\n editStates.modalEdit.cancelEdit();\r\n else if (editStates.cellEdit.editingCell.value.rowKey)\r\n editStates.cellEdit.cancelEditCell();\r\n else if (editStates.rowEdit.editingRowKey.value)\r\n editStates.rowEdit.cancelEditRow();\r\n },\r\n\r\n /** 保存编辑 */\r\n async save() {\r\n if (editStates.modalEdit.isModalVisible.value)\r\n await editStates.modalEdit.saveEdit();\r\n else if (editStates.cellEdit.editingCell.value.rowKey)\r\n await editStates.cellEdit.saveEditCell();\r\n else if (editStates.rowEdit.editingRowKey.value)\r\n await editStates.rowEdit.saveEditRow();\r\n },\r\n\r\n /** 是否正在编辑 */\r\n isEditing(rowKey: DataTableRowKey, columnKey?: string) {\r\n if (config.editMode === \"modal\")\r\n return editStates.modalEdit.isEditingRow(rowKey);\r\n if (columnKey)\r\n return editStates.cellEdit.isEditingCell(rowKey, columnKey);\r\n return editStates.rowEdit.isEditingRow(rowKey);\r\n },\r\n\r\n /** 获取当前编辑数据 */\r\n getEditingData() {\r\n if (editStates.modalEdit.isModalVisible.value)\r\n return editStates.modalEdit.editingData;\r\n if (editStates.rowEdit.editingRowKey.value) {\r\n return editStates.rowEdit.getEditingRowData(\r\n editStates.rowEdit.editingRowKey.value!,\r\n );\r\n }\r\n return null;\r\n },\r\n },\r\n\r\n /* 展开控制 */\r\n expand: {\r\n /** 展开行 */\r\n async row(rowKey: DataTableRowKey) {\r\n if (expandState) {\r\n const currentKeys = [...expandState.expandedKeys.value];\r\n if (!currentKeys.includes(rowKey)) {\r\n currentKeys.push(rowKey);\r\n expandState.handleExpandChange(currentKeys);\r\n }\r\n }\r\n },\r\n\r\n /** 折叠行 */\r\n collapse(rowKey: DataTableRowKey) {\r\n if (expandState) {\r\n const currentKeys = expandState.expandedKeys.value.filter(\r\n (key) => key !== rowKey,\r\n );\r\n expandState.handleExpandChange(currentKeys);\r\n }\r\n },\r\n\r\n /** 展开折叠切换 */\r\n async toggle(rowKey: DataTableRowKey) {\r\n if (expandState?.expandedKeys.value.includes(rowKey)) {\r\n this.collapse(rowKey);\r\n } else {\r\n await this.row(rowKey);\r\n }\r\n },\r\n\r\n /** 展开所有行 */\r\n async all() {\r\n await expandState?.expandAll();\r\n },\r\n\r\n /** 折叠所有行 */\r\n collapseAll() {\r\n expandState?.collapseAll();\r\n },\r\n\r\n /** 检查行是否已展开 */\r\n isExpanded(rowKey: DataTableRowKey) {\r\n return expandState?.expandedKeys.value.includes(rowKey) ?? false;\r\n },\r\n },\r\n\r\n /* 选择控制 */\r\n selection: {\r\n /** 选择指定行 */\r\n select(rowKey: DataTableRowKey) {\r\n if (\r\n expandState?.checkedKeys.value &&\r\n !expandState.checkedKeys.value.includes(rowKey)\r\n ) {\r\n const newKeys = [...expandState.checkedKeys.value, rowKey];\r\n expandState.handleSelectionChange(newKeys);\r\n }\r\n },\r\n\r\n /** 取消选择指定行 */\r\n unselect(rowKey: DataTableRowKey) {\r\n if (expandState?.checkedKeys.value) {\r\n const newKeys = expandState.checkedKeys.value.filter(\r\n (key) => key !== rowKey,\r\n );\r\n expandState.handleSelectionChange(newKeys);\r\n }\r\n },\r\n\r\n /** 选择所有行 */\r\n all() {\r\n expandState?.selectAll();\r\n },\r\n\r\n /** 清除所有行选择 */\r\n clear() {\r\n expandState?.clearSelection();\r\n },\r\n\r\n /** 检查行是否已选择 */\r\n isSelected(rowKey: DataTableRowKey) {\r\n return expandState?.checkedKeys.value.includes(rowKey) ?? false;\r\n },\r\n\r\n /** 获取所有已选择的行数据 */\r\n getSelected() {\r\n if (!expandState?.checkedKeys.value) return [];\r\n return data().filter((row) =>\r\n expandState!.checkedKeys.value.includes(rowKey(row)),\r\n );\r\n },\r\n },\r\n\r\n /* 子选择控制 */\r\n childSelection: {\r\n /** 选择指定父行下的子行 */\r\n select(parentKey: DataTableRowKey, childKey: DataTableRowKey) {\r\n if (expandState?.childSelections.value) {\r\n const current =\r\n expandState.childSelections.value.get(parentKey) || [];\r\n if (!current.includes(childKey)) {\r\n const newSelection = [...current, childKey];\r\n expandState.childSelections.value.set(parentKey, newSelection);\r\n emit(\"child-selection-change\", parentKey, newSelection, []);\r\n }\r\n }\r\n },\r\n\r\n /** 取消选择指定父行下的子行 */\r\n unselect(parentKey: DataTableRowKey, childKey: DataTableRowKey) {\r\n if (expandState?.childSelections.value) {\r\n const current =\r\n expandState.childSelections.value.get(parentKey) || [];\r\n const newSelection = current.filter((k) => k !== childKey);\r\n expandState.childSelections.value.set(parentKey, newSelection);\r\n emit(\"child-selection-change\", parentKey, newSelection, []);\r\n }\r\n },\r\n\r\n /** 选择指定父行下的所有子行 */\r\n selectAll(parentKey: DataTableRowKey) {\r\n if (\r\n expandState?.childSelections.value &&\r\n expandState.expandDataMap?.value\r\n ) {\r\n const expandData =\r\n expandState.expandDataMap.value.get(parentKey) || [];\r\n const allChildKeys = expandData.map(\r\n (child: DataRecord) => child.id,\r\n );\r\n expandState.childSelections.value.set(parentKey, allChildKeys);\r\n emit(\"child-selection-change\", parentKey, allChildKeys, expandData);\r\n }\r\n },\r\n\r\n /** 清除指定父行下的所有子行选择 */\r\n clear(parentKey: DataTableRowKey) {\r\n if (expandState?.childSelections.value) {\r\n expandState.childSelections.value.set(parentKey, []);\r\n emit(\"child-selection-change\", parentKey, [], []);\r\n }\r\n },\r\n\r\n /** 获取指定父行下所有已选择的子行数据 */\r\n getSelected(parentKey: DataTableRowKey) {\r\n if (\r\n !expandState?.childSelections.value ||\r\n !expandState.expandDataMap?.value\r\n ) {\r\n return [];\r\n }\r\n const selectedKeys =\r\n expandState.childSelections.value.get(parentKey) || [];\r\n const expandData =\r\n expandState.expandDataMap.value.get(parentKey) || [];\r\n return expandData.filter((child: DataRecord) =>\r\n selectedKeys.includes(child.id),\r\n );\r\n },\r\n },\r\n\r\n /* 动态行控制 */\r\n dynamicRows: {\r\n /** 添加行 */\r\n add() {\r\n dynamicRowsState?.addRow();\r\n },\r\n /** 插入行 */\r\n insert() {\r\n dynamicRowsState?.insertRow();\r\n },\r\n\r\n /** 删除行 */\r\n delete() {\r\n dynamicRowsState?.deleteRow();\r\n },\r\n /** 复制行 */\r\n copy() {\r\n dynamicRowsState?.copyRow();\r\n },\r\n /** 上移动态行 */\r\n moveUp() {\r\n dynamicRowsState?.moveRowUp();\r\n },\r\n /** 下移动态行 */\r\n moveDown() {\r\n dynamicRowsState?.moveRowDown();\r\n },\r\n /** 清空动态行数据 */\r\n clearSelection() {\r\n dynamicRowsState?.clearSelection();\r\n },\r\n /** 获取当前选中的动态行数据 */\r\n getSelected() {\r\n return dynamicRowsState?.selectedRowData.value || null;\r\n },\r\n\r\n /** 打印表格 */\r\n async print(elementRef?: HTMLElement) {\r\n if (dynamicRowsState && elementRef) {\r\n await dynamicRowsState.handlePrint(ref(elementRef));\r\n }\r\n },\r\n\r\n /** 导出表格数据 */\r\n async download(elementRef?: HTMLElement, filename?: string) {\r\n if (dynamicRowsState && elementRef) {\r\n await dynamicRowsState.handleDownload(ref(elementRef), filename);\r\n }\r\n },\r\n },\r\n\r\n /** 清除所有选择 */\r\n clearAllSelections() {\r\n expandState?.clearAllSelections();\r\n },\r\n };\r\n };\r\n\r\n const stateManager = createStateManager();\r\n\r\n /* ================= 计算属性 ================= */\r\n\r\n const expandedKeys = computed(() => expandState?.expandedKeys.value ?? []);\r\n const checkedKeys = computed(() => expandState?.checkedKeys.value ?? []);\r\n\r\n /* ================= 返回管理器实例 ================= */\r\n\r\n return {\r\n /* 编辑状态 */\r\n editStates,\r\n\r\n /* 功能状态 */\r\n expandState,\r\n dynamicRowsState,\r\n\r\n /* 状态管理器 */\r\n stateManager,\r\n\r\n /* 计算属性 */\r\n expandedKeys,\r\n checkedKeys,\r\n\r\n /* 事件处理器 */\r\n eventHandlers,\r\n };\r\n}\r\n","/*\r\n * @Description: 表格分页逻辑 Hook\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { ref, computed, watch, watchEffect, unref } from \"vue\";\r\nimport type { Ref, ComputedRef } from \"vue\";\r\nimport type { PaginationConfig, DataRecord } from \"../types\";\r\n\r\n/* ================= 类型定义 ================= */\r\n\r\n/** 分页信息对象(naive-ui pagination prefix/suffix 回调参数) */\r\ninterface PaginationRenderInfo {\r\n itemCount: number;\r\n startIndex: number;\r\n endIndex: number;\r\n}\r\n\r\nexport interface UsePaginationOptions<T extends DataRecord = DataRecord> {\r\n /** 数据源 - 支持函数、Ref 或 ComputedRef */\r\n data: (() => T[]) | Ref<T[]> | ComputedRef<T[]>;\r\n /** 分页配置 */\r\n config: Ref<PaginationConfig | null> | ComputedRef<PaginationConfig | null>;\r\n /** 事件触发器 */\r\n emit?: (event: \"pagination-change\", page: number, pageSize: number) => void;\r\n}\r\n\r\nexport interface UsePaginationReturn<T extends DataRecord = DataRecord> {\r\n currentPage: Ref<number>;\r\n currentPageSize: Ref<number>;\r\n paginatedData: ComputedRef<T[]>;\r\n paginationConfig: ComputedRef<any>;\r\n handlePageChange: (page: number) => void;\r\n handlePageSizeChange: (pageSize: number) => void;\r\n resetToFirstPage: () => void;\r\n getTotalPages: () => number;\r\n}\r\n\r\n/* ================= 默认配置 ================= */\r\nconst DEFAULT_PAGINATION_CONFIG = {\r\n enabled: true,\r\n page: 1,\r\n pageSize: 10,\r\n showSizePicker: true,\r\n showQuickJumper: true,\r\n pageSizes: [10, 20, 50, 100],\r\n simple: false,\r\n size: \"medium\" as const,\r\n};\r\n\r\n/* ================= Hook 实现 ================= */\r\nexport function usePagination<T extends DataRecord = DataRecord>(\r\n options: UsePaginationOptions<T>,\r\n): UsePaginationReturn<T> {\r\n const { data, config, emit } = options;\r\n\r\n /* ================= 响应式状态 ================= */\r\n const currentPage = ref(1);\r\n const currentPageSize = ref(10);\r\n\r\n /* ================= 数据源统一处理 ================= */\r\n const dataSource = computed(() => {\r\n if (typeof data === \"function\") {\r\n return data() || [];\r\n }\r\n return unref(data) || [];\r\n });\r\n\r\n /* ================= 计算属性 ================= */\r\n\r\n /** 分页后的数据 */\r\n const paginatedData = computed(() => {\r\n if (!config.value?.enabled) {\r\n return dataSource.value;\r\n }\r\n\r\n const start = (currentPage.value - 1) * currentPageSize.value;\r\n const end = start + currentPageSize.value;\r\n return dataSource.value.slice(start, end);\r\n });\r\n\r\n /** 分页配置对象 */\r\n const paginationConfig = computed(() => {\r\n if (!config.value?.enabled) return null;\r\n\r\n return {\r\n page: currentPage.value,\r\n pageSize: currentPageSize.value,\r\n itemCount: dataSource.value.length,\r\n showSizePicker:\r\n config.value.showSizePicker ?? DEFAULT_PAGINATION_CONFIG.showSizePicker,\r\n showQuickJumper:\r\n config.value.showQuickJumper ??\r\n DEFAULT_PAGINATION_CONFIG.showQuickJumper,\r\n pageSizes: config.value.pageSizes ?? DEFAULT_PAGINATION_CONFIG.pageSizes,\r\n simple: config.value.simple ?? DEFAULT_PAGINATION_CONFIG.simple,\r\n size: config.value.size ?? DEFAULT_PAGINATION_CONFIG.size,\r\n prefix: (info: PaginationRenderInfo) => `共 ${info.itemCount} 条`,\r\n suffix: (info: PaginationRenderInfo) =>\r\n `第 ${info.startIndex + 1}-${info.endIndex} 条`,\r\n \"onUpdate:page\": handlePageChange,\r\n \"onUpdate:pageSize\": handlePageSizeChange,\r\n };\r\n });\r\n\r\n /* ================= 事件处理 ================= */\r\n\r\n /** 页码变化处理 */\r\n const handlePageChange = (page: number) => {\r\n currentPage.value = page;\r\n emit?.(\"pagination-change\", page, currentPageSize.value);\r\n };\r\n\r\n /** 页面大小变化处理 */\r\n const handlePageSizeChange = (pageSize: number) => {\r\n currentPageSize.value = pageSize;\r\n currentPage.value = 1;\r\n emit?.(\"pagination-change\", 1, pageSize);\r\n };\r\n\r\n /** 重置到第一页 */\r\n const resetToFirstPage = () => {\r\n if (currentPage.value !== 1) {\r\n handlePageChange(1);\r\n }\r\n };\r\n\r\n /** 获取总页数 */\r\n const getTotalPages = () => {\r\n if (!config.value?.enabled || currentPageSize.value === 0) return 1;\r\n return Math.ceil(dataSource.value.length / currentPageSize.value);\r\n };\r\n\r\n /* ================= 响应式逻辑 ================= */\r\n\r\n /** 初始化分页配置 */\r\n watchEffect(() => {\r\n if (config.value?.enabled) {\r\n currentPage.value = config.value.page ?? DEFAULT_PAGINATION_CONFIG.page;\r\n currentPageSize.value =\r\n config.value.pageSize ?? DEFAULT_PAGINATION_CONFIG.pageSize;\r\n }\r\n });\r\n\r\n /** 监听数据变化,确保分页状态正确 */\r\n watch(\r\n () => dataSource.value.length,\r\n (newLength) => {\r\n if (config.value?.enabled && currentPage.value > 1) {\r\n const maxPage = Math.ceil(newLength / currentPageSize.value);\r\n if (currentPage.value > maxPage) {\r\n currentPage.value = Math.max(1, maxPage);\r\n }\r\n }\r\n },\r\n );\r\n\r\n return {\r\n currentPage,\r\n currentPageSize,\r\n paginatedData,\r\n paginationConfig,\r\n handlePageChange,\r\n handlePageSizeChange,\r\n resetToFirstPage,\r\n getTotalPages,\r\n };\r\n}\r\n","/*\r\n * @Description: 表格操作按钮Hook\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { h } from \"vue\";\r\nimport type { VNodeChild } from \"vue\";\r\nimport { NButton, NSpace, NDropdown, useMessage, useDialog } from \"naive-ui\";\r\nimport type { DataTableRowKey } from \"naive-ui/es\";\r\nimport type {\r\n DataRecord,\r\n ApiFunction,\r\n UseTableActionsOptions,\r\n UseTableActionsReturn,\r\n} from \"../types\";\r\nimport C_Icon from \"../../C_Icon/index.vue\";\r\n\r\n/**\r\n * 表格操作Hook\r\n */\r\nexport function useTableActions<T extends DataRecord = DataRecord>(\r\n options: UseTableActionsOptions<T>,\r\n): UseTableActionsReturn<T> {\r\n const { actions, config, tableManager, rowKey, emit, onViewDetail } = options;\r\n const message = useMessage();\r\n const dialog = useDialog();\r\n\r\n /* 检查操作是否启用 */\r\n const isActionEnabled = (key: \"edit\" | \"delete\" | \"detail\") =>\r\n actions.value?.[key] !== false;\r\n\r\n /* 类型守卫:检查是否为有效API函数 */\r\n const isValidApiFunction = <TData extends DataRecord>(\r\n action: false | ApiFunction<TData> | undefined,\r\n ): action is ApiFunction<TData> => {\r\n return action !== false && typeof action === \"function\";\r\n };\r\n\r\n /* 自动提取API响应数据 */\r\n const extractApiResponseData = <TData>(response: unknown): TData => {\r\n if (response && typeof response === \"object\" && \"data\" in response) {\r\n return (response as Record<string, unknown>).data as TData;\r\n }\r\n return response as TData;\r\n };\r\n\r\n /* 创建按钮的通用方法 */\r\n const createButton = (\r\n icon: string,\r\n title: string,\r\n type = \"primary\",\r\n onClick: () => void,\r\n ) =>\r\n h(NButton, { size: \"small\", type, quaternary: true, onClick }, () => [\r\n h(C_Icon, { name: icon, size: 14, title }),\r\n ]);\r\n\r\n /* 处理编辑操作 */\r\n const handleEdit = (row: T, _index: number) => {\r\n const rowKeyValue = rowKey(row);\r\n const editAction = actions.value?.edit;\r\n\r\n if (config.value.editMode === \"modal\") {\r\n tableManager.editStates.modalEdit.startEdit(\r\n rowKeyValue,\r\n { ...row },\r\n editAction,\r\n );\r\n } else {\r\n tableManager.editStates.rowEdit.startEditRow(rowKeyValue, editAction);\r\n }\r\n };\r\n\r\n /* 执行删除API */\r\n const executeDelete = async (\r\n deleteAction: ApiFunction<T>,\r\n row: T,\r\n index: number,\r\n ) => {\r\n try {\r\n await deleteAction(row, index);\r\n message.success(\"删除成功\");\r\n emit(\"row-delete\", row, index);\r\n } catch (error) {\r\n console.error(\"删除失败:\", error);\r\n message.error(\"删除失败\");\r\n throw error;\r\n }\r\n };\r\n\r\n /* 处理删除操作 */\r\n const handleDelete = (row: T, index: number) => {\r\n const deleteAction = actions.value?.delete;\r\n\r\n if (!isValidApiFunction(deleteAction)) {\r\n return;\r\n }\r\n\r\n dialog.warning({\r\n title: \"确认删除\",\r\n content: \"确定要删除这条记录吗?\",\r\n positiveText: \"确定\",\r\n negativeText: \"取消\",\r\n onPositiveClick: () => executeDelete(deleteAction, row, index),\r\n });\r\n };\r\n\r\n /* 处理详情操作 */\r\n const handleDetail = async (row: T, index: number) => {\r\n const detailAction = actions.value?.detail;\r\n\r\n if (!isValidApiFunction(detailAction)) {\r\n onViewDetail?.(row);\r\n return;\r\n }\r\n\r\n try {\r\n const apiResponse = await detailAction(row, index);\r\n const detailData = extractApiResponseData<T>(apiResponse);\r\n onViewDetail?.(detailData || row);\r\n } catch (error) {\r\n console.error(\"获取详情失败:\", error);\r\n message.error(\"获取详情失败\");\r\n onViewDetail?.(row);\r\n }\r\n };\r\n\r\n /* 渲染行编辑按钮 */\r\n const renderRowEditButtons = (rowKeyValue: DataTableRowKey) => {\r\n const isEditing = tableManager.editStates.rowEdit.isEditingRow(rowKeyValue);\r\n\r\n if (isEditing) {\r\n return [\r\n createButton(\"mdi:check\", \"保存\", \"primary\", () =>\r\n tableManager.editStates.rowEdit.saveEditRow(),\r\n ),\r\n createButton(\"mdi:close\", \"取消\", \"default\", () =>\r\n tableManager.editStates.rowEdit.cancelEditRow(),\r\n ),\r\n ];\r\n }\r\n\r\n return [\r\n createButton(\"mdi:pencil\", \"编辑\", \"warning\", () =>\r\n tableManager.editStates.rowEdit.startEditRow(rowKeyValue),\r\n ),\r\n ];\r\n };\r\n\r\n /* 渲染基础操作按钮 */\r\n const renderBasicActions = (row: T, index: number) => {\r\n const buttons: VNodeChild[] = [];\r\n\r\n if (isActionEnabled(\"detail\")) {\r\n buttons.push(\r\n createButton(\"mdi:eye\", \"详情\", \"info\", () => handleDetail(row, index)),\r\n );\r\n }\r\n\r\n if (\r\n config.value.editMode === \"modal\" &&\r\n (isActionEnabled(\"edit\") || config.value.editable)\r\n ) {\r\n buttons.push(\r\n createButton(\"mdi:pencil\", \"编辑\", \"warning\", () =>\r\n handleEdit(row, index),\r\n ),\r\n );\r\n }\r\n\r\n if (isActionEnabled(\"delete\")) {\r\n buttons.push(\r\n createButton(\"mdi:delete\", \"删除\", \"error\", () =>\r\n handleDelete(row, index),\r\n ),\r\n );\r\n }\r\n\r\n return buttons;\r\n };\r\n\r\n /* 渲染自定义操作下拉菜单 */\r\n const renderCustomDropdown = (row: T, index: number) => {\r\n const customActions = actions.value?.custom;\r\n if (!customActions?.length) return null;\r\n\r\n const visibleActions = customActions.filter((action) =>\r\n action.show ? action.show(row, index) : true,\r\n );\r\n\r\n if (!visibleActions.length) return null;\r\n\r\n const options = visibleActions.map((action) => {\r\n const label =\r\n typeof action.label === \"function\"\r\n ? action.label(row, index)\r\n : action.label;\r\n const icon =\r\n typeof action.icon === \"function\"\r\n ? action.icon(row, index)\r\n : action.icon;\r\n\r\n return {\r\n label,\r\n key: action.key,\r\n icon: () => h(C_Icon, { name: icon, size: 14 }),\r\n disabled: action.disabled?.(row, index) || false,\r\n };\r\n });\r\n\r\n return h(\r\n NDropdown,\r\n {\r\n options,\r\n onSelect: (key: string) => {\r\n const action = visibleActions.find((a) => a.key === key);\r\n if (action) {\r\n try {\r\n action.onClick(row, index);\r\n } catch (error) {\r\n console.error(`操作\"${action.label}\"执行失败:`, error);\r\n message.error(`${action.label}失败`);\r\n }\r\n }\r\n },\r\n },\r\n () =>\r\n createButton(\"mdi:dots-horizontal\", \"更多操作\", \"default\", () => {}),\r\n );\r\n };\r\n\r\n /* 主渲染方法 */\r\n const renderActions = (row: T, index: number): VNodeChild => {\r\n if (actions.value?.render) {\r\n return actions.value.render(row, index);\r\n }\r\n\r\n const rowKeyValue = rowKey(row);\r\n const isRowEditMode = [\"row\", \"both\"].includes(config.value.editMode);\r\n\r\n if (\r\n isRowEditMode &&\r\n tableManager.editStates.rowEdit.isEditingRow(rowKeyValue)\r\n ) {\r\n return h(NSpace, { size: 2, wrap: false }, () =>\r\n renderRowEditButtons(rowKeyValue),\r\n );\r\n }\r\n\r\n const allButtons = [\r\n ...(isRowEditMode ? renderRowEditButtons(rowKeyValue) : []),\r\n ...renderBasicActions(row, index),\r\n ];\r\n\r\n const dropdown = renderCustomDropdown(row, index);\r\n if (dropdown) allButtons.push(dropdown);\r\n\r\n return h(NSpace, { size: 2, wrap: false }, () => allButtons);\r\n };\r\n\r\n return { renderActions, isActionEnabled };\r\n}\r\n","/*\r\n * @Description: 表格配置中心 — 编辑组件映射、表单生成、显示值处理\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n */\r\n\r\nimport { h } from \"vue\";\r\nimport { NInput, NInputNumber, NSwitch, NDatePicker, NSelect } from \"naive-ui\";\r\nimport type { TableColumn, EditType } from \"./types\";\r\n\r\n/* ================= 编辑组件映射 ================= */\r\n\r\nexport const EDIT_COMPONENTS: Record<EditType, any> = {\r\n number: NInputNumber,\r\n switch: NSwitch,\r\n input: NInput,\r\n email: NInput,\r\n mobile: NInput,\r\n date: (props: any) =>\r\n h(NDatePicker, { ...props, type: \"date\", format: \"yyyy-MM-dd\" }),\r\n select: (props: any) =>\r\n h(NSelect, { ...props, options: props.options || [] }),\r\n textarea: (props: any) => h(NInput, { ...props, type: \"textarea\", rows: 3 }),\r\n};\r\n\r\n/* ================= 表单选项生成 ================= */\r\n\r\ninterface FormOption {\r\n prop: string;\r\n label: string;\r\n type: string;\r\n placeholder: string;\r\n rules: any[];\r\n attrs: any;\r\n layout: { span: number };\r\n show: boolean;\r\n}\r\n\r\ntype ComponentType = string;\r\n\r\nconst EDIT_TO_FORM_TYPE: Record<string, ComponentType> = {\r\n number: \"inputNumber\",\r\n date: \"datePicker\",\r\n textarea: \"textarea\",\r\n select: \"select\",\r\n switch: \"switch\",\r\n};\r\n\r\n/**\r\n * 根据可编辑列配置自动生成表单选项(用于编辑弹窗)\r\n */\r\nexport const generateFormOptions = (columns: TableColumn[]): FormOption[] =>\r\n columns.map((column) => {\r\n const rules: any[] = (column as any).required\r\n ? [\r\n {\r\n required: true,\r\n message: `请输入${(column as any).title}`,\r\n trigger: [\"blur\", \"input\"],\r\n validator: async (_: any, value: any) => {\r\n if (!value && value !== 0 && value !== false)\r\n throw new Error(`请输入${(column as any).title}`);\r\n },\r\n },\r\n ]\r\n : [];\r\n\r\n return {\r\n prop: (column as any).key,\r\n label: (column as any).title || (column as any).key,\r\n type: EDIT_TO_FORM_TYPE[(column as any).editType || \"input\"] || \"input\",\r\n placeholder: `请输入${(column as any).title}`,\r\n rules,\r\n attrs: (column as any).editProps || {},\r\n layout: { span: 1 },\r\n show: true,\r\n };\r\n });\r\n","/*\r\n * @Description: 表格列处理引擎 — 列映射、单元格渲染、列设置状态管理\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport { h, ref, watch, computed } from \"vue\";\r\nimport type { Ref, VNodeChild, ComputedRef } from \"vue\";\r\nimport type { DataTableRowKey, DataTableColumn } from \"naive-ui/es\";\r\nimport type { TableColumn, DataRecord } from \"../types\";\r\nimport type { ResolvedConfig } from \"./useTableConfig\";\r\nimport { EDIT_COMPONENTS } from \"../data\";\r\nimport C_Icon from \"../../C_Icon/index.vue\";\r\n\r\n/* ================= 内部辅助类型 ================= */\r\n\r\n/**\r\n * 内部列类型,展平 TableColumn 联合类型以便直接访问 key/title/visible 等属性\r\n */\r\ntype ColumnWithKey = TableColumn & {\r\n key?: string;\r\n title?: string;\r\n visible?: boolean;\r\n width?: number | string;\r\n align?: string;\r\n titleAlign?: string;\r\n};\r\n\r\n/** useTableColumns 中对 tableManager 的最小依赖接口 */\r\ninterface TableManagerRef {\r\n editStates: {\r\n cellEdit: {\r\n isEditingCell: (rowKey: DataTableRowKey, columnKey: string) => boolean;\r\n getEditingCellValue: (\r\n rowKey: DataTableRowKey,\r\n columnKey: string,\r\n ) => unknown;\r\n updateEditingCellValue: (\r\n rowKey: DataTableRowKey,\r\n columnKey: string,\r\n value: unknown,\r\n ) => void;\r\n saveEditCell: () => Promise<unknown>;\r\n cancelEditCell: () => void;\r\n startEditCell: (rowKey: DataTableRowKey, columnKey: string) => void;\r\n };\r\n rowEdit: {\r\n isEditingRow: (rowKey: DataTableRowKey) => boolean;\r\n getEditingRowData: (rowKey: DataTableRowKey) => DataRecord | undefined;\r\n updateEditingRowData: (\r\n rowKey: DataTableRowKey,\r\n field: string,\r\n value: unknown,\r\n ) => void;\r\n };\r\n };\r\n dynamicRowsState?: {\r\n enhanceColumns: (columns: TableColumn[]) => TableColumn[];\r\n } | null;\r\n expandState?: {\r\n getTableColumns: (originalColumns: TableColumn[]) => DataTableColumn[];\r\n } | null;\r\n}\r\n\r\n/* ================= 渲染工具函数 ================= */\r\n\r\n/**\r\n * 渲染编辑组件(行编辑/单元格编辑通用)\r\n */\r\nexport function renderEditComponent(\r\n column: TableColumn,\r\n value: unknown,\r\n onUpdate: (val: unknown) => void,\r\n): VNodeChild {\r\n if (column.editRender) return column.editRender(value, {} as DataRecord, 0);\r\n\r\n const col = column as ColumnWithKey;\r\n const componentProps = {\r\n value,\r\n \"onUpdate:value\": onUpdate,\r\n placeholder: `请输入${col.title ?? \"\"}`,\r\n style: { width: \"100%\" },\r\n ...column.editProps,\r\n };\r\n\r\n const Component =\r\n EDIT_COMPONENTS[column.editType || \"input\"] || EDIT_COMPONENTS.input;\r\n return h(Component, componentProps);\r\n}\r\n\r\n/**\r\n * 渲染只读单元格\r\n */\r\nexport function renderDisplayCell(\r\n column: TableColumn,\r\n rowData: DataRecord,\r\n rowIndex: number,\r\n value: unknown,\r\n): VNodeChild {\r\n return column.render\r\n ? (column.render(rowData, rowIndex) ?? String(value ?? \"\"))\r\n : String(value ?? \"\");\r\n}\r\n\r\n/**\r\n * 渲染编辑中的单元格(带保存/取消按钮)\r\n */\r\nexport function renderEditingCell(\r\n column: TableColumn,\r\n value: unknown,\r\n onUpdate: (val: unknown) => void,\r\n onSave: () => void,\r\n onCancel: () => void,\r\n): VNodeChild {\r\n const actionBtn = (\r\n name: string,\r\n title: string,\r\n onClick: (e: Event) => void,\r\n ) =>\r\n h(\r\n \"button\",\r\n {\r\n class: `cell-action-btn cell-action-${name}`,\r\n title,\r\n type: \"button\",\r\n onClick: (e: Event) => {\r\n e.stopPropagation();\r\n e.preventDefault();\r\n onClick(e);\r\n },\r\n },\r\n [\r\n h(C_Icon, {\r\n name: `mdi:${name === \"save\" ? \"check\" : \"close\"}`,\r\n title: name === \"save\" ? \"保存\" : \"取消\",\r\n size: 12,\r\n }),\r\n ],\r\n );\r\n\r\n return h(\"div\", { class: \"cell-editing-container\" }, [\r\n h(\"div\", { class: \"cell-editing-input\" }, [\r\n renderEditComponent(column, value, onUpdate),\r\n ]),\r\n h(\"div\", { class: \"cell-editing-actions\" }, [\r\n actionBtn(\"save\", \"保存\", onSave),\r\n actionBtn(\"cancel\", \"取消\", onCancel),\r\n ]),\r\n ]);\r\n}\r\n\r\n/**\r\n * 渲染可编辑单元格(显示值 + 编辑图标)\r\n */\r\nexport function renderEditableCell(\r\n column: TableColumn,\r\n rowData: DataRecord,\r\n rowIndex: number,\r\n value: unknown,\r\n onStartEdit: () => void,\r\n): VNodeChild {\r\n const displayValue = column.render\r\n ? (column.render(rowData, rowIndex) ?? String(value ?? \"\"))\r\n : String(value ?? \"\");\r\n\r\n return h(\"div\", { class: \"cell-edit-wrapper\" }, [\r\n h(\"span\", { class: \"cell-value\" }, displayValue),\r\n h(C_Icon, {\r\n name: \"mdi:square-edit-outline\",\r\n title: \"编辑\",\r\n class: \"cell-edit-icon\",\r\n size: 14,\r\n clickable: true,\r\n onClick: (e: Event) => {\r\n e.stopPropagation();\r\n onStartEdit();\r\n },\r\n }),\r\n ]);\r\n}\r\n\r\n/* ================= 组合式函数入参 ================= */\r\n\r\nexport interface UseTableColumnsOptions {\r\n /** 原始列配置 */\r\n rawColumns: ComputedRef<TableColumn[]>;\r\n /** 统一配置 */\r\n config: ComputedRef<ResolvedConfig>;\r\n /** 默认列宽 */\r\n columnWidth: number;\r\n /** 用户设定的 scrollX */\r\n scrollX?: number | string;\r\n /** 行键获取函数 */\r\n rowKey: (row: DataRecord) => DataTableRowKey;\r\n /** 表格管理器 */\r\n tableManager: TableManagerRef;\r\n /** 操作列渲染函数 */\r\n actionsRenderer: (row: DataRecord, index: number) => VNodeChild;\r\n /** 编辑模式检查器 */\r\n editModeChecker: ComputedRef<{\r\n isNonEditable: (column: TableColumn) => boolean;\r\n isRowEditMode: () => boolean;\r\n isCellEditMode: () => boolean;\r\n }>;\r\n}\r\n\r\nexport interface UseTableColumnsReturn {\r\n reactiveColumns: Ref<TableColumn[]>;\r\n showSettingsPanel: Ref<boolean>;\r\n computedColumns: ComputedRef<DataTableColumn[]>;\r\n computedScrollX: ComputedRef<number | string | undefined>;\r\n handleColumnChange: (columns: TableColumn[]) => void;\r\n}\r\n\r\n/* ================= 主函数 ================= */\r\n\r\n/**\r\n * 表格列处理引擎\r\n */\r\nexport function useTableColumns(\r\n options: UseTableColumnsOptions,\r\n): UseTableColumnsReturn {\r\n const {\r\n rawColumns,\r\n config,\r\n columnWidth,\r\n rowKey,\r\n tableManager,\r\n actionsRenderer,\r\n editModeChecker,\r\n } = options;\r\n\r\n /* ================= 响应式列状态 ================= */\r\n\r\n const reactiveColumns = ref<TableColumn[]>([]);\r\n const showSettingsPanel = ref(false);\r\n\r\n /** 同步外部列配置到响应式状态 */\r\n const syncColumns = (newColumns: TableColumn[]) => {\r\n const existingActions = reactiveColumns.value.find(\r\n (col) => (col as ColumnWithKey).key === \"_actions\",\r\n );\r\n reactiveColumns.value = [\r\n ...newColumns,\r\n existingActions ||\r\n ({\r\n key: \"_actions\",\r\n title: \"操作\",\r\n width: 180,\r\n editable: false,\r\n visible: true,\r\n fixed: \"right\",\r\n } as TableColumn),\r\n ];\r\n };\r\n\r\n watch(\r\n rawColumns,\r\n (cols) => {\r\n if (cols?.length) syncColumns(cols);\r\n },\r\n { deep: true, immediate: true },\r\n );\r\n\r\n /* ================= 单元格渲染 ================= */\r\n\r\n /** 单元格编辑模式渲染 */\r\n const renderCellEdit = (\r\n column: TableColumn,\r\n rowData: DataRecord,\r\n rowIndex: number,\r\n rowKeyVal: DataTableRowKey,\r\n ): VNodeChild => {\r\n const col = column as ColumnWithKey;\r\n const colKey = col.key ?? \"\";\r\n const value = rowData[colKey];\r\n const {\r\n isEditingCell,\r\n getEditingCellValue,\r\n updateEditingCellValue,\r\n saveEditCell,\r\n cancelEditCell,\r\n startEditCell,\r\n } = tableManager.editStates.cellEdit;\r\n\r\n if (isEditingCell(rowKeyVal, colKey)) {\r\n return renderEditingCell(\r\n column,\r\n getEditingCellValue(rowKeyVal, colKey) ?? value,\r\n (val: unknown) => updateEditingCellValue(rowKeyVal, colKey, val),\r\n () => saveEditCell(),\r\n () => cancelEditCell(),\r\n );\r\n }\r\n\r\n return renderEditableCell(column, rowData, rowIndex, value, () =>\r\n startEditCell(rowKeyVal, colKey),\r\n );\r\n };\r\n\r\n /** 统一单元格渲染入口 */\r\n const renderCell = (\r\n column: TableColumn,\r\n rowData: DataRecord,\r\n rowIndex: number,\r\n ): VNodeChild => {\r\n const col = column as ColumnWithKey;\r\n const colKey = col.key ?? \"\";\r\n const value = rowData[colKey];\r\n const key = rowKey(rowData);\r\n const checker = editModeChecker.value;\r\n\r\n if (checker.isNonEditable(column)) {\r\n return renderDisplayCell(column, rowData, rowIndex, value);\r\n }\r\n\r\n if (\r\n checker.isRowEditMode() &&\r\n tableManager.editStates.rowEdit.isEditingRow(key)\r\n ) {\r\n return renderEditComponent(\r\n column,\r\n tableManager.editStates.rowEdit.getEditingRowData(key)?.[colKey] ??\r\n value,\r\n (val: unknown) =>\r\n tableManager.editStates.rowEdit.updateEditingRowData(\r\n key,\r\n colKey,\r\n val,\r\n ),\r\n );\r\n }\r\n\r\n if (checker.isCellEditMode()) {\r\n return renderCellEdit(column, rowData, rowIndex, key);\r\n }\r\n\r\n return renderDisplayCell(column, rowData, rowIndex, value);\r\n };\r\n\r\n /* ================= 列映射 ================= */\r\n\r\n const getColWidth = (col: TableColumn): number => {\r\n const w = (col as ColumnWithKey).width || columnWidth || 180;\r\n return typeof w === \"number\" ? w : 180;\r\n };\r\n\r\n /** 序号列 */\r\n const mapIndexColumn = (column: TableColumn): DataTableColumn => {\r\n const col = column as ColumnWithKey;\r\n return {\r\n key: \"_index\",\r\n title: col.title || \"序号\",\r\n width:\r\n typeof (col.width || 50) === \"number\"\r\n ? (col.width as number) || 50\r\n : 50,\r\n titleAlign: \"center\" as const,\r\n align: \"center\" as const,\r\n render: (_: DataRecord, index: number) => index + 1,\r\n fixed: column.fixed,\r\n };\r\n };\r\n\r\n /** 普通数据列 */\r\n const mapRegularColumn = (column: TableColumn): DataTableColumn => {\r\n const col = column as ColumnWithKey;\r\n const base: Record<string, unknown> = {\r\n ...col,\r\n width: getColWidth(column),\r\n titleAlign: col.titleAlign || (\"center\" as const),\r\n align: col.align || (\"center\" as const),\r\n render:\r\n column.render ||\r\n ((rowData: DataRecord, rowIndex: number) =>\r\n renderCell(column, rowData, rowIndex)),\r\n };\r\n\r\n if (column.fixed) base.fixed = column.fixed;\r\n\r\n if (column.resizable && typeof base.width === \"number\") {\r\n base.resizable = true;\r\n base.minWidth = column.minWidth || 80;\r\n base.maxWidth = column.maxWidth || 500;\r\n }\r\n\r\n return base as unknown as DataTableColumn;\r\n };\r\n\r\n /* ================= 计算列 ================= */\r\n\r\n const computedColumns = computed((): DataTableColumn[] => {\r\n let cols: DataTableColumn[] = reactiveColumns.value\r\n .filter((c) => {\r\n const col = c as ColumnWithKey;\r\n return col.visible !== false && col.key !== \"_actions\";\r\n })\r\n .map((c) => {\r\n const col = c as ColumnWithKey;\r\n return col.type === \"index\" ? mapIndexColumn(c) : mapRegularColumn(c);\r\n }) as DataTableColumn[];\r\n\r\n if (tableManager.dynamicRowsState) {\r\n cols = tableManager.dynamicRowsState.enhanceColumns(\r\n cols as unknown as TableColumn[],\r\n ) as unknown as DataTableColumn[];\r\n }\r\n\r\n if (\r\n tableManager.expandState &&\r\n (config.value.expandable || config.value.enableSelection)\r\n ) {\r\n cols = tableManager.expandState.getTableColumns(\r\n cols as unknown as TableColumn[],\r\n ) as unknown as DataTableColumn[];\r\n }\r\n\r\n const actionsMeta = reactiveColumns.value.find(\r\n (c) => (c as ColumnWithKey).key === \"_actions\",\r\n );\r\n cols.push({\r\n key: \"_actions\",\r\n title: \"操作\",\r\n align: \"center\" as const,\r\n titleAlign: \"center\" as const,\r\n render: actionsRenderer,\r\n fixed: (actionsMeta as ColumnWithKey)?.fixed,\r\n });\r\n\r\n return cols;\r\n });\r\n\r\n /* ================= 横向滚动 ================= */\r\n\r\n const computedScrollX = computed(() => {\r\n if (options.scrollX !== undefined) return options.scrollX;\r\n\r\n const hasFixed = reactiveColumns.value.some((c) => {\r\n const col = c as ColumnWithKey;\r\n return col.fixed && col.visible !== false;\r\n });\r\n if (!hasFixed) return undefined;\r\n\r\n const total = reactiveColumns.value\r\n .filter((c) => (c as ColumnWithKey).visible !== false)\r\n .reduce((sum: number, c) => sum + getColWidth(c), 0);\r\n\r\n return total + 200;\r\n });\r\n\r\n /* ================= 列设置变更 ================= */\r\n\r\n const handleColumnChange = (columns: TableColumn[]) => {\r\n reactiveColumns.value = columns.map((col) => {\r\n const c = col as ColumnWithKey;\r\n return {\r\n ...col,\r\n visible: c.visible !== false,\r\n fixed: col.fixed,\r\n width: c.width || columnWidth,\r\n align: c.align || \"center\",\r\n titleAlign: c.titleAlign || \"center\",\r\n } as unknown as TableColumn;\r\n });\r\n };\r\n\r\n return {\r\n reactiveColumns,\r\n showSettingsPanel,\r\n computedColumns,\r\n computedScrollX,\r\n handleColumnChange,\r\n };\r\n}\r\n","/*\r\n * @Description: ColumnSettings 配置与工具函数\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n */\r\n\r\nimport type { TableColumn } from \"../../types\";\r\n\r\n/** 固定列下拉选项 */\r\nexport const getFixedOptions = (column: TableColumn) => [\r\n {\r\n label: column.fixed ? \"✓ 取消固定\" : \"不固定\",\r\n key: \"none\",\r\n disabled: !column.fixed,\r\n },\r\n {\r\n label: column.fixed === \"left\" ? \"✓ 固定左侧\" : \"固定左侧\",\r\n key: \"left\",\r\n disabled: false,\r\n },\r\n {\r\n label: column.fixed === \"right\" ? \"✓ 固定右侧\" : \"固定右侧\",\r\n key: \"right\",\r\n disabled: false,\r\n },\r\n];\r\n\r\n/** 不可操作的特殊列 key */\r\nexport const SPECIAL_COLUMN_KEYS = [\"_actions\"] as const;\r\n\r\n/** 不可拖拽的列 type */\r\nexport const SPECIAL_COLUMN_TYPES = [\"selection\", \"expand\"] as const;\r\n\r\n/** 判断是否为特殊列(不可调宽、不可拖拽) */\r\nexport const isSpecialColumn = (column: TableColumn): boolean =>\r\n SPECIAL_COLUMN_KEYS.includes(\r\n column.key as (typeof SPECIAL_COLUMN_KEYS)[number],\r\n ) ||\r\n SPECIAL_COLUMN_TYPES.includes(\r\n column.type as (typeof SPECIAL_COLUMN_TYPES)[number],\r\n );\r\n","<!--\r\n * @Description: 列设置面板 — 搜索、拖拽排序、可见性、固定列、列宽调整\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n -->\r\n\r\n<template>\r\n <div class=\"column-management-tab\">\r\n <!-- 搜索框和列宽调整开关 -->\r\n <div class=\"search-row\">\r\n <NInput\r\n v-model:value=\"searchText\"\r\n placeholder=\"搜索列名...\"\r\n clearable\r\n class=\"search-input\"\r\n >\r\n <template #prefix>\r\n <C_Icon name=\"mdi:magnify\" />\r\n </template>\r\n </NInput>\r\n\r\n <div class=\"resizable-control\">\r\n <C_Icon\r\n name=\"mdi:arrow-split-vertical\"\r\n size=\"14\"\r\n :title=\"\r\n enableResizable ? '开启后可拖拽列边界调整宽度' : '允许调整列宽'\r\n \"\r\n />\r\n <NText :style=\"{ fontSize: '12px', marginLeft: '4px' }\">\r\n 列宽调整\r\n </NText>\r\n <NSwitch\r\n v-model:value=\"enableResizable\"\r\n size=\"small\"\r\n style=\"margin-left: 6px\"\r\n @update:value=\"handleResizableChange\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- 顶部操作栏:统计信息和快捷操作按钮 -->\r\n <div class=\"top-actions-bar\">\r\n <div class=\"stats-info\">\r\n <NText depth=\"3\" :style=\"{ fontSize: '13px' }\">\r\n 已选 {{ visibleCount }} / 总共 {{ totalCount }} 列\r\n </NText>\r\n </div>\r\n <div class=\"quick-actions\">\r\n <NSpace :size=\"6\">\r\n <NButton size=\"tiny\" @click=\"selectAll\"> 全选 </NButton>\r\n <NButton size=\"tiny\" @click=\"selectNone\"> 全不选 </NButton>\r\n <NButton size=\"tiny\" @click=\"resetColumns\"> 重置 </NButton>\r\n </NSpace>\r\n </div>\r\n </div>\r\n\r\n <!-- 列列表 -->\r\n <div ref=\"listRef\" class=\"column-list\">\r\n <div\r\n v-for=\"(column, index) in filteredColumns\"\r\n :key=\"column.key\"\r\n class=\"column-item\"\r\n :class=\"{\r\n disabled: column.key === '_actions',\r\n 'fixed-left': column.fixed === 'left',\r\n 'fixed-right': column.fixed === 'right',\r\n }\"\r\n :draggable=\"column.key !== '_actions'\"\r\n @dragstart=\"handleDragStart(index, $event)\"\r\n @dragover=\"handleDragOver(index, $event)\"\r\n @dragend=\"handleDragEnd\"\r\n @drop=\"handleDrop(index)\"\r\n >\r\n <div class=\"column-info\">\r\n <div class=\"column-controls\">\r\n <C_Icon\r\n name=\"mdi:drag\"\r\n size=\"16\"\r\n class=\"drag-handle\"\r\n :class=\"{ disabled: column.key === '_actions' }\"\r\n />\r\n <NCheckbox\r\n :checked=\"column.visible !== false\"\r\n :disabled=\"column.key === '_actions'\"\r\n @update:checked=\"\r\n (value: boolean) => toggleColumnVisibility(index, value)\r\n \"\r\n />\r\n </div>\r\n <div class=\"column-details\">\r\n <NSpace align=\"center\" :size=\"6\">\r\n <NText strong :style=\"{ fontSize: '13px' }\">\r\n {{ column.title || column.key }}\r\n </NText>\r\n <NTag v-if=\"column.fixed === 'left'\" size=\"tiny\" type=\"info\">\r\n 左固定\r\n </NTag>\r\n <NTag v-if=\"column.fixed === 'right'\" size=\"tiny\" type=\"warning\">\r\n 右固定\r\n </NTag>\r\n </NSpace>\r\n <NText depth=\"3\" :style=\"{ fontSize: '11px' }\">\r\n {{ column.key }}\r\n </NText>\r\n </div>\r\n </div>\r\n <div class=\"column-actions\">\r\n <div class=\"drag-controls\">\r\n <C_Icon\r\n name=\"mdi:chevron-up\"\r\n size=\"14\"\r\n title=\"上移\"\r\n :clickable=\"index !== 0\"\r\n :class=\"{ disabled: index === 0 }\"\r\n @click=\"index !== 0 && moveColumn(index, index - 1)\"\r\n />\r\n <C_Icon\r\n name=\"mdi:chevron-down\"\r\n size=\"14\"\r\n title=\"下移\"\r\n :clickable=\"index !== filteredColumns.length - 1\"\r\n :class=\"{ disabled: index === filteredColumns.length - 1 }\"\r\n @click=\"\r\n index !== filteredColumns.length - 1 &&\r\n moveColumn(index, index + 1)\r\n \"\r\n />\r\n </div>\r\n <NDropdown\r\n :options=\"getFixedOptions(column)\"\r\n @select=\"(value: string) => handleFixedSelect(index, value)\"\r\n >\r\n <C_Icon\r\n name=\"mdi:pin\"\r\n size=\"14\"\r\n title=\"固定列\"\r\n clickable\r\n :style=\"{\r\n color: column.fixed ? 'var(--n-primary-color)' : undefined,\r\n }\"\r\n />\r\n </NDropdown>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, onMounted } from \"vue\";\r\nimport {\r\n NInput,\r\n NText,\r\n NSwitch,\r\n NSpace,\r\n NButton,\r\n NCheckbox,\r\n NTag,\r\n NDropdown,\r\n} from \"naive-ui/es\";\r\nimport C_Icon from \"../../../C_Icon/index.vue\";\r\nimport type { TableColumn } from \"../../types\";\r\nimport { getFixedOptions, isSpecialColumn } from \"./data\";\r\n\r\ndefineOptions({ name: \"ColumnSettings\" });\r\n\r\n/* ================= Props & Emits ================= */\r\n\r\nconst props = defineProps<{ columns: TableColumn[] }>();\r\nconst emit = defineEmits<{ (e: \"change\", columns: TableColumn[]): void }>();\r\n\r\n/* ================= 响应式状态 ================= */\r\n\r\nconst localColumns = ref<TableColumn[]>([...props.columns]);\r\nconst searchText = ref(\"\");\r\nconst listRef = ref<HTMLElement>();\r\nconst draggedIndex = ref<number | null>(null);\r\nconst dragOverIndex = ref<number | null>(null);\r\nconst enableResizable = ref(false);\r\n\r\nonMounted(() => {\r\n enableResizable.value = localColumns.value.some(\r\n (col) => col.resizable === true,\r\n );\r\n});\r\n\r\n/* ================= 计算属性 ================= */\r\n\r\nconst filteredColumns = computed(() => {\r\n if (!searchText.value) return localColumns.value;\r\n const search = searchText.value.toLowerCase();\r\n return localColumns.value.filter(\r\n (col) =>\r\n col.title?.toLowerCase().includes(search) ||\r\n col.key.toLowerCase().includes(search),\r\n );\r\n});\r\n\r\nconst visibleCount = computed(\r\n () => localColumns.value.filter((col) => col.visible !== false).length,\r\n);\r\nconst totalCount = computed(() => localColumns.value.length);\r\n\r\n/* ================= 批量操作 ================= */\r\n\r\nconst setAllColumnsVisible = (visible: boolean) => {\r\n localColumns.value.forEach((col) => {\r\n if (col.key !== \"_actions\") col.visible = visible;\r\n });\r\n applyChanges();\r\n};\r\n\r\nconst selectAll = () => setAllColumnsVisible(true);\r\nconst selectNone = () => setAllColumnsVisible(false);\r\n\r\n/* ================= 列属性更新 ================= */\r\n\r\nconst findOriginalIndex = (filteredIndex: number): number => {\r\n const column = filteredColumns.value[filteredIndex];\r\n return localColumns.value.findIndex((col) => col.key === column.key);\r\n};\r\n\r\nconst updateColumnProperty = (\r\n index: number,\r\n updater: (col: TableColumn) => void,\r\n) => {\r\n const originalIndex = findOriginalIndex(index);\r\n if (originalIndex !== -1) {\r\n updater(localColumns.value[originalIndex]);\r\n applyChanges();\r\n }\r\n};\r\n\r\nconst toggleColumnVisibility = (index: number, visible: boolean) => {\r\n updateColumnProperty(index, (col) => {\r\n col.visible = visible;\r\n });\r\n};\r\n\r\nconst handleFixedSelect = (index: number, value: string) => {\r\n updateColumnProperty(index, (col) => {\r\n col.fixed = value === \"none\" ? undefined : (value as \"left\" | \"right\");\r\n });\r\n};\r\n\r\nconst applyChanges = () => emit(\"change\", [...localColumns.value]);\r\n\r\nconst resetColumns = () => {\r\n localColumns.value = [...props.columns];\r\n applyChanges();\r\n};\r\n\r\n/* ================= 列宽调整 ================= */\r\n\r\nconst handleResizableChange = (value: boolean) => {\r\n localColumns.value.forEach((col) => {\r\n if (!isSpecialColumn(col)) {\r\n col.resizable = value;\r\n if (value) {\r\n col.minWidth = col.minWidth || 80;\r\n col.maxWidth = col.maxWidth || 500;\r\n }\r\n }\r\n });\r\n applyChanges();\r\n};\r\n\r\n/* ================= 拖拽排序 ================= */\r\n\r\nconst moveColumn = (fromIndex: number, toIndex: number) => {\r\n const originalFromIndex = findOriginalIndex(fromIndex);\r\n const originalToIndex = findOriginalIndex(toIndex);\r\n if (originalFromIndex !== -1 && originalToIndex !== -1) {\r\n const [movedColumn] = localColumns.value.splice(originalFromIndex, 1);\r\n localColumns.value.splice(originalToIndex, 0, movedColumn);\r\n applyChanges();\r\n }\r\n};\r\n\r\nconst handleDragStart = (index: number, event: DragEvent) => {\r\n const column = filteredColumns.value[index];\r\n if (column.key === \"_actions\") {\r\n event.preventDefault();\r\n return;\r\n }\r\n draggedIndex.value = index;\r\n if (event.dataTransfer) event.dataTransfer.effectAllowed = \"move\";\r\n};\r\n\r\nconst handleDragOver = (index: number, event: DragEvent) => {\r\n event.preventDefault();\r\n if (\r\n draggedIndex.value === null ||\r\n filteredColumns.value[index].key === \"_actions\"\r\n )\r\n return;\r\n dragOverIndex.value = index;\r\n if (event.dataTransfer) event.dataTransfer.dropEffect = \"move\";\r\n};\r\n\r\nconst handleDrop = (toIndex: number) => {\r\n if (\r\n draggedIndex.value === null ||\r\n filteredColumns.value[toIndex].key === \"_actions\"\r\n )\r\n return;\r\n moveColumn(draggedIndex.value, toIndex);\r\n draggedIndex.value = null;\r\n dragOverIndex.value = null;\r\n};\r\n\r\nconst handleDragEnd = () => {\r\n draggedIndex.value = null;\r\n dragOverIndex.value = null;\r\n};\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n@use \"./index.scss\";\r\n</style>\r\n","<!--\r\n * @Description: 列设置面板 — 搜索、拖拽排序、可见性、固定列、列宽调整\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n -->\r\n\r\n<template>\r\n <div class=\"column-management-tab\">\r\n <!-- 搜索框和列宽调整开关 -->\r\n <div class=\"search-row\">\r\n <NInput\r\n v-model:value=\"searchText\"\r\n placeholder=\"搜索列名...\"\r\n clearable\r\n class=\"search-input\"\r\n >\r\n <template #prefix>\r\n <C_Icon name=\"mdi:magnify\" />\r\n </template>\r\n </NInput>\r\n\r\n <div class=\"resizable-control\">\r\n <C_Icon\r\n name=\"mdi:arrow-split-vertical\"\r\n size=\"14\"\r\n :title=\"\r\n enableResizable ? '开启后可拖拽列边界调整宽度' : '允许调整列宽'\r\n \"\r\n />\r\n <NText :style=\"{ fontSize: '12px', marginLeft: '4px' }\">\r\n 列宽调整\r\n </NText>\r\n <NSwitch\r\n v-model:value=\"enableResizable\"\r\n size=\"small\"\r\n style=\"margin-left: 6px\"\r\n @update:value=\"handleResizableChange\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- 顶部操作栏:统计信息和快捷操作按钮 -->\r\n <div class=\"top-actions-bar\">\r\n <div class=\"stats-info\">\r\n <NText depth=\"3\" :style=\"{ fontSize: '13px' }\">\r\n 已选 {{ visibleCount }} / 总共 {{ totalCount }} 列\r\n </NText>\r\n </div>\r\n <div class=\"quick-actions\">\r\n <NSpace :size=\"6\">\r\n <NButton size=\"tiny\" @click=\"selectAll\"> 全选 </NButton>\r\n <NButton size=\"tiny\" @click=\"selectNone\"> 全不选 </NButton>\r\n <NButton size=\"tiny\" @click=\"resetColumns\"> 重置 </NButton>\r\n </NSpace>\r\n </div>\r\n </div>\r\n\r\n <!-- 列列表 -->\r\n <div ref=\"listRef\" class=\"column-list\">\r\n <div\r\n v-for=\"(column, index) in filteredColumns\"\r\n :key=\"column.key\"\r\n class=\"column-item\"\r\n :class=\"{\r\n disabled: column.key === '_actions',\r\n 'fixed-left': column.fixed === 'left',\r\n 'fixed-right': column.fixed === 'right',\r\n }\"\r\n :draggable=\"column.key !== '_actions'\"\r\n @dragstart=\"handleDragStart(index, $event)\"\r\n @dragover=\"handleDragOver(index, $event)\"\r\n @dragend=\"handleDragEnd\"\r\n @drop=\"handleDrop(index)\"\r\n >\r\n <div class=\"column-info\">\r\n <div class=\"column-controls\">\r\n <C_Icon\r\n name=\"mdi:drag\"\r\n size=\"16\"\r\n class=\"drag-handle\"\r\n :class=\"{ disabled: column.key === '_actions' }\"\r\n />\r\n <NCheckbox\r\n :checked=\"column.visible !== false\"\r\n :disabled=\"column.key === '_actions'\"\r\n @update:checked=\"\r\n (value: boolean) => toggleColumnVisibility(index, value)\r\n \"\r\n />\r\n </div>\r\n <div class=\"column-details\">\r\n <NSpace align=\"center\" :size=\"6\">\r\n <NText strong :style=\"{ fontSize: '13px' }\">\r\n {{ column.title || column.key }}\r\n </NText>\r\n <NTag v-if=\"column.fixed === 'left'\" size=\"tiny\" type=\"info\">\r\n 左固定\r\n </NTag>\r\n <NTag v-if=\"column.fixed === 'right'\" size=\"tiny\" type=\"warning\">\r\n 右固定\r\n </NTag>\r\n </NSpace>\r\n <NText depth=\"3\" :style=\"{ fontSize: '11px' }\">\r\n {{ column.key }}\r\n </NText>\r\n </div>\r\n </div>\r\n <div class=\"column-actions\">\r\n <div class=\"drag-controls\">\r\n <C_Icon\r\n name=\"mdi:chevron-up\"\r\n size=\"14\"\r\n title=\"上移\"\r\n :clickable=\"index !== 0\"\r\n :class=\"{ disabled: index === 0 }\"\r\n @click=\"index !== 0 && moveColumn(index, index - 1)\"\r\n />\r\n <C_Icon\r\n name=\"mdi:chevron-down\"\r\n size=\"14\"\r\n title=\"下移\"\r\n :clickable=\"index !== filteredColumns.length - 1\"\r\n :class=\"{ disabled: index === filteredColumns.length - 1 }\"\r\n @click=\"\r\n index !== filteredColumns.length - 1 &&\r\n moveColumn(index, index + 1)\r\n \"\r\n />\r\n </div>\r\n <NDropdown\r\n :options=\"getFixedOptions(column)\"\r\n @select=\"(value: string) => handleFixedSelect(index, value)\"\r\n >\r\n <C_Icon\r\n name=\"mdi:pin\"\r\n size=\"14\"\r\n title=\"固定列\"\r\n clickable\r\n :style=\"{\r\n color: column.fixed ? 'var(--n-primary-color)' : undefined,\r\n }\"\r\n />\r\n </NDropdown>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, onMounted } from \"vue\";\r\nimport {\r\n NInput,\r\n NText,\r\n NSwitch,\r\n NSpace,\r\n NButton,\r\n NCheckbox,\r\n NTag,\r\n NDropdown,\r\n} from \"naive-ui/es\";\r\nimport C_Icon from \"../../../C_Icon/index.vue\";\r\nimport type { TableColumn } from \"../../types\";\r\nimport { getFixedOptions, isSpecialColumn } from \"./data\";\r\n\r\ndefineOptions({ name: \"ColumnSettings\" });\r\n\r\n/* ================= Props & Emits ================= */\r\n\r\nconst props = defineProps<{ columns: TableColumn[] }>();\r\nconst emit = defineEmits<{ (e: \"change\", columns: TableColumn[]): void }>();\r\n\r\n/* ================= 响应式状态 ================= */\r\n\r\nconst localColumns = ref<TableColumn[]>([...props.columns]);\r\nconst searchText = ref(\"\");\r\nconst listRef = ref<HTMLElement>();\r\nconst draggedIndex = ref<number | null>(null);\r\nconst dragOverIndex = ref<number | null>(null);\r\nconst enableResizable = ref(false);\r\n\r\nonMounted(() => {\r\n enableResizable.value = localColumns.value.some(\r\n (col) => col.resizable === true,\r\n );\r\n});\r\n\r\n/* ================= 计算属性 ================= */\r\n\r\nconst filteredColumns = computed(() => {\r\n if (!searchText.value) return localColumns.value;\r\n const search = searchText.value.toLowerCase();\r\n return localColumns.value.filter(\r\n (col) =>\r\n col.title?.toLowerCase().includes(search) ||\r\n col.key.toLowerCase().includes(search),\r\n );\r\n});\r\n\r\nconst visibleCount = computed(\r\n () => localColumns.value.filter((col) => col.visible !== false).length,\r\n);\r\nconst totalCount = computed(() => localColumns.value.length);\r\n\r\n/* ================= 批量操作 ================= */\r\n\r\nconst setAllColumnsVisible = (visible: boolean) => {\r\n localColumns.value.forEach((col) => {\r\n if (col.key !== \"_actions\") col.visible = visible;\r\n });\r\n applyChanges();\r\n};\r\n\r\nconst selectAll = () => setAllColumnsVisible(true);\r\nconst selectNone = () => setAllColumnsVisible(false);\r\n\r\n/* ================= 列属性更新 ================= */\r\n\r\nconst findOriginalIndex = (filteredIndex: number): number => {\r\n const column = filteredColumns.value[filteredIndex];\r\n return localColumns.value.findIndex((col) => col.key === column.key);\r\n};\r\n\r\nconst updateColumnProperty = (\r\n index: number,\r\n updater: (col: TableColumn) => void,\r\n) => {\r\n const originalIndex = findOriginalIndex(index);\r\n if (originalIndex !== -1) {\r\n updater(localColumns.value[originalIndex]);\r\n applyChanges();\r\n }\r\n};\r\n\r\nconst toggleColumnVisibility = (index: number, visible: boolean) => {\r\n updateColumnProperty(index, (col) => {\r\n col.visible = visible;\r\n });\r\n};\r\n\r\nconst handleFixedSelect = (index: number, value: string) => {\r\n updateColumnProperty(index, (col) => {\r\n col.fixed = value === \"none\" ? undefined : (value as \"left\" | \"right\");\r\n });\r\n};\r\n\r\nconst applyChanges = () => emit(\"change\", [...localColumns.value]);\r\n\r\nconst resetColumns = () => {\r\n localColumns.value = [...props.columns];\r\n applyChanges();\r\n};\r\n\r\n/* ================= 列宽调整 ================= */\r\n\r\nconst handleResizableChange = (value: boolean) => {\r\n localColumns.value.forEach((col) => {\r\n if (!isSpecialColumn(col)) {\r\n col.resizable = value;\r\n if (value) {\r\n col.minWidth = col.minWidth || 80;\r\n col.maxWidth = col.maxWidth || 500;\r\n }\r\n }\r\n });\r\n applyChanges();\r\n};\r\n\r\n/* ================= 拖拽排序 ================= */\r\n\r\nconst moveColumn = (fromIndex: number, toIndex: number) => {\r\n const originalFromIndex = findOriginalIndex(fromIndex);\r\n const originalToIndex = findOriginalIndex(toIndex);\r\n if (originalFromIndex !== -1 && originalToIndex !== -1) {\r\n const [movedColumn] = localColumns.value.splice(originalFromIndex, 1);\r\n localColumns.value.splice(originalToIndex, 0, movedColumn);\r\n applyChanges();\r\n }\r\n};\r\n\r\nconst handleDragStart = (index: number, event: DragEvent) => {\r\n const column = filteredColumns.value[index];\r\n if (column.key === \"_actions\") {\r\n event.preventDefault();\r\n return;\r\n }\r\n draggedIndex.value = index;\r\n if (event.dataTransfer) event.dataTransfer.effectAllowed = \"move\";\r\n};\r\n\r\nconst handleDragOver = (index: number, event: DragEvent) => {\r\n event.preventDefault();\r\n if (\r\n draggedIndex.value === null ||\r\n filteredColumns.value[index].key === \"_actions\"\r\n )\r\n return;\r\n dragOverIndex.value = index;\r\n if (event.dataTransfer) event.dataTransfer.dropEffect = \"move\";\r\n};\r\n\r\nconst handleDrop = (toIndex: number) => {\r\n if (\r\n draggedIndex.value === null ||\r\n filteredColumns.value[toIndex].key === \"_actions\"\r\n )\r\n return;\r\n moveColumn(draggedIndex.value, toIndex);\r\n draggedIndex.value = null;\r\n dragOverIndex.value = null;\r\n};\r\n\r\nconst handleDragEnd = () => {\r\n draggedIndex.value = null;\r\n dragOverIndex.value = null;\r\n};\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n@use \"./index.scss\";\r\n</style>\r\n","<!--\r\n * @Description: 列设置面板 — 搜索、拖拽排序、可见性、固定列、列宽调整\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n -->\r\n\r\n<template>\r\n <div class=\"column-management-tab\">\r\n <!-- 搜索框和列宽调整开关 -->\r\n <div class=\"search-row\">\r\n <NInput\r\n v-model:value=\"searchText\"\r\n placeholder=\"搜索列名...\"\r\n clearable\r\n class=\"search-input\"\r\n >\r\n <template #prefix>\r\n <C_Icon name=\"mdi:magnify\" />\r\n </template>\r\n </NInput>\r\n\r\n <div class=\"resizable-control\">\r\n <C_Icon\r\n name=\"mdi:arrow-split-vertical\"\r\n size=\"14\"\r\n :title=\"\r\n enableResizable ? '开启后可拖拽列边界调整宽度' : '允许调整列宽'\r\n \"\r\n />\r\n <NText :style=\"{ fontSize: '12px', marginLeft: '4px' }\">\r\n 列宽调整\r\n </NText>\r\n <NSwitch\r\n v-model:value=\"enableResizable\"\r\n size=\"small\"\r\n style=\"margin-left: 6px\"\r\n @update:value=\"handleResizableChange\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- 顶部操作栏:统计信息和快捷操作按钮 -->\r\n <div class=\"top-actions-bar\">\r\n <div class=\"stats-info\">\r\n <NText depth=\"3\" :style=\"{ fontSize: '13px' }\">\r\n 已选 {{ visibleCount }} / 总共 {{ totalCount }} 列\r\n </NText>\r\n </div>\r\n <div class=\"quick-actions\">\r\n <NSpace :size=\"6\">\r\n <NButton size=\"tiny\" @click=\"selectAll\"> 全选 </NButton>\r\n <NButton size=\"tiny\" @click=\"selectNone\"> 全不选 </NButton>\r\n <NButton size=\"tiny\" @click=\"resetColumns\"> 重置 </NButton>\r\n </NSpace>\r\n </div>\r\n </div>\r\n\r\n <!-- 列列表 -->\r\n <div ref=\"listRef\" class=\"column-list\">\r\n <div\r\n v-for=\"(column, index) in filteredColumns\"\r\n :key=\"column.key\"\r\n class=\"column-item\"\r\n :class=\"{\r\n disabled: column.key === '_actions',\r\n 'fixed-left': column.fixed === 'left',\r\n 'fixed-right': column.fixed === 'right',\r\n }\"\r\n :draggable=\"column.key !== '_actions'\"\r\n @dragstart=\"handleDragStart(index, $event)\"\r\n @dragover=\"handleDragOver(index, $event)\"\r\n @dragend=\"handleDragEnd\"\r\n @drop=\"handleDrop(index)\"\r\n >\r\n <div class=\"column-info\">\r\n <div class=\"column-controls\">\r\n <C_Icon\r\n name=\"mdi:drag\"\r\n size=\"16\"\r\n class=\"drag-handle\"\r\n :class=\"{ disabled: column.key === '_actions' }\"\r\n />\r\n <NCheckbox\r\n :checked=\"column.visible !== false\"\r\n :disabled=\"column.key === '_actions'\"\r\n @update:checked=\"\r\n (value: boolean) => toggleColumnVisibility(index, value)\r\n \"\r\n />\r\n </div>\r\n <div class=\"column-details\">\r\n <NSpace align=\"center\" :size=\"6\">\r\n <NText strong :style=\"{ fontSize: '13px' }\">\r\n {{ column.title || column.key }}\r\n </NText>\r\n <NTag v-if=\"column.fixed === 'left'\" size=\"tiny\" type=\"info\">\r\n 左固定\r\n </NTag>\r\n <NTag v-if=\"column.fixed === 'right'\" size=\"tiny\" type=\"warning\">\r\n 右固定\r\n </NTag>\r\n </NSpace>\r\n <NText depth=\"3\" :style=\"{ fontSize: '11px' }\">\r\n {{ column.key }}\r\n </NText>\r\n </div>\r\n </div>\r\n <div class=\"column-actions\">\r\n <div class=\"drag-controls\">\r\n <C_Icon\r\n name=\"mdi:chevron-up\"\r\n size=\"14\"\r\n title=\"上移\"\r\n :clickable=\"index !== 0\"\r\n :class=\"{ disabled: index === 0 }\"\r\n @click=\"index !== 0 && moveColumn(index, index - 1)\"\r\n />\r\n <C_Icon\r\n name=\"mdi:chevron-down\"\r\n size=\"14\"\r\n title=\"下移\"\r\n :clickable=\"index !== filteredColumns.length - 1\"\r\n :class=\"{ disabled: index === filteredColumns.length - 1 }\"\r\n @click=\"\r\n index !== filteredColumns.length - 1 &&\r\n moveColumn(index, index + 1)\r\n \"\r\n />\r\n </div>\r\n <NDropdown\r\n :options=\"getFixedOptions(column)\"\r\n @select=\"(value: string) => handleFixedSelect(index, value)\"\r\n >\r\n <C_Icon\r\n name=\"mdi:pin\"\r\n size=\"14\"\r\n title=\"固定列\"\r\n clickable\r\n :style=\"{\r\n color: column.fixed ? 'var(--n-primary-color)' : undefined,\r\n }\"\r\n />\r\n </NDropdown>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, onMounted } from \"vue\";\r\nimport {\r\n NInput,\r\n NText,\r\n NSwitch,\r\n NSpace,\r\n NButton,\r\n NCheckbox,\r\n NTag,\r\n NDropdown,\r\n} from \"naive-ui/es\";\r\nimport C_Icon from \"../../../C_Icon/index.vue\";\r\nimport type { TableColumn } from \"../../types\";\r\nimport { getFixedOptions, isSpecialColumn } from \"./data\";\r\n\r\ndefineOptions({ name: \"ColumnSettings\" });\r\n\r\n/* ================= Props & Emits ================= */\r\n\r\nconst props = defineProps<{ columns: TableColumn[] }>();\r\nconst emit = defineEmits<{ (e: \"change\", columns: TableColumn[]): void }>();\r\n\r\n/* ================= 响应式状态 ================= */\r\n\r\nconst localColumns = ref<TableColumn[]>([...props.columns]);\r\nconst searchText = ref(\"\");\r\nconst listRef = ref<HTMLElement>();\r\nconst draggedIndex = ref<number | null>(null);\r\nconst dragOverIndex = ref<number | null>(null);\r\nconst enableResizable = ref(false);\r\n\r\nonMounted(() => {\r\n enableResizable.value = localColumns.value.some(\r\n (col) => col.resizable === true,\r\n );\r\n});\r\n\r\n/* ================= 计算属性 ================= */\r\n\r\nconst filteredColumns = computed(() => {\r\n if (!searchText.value) return localColumns.value;\r\n const search = searchText.value.toLowerCase();\r\n return localColumns.value.filter(\r\n (col) =>\r\n col.title?.toLowerCase().includes(search) ||\r\n col.key.toLowerCase().includes(search),\r\n );\r\n});\r\n\r\nconst visibleCount = computed(\r\n () => localColumns.value.filter((col) => col.visible !== false).length,\r\n);\r\nconst totalCount = computed(() => localColumns.value.length);\r\n\r\n/* ================= 批量操作 ================= */\r\n\r\nconst setAllColumnsVisible = (visible: boolean) => {\r\n localColumns.value.forEach((col) => {\r\n if (col.key !== \"_actions\") col.visible = visible;\r\n });\r\n applyChanges();\r\n};\r\n\r\nconst selectAll = () => setAllColumnsVisible(true);\r\nconst selectNone = () => setAllColumnsVisible(false);\r\n\r\n/* ================= 列属性更新 ================= */\r\n\r\nconst findOriginalIndex = (filteredIndex: number): number => {\r\n const column = filteredColumns.value[filteredIndex];\r\n return localColumns.value.findIndex((col) => col.key === column.key);\r\n};\r\n\r\nconst updateColumnProperty = (\r\n index: number,\r\n updater: (col: TableColumn) => void,\r\n) => {\r\n const originalIndex = findOriginalIndex(index);\r\n if (originalIndex !== -1) {\r\n updater(localColumns.value[originalIndex]);\r\n applyChanges();\r\n }\r\n};\r\n\r\nconst toggleColumnVisibility = (index: number, visible: boolean) => {\r\n updateColumnProperty(index, (col) => {\r\n col.visible = visible;\r\n });\r\n};\r\n\r\nconst handleFixedSelect = (index: number, value: string) => {\r\n updateColumnProperty(index, (col) => {\r\n col.fixed = value === \"none\" ? undefined : (value as \"left\" | \"right\");\r\n });\r\n};\r\n\r\nconst applyChanges = () => emit(\"change\", [...localColumns.value]);\r\n\r\nconst resetColumns = () => {\r\n localColumns.value = [...props.columns];\r\n applyChanges();\r\n};\r\n\r\n/* ================= 列宽调整 ================= */\r\n\r\nconst handleResizableChange = (value: boolean) => {\r\n localColumns.value.forEach((col) => {\r\n if (!isSpecialColumn(col)) {\r\n col.resizable = value;\r\n if (value) {\r\n col.minWidth = col.minWidth || 80;\r\n col.maxWidth = col.maxWidth || 500;\r\n }\r\n }\r\n });\r\n applyChanges();\r\n};\r\n\r\n/* ================= 拖拽排序 ================= */\r\n\r\nconst moveColumn = (fromIndex: number, toIndex: number) => {\r\n const originalFromIndex = findOriginalIndex(fromIndex);\r\n const originalToIndex = findOriginalIndex(toIndex);\r\n if (originalFromIndex !== -1 && originalToIndex !== -1) {\r\n const [movedColumn] = localColumns.value.splice(originalFromIndex, 1);\r\n localColumns.value.splice(originalToIndex, 0, movedColumn);\r\n applyChanges();\r\n }\r\n};\r\n\r\nconst handleDragStart = (index: number, event: DragEvent) => {\r\n const column = filteredColumns.value[index];\r\n if (column.key === \"_actions\") {\r\n event.preventDefault();\r\n return;\r\n }\r\n draggedIndex.value = index;\r\n if (event.dataTransfer) event.dataTransfer.effectAllowed = \"move\";\r\n};\r\n\r\nconst handleDragOver = (index: number, event: DragEvent) => {\r\n event.preventDefault();\r\n if (\r\n draggedIndex.value === null ||\r\n filteredColumns.value[index].key === \"_actions\"\r\n )\r\n return;\r\n dragOverIndex.value = index;\r\n if (event.dataTransfer) event.dataTransfer.dropEffect = \"move\";\r\n};\r\n\r\nconst handleDrop = (toIndex: number) => {\r\n if (\r\n draggedIndex.value === null ||\r\n filteredColumns.value[toIndex].key === \"_actions\"\r\n )\r\n return;\r\n moveColumn(draggedIndex.value, toIndex);\r\n draggedIndex.value = null;\r\n dragOverIndex.value = null;\r\n};\r\n\r\nconst handleDragEnd = () => {\r\n draggedIndex.value = null;\r\n dragOverIndex.value = null;\r\n};\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n@use \"./index.scss\";\r\n</style>\r\n","<!--\r\n * @Description: C_Table 超级表格组件(薄 UI 壳)\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n *\r\n * 使用侧 API:\r\n * <C_Table :columns=\"cols\" :data=\"data\" :loading=\"loading\" :config=\"tableConfig\" />\r\n *\r\n * config 收拢了所有功能配置:edit / selection / expand / pagination / dynamicRows / toolbar / display\r\n * 列处理 → composables/useTableColumns.ts\r\n * 配置解析 → composables/useTableConfig.ts\r\n * 编辑/展开/动态行 → composables/useTableManager.ts\r\n -->\r\n\r\n<template>\r\n <div class=\"c-table-wrapper\">\r\n <!-- 动态行工具栏 -->\r\n <component\r\n v-if=\"tableManager.dynamicRowsState\"\r\n :is=\"tableManager.dynamicRowsState.renderToolbar()\"\r\n />\r\n\r\n <!-- 表格工具栏 -->\r\n <div v-if=\"resolved.showToolbar\" class=\"table-toolbar\">\r\n <div class=\"toolbar-left\">\r\n <slot name=\"toolbar-left\" />\r\n </div>\r\n <div class=\"toolbar-right\">\r\n <slot name=\"toolbar-right\" />\r\n <C_Icon\r\n v-if=\"resolved.enableColumnSettings\"\r\n name=\"mdi:cog\"\r\n size=\"18\"\r\n title=\"表格设置\"\r\n clickable\r\n class=\"column-settings-btn\"\r\n @click=\"showSettingsPanel = true\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- 表格主体 -->\r\n <NDataTable\r\n ref=\"tableRef\"\r\n v-bind=\"{ ...computedTableProps, ...$attrs }\"\r\n :columns=\"computedColumns\"\r\n :data=\"normalizedData\"\r\n :loading=\"normalizedLoading\"\r\n :row-key=\"rowKey\"\r\n :expanded-row-keys=\"tableManager.expandedKeys.value\"\r\n :checked-row-keys=\"tableManager.checkedKeys.value\"\r\n @update:expanded-row-keys=\"tableManager.expandState?.handleExpandChange\"\r\n @update:checked-row-keys=\"tableManager.expandState?.handleSelectionChange\"\r\n :scroll-x=\"computedScrollX\"\r\n style=\"width: 100%\"\r\n />\r\n\r\n <!-- 分页 -->\r\n <NPagination\r\n v-if=\"pagination.paginationConfig.value\"\r\n v-bind=\"pagination.paginationConfig.value\"\r\n class=\"pagination-wrapper\"\r\n />\r\n\r\n <!-- 编辑弹窗 -->\r\n <NModal\r\n v-if=\"resolved.editMode === 'modal' || resolved.editMode === 'both'\"\r\n v-model:show=\"modalVisible\"\r\n :title=\"resolved.modalTitle\"\r\n :width=\"resolved.modalWidth\"\r\n preset=\"card\"\r\n :mask-closable=\"false\"\r\n :close-on-esc=\"false\"\r\n class=\"w60%\"\r\n :closable=\"false\"\r\n >\r\n <C_Form\r\n v-if=\"modalVisible && formOptions.length\"\r\n ref=\"editFormRef\"\r\n :key=\"formKey\"\r\n v-model=\"localEditingData\"\r\n :options=\"formOptions\"\r\n :config=\"{\r\n layout: 'grid',\r\n grid: { cols: 2, xGap: 16, yGap: 16 },\r\n showActions: false,\r\n }\"\r\n />\r\n <template #action>\r\n <NSpace justify=\"end\">\r\n <NButton @click=\"handleModalCancel\">取消</NButton>\r\n <NButton\r\n type=\"primary\"\r\n :loading=\"modalSubmitLoading\"\r\n @click=\"handleModalSave\"\r\n >\r\n 保存\r\n </NButton>\r\n </NSpace>\r\n </template>\r\n </NModal>\r\n\r\n <!-- 动态行确认删除弹窗 -->\r\n <component\r\n v-if=\"tableManager.dynamicRowsState\"\r\n :is=\"tableManager.dynamicRowsState.renderConfirmModal()\"\r\n />\r\n\r\n <!-- 列设置抽屉 -->\r\n <NDrawer\r\n v-model:show=\"showSettingsPanel\"\r\n :width=\"420\"\r\n placement=\"right\"\r\n :mask-closable=\"true\"\r\n >\r\n <NDrawerContent title=\"列设置\" closable>\r\n <ColumnSettings\r\n :columns=\"reactiveColumns\"\r\n @change=\"onColumnSettingsChange\"\r\n />\r\n </NDrawerContent>\r\n </NDrawer>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, watch, onMounted, onBeforeUnmount } from \"vue\";\r\nimport type { ComponentPublicInstance } from \"vue\";\r\nimport {\r\n type DataTableRowKey,\r\n NDataTable,\r\n NPagination,\r\n NModal,\r\n NSpace,\r\n NButton,\r\n NDrawer,\r\n NDrawerContent,\r\n} from \"naive-ui/es\";\r\nimport type {\r\n TableColumn,\r\n TableEmits,\r\n DataRecord,\r\n MaybeRefLike,\r\n} from \"./types\";\r\nimport {\r\n resolveConfig,\r\n createEditModeChecker,\r\n type TableConfig,\r\n type CrudBinding,\r\n} from \"./composables/useTableConfig\";\r\nimport { useTableManager } from \"./composables/useTableManager\";\r\nimport { usePagination } from \"./composables/usePagination\";\r\nimport { useTableActions } from \"./composables/useTableActions\";\r\nimport { useTableColumns } from \"./composables/useTableColumns\";\r\nimport { generateFormOptions } from \"./data\";\r\nimport ColumnSettings from \"./components/ColumnSettings/index.vue\";\r\nimport C_Icon from \"../C_Icon/index.vue\";\r\nimport C_Form from \"../C_Form/index.vue\";\r\n\r\ndefineOptions({ name: \"C_Table\", inheritAttrs: false });\r\n\r\n/* ================= Props(极简 API) ================= */\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 列配置(crud 模式下可省略) */\r\n columns?: TableColumn[];\r\n /** 数据源(crud 模式下可省略) */\r\n data?: MaybeRefLike<DataRecord[]>;\r\n /** 加载状态 */\r\n loading?: MaybeRefLike<boolean>;\r\n /** 行唯一键 */\r\n rowKey?: (row: DataRecord) => DataTableRowKey;\r\n /** 统一功能配置(edit / selection / expand / pagination / dynamicRows / toolbar / display) */\r\n config?: TableConfig;\r\n /** CRUD 绑定 — 传入 useTableCrud() 的返回值,自动接管 data/columns/loading/actions/pagination/events */\r\n crud?: CrudBinding;\r\n }>(),\r\n {\r\n loading: false,\r\n rowKey: (row: DataRecord) => row.id as DataTableRowKey,\r\n config: () => ({}),\r\n },\r\n);\r\n\r\nconst emit = defineEmits<\r\n TableEmits & {\r\n \"row-add\": [newRow: DataRecord];\r\n \"row-delete\": [deletedRow: DataRecord, index: number];\r\n \"row-copy\": [originalRow: DataRecord, newRow: DataRecord];\r\n \"row-move\": [row: DataRecord, fromIndex: number, toIndex: number];\r\n \"row-selection-change\": [\r\n selectedKey: DataTableRowKey | null,\r\n selectedRow: DataRecord | null,\r\n ];\r\n \"pagination-change\": [page: number, pageSize: number];\r\n \"view-detail\": [data: DataRecord];\r\n \"column-change\": [columns: TableColumn[]];\r\n }\r\n>();\r\n\r\n/* ================= CRUD 桥接 ================= */\r\n\r\n/** 包装 emit:在触发事件的同时自动调用 crud 对应的方法 */\r\nconst bridgedEmit: typeof emit = (event: any, ...args: any[]) => {\r\n (emit as any)(event, ...args);\r\n\r\n if (!props.crud) return;\r\n const handlers: Record<string, ((...a: any[]) => void) | undefined> = {\r\n save: props.crud.save,\r\n cancel: props.crud.handleCancel,\r\n \"pagination-change\": props.crud.handlePaginationChange,\r\n \"row-delete\": props.crud.handleRowDelete,\r\n \"view-detail\": props.crud.detail?.show,\r\n };\r\n handlers[event]?.(...args);\r\n};\r\n\r\n/* ================= 有效值(crud 优先 → props 覆盖) ================= */\r\n\r\n/** 合并 crud 返回的 actions/pagination 到用户 config */\r\nconst effectiveConfig = computed<TableConfig>(() => {\r\n if (!props.crud) return props.config || {};\r\n const fromCrud: Partial<TableConfig> = {};\r\n if (props.crud.actions) fromCrud.actions = props.crud.actions.value;\r\n if (props.crud.pagination) fromCrud.pagination = props.crud.pagination.value;\r\n return { ...fromCrud, ...props.config };\r\n});\r\n\r\nconst effectiveColumns = computed<TableColumn[]>(\r\n () => props.columns ?? props.crud?.columns.value ?? [],\r\n);\r\n\r\n/* ================= 配置解析 ================= */\r\n\r\nconst resolved = computed(() => resolveConfig(effectiveConfig.value));\r\nconst editModeChecker = computed(() => createEditModeChecker(resolved.value));\r\n\r\n/* ================= 数据规范化(兼容跨实例 Ref) ================= */\r\n\r\nconst unwrapRef = <T,>(val: MaybeRefLike<T> | undefined): T | undefined =>\r\n val && typeof val === \"object\" && \"value\" in val ? val.value : (val as T);\r\n\r\nconst normalizedData = computed<DataRecord[]>(\r\n () => unwrapRef(props.data) ?? props.crud?.data.value ?? [],\r\n);\r\n\r\nconst normalizedLoading = computed<boolean>(\r\n () => unwrapRef(props.loading) ?? props.crud?.loading.value ?? false,\r\n);\r\n\r\n/* ================= Hooks ================= */\r\n\r\nconst pagination = usePagination({\r\n data: normalizedData,\r\n config: computed(() => resolved.value.pagination),\r\n emit: bridgedEmit,\r\n});\r\n\r\nconst tableManager = useTableManager({\r\n config: resolved.value,\r\n data: () => normalizedData.value,\r\n rowKey: props.rowKey,\r\n emit: bridgedEmit,\r\n});\r\n\r\nconst tableActions = useTableActions({\r\n actions: computed(() => effectiveConfig.value.actions || {}),\r\n config: resolved,\r\n tableManager,\r\n rowKey: props.rowKey,\r\n emit: bridgedEmit,\r\n onViewDetail: (data: DataRecord) => bridgedEmit(\"view-detail\", data),\r\n});\r\n\r\nconst columnState = useTableColumns({\r\n rawColumns: effectiveColumns,\r\n config: resolved,\r\n columnWidth: resolved.value.columnWidth,\r\n scrollX: resolved.value.scrollX,\r\n rowKey: props.rowKey,\r\n tableManager,\r\n actionsRenderer: tableActions.renderActions,\r\n editModeChecker,\r\n});\r\n\r\nconst { showSettingsPanel, reactiveColumns, computedColumns, computedScrollX } =\r\n columnState;\r\n\r\n/* ================= 表格属性 ================= */\r\n\r\nconst tableRef = ref<ComponentPublicInstance>();\r\n\r\nconst computedTableProps = computed(() => ({\r\n striped: resolved.value.striped,\r\n bordered: resolved.value.bordered,\r\n singleLine: resolved.value.singleLine,\r\n size: resolved.value.size,\r\n maxHeight: resolved.value.maxHeight,\r\n}));\r\n\r\n/* ================= 编辑弹窗 ================= */\r\n\r\nconst editFormRef = ref<any>();\r\nconst modalSubmitLoading = ref(false);\r\nconst localEditingData = ref<DataRecord>({});\r\n\r\nconst modalVisible = computed({\r\n get: () => tableManager.editStates.modalEdit.isModalVisible.value,\r\n set: (val: boolean) => {\r\n tableManager.editStates.modalEdit.isModalVisible.value = val;\r\n },\r\n});\r\n\r\nconst editableColumns = computed(() =>\r\n effectiveColumns.value.filter(\r\n (col): col is TableColumn => col.editable !== false,\r\n ),\r\n);\r\n\r\nconst formKey = computed(\r\n () =>\r\n `edit-form-${tableManager.editStates.modalEdit.editingRowKey.value || \"new\"}`,\r\n);\r\n\r\nconst formOptions = computed(() => generateFormOptions(editableColumns.value));\r\n\r\nwatch(\r\n () => tableManager.editStates.modalEdit.editingData.value,\r\n (newData) => {\r\n if (newData && Object.keys(newData).length > 0) {\r\n localEditingData.value = JSON.parse(JSON.stringify(newData));\r\n }\r\n },\r\n { immediate: true, deep: true },\r\n);\r\n\r\nlet modalCloseTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\nwatch(modalVisible, (visible) => {\r\n if (!visible) {\r\n modalCloseTimer = setTimeout(() => {\r\n localEditingData.value = {};\r\n modalCloseTimer = null;\r\n }, 300);\r\n }\r\n});\r\n\r\nconst handleModalSave = async () => {\r\n if (!editFormRef.value) return;\r\n modalSubmitLoading.value = true;\r\n try {\r\n await editFormRef.value.validate();\r\n await tableManager.editStates.modalEdit.saveEdit(localEditingData.value);\r\n } catch {\r\n /* 表单验证错误由组件内联显示 */\r\n } finally {\r\n modalSubmitLoading.value = false;\r\n }\r\n};\r\n\r\nconst handleModalCancel = () => {\r\n localEditingData.value = {};\r\n tableManager.editStates.modalEdit.cancelEdit();\r\n};\r\n\r\n/* ================= 列设置 ================= */\r\n\r\nconst onColumnSettingsChange = (columns: TableColumn[]) => {\r\n columnState.handleColumnChange(columns);\r\n emit(\"column-change\", columnState.reactiveColumns.value);\r\n};\r\n\r\n/* ================= Expose ================= */\r\n\r\nconst { edit, expand, selection, dynamicRows } = tableManager.stateManager;\r\n\r\nconst exposedApi = {\r\n startEdit: edit.start,\r\n expandAll: expand.all,\r\n collapseAll: expand.collapseAll,\r\n selectAll: selection.all,\r\n clearSelection: selection.clear,\r\n clearAllSelections: tableManager.stateManager.clearAllSelections,\r\n clearRowSelection: dynamicRows?.clearSelection,\r\n resetToFirstPage: pagination.resetToFirstPage,\r\n getSelectedRows: selection.getSelected,\r\n getEditingData: edit.getEditingData,\r\n isEditing: edit.isEditing,\r\n isExpanded: expand.isExpanded,\r\n getManager: () => tableManager.stateManager,\r\n};\r\n\r\ndefineExpose(exposedApi);\r\n\r\n/* 自动连接 crud.tableRef */\r\nonMounted(() => {\r\n const crudRef = props.crud?.tableRef;\r\n if (crudRef) crudRef.value = exposedApi;\r\n});\r\n\r\nonBeforeUnmount(() => {\r\n if (modalCloseTimer) clearTimeout(modalCloseTimer);\r\n});\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n@use \"./index.scss\";\r\n</style>\r\n","<!--\r\n * @Description: C_Table 超级表格组件(薄 UI 壳)\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n *\r\n * 使用侧 API:\r\n * <C_Table :columns=\"cols\" :data=\"data\" :loading=\"loading\" :config=\"tableConfig\" />\r\n *\r\n * config 收拢了所有功能配置:edit / selection / expand / pagination / dynamicRows / toolbar / display\r\n * 列处理 → composables/useTableColumns.ts\r\n * 配置解析 → composables/useTableConfig.ts\r\n * 编辑/展开/动态行 → composables/useTableManager.ts\r\n -->\r\n\r\n<template>\r\n <div class=\"c-table-wrapper\">\r\n <!-- 动态行工具栏 -->\r\n <component\r\n v-if=\"tableManager.dynamicRowsState\"\r\n :is=\"tableManager.dynamicRowsState.renderToolbar()\"\r\n />\r\n\r\n <!-- 表格工具栏 -->\r\n <div v-if=\"resolved.showToolbar\" class=\"table-toolbar\">\r\n <div class=\"toolbar-left\">\r\n <slot name=\"toolbar-left\" />\r\n </div>\r\n <div class=\"toolbar-right\">\r\n <slot name=\"toolbar-right\" />\r\n <C_Icon\r\n v-if=\"resolved.enableColumnSettings\"\r\n name=\"mdi:cog\"\r\n size=\"18\"\r\n title=\"表格设置\"\r\n clickable\r\n class=\"column-settings-btn\"\r\n @click=\"showSettingsPanel = true\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- 表格主体 -->\r\n <NDataTable\r\n ref=\"tableRef\"\r\n v-bind=\"{ ...computedTableProps, ...$attrs }\"\r\n :columns=\"computedColumns\"\r\n :data=\"normalizedData\"\r\n :loading=\"normalizedLoading\"\r\n :row-key=\"rowKey\"\r\n :expanded-row-keys=\"tableManager.expandedKeys.value\"\r\n :checked-row-keys=\"tableManager.checkedKeys.value\"\r\n @update:expanded-row-keys=\"tableManager.expandState?.handleExpandChange\"\r\n @update:checked-row-keys=\"tableManager.expandState?.handleSelectionChange\"\r\n :scroll-x=\"computedScrollX\"\r\n style=\"width: 100%\"\r\n />\r\n\r\n <!-- 分页 -->\r\n <NPagination\r\n v-if=\"pagination.paginationConfig.value\"\r\n v-bind=\"pagination.paginationConfig.value\"\r\n class=\"pagination-wrapper\"\r\n />\r\n\r\n <!-- 编辑弹窗 -->\r\n <NModal\r\n v-if=\"resolved.editMode === 'modal' || resolved.editMode === 'both'\"\r\n v-model:show=\"modalVisible\"\r\n :title=\"resolved.modalTitle\"\r\n :width=\"resolved.modalWidth\"\r\n preset=\"card\"\r\n :mask-closable=\"false\"\r\n :close-on-esc=\"false\"\r\n class=\"w60%\"\r\n :closable=\"false\"\r\n >\r\n <C_Form\r\n v-if=\"modalVisible && formOptions.length\"\r\n ref=\"editFormRef\"\r\n :key=\"formKey\"\r\n v-model=\"localEditingData\"\r\n :options=\"formOptions\"\r\n :config=\"{\r\n layout: 'grid',\r\n grid: { cols: 2, xGap: 16, yGap: 16 },\r\n showActions: false,\r\n }\"\r\n />\r\n <template #action>\r\n <NSpace justify=\"end\">\r\n <NButton @click=\"handleModalCancel\">取消</NButton>\r\n <NButton\r\n type=\"primary\"\r\n :loading=\"modalSubmitLoading\"\r\n @click=\"handleModalSave\"\r\n >\r\n 保存\r\n </NButton>\r\n </NSpace>\r\n </template>\r\n </NModal>\r\n\r\n <!-- 动态行确认删除弹窗 -->\r\n <component\r\n v-if=\"tableManager.dynamicRowsState\"\r\n :is=\"tableManager.dynamicRowsState.renderConfirmModal()\"\r\n />\r\n\r\n <!-- 列设置抽屉 -->\r\n <NDrawer\r\n v-model:show=\"showSettingsPanel\"\r\n :width=\"420\"\r\n placement=\"right\"\r\n :mask-closable=\"true\"\r\n >\r\n <NDrawerContent title=\"列设置\" closable>\r\n <ColumnSettings\r\n :columns=\"reactiveColumns\"\r\n @change=\"onColumnSettingsChange\"\r\n />\r\n </NDrawerContent>\r\n </NDrawer>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, watch, onMounted, onBeforeUnmount } from \"vue\";\r\nimport type { ComponentPublicInstance } from \"vue\";\r\nimport {\r\n type DataTableRowKey,\r\n NDataTable,\r\n NPagination,\r\n NModal,\r\n NSpace,\r\n NButton,\r\n NDrawer,\r\n NDrawerContent,\r\n} from \"naive-ui/es\";\r\nimport type {\r\n TableColumn,\r\n TableEmits,\r\n DataRecord,\r\n MaybeRefLike,\r\n} from \"./types\";\r\nimport {\r\n resolveConfig,\r\n createEditModeChecker,\r\n type TableConfig,\r\n type CrudBinding,\r\n} from \"./composables/useTableConfig\";\r\nimport { useTableManager } from \"./composables/useTableManager\";\r\nimport { usePagination } from \"./composables/usePagination\";\r\nimport { useTableActions } from \"./composables/useTableActions\";\r\nimport { useTableColumns } from \"./composables/useTableColumns\";\r\nimport { generateFormOptions } from \"./data\";\r\nimport ColumnSettings from \"./components/ColumnSettings/index.vue\";\r\nimport C_Icon from \"../C_Icon/index.vue\";\r\nimport C_Form from \"../C_Form/index.vue\";\r\n\r\ndefineOptions({ name: \"C_Table\", inheritAttrs: false });\r\n\r\n/* ================= Props(极简 API) ================= */\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 列配置(crud 模式下可省略) */\r\n columns?: TableColumn[];\r\n /** 数据源(crud 模式下可省略) */\r\n data?: MaybeRefLike<DataRecord[]>;\r\n /** 加载状态 */\r\n loading?: MaybeRefLike<boolean>;\r\n /** 行唯一键 */\r\n rowKey?: (row: DataRecord) => DataTableRowKey;\r\n /** 统一功能配置(edit / selection / expand / pagination / dynamicRows / toolbar / display) */\r\n config?: TableConfig;\r\n /** CRUD 绑定 — 传入 useTableCrud() 的返回值,自动接管 data/columns/loading/actions/pagination/events */\r\n crud?: CrudBinding;\r\n }>(),\r\n {\r\n loading: false,\r\n rowKey: (row: DataRecord) => row.id as DataTableRowKey,\r\n config: () => ({}),\r\n },\r\n);\r\n\r\nconst emit = defineEmits<\r\n TableEmits & {\r\n \"row-add\": [newRow: DataRecord];\r\n \"row-delete\": [deletedRow: DataRecord, index: number];\r\n \"row-copy\": [originalRow: DataRecord, newRow: DataRecord];\r\n \"row-move\": [row: DataRecord, fromIndex: number, toIndex: number];\r\n \"row-selection-change\": [\r\n selectedKey: DataTableRowKey | null,\r\n selectedRow: DataRecord | null,\r\n ];\r\n \"pagination-change\": [page: number, pageSize: number];\r\n \"view-detail\": [data: DataRecord];\r\n \"column-change\": [columns: TableColumn[]];\r\n }\r\n>();\r\n\r\n/* ================= CRUD 桥接 ================= */\r\n\r\n/** 包装 emit:在触发事件的同时自动调用 crud 对应的方法 */\r\nconst bridgedEmit: typeof emit = (event: any, ...args: any[]) => {\r\n (emit as any)(event, ...args);\r\n\r\n if (!props.crud) return;\r\n const handlers: Record<string, ((...a: any[]) => void) | undefined> = {\r\n save: props.crud.save,\r\n cancel: props.crud.handleCancel,\r\n \"pagination-change\": props.crud.handlePaginationChange,\r\n \"row-delete\": props.crud.handleRowDelete,\r\n \"view-detail\": props.crud.detail?.show,\r\n };\r\n handlers[event]?.(...args);\r\n};\r\n\r\n/* ================= 有效值(crud 优先 → props 覆盖) ================= */\r\n\r\n/** 合并 crud 返回的 actions/pagination 到用户 config */\r\nconst effectiveConfig = computed<TableConfig>(() => {\r\n if (!props.crud) return props.config || {};\r\n const fromCrud: Partial<TableConfig> = {};\r\n if (props.crud.actions) fromCrud.actions = props.crud.actions.value;\r\n if (props.crud.pagination) fromCrud.pagination = props.crud.pagination.value;\r\n return { ...fromCrud, ...props.config };\r\n});\r\n\r\nconst effectiveColumns = computed<TableColumn[]>(\r\n () => props.columns ?? props.crud?.columns.value ?? [],\r\n);\r\n\r\n/* ================= 配置解析 ================= */\r\n\r\nconst resolved = computed(() => resolveConfig(effectiveConfig.value));\r\nconst editModeChecker = computed(() => createEditModeChecker(resolved.value));\r\n\r\n/* ================= 数据规范化(兼容跨实例 Ref) ================= */\r\n\r\nconst unwrapRef = <T,>(val: MaybeRefLike<T> | undefined): T | undefined =>\r\n val && typeof val === \"object\" && \"value\" in val ? val.value : (val as T);\r\n\r\nconst normalizedData = computed<DataRecord[]>(\r\n () => unwrapRef(props.data) ?? props.crud?.data.value ?? [],\r\n);\r\n\r\nconst normalizedLoading = computed<boolean>(\r\n () => unwrapRef(props.loading) ?? props.crud?.loading.value ?? false,\r\n);\r\n\r\n/* ================= Hooks ================= */\r\n\r\nconst pagination = usePagination({\r\n data: normalizedData,\r\n config: computed(() => resolved.value.pagination),\r\n emit: bridgedEmit,\r\n});\r\n\r\nconst tableManager = useTableManager({\r\n config: resolved.value,\r\n data: () => normalizedData.value,\r\n rowKey: props.rowKey,\r\n emit: bridgedEmit,\r\n});\r\n\r\nconst tableActions = useTableActions({\r\n actions: computed(() => effectiveConfig.value.actions || {}),\r\n config: resolved,\r\n tableManager,\r\n rowKey: props.rowKey,\r\n emit: bridgedEmit,\r\n onViewDetail: (data: DataRecord) => bridgedEmit(\"view-detail\", data),\r\n});\r\n\r\nconst columnState = useTableColumns({\r\n rawColumns: effectiveColumns,\r\n config: resolved,\r\n columnWidth: resolved.value.columnWidth,\r\n scrollX: resolved.value.scrollX,\r\n rowKey: props.rowKey,\r\n tableManager,\r\n actionsRenderer: tableActions.renderActions,\r\n editModeChecker,\r\n});\r\n\r\nconst { showSettingsPanel, reactiveColumns, computedColumns, computedScrollX } =\r\n columnState;\r\n\r\n/* ================= 表格属性 ================= */\r\n\r\nconst tableRef = ref<ComponentPublicInstance>();\r\n\r\nconst computedTableProps = computed(() => ({\r\n striped: resolved.value.striped,\r\n bordered: resolved.value.bordered,\r\n singleLine: resolved.value.singleLine,\r\n size: resolved.value.size,\r\n maxHeight: resolved.value.maxHeight,\r\n}));\r\n\r\n/* ================= 编辑弹窗 ================= */\r\n\r\nconst editFormRef = ref<any>();\r\nconst modalSubmitLoading = ref(false);\r\nconst localEditingData = ref<DataRecord>({});\r\n\r\nconst modalVisible = computed({\r\n get: () => tableManager.editStates.modalEdit.isModalVisible.value,\r\n set: (val: boolean) => {\r\n tableManager.editStates.modalEdit.isModalVisible.value = val;\r\n },\r\n});\r\n\r\nconst editableColumns = computed(() =>\r\n effectiveColumns.value.filter(\r\n (col): col is TableColumn => col.editable !== false,\r\n ),\r\n);\r\n\r\nconst formKey = computed(\r\n () =>\r\n `edit-form-${tableManager.editStates.modalEdit.editingRowKey.value || \"new\"}`,\r\n);\r\n\r\nconst formOptions = computed(() => generateFormOptions(editableColumns.value));\r\n\r\nwatch(\r\n () => tableManager.editStates.modalEdit.editingData.value,\r\n (newData) => {\r\n if (newData && Object.keys(newData).length > 0) {\r\n localEditingData.value = JSON.parse(JSON.stringify(newData));\r\n }\r\n },\r\n { immediate: true, deep: true },\r\n);\r\n\r\nlet modalCloseTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\nwatch(modalVisible, (visible) => {\r\n if (!visible) {\r\n modalCloseTimer = setTimeout(() => {\r\n localEditingData.value = {};\r\n modalCloseTimer = null;\r\n }, 300);\r\n }\r\n});\r\n\r\nconst handleModalSave = async () => {\r\n if (!editFormRef.value) return;\r\n modalSubmitLoading.value = true;\r\n try {\r\n await editFormRef.value.validate();\r\n await tableManager.editStates.modalEdit.saveEdit(localEditingData.value);\r\n } catch {\r\n /* 表单验证错误由组件内联显示 */\r\n } finally {\r\n modalSubmitLoading.value = false;\r\n }\r\n};\r\n\r\nconst handleModalCancel = () => {\r\n localEditingData.value = {};\r\n tableManager.editStates.modalEdit.cancelEdit();\r\n};\r\n\r\n/* ================= 列设置 ================= */\r\n\r\nconst onColumnSettingsChange = (columns: TableColumn[]) => {\r\n columnState.handleColumnChange(columns);\r\n emit(\"column-change\", columnState.reactiveColumns.value);\r\n};\r\n\r\n/* ================= Expose ================= */\r\n\r\nconst { edit, expand, selection, dynamicRows } = tableManager.stateManager;\r\n\r\nconst exposedApi = {\r\n startEdit: edit.start,\r\n expandAll: expand.all,\r\n collapseAll: expand.collapseAll,\r\n selectAll: selection.all,\r\n clearSelection: selection.clear,\r\n clearAllSelections: tableManager.stateManager.clearAllSelections,\r\n clearRowSelection: dynamicRows?.clearSelection,\r\n resetToFirstPage: pagination.resetToFirstPage,\r\n getSelectedRows: selection.getSelected,\r\n getEditingData: edit.getEditingData,\r\n isEditing: edit.isEditing,\r\n isExpanded: expand.isExpanded,\r\n getManager: () => tableManager.stateManager,\r\n};\r\n\r\ndefineExpose(exposedApi);\r\n\r\n/* 自动连接 crud.tableRef */\r\nonMounted(() => {\r\n const crudRef = props.crud?.tableRef;\r\n if (crudRef) crudRef.value = exposedApi;\r\n});\r\n\r\nonBeforeUnmount(() => {\r\n if (modalCloseTimer) clearTimeout(modalCloseTimer);\r\n});\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n@use \"./index.scss\";\r\n</style>\r\n","<!--\r\n * @Description: C_Table 超级表格组件(薄 UI 壳)\r\n * @Migration: naive-ui-components 组件库迁移版本\r\n * Copyright (c) 2025 by CHENY, All Rights Reserved.\r\n *\r\n * 使用侧 API:\r\n * <C_Table :columns=\"cols\" :data=\"data\" :loading=\"loading\" :config=\"tableConfig\" />\r\n *\r\n * config 收拢了所有功能配置:edit / selection / expand / pagination / dynamicRows / toolbar / display\r\n * 列处理 → composables/useTableColumns.ts\r\n * 配置解析 → composables/useTableConfig.ts\r\n * 编辑/展开/动态行 → composables/useTableManager.ts\r\n -->\r\n\r\n<template>\r\n <div class=\"c-table-wrapper\">\r\n <!-- 动态行工具栏 -->\r\n <component\r\n v-if=\"tableManager.dynamicRowsState\"\r\n :is=\"tableManager.dynamicRowsState.renderToolbar()\"\r\n />\r\n\r\n <!-- 表格工具栏 -->\r\n <div v-if=\"resolved.showToolbar\" class=\"table-toolbar\">\r\n <div class=\"toolbar-left\">\r\n <slot name=\"toolbar-left\" />\r\n </div>\r\n <div class=\"toolbar-right\">\r\n <slot name=\"toolbar-right\" />\r\n <C_Icon\r\n v-if=\"resolved.enableColumnSettings\"\r\n name=\"mdi:cog\"\r\n size=\"18\"\r\n title=\"表格设置\"\r\n clickable\r\n class=\"column-settings-btn\"\r\n @click=\"showSettingsPanel = true\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <!-- 表格主体 -->\r\n <NDataTable\r\n ref=\"tableRef\"\r\n v-bind=\"{ ...computedTableProps, ...$attrs }\"\r\n :columns=\"computedColumns\"\r\n :data=\"normalizedData\"\r\n :loading=\"normalizedLoading\"\r\n :row-key=\"rowKey\"\r\n :expanded-row-keys=\"tableManager.expandedKeys.value\"\r\n :checked-row-keys=\"tableManager.checkedKeys.value\"\r\n @update:expanded-row-keys=\"tableManager.expandState?.handleExpandChange\"\r\n @update:checked-row-keys=\"tableManager.expandState?.handleSelectionChange\"\r\n :scroll-x=\"computedScrollX\"\r\n style=\"width: 100%\"\r\n />\r\n\r\n <!-- 分页 -->\r\n <NPagination\r\n v-if=\"pagination.paginationConfig.value\"\r\n v-bind=\"pagination.paginationConfig.value\"\r\n class=\"pagination-wrapper\"\r\n />\r\n\r\n <!-- 编辑弹窗 -->\r\n <NModal\r\n v-if=\"resolved.editMode === 'modal' || resolved.editMode === 'both'\"\r\n v-model:show=\"modalVisible\"\r\n :title=\"resolved.modalTitle\"\r\n :width=\"resolved.modalWidth\"\r\n preset=\"card\"\r\n :mask-closable=\"false\"\r\n :close-on-esc=\"false\"\r\n class=\"w60%\"\r\n :closable=\"false\"\r\n >\r\n <C_Form\r\n v-if=\"modalVisible && formOptions.length\"\r\n ref=\"editFormRef\"\r\n :key=\"formKey\"\r\n v-model=\"localEditingData\"\r\n :options=\"formOptions\"\r\n :config=\"{\r\n layout: 'grid',\r\n grid: { cols: 2, xGap: 16, yGap: 16 },\r\n showActions: false,\r\n }\"\r\n />\r\n <template #action>\r\n <NSpace justify=\"end\">\r\n <NButton @click=\"handleModalCancel\">取消</NButton>\r\n <NButton\r\n type=\"primary\"\r\n :loading=\"modalSubmitLoading\"\r\n @click=\"handleModalSave\"\r\n >\r\n 保存\r\n </NButton>\r\n </NSpace>\r\n </template>\r\n </NModal>\r\n\r\n <!-- 动态行确认删除弹窗 -->\r\n <component\r\n v-if=\"tableManager.dynamicRowsState\"\r\n :is=\"tableManager.dynamicRowsState.renderConfirmModal()\"\r\n />\r\n\r\n <!-- 列设置抽屉 -->\r\n <NDrawer\r\n v-model:show=\"showSettingsPanel\"\r\n :width=\"420\"\r\n placement=\"right\"\r\n :mask-closable=\"true\"\r\n >\r\n <NDrawerContent title=\"列设置\" closable>\r\n <ColumnSettings\r\n :columns=\"reactiveColumns\"\r\n @change=\"onColumnSettingsChange\"\r\n />\r\n </NDrawerContent>\r\n </NDrawer>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, watch, onMounted, onBeforeUnmount } from \"vue\";\r\nimport type { ComponentPublicInstance } from \"vue\";\r\nimport {\r\n type DataTableRowKey,\r\n NDataTable,\r\n NPagination,\r\n NModal,\r\n NSpace,\r\n NButton,\r\n NDrawer,\r\n NDrawerContent,\r\n} from \"naive-ui/es\";\r\nimport type {\r\n TableColumn,\r\n TableEmits,\r\n DataRecord,\r\n MaybeRefLike,\r\n} from \"./types\";\r\nimport {\r\n resolveConfig,\r\n createEditModeChecker,\r\n type TableConfig,\r\n type CrudBinding,\r\n} from \"./composables/useTableConfig\";\r\nimport { useTableManager } from \"./composables/useTableManager\";\r\nimport { usePagination } from \"./composables/usePagination\";\r\nimport { useTableActions } from \"./composables/useTableActions\";\r\nimport { useTableColumns } from \"./composables/useTableColumns\";\r\nimport { generateFormOptions } from \"./data\";\r\nimport ColumnSettings from \"./components/ColumnSettings/index.vue\";\r\nimport C_Icon from \"../C_Icon/index.vue\";\r\nimport C_Form from \"../C_Form/index.vue\";\r\n\r\ndefineOptions({ name: \"C_Table\", inheritAttrs: false });\r\n\r\n/* ================= Props(极简 API) ================= */\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** 列配置(crud 模式下可省略) */\r\n columns?: TableColumn[];\r\n /** 数据源(crud 模式下可省略) */\r\n data?: MaybeRefLike<DataRecord[]>;\r\n /** 加载状态 */\r\n loading?: MaybeRefLike<boolean>;\r\n /** 行唯一键 */\r\n rowKey?: (row: DataRecord) => DataTableRowKey;\r\n /** 统一功能配置(edit / selection / expand / pagination / dynamicRows / toolbar / display) */\r\n config?: TableConfig;\r\n /** CRUD 绑定 — 传入 useTableCrud() 的返回值,自动接管 data/columns/loading/actions/pagination/events */\r\n crud?: CrudBinding;\r\n }>(),\r\n {\r\n loading: false,\r\n rowKey: (row: DataRecord) => row.id as DataTableRowKey,\r\n config: () => ({}),\r\n },\r\n);\r\n\r\nconst emit = defineEmits<\r\n TableEmits & {\r\n \"row-add\": [newRow: DataRecord];\r\n \"row-delete\": [deletedRow: DataRecord, index: number];\r\n \"row-copy\": [originalRow: DataRecord, newRow: DataRecord];\r\n \"row-move\": [row: DataRecord, fromIndex: number, toIndex: number];\r\n \"row-selection-change\": [\r\n selectedKey: DataTableRowKey | null,\r\n selectedRow: DataRecord | null,\r\n ];\r\n \"pagination-change\": [page: number, pageSize: number];\r\n \"view-detail\": [data: DataRecord];\r\n \"column-change\": [columns: TableColumn[]];\r\n }\r\n>();\r\n\r\n/* ================= CRUD 桥接 ================= */\r\n\r\n/** 包装 emit:在触发事件的同时自动调用 crud 对应的方法 */\r\nconst bridgedEmit: typeof emit = (event: any, ...args: any[]) => {\r\n (emit as any)(event, ...args);\r\n\r\n if (!props.crud) return;\r\n const handlers: Record<string, ((...a: any[]) => void) | undefined> = {\r\n save: props.crud.save,\r\n cancel: props.crud.handleCancel,\r\n \"pagination-change\": props.crud.handlePaginationChange,\r\n \"row-delete\": props.crud.handleRowDelete,\r\n \"view-detail\": props.crud.detail?.show,\r\n };\r\n handlers[event]?.(...args);\r\n};\r\n\r\n/* ================= 有效值(crud 优先 → props 覆盖) ================= */\r\n\r\n/** 合并 crud 返回的 actions/pagination 到用户 config */\r\nconst effectiveConfig = computed<TableConfig>(() => {\r\n if (!props.crud) return props.config || {};\r\n const fromCrud: Partial<TableConfig> = {};\r\n if (props.crud.actions) fromCrud.actions = props.crud.actions.value;\r\n if (props.crud.pagination) fromCrud.pagination = props.crud.pagination.value;\r\n return { ...fromCrud, ...props.config };\r\n});\r\n\r\nconst effectiveColumns = computed<TableColumn[]>(\r\n () => props.columns ?? props.crud?.columns.value ?? [],\r\n);\r\n\r\n/* ================= 配置解析 ================= */\r\n\r\nconst resolved = computed(() => resolveConfig(effectiveConfig.value));\r\nconst editModeChecker = computed(() => createEditModeChecker(resolved.value));\r\n\r\n/* ================= 数据规范化(兼容跨实例 Ref) ================= */\r\n\r\nconst unwrapRef = <T,>(val: MaybeRefLike<T> | undefined): T | undefined =>\r\n val && typeof val === \"object\" && \"value\" in val ? val.value : (val as T);\r\n\r\nconst normalizedData = computed<DataRecord[]>(\r\n () => unwrapRef(props.data) ?? props.crud?.data.value ?? [],\r\n);\r\n\r\nconst normalizedLoading = computed<boolean>(\r\n () => unwrapRef(props.loading) ?? props.crud?.loading.value ?? false,\r\n);\r\n\r\n/* ================= Hooks ================= */\r\n\r\nconst pagination = usePagination({\r\n data: normalizedData,\r\n config: computed(() => resolved.value.pagination),\r\n emit: bridgedEmit,\r\n});\r\n\r\nconst tableManager = useTableManager({\r\n config: resolved.value,\r\n data: () => normalizedData.value,\r\n rowKey: props.rowKey,\r\n emit: bridgedEmit,\r\n});\r\n\r\nconst tableActions = useTableActions({\r\n actions: computed(() => effectiveConfig.value.actions || {}),\r\n config: resolved,\r\n tableManager,\r\n rowKey: props.rowKey,\r\n emit: bridgedEmit,\r\n onViewDetail: (data: DataRecord) => bridgedEmit(\"view-detail\", data),\r\n});\r\n\r\nconst columnState = useTableColumns({\r\n rawColumns: effectiveColumns,\r\n config: resolved,\r\n columnWidth: resolved.value.columnWidth,\r\n scrollX: resolved.value.scrollX,\r\n rowKey: props.rowKey,\r\n tableManager,\r\n actionsRenderer: tableActions.renderActions,\r\n editModeChecker,\r\n});\r\n\r\nconst { showSettingsPanel, reactiveColumns, computedColumns, computedScrollX } =\r\n columnState;\r\n\r\n/* ================= 表格属性 ================= */\r\n\r\nconst tableRef = ref<ComponentPublicInstance>();\r\n\r\nconst computedTableProps = computed(() => ({\r\n striped: resolved.value.striped,\r\n bordered: resolved.value.bordered,\r\n singleLine: resolved.value.singleLine,\r\n size: resolved.value.size,\r\n maxHeight: resolved.value.maxHeight,\r\n}));\r\n\r\n/* ================= 编辑弹窗 ================= */\r\n\r\nconst editFormRef = ref<any>();\r\nconst modalSubmitLoading = ref(false);\r\nconst localEditingData = ref<DataRecord>({});\r\n\r\nconst modalVisible = computed({\r\n get: () => tableManager.editStates.modalEdit.isModalVisible.value,\r\n set: (val: boolean) => {\r\n tableManager.editStates.modalEdit.isModalVisible.value = val;\r\n },\r\n});\r\n\r\nconst editableColumns = computed(() =>\r\n effectiveColumns.value.filter(\r\n (col): col is TableColumn => col.editable !== false,\r\n ),\r\n);\r\n\r\nconst formKey = computed(\r\n () =>\r\n `edit-form-${tableManager.editStates.modalEdit.editingRowKey.value || \"new\"}`,\r\n);\r\n\r\nconst formOptions = computed(() => generateFormOptions(editableColumns.value));\r\n\r\nwatch(\r\n () => tableManager.editStates.modalEdit.editingData.value,\r\n (newData) => {\r\n if (newData && Object.keys(newData).length > 0) {\r\n localEditingData.value = JSON.parse(JSON.stringify(newData));\r\n }\r\n },\r\n { immediate: true, deep: true },\r\n);\r\n\r\nlet modalCloseTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\nwatch(modalVisible, (visible) => {\r\n if (!visible) {\r\n modalCloseTimer = setTimeout(() => {\r\n localEditingData.value = {};\r\n modalCloseTimer = null;\r\n }, 300);\r\n }\r\n});\r\n\r\nconst handleModalSave = async () => {\r\n if (!editFormRef.value) return;\r\n modalSubmitLoading.value = true;\r\n try {\r\n await editFormRef.value.validate();\r\n await tableManager.editStates.modalEdit.saveEdit(localEditingData.value);\r\n } catch {\r\n /* 表单验证错误由组件内联显示 */\r\n } finally {\r\n modalSubmitLoading.value = false;\r\n }\r\n};\r\n\r\nconst handleModalCancel = () => {\r\n localEditingData.value = {};\r\n tableManager.editStates.modalEdit.cancelEdit();\r\n};\r\n\r\n/* ================= 列设置 ================= */\r\n\r\nconst onColumnSettingsChange = (columns: TableColumn[]) => {\r\n columnState.handleColumnChange(columns);\r\n emit(\"column-change\", columnState.reactiveColumns.value);\r\n};\r\n\r\n/* ================= Expose ================= */\r\n\r\nconst { edit, expand, selection, dynamicRows } = tableManager.stateManager;\r\n\r\nconst exposedApi = {\r\n startEdit: edit.start,\r\n expandAll: expand.all,\r\n collapseAll: expand.collapseAll,\r\n selectAll: selection.all,\r\n clearSelection: selection.clear,\r\n clearAllSelections: tableManager.stateManager.clearAllSelections,\r\n clearRowSelection: dynamicRows?.clearSelection,\r\n resetToFirstPage: pagination.resetToFirstPage,\r\n getSelectedRows: selection.getSelected,\r\n getEditingData: edit.getEditingData,\r\n isEditing: edit.isEditing,\r\n isExpanded: expand.isExpanded,\r\n getManager: () => tableManager.stateManager,\r\n};\r\n\r\ndefineExpose(exposedApi);\r\n\r\n/* 自动连接 crud.tableRef */\r\nonMounted(() => {\r\n const crudRef = props.crud?.tableRef;\r\n if (crudRef) crudRef.value = exposedApi;\r\n});\r\n\r\nonBeforeUnmount(() => {\r\n if (modalCloseTimer) clearTimeout(modalCloseTimer);\r\n});\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n@use \"./index.scss\";\r\n</style>\r\n"],"mappings":"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"}