ff-ui-plus 2.0.7

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 (319) hide show
  1. package/.nvmrc +1 -0
  2. package/.prettierrc.cjs +41 -0
  3. package/.stylelintignore +5 -0
  4. package/LICENSE +21 -0
  5. package/README.md +265 -0
  6. package/commitlint.config.cjs +162 -0
  7. package/global.d.ts +27 -0
  8. package/index.html +16 -0
  9. package/lib.sh +9 -0
  10. package/lint-staged.config.cjs +8 -0
  11. package/package.json +149 -0
  12. package/packages/components/adaptive-page/index.ts +5 -0
  13. package/packages/components/adaptive-page/src/index.vue +85 -0
  14. package/packages/components/adaptive-page/src/type.ts +9 -0
  15. package/packages/components/adaptive-page/style/css.ts +1 -0
  16. package/packages/components/adaptive-page/style/index.ts +1 -0
  17. package/packages/components/button/index.ts +5 -0
  18. package/packages/components/button/src/index.vue +41 -0
  19. package/packages/components/button/src/type.ts +11 -0
  20. package/packages/components/button/style/css.ts +1 -0
  21. package/packages/components/button/style/index.ts +1 -0
  22. package/packages/components/chart/index.ts +5 -0
  23. package/packages/components/chart/src/index.vue +121 -0
  24. package/packages/components/chart/src/type.ts +7 -0
  25. package/packages/components/chart/style/css.ts +1 -0
  26. package/packages/components/chart/style/index.ts +1 -0
  27. package/packages/components/checkbox/index.ts +3 -0
  28. package/packages/components/checkbox/src/checkbox.d.ts +5 -0
  29. package/packages/components/checkbox/src/index.vue +67 -0
  30. package/packages/components/checkbox/style/css.ts +1 -0
  31. package/packages/components/checkbox/style/index.ts +1 -0
  32. package/packages/components/date-picker/index.ts +5 -0
  33. package/packages/components/date-picker/src/index.vue +228 -0
  34. package/packages/components/date-picker/src/type.ts +22 -0
  35. package/packages/components/date-picker/style/css.ts +1 -0
  36. package/packages/components/date-picker/style/index.ts +1 -0
  37. package/packages/components/detail/index.ts +5 -0
  38. package/packages/components/detail/src/index.vue +102 -0
  39. package/packages/components/detail/src/renderLabel.vue +15 -0
  40. package/packages/components/detail/src/renderTooltip.vue +15 -0
  41. package/packages/components/detail/src/type.ts +28 -0
  42. package/packages/components/detail/style/css.ts +1 -0
  43. package/packages/components/detail/style/index.ts +1 -0
  44. package/packages/components/form/index.ts +5 -0
  45. package/packages/components/form/src/index.vue +407 -0
  46. package/packages/components/form/src/renderBtn.vue +15 -0
  47. package/packages/components/form/src/renderComp.vue +15 -0
  48. package/packages/components/form/src/type.ts +26 -0
  49. package/packages/components/form/style/css.ts +1 -0
  50. package/packages/components/form/style/index.ts +1 -0
  51. package/packages/components/index.ts +20 -0
  52. package/packages/components/input/index.ts +5 -0
  53. package/packages/components/input/src/index.vue +225 -0
  54. package/packages/components/input/src/type.ts +14 -0
  55. package/packages/components/input/style/css.ts +1 -0
  56. package/packages/components/input/style/index.ts +1 -0
  57. package/packages/components/layout-page/index.ts +4 -0
  58. package/packages/components/layout-page/src/index.vue +74 -0
  59. package/packages/components/layout-page/style/css.ts +1 -0
  60. package/packages/components/layout-page/style/index.ts +1 -0
  61. package/packages/components/layout-page-item/index.ts +3 -0
  62. package/packages/components/layout-page-item/src/index.vue +16 -0
  63. package/packages/components/layout-page-item/style/css.ts +1 -0
  64. package/packages/components/layout-page-item/style/index.ts +1 -0
  65. package/packages/components/module-form/index.ts +4 -0
  66. package/packages/components/module-form/src/index.vue +243 -0
  67. package/packages/components/module-form/src/moduleDetail.vue +61 -0
  68. package/packages/components/module-form/src/moduleForm.vue +88 -0
  69. package/packages/components/module-form/src/type.ts +16 -0
  70. package/packages/components/module-form/style/css.ts +1 -0
  71. package/packages/components/module-form/style/index.ts +1 -0
  72. package/packages/components/package.json +9 -0
  73. package/packages/components/query-condition/index.ts +4 -0
  74. package/packages/components/query-condition/src/index.vue +478 -0
  75. package/packages/components/query-condition/src/moreChoose.vue +159 -0
  76. package/packages/components/query-condition/src/renderComp.vue +15 -0
  77. package/packages/components/query-condition/src/type.ts +22 -0
  78. package/packages/components/query-condition/src/useComputed.ts +94 -0
  79. package/packages/components/query-condition/style/css.ts +1 -0
  80. package/packages/components/query-condition/style/index.ts +1 -0
  81. package/packages/components/radio/index.ts +3 -0
  82. package/packages/components/radio/src/index.vue +73 -0
  83. package/packages/components/radio/src/radio.d.ts +12 -0
  84. package/packages/components/radio/style/css.ts +1 -0
  85. package/packages/components/radio/style/index.ts +1 -0
  86. package/packages/components/select/index.ts +4 -0
  87. package/packages/components/select/src/index.vue +240 -0
  88. package/packages/components/select/src/type.ts +43 -0
  89. package/packages/components/select/style/css.ts +1 -0
  90. package/packages/components/select/style/index.ts +1 -0
  91. package/packages/components/select-icon/index.ts +4 -0
  92. package/packages/components/select-icon/src/index.vue +128 -0
  93. package/packages/components/select-icon/style/css.ts +1 -0
  94. package/packages/components/select-icon/style/index.ts +1 -0
  95. package/packages/components/select-table/index.ts +4 -0
  96. package/packages/components/select-table/src/ClickOutside.ts +106 -0
  97. package/packages/components/select-table/src/index.vue +851 -0
  98. package/packages/components/select-table/src/renderCol.vue +20 -0
  99. package/packages/components/select-table/src/type.ts +56 -0
  100. package/packages/components/select-table/src/useVirtualized.ts +86 -0
  101. package/packages/components/select-table/style/css.ts +1 -0
  102. package/packages/components/select-table/style/index.ts +1 -0
  103. package/packages/components/step-wizard/index.ts +4 -0
  104. package/packages/components/step-wizard/src/index.vue +99 -0
  105. package/packages/components/step-wizard/src/type.ts +17 -0
  106. package/packages/components/step-wizard/style/css.ts +1 -0
  107. package/packages/components/step-wizard/style/index.ts +1 -0
  108. package/packages/components/table/index.ts +5 -0
  109. package/packages/components/table/src/ColumnSet.vue +176 -0
  110. package/packages/components/table/src/TTableColumn.vue +100 -0
  111. package/packages/components/table/src/densitySet.vue +91 -0
  112. package/packages/components/table/src/firstColumn.vue +132 -0
  113. package/packages/components/table/src/index.vue +926 -0
  114. package/packages/components/table/src/operator.vue +246 -0
  115. package/packages/components/table/src/renderCol.vue +20 -0
  116. package/packages/components/table/src/renderHeader.vue +18 -0
  117. package/packages/components/table/src/singleEdit.vue +354 -0
  118. package/packages/components/table/src/singleEditCell.vue +303 -0
  119. package/packages/components/table/src/tableProps.ts +162 -0
  120. package/packages/components/table/src/useExpose.ts +74 -0
  121. package/packages/components/table/src/useVirtualized.ts +70 -0
  122. package/packages/components/table/style/css.ts +1 -0
  123. package/packages/components/table/style/index.ts +1 -0
  124. package/packages/components/tabs/index.ts +4 -0
  125. package/packages/components/tabs/src/index.vue +50 -0
  126. package/packages/components/tabs/style/css.ts +1 -0
  127. package/packages/components/tabs/style/index.ts +1 -0
  128. package/packages/components/timer-btn/index.ts +4 -0
  129. package/packages/components/timer-btn/src/index.vue +57 -0
  130. package/packages/components/timer-btn/style/css.ts +1 -0
  131. package/packages/components/timer-btn/style/index.ts +1 -0
  132. package/packages/components/utils/index.ts +142 -0
  133. package/packages/components/utils/install.ts +16 -0
  134. package/packages/eslint-config/build.config.ts +16 -0
  135. package/packages/eslint-config/dist/index.cjs +122 -0
  136. package/packages/eslint-config/dist/index.d.cts +92 -0
  137. package/packages/eslint-config/dist/index.d.mts +92 -0
  138. package/packages/eslint-config/dist/index.d.ts +92 -0
  139. package/packages/eslint-config/dist/index.mjs +120 -0
  140. package/packages/eslint-config/package.json +34 -0
  141. package/packages/eslint-config/src/index.ts +121 -0
  142. package/packages/ff-ui-plus/component.ts +55 -0
  143. package/packages/ff-ui-plus/defaults.ts +4 -0
  144. package/packages/ff-ui-plus/index.ts +9 -0
  145. package/packages/ff-ui-plus/make-installer.ts +10 -0
  146. package/packages/ff-ui-plus/package.json +117 -0
  147. package/packages/ff-ui-plus/version.ts +1 -0
  148. package/packages/hooks/index.ts +1 -0
  149. package/packages/hooks/package.json +9 -0
  150. package/packages/hooks/useLocale.ts +53 -0
  151. package/packages/locale/index.ts +11 -0
  152. package/packages/locale/lang/en.ts +157 -0
  153. package/packages/locale/lang/zh-cn.ts +155 -0
  154. package/packages/locale/package.json +12 -0
  155. package/packages/resolver/package.json +23 -0
  156. package/packages/resolver/src/index.ts +99 -0
  157. package/packages/theme-chalk/build.ts +76 -0
  158. package/packages/theme-chalk/dist/index.css +1 -0
  159. package/packages/theme-chalk/dist/src/adaptive-page.scss +48 -0
  160. package/packages/theme-chalk/dist/src/button.scss +23 -0
  161. package/packages/theme-chalk/dist/src/chart.scss +10 -0
  162. package/packages/theme-chalk/dist/src/checkbox.scss +0 -0
  163. package/packages/theme-chalk/dist/src/date-picker.scss +3 -0
  164. package/packages/theme-chalk/dist/src/detail.scss +7 -0
  165. package/packages/theme-chalk/dist/src/form.scss +104 -0
  166. package/packages/theme-chalk/dist/src/index.scss +19 -0
  167. package/packages/theme-chalk/dist/src/input.scss +0 -0
  168. package/packages/theme-chalk/dist/src/layout-page-item.scss +10 -0
  169. package/packages/theme-chalk/dist/src/layout-page.scss +37 -0
  170. package/packages/theme-chalk/dist/src/module-form.scss +335 -0
  171. package/packages/theme-chalk/dist/src/query-condition.scss +132 -0
  172. package/packages/theme-chalk/dist/src/radio.scss +0 -0
  173. package/packages/theme-chalk/dist/src/select-icon.scss +61 -0
  174. package/packages/theme-chalk/dist/src/select-table.scss +71 -0
  175. package/packages/theme-chalk/dist/src/select.scss +7 -0
  176. package/packages/theme-chalk/dist/src/step-wizard.scss +51 -0
  177. package/packages/theme-chalk/dist/src/table.scss +381 -0
  178. package/packages/theme-chalk/dist/src/tabs.scss +20 -0
  179. package/packages/theme-chalk/dist/src/timer-btn.scss +21 -0
  180. package/packages/theme-chalk/dist/t-adaptive-page.css +1 -0
  181. package/packages/theme-chalk/dist/t-button.css +1 -0
  182. package/packages/theme-chalk/dist/t-chart.css +1 -0
  183. package/packages/theme-chalk/dist/t-checkbox.css +0 -0
  184. package/packages/theme-chalk/dist/t-date-picker.css +1 -0
  185. package/packages/theme-chalk/dist/t-detail.css +1 -0
  186. package/packages/theme-chalk/dist/t-form.css +1 -0
  187. package/packages/theme-chalk/dist/t-input.css +0 -0
  188. package/packages/theme-chalk/dist/t-layout-page-item.css +1 -0
  189. package/packages/theme-chalk/dist/t-layout-page.css +1 -0
  190. package/packages/theme-chalk/dist/t-module-form.css +1 -0
  191. package/packages/theme-chalk/dist/t-query-condition.css +1 -0
  192. package/packages/theme-chalk/dist/t-radio.css +0 -0
  193. package/packages/theme-chalk/dist/t-select-icon.css +1 -0
  194. package/packages/theme-chalk/dist/t-select-table.css +1 -0
  195. package/packages/theme-chalk/dist/t-select.css +1 -0
  196. package/packages/theme-chalk/dist/t-step-wizard.css +1 -0
  197. package/packages/theme-chalk/dist/t-table.css +1 -0
  198. package/packages/theme-chalk/dist/t-tabs.css +1 -0
  199. package/packages/theme-chalk/dist/t-timer-btn.css +1 -0
  200. package/packages/theme-chalk/mixins/config.scss +8 -0
  201. package/packages/theme-chalk/mixins/function.scss +71 -0
  202. package/packages/theme-chalk/mixins/mixins.scss +79 -0
  203. package/packages/theme-chalk/package.json +21 -0
  204. package/packages/theme-chalk/src/adaptive-page.scss +48 -0
  205. package/packages/theme-chalk/src/button.scss +23 -0
  206. package/packages/theme-chalk/src/chart.scss +10 -0
  207. package/packages/theme-chalk/src/checkbox.scss +0 -0
  208. package/packages/theme-chalk/src/date-picker.scss +3 -0
  209. package/packages/theme-chalk/src/detail.scss +7 -0
  210. package/packages/theme-chalk/src/form.scss +104 -0
  211. package/packages/theme-chalk/src/index.scss +19 -0
  212. package/packages/theme-chalk/src/input.scss +0 -0
  213. package/packages/theme-chalk/src/layout-page-item.scss +10 -0
  214. package/packages/theme-chalk/src/layout-page.scss +37 -0
  215. package/packages/theme-chalk/src/module-form.scss +335 -0
  216. package/packages/theme-chalk/src/query-condition.scss +132 -0
  217. package/packages/theme-chalk/src/radio.scss +0 -0
  218. package/packages/theme-chalk/src/select-icon.scss +61 -0
  219. package/packages/theme-chalk/src/select-table.scss +71 -0
  220. package/packages/theme-chalk/src/select.scss +7 -0
  221. package/packages/theme-chalk/src/step-wizard.scss +51 -0
  222. package/packages/theme-chalk/src/table.scss +381 -0
  223. package/packages/theme-chalk/src/tabs.scss +20 -0
  224. package/packages/theme-chalk/src/timer-btn.scss +21 -0
  225. package/packages/types/global.ts +34 -0
  226. package/packages/types/index.ts +1 -0
  227. package/packages/types/package.json +10 -0
  228. package/packages/utils/build.config.ts +23 -0
  229. package/packages/utils/dist/cookie.cjs +1 -0
  230. package/packages/utils/dist/cookie.d.cts +16 -0
  231. package/packages/utils/dist/cookie.d.mts +16 -0
  232. package/packages/utils/dist/cookie.d.ts +16 -0
  233. package/packages/utils/dist/cookie.mjs +1 -0
  234. package/packages/utils/dist/day.cjs +1 -0
  235. package/packages/utils/dist/day.d.cts +37 -0
  236. package/packages/utils/dist/day.d.mts +37 -0
  237. package/packages/utils/dist/day.d.ts +37 -0
  238. package/packages/utils/dist/day.mjs +1 -0
  239. package/packages/utils/dist/file.cjs +1 -0
  240. package/packages/utils/dist/file.d.cts +61 -0
  241. package/packages/utils/dist/file.d.mts +61 -0
  242. package/packages/utils/dist/file.d.ts +61 -0
  243. package/packages/utils/dist/file.mjs +1 -0
  244. package/packages/utils/dist/index.cjs +1 -0
  245. package/packages/utils/dist/index.d.cts +13 -0
  246. package/packages/utils/dist/index.d.mts +13 -0
  247. package/packages/utils/dist/index.d.ts +13 -0
  248. package/packages/utils/dist/index.mjs +1 -0
  249. package/packages/utils/dist/is.cjs +1 -0
  250. package/packages/utils/dist/is.d.cts +117 -0
  251. package/packages/utils/dist/is.d.mts +117 -0
  252. package/packages/utils/dist/is.d.ts +117 -0
  253. package/packages/utils/dist/is.mjs +1 -0
  254. package/packages/utils/dist/letter.cjs +1 -0
  255. package/packages/utils/dist/letter.d.cts +12 -0
  256. package/packages/utils/dist/letter.d.mts +12 -0
  257. package/packages/utils/dist/letter.d.ts +12 -0
  258. package/packages/utils/dist/letter.mjs +1 -0
  259. package/packages/utils/dist/number.cjs +1 -0
  260. package/packages/utils/dist/number.d.cts +23 -0
  261. package/packages/utils/dist/number.d.mts +23 -0
  262. package/packages/utils/dist/number.d.ts +23 -0
  263. package/packages/utils/dist/number.mjs +1 -0
  264. package/packages/utils/dist/openExe.cjs +1 -0
  265. package/packages/utils/dist/openExe.d.cts +9 -0
  266. package/packages/utils/dist/openExe.d.mts +9 -0
  267. package/packages/utils/dist/openExe.d.ts +9 -0
  268. package/packages/utils/dist/openExe.mjs +1 -0
  269. package/packages/utils/dist/storage.cjs +1 -0
  270. package/packages/utils/dist/storage.d.cts +46 -0
  271. package/packages/utils/dist/storage.d.mts +46 -0
  272. package/packages/utils/dist/storage.d.ts +46 -0
  273. package/packages/utils/dist/storage.mjs +1 -0
  274. package/packages/utils/dist/validate.cjs +1 -0
  275. package/packages/utils/dist/validate.d.cts +32 -0
  276. package/packages/utils/dist/validate.d.mts +32 -0
  277. package/packages/utils/dist/validate.d.ts +32 -0
  278. package/packages/utils/dist/validate.mjs +1 -0
  279. package/packages/utils/dist/ws.cjs +1 -0
  280. package/packages/utils/dist/ws.d.cts +86 -0
  281. package/packages/utils/dist/ws.d.mts +86 -0
  282. package/packages/utils/dist/ws.d.ts +86 -0
  283. package/packages/utils/dist/ws.mjs +1 -0
  284. package/packages/utils/package.json +42 -0
  285. package/packages/utils/src/cookie.ts +24 -0
  286. package/packages/utils/src/day.ts +66 -0
  287. package/packages/utils/src/file.ts +173 -0
  288. package/packages/utils/src/index.ts +10 -0
  289. package/packages/utils/src/is.ts +159 -0
  290. package/packages/utils/src/letter.ts +15 -0
  291. package/packages/utils/src/number.ts +37 -0
  292. package/packages/utils/src/openExe.ts +45 -0
  293. package/packages/utils/src/storage.ts +77 -0
  294. package/packages/utils/src/validate.ts +55 -0
  295. package/packages/utils/src/ws.ts +191 -0
  296. package/pnpm-workspace.yaml +3 -0
  297. package/publish.sh +37 -0
  298. package/resolver.sh +9 -0
  299. package/scripts/build/all.ts +152 -0
  300. package/scripts/build/build.config.ts +10 -0
  301. package/scripts/build/dist/index.cjs +7 -0
  302. package/scripts/build/dist/index.d.ts +2 -0
  303. package/scripts/build/dist/index.mjs +12 -0
  304. package/scripts/build/index.ts +63 -0
  305. package/scripts/build/modules.ts +141 -0
  306. package/scripts/build/package.json +14 -0
  307. package/scripts/release/gen-version.ts +12 -0
  308. package/scripts/release/index.ts +209 -0
  309. package/scripts/utils/excludeFiles.ts +14 -0
  310. package/scripts/utils/index.ts +88 -0
  311. package/scripts/utils/main.ts +14 -0
  312. package/scripts/utils/paths.ts +40 -0
  313. package/scripts/utils/plugin.ts +61 -0
  314. package/tsconfig.base.json +23 -0
  315. package/tsconfig.vitest.json +11 -0
  316. package/tsconfig.web.json +18 -0
  317. package/typings/env.d.ts +22 -0
  318. package/typings/index.d.ts +161 -0
  319. package/vitest.config.ts +22 -0
@@ -0,0 +1,926 @@
1
+ <template>
2
+ <div class="t-table" ref="TTableBox" v-loading="tableLoading" :element-loading-text="loadingTxt">
3
+ <div
4
+ class="header_wrap"
5
+ :style="{
6
+ paddingBottom:
7
+ tableTitle ||
8
+ title ||
9
+ isShow('title') ||
10
+ isShow('toolbar') ||
11
+ isSlotToolbar ||
12
+ columnSetting ||
13
+ densitySeting
14
+ ? '10px'
15
+ : 0
16
+ }"
17
+ >
18
+ <div class="header_title" v-if="tableTitle || title || $slots.title || isSlotTitle">
19
+ <template v-if="$slots.title || isSlotTitle">
20
+ <slot name="title" />
21
+ </template>
22
+ <template v-else>
23
+ <span v-if="tableTitle">{{ tableTitle }}</span>
24
+ <span v-else>{{ title }}</span>
25
+ </template>
26
+ </div>
27
+ <div class="toolbar_top">
28
+ <slot name="toolbar"></slot>
29
+ <div
30
+ class="header_right_wrap"
31
+ :style="{
32
+ marginLeft: isShow('toolbar') || isSlotToolbar ? '10px' : 0
33
+ }"
34
+ >
35
+ <slot name="btn" />
36
+ <column-set
37
+ v-if="columnSetting && !isTableHeader"
38
+ v-bind="$attrs"
39
+ :title="title || tableTitle"
40
+ :columns="renderColumns"
41
+ ref="columnSetRef"
42
+ @columnSetting="v => (state.columnSet = v)"
43
+ />
44
+ <div
45
+ :style="{
46
+ marginLeft: columnSetting ? '10px' : 0
47
+ }"
48
+ >
49
+ <density-set
50
+ v-if="densitySeting"
51
+ v-bind="$attrs"
52
+ :default-size="state.size"
53
+ @click-density="handleClickDensity"
54
+ />
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </div>
59
+ <div class="title-tip" v-if="isShow('titleTip')">
60
+ <slot name="titleTip" />
61
+ </div>
62
+ <el-table
63
+ ref="TTable"
64
+ :data="state.tableData"
65
+ :class="{
66
+ cursor: isCopy,
67
+ row_sort: isRowSort,
68
+ row_sort_none: isRowSortIcon,
69
+ tree_style: isTree,
70
+ highlightCurrentRow: highlightCurrentRow,
71
+ radioStyle: radioStyleClass || props.rowClickCheckbox,
72
+ multile_head_column: isTableHeader,
73
+ t_table_use_virtual: useVirtual
74
+ }"
75
+ :highlight-current-row="highlightCurrentRow"
76
+ :border="border || table.border || isTableBorder || useVirtual"
77
+ :size="state.size"
78
+ v-bind="$attrs"
79
+ @cell-dblclick="cellDblclick"
80
+ @row-click="rowClick"
81
+ >
82
+ <el-table-column
83
+ v-if="isRowSortIcon"
84
+ v-bind="{
85
+ width: rowSortIconBind.width || 55,
86
+ 'min-width': rowSortIconBind['min-width'] || rowSortIconBind.minWidth,
87
+ label: rowSortIconBind.label || t('plus.table.dragTxt'),
88
+ fixed: rowSortIconBind.fixed,
89
+ align: rowSortIconBind.align || align,
90
+ ...rowSortIconBind
91
+ }"
92
+ >
93
+ <template #default>
94
+ <el-icon class="row_drag" :color="rowSortIconBind.color" :size="rowSortIconBind.size">
95
+ <Rank />
96
+ </el-icon>
97
+ </template>
98
+ </el-table-column>
99
+ <first-column
100
+ :table="table"
101
+ v-model:radioVal="radioVal"
102
+ :align="align"
103
+ :isPaginationCumulative="isPaginationCumulative"
104
+ :isShowPagination="isShowPagination"
105
+ @radio-change="radioHandleChange"
106
+ >
107
+ <template v-for="(_index, name) in slots" v-slot:[name]="data">
108
+ <slot :name="name" v-bind="data"></slot>
109
+ </template>
110
+ </first-column>
111
+ <template v-for="(item, index) in renderColumns">
112
+ <template v-if="!item.children">
113
+ <el-table-column
114
+ v-if="typeof item.isShowCol == 'function' ? item.isShowCol(item) : !item.isShowCol"
115
+ :key="index + 'i'"
116
+ :type="item.type"
117
+ :label="item.label"
118
+ :prop="item.prop"
119
+ :min-width="item['min-width'] || item.minWidth"
120
+ :width="item.width"
121
+ :sortable="item.sortable || item.sort || sortable"
122
+ :align="item.align || align"
123
+ :fixed="item.fixed"
124
+ :formatter="item.formatter"
125
+ v-bind="
126
+ typeof item.bind == 'function'
127
+ ? item.bind(item)
128
+ : { 'show-overflow-tooltip': true, ...item.bind }
129
+ "
130
+ >
131
+ <template #header v-if="item.headerRequired || item.renderHeader || item.isClickEdit">
132
+ <render-header v-if="item.renderHeader" :column="item" :render="item.renderHeader" />
133
+ <div style="display: inline" v-if="item.headerRequired && emptyDataRequired">
134
+ <span style="color: #f56c6c; font-size: 16px; margin-right: 3px">*</span>
135
+ <span>{{ item.label }}</span>
136
+ </div>
137
+ <div
138
+ v-if="item.isClickEdit"
139
+ class="click_edit"
140
+ :style="{ justifyContent: item.editIconAlign || align || 'center' }"
141
+ >
142
+ <span>{{ item.label }}</span>
143
+ <el-icon v-if="!item.isShowEditIcon" v-bind="{ size: 14, ...item.editIconBind }">
144
+ <Edit />
145
+ </el-icon>
146
+ </div>
147
+ </template>
148
+ <template #default="scope">
149
+ <!-- render渲染 -->
150
+ <template v-if="item.render">
151
+ <render-col
152
+ :column="item"
153
+ :row="scope.row"
154
+ :render="item.render"
155
+ :index="scope.$index"
156
+ />
157
+ </template>
158
+ <!-- 自定义插槽 -->
159
+ <template v-if="item.slotName">
160
+ <slot :name="item.slotName" :scope="scope"></slot>
161
+ </template>
162
+ <!-- 单个单元格编辑 -->
163
+ <template
164
+ v-if="typeof item.canEdit == 'function' ? item.canEdit(scope) : item.canEdit"
165
+ >
166
+ <el-form
167
+ :model="state.tableData[scope.$index]"
168
+ :rules="isEditRules ? table.rules : {}"
169
+ class="t_edit_cell_form"
170
+ :class="{
171
+ t_edit_cell_form_rules: isEditRules
172
+ }"
173
+ :ref="(el:any) => handleRef(el, scope,item)"
174
+ @submit.prevent
175
+ >
176
+ <single-edit-cell
177
+ :configEdit="item.configEdit"
178
+ v-model="scope.row[item.prop]"
179
+ :prop="item.prop"
180
+ :scope="scope"
181
+ :indexColumns="index"
182
+ :ref="(el:any) => handleEditTableRef(el, scope,item)"
183
+ @handleEvent="handleEvent($event, scope.$index)"
184
+ @keyup-handle="handleKeyup"
185
+ v-bind="$attrs"
186
+ >
187
+ <template v-for="(_index, name) in slots" v-slot:[name]="data">
188
+ <slot :name="name" v-bind="data"></slot>
189
+ </template>
190
+ </single-edit-cell>
191
+ </el-form>
192
+ </template>
193
+ <!-- 单击单元格编辑 -->
194
+ <template v-if="item.isClickEdit">
195
+ <single-edit
196
+ :isClickEdit="item.isClickEdit"
197
+ :configEdit="item.configEdit"
198
+ v-model="scope.row[scope.column.property]"
199
+ v-bind="$attrs"
200
+ ref="editClickCell"
201
+ >
202
+ <template v-for="(_index, name) in slots" v-slot:[name]="data">
203
+ <slot :name="name" v-bind="data"></slot>
204
+ </template>
205
+ </single-edit>
206
+ </template>
207
+ <!-- 字典过滤 -->
208
+ <template v-if="item.filters && item.filters.list">
209
+ {{
210
+ constantEscape(
211
+ scope.row[item.prop],
212
+ table.listTypeInfo[item.filters.list],
213
+ item.filters.key || "value",
214
+ item.filters.label || "label"
215
+ )
216
+ }}
217
+ </template>
218
+ <div
219
+ v-if="
220
+ !item.render &&
221
+ !item.slotName &&
222
+ !item.canEdit &&
223
+ !item.filters &&
224
+ !item.isClickEdit &&
225
+ !item.formatter
226
+ "
227
+ >
228
+ <span>{{ scope.row[item.prop] }}</span>
229
+ </div>
230
+ </template>
231
+ </el-table-column>
232
+ </template>
233
+ <!-- 表头合并单元格 -->
234
+ <t-table-column
235
+ v-else
236
+ :key="index + 'm'"
237
+ :item="item"
238
+ :align="align"
239
+ v-bind="$attrs"
240
+ :sortable="sortable"
241
+ >
242
+ <template v-for="(_index, name) in slots" v-slot:[name]="data">
243
+ <slot :name="name" v-bind="data"></slot>
244
+ </template>
245
+ </t-table-column>
246
+ </template>
247
+ <slot></slot>
248
+ <Operator
249
+ :table="table"
250
+ :btnPermissions="btnPermissions"
251
+ :tableData="state.tableData"
252
+ :align="align"
253
+ />
254
+ <template #append>
255
+ <slot name="append"></slot>
256
+ </template>
257
+ <template #empty>
258
+ <slot name="empty"></slot>
259
+ </template>
260
+ </el-table>
261
+ <!-- 分页器 -->
262
+ <el-pagination
263
+ v-if="state.tableData && state.tableData.length && isShowPagination"
264
+ v-model:current-page="table.currentPage"
265
+ @current-change="handlesCurrentChange"
266
+ :page-sizes="table.pageSizes || [10, 20, 50, 100]"
267
+ v-model:page-size="table.pageSize"
268
+ :layout="table.layout || 'total,sizes, prev, pager, next, jumper'"
269
+ :prev-text="table.prevText"
270
+ :next-text="table.nextText"
271
+ :total="table.total || 0"
272
+ :size="table.size || 'small'"
273
+ v-bind="$attrs"
274
+ background
275
+ >
276
+ <slot name="pagination"></slot>
277
+ </el-pagination>
278
+ <footer
279
+ class="handle_wrap"
280
+ :style="{ textAlign: footerBtnAlign as any }"
281
+ v-if="isShowFooterBtn && state.tableData && state.tableData.length > 0"
282
+ >
283
+ <slot name="footer" />
284
+ <div v-if="!slots.footer">
285
+ <el-button type="primary" @click="save">{{ saveBtnTxt }}</el-button>
286
+ </div>
287
+ </footer>
288
+ </div>
289
+ </template>
290
+
291
+ <script setup lang="ts">
292
+ import {
293
+ computed,
294
+ ref,
295
+ watch,
296
+ useSlots,
297
+ reactive,
298
+ onMounted,
299
+ onUpdated,
300
+ onBeforeUnmount
301
+ } from "vue"
302
+ import { Rank, Edit } from "@element-plus/icons-vue"
303
+ import { ElMessage } from "element-plus"
304
+ import type { ComponentSize } from "element-plus/es/constants"
305
+ import Sortable from "sortablejs"
306
+ import TTableColumn from "@ff-ui-plus/components/table/src/TTableColumn.vue"
307
+ import SingleEditCell from "@ff-ui-plus/components/table/src/singleEditCell.vue"
308
+ import SingleEdit from "@ff-ui-plus/components/table/src/singleEdit.vue"
309
+ import ColumnSet from "@ff-ui-plus/components/table/src/ColumnSet.vue"
310
+ import RenderCol from "@ff-ui-plus/components/table/src/renderCol.vue"
311
+ import Operator from "@ff-ui-plus/components/table/src/operator.vue"
312
+ import RenderHeader from "@ff-ui-plus/components/table/src/renderHeader.vue"
313
+ import FirstColumn from "@ff-ui-plus/components/table/src/firstColumn.vue"
314
+ import DensitySet from "@ff-ui-plus/components/table/src/densitySet.vue"
315
+ // 虚拟滚动
316
+ import { useVirtualized } from "./useVirtualized"
317
+ const {
318
+ scrollContainerEl,
319
+ updateRenderedItemCache,
320
+ updateOffset,
321
+ getDom,
322
+ saveDATA,
323
+ getItemHeightFromCache
324
+ } = useVirtualized()
325
+ import { useExpose } from "./useExpose"
326
+ const {
327
+ TTable,
328
+ clearSelection,
329
+ getSelectionRows,
330
+ toggleRowSelection,
331
+ toggleAllSelection,
332
+ toggleRowExpansion,
333
+ setCurrentRow,
334
+ clearSort,
335
+ clearFilter,
336
+ doLayout,
337
+ sort,
338
+ scrollTo,
339
+ setScrollTop,
340
+ setScrollLeft
341
+ } = useExpose()
342
+ import { tableProps } from "./tableProps"
343
+ const props = defineProps(tableProps)
344
+ import { useLocale } from "@ff-ui-plus/hooks"
345
+ const { t } = useLocale()
346
+ defineOptions({
347
+ name: "TTable"
348
+ })
349
+ // 初始化数据
350
+ let state = reactive({
351
+ size: props.defaultSize,
352
+ tableData: props.table.data,
353
+ columnSet: [],
354
+ copyTableData: [] // 键盘事件
355
+ })
356
+ // 空数据时表头是否显示校验红点
357
+ const emptyDataRequired = computed(() => {
358
+ if (props.isEmptyDataRequired) {
359
+ return state.tableData.length > 0
360
+ } else {
361
+ return true
362
+ }
363
+ })
364
+ // 单选框
365
+ const radioVal = ref<number | any>("")
366
+ // 判断单选选中及取消选中
367
+ const forbidden = ref(true)
368
+ // 获取t-table ref
369
+ const TTableBox = ref<HTMLElement | any>(null)
370
+ // 获取columnSet Ref
371
+ const columnSetRef = ref<HTMLElement | any>(null)
372
+ // 获取form ref
373
+ const formRef = ref({})
374
+ // 动态form ref
375
+ const handleRef = (
376
+ el: any,
377
+ scope: { $index: number; column: { property: string } },
378
+ item: { prop: any }
379
+ ) => {
380
+ if (el) {
381
+ formRef.value[`formRef-${scope.$index}-${item.prop || scope.column.property}`] = el
382
+ }
383
+ }
384
+ // 获取所有单元格编辑组件 ref
385
+ const editTableRef: any = ref({})
386
+ // 动态单元格编辑组件 ref
387
+ const handleEditTableRef = (
388
+ el: any,
389
+ scope: { $index: number; column: { property: string } },
390
+ item: { prop: any }
391
+ ) => {
392
+ if (el) {
393
+ editTableRef.value[`singleEditRef-${scope.$index}-${item.prop || scope.column.property}`] = el
394
+ }
395
+ }
396
+ // 抛出事件
397
+ const emits = defineEmits([
398
+ "save",
399
+ "page-change",
400
+ "handleEvent",
401
+ "radioChange",
402
+ "rowSort",
403
+ "validateError"
404
+ ])
405
+ // 获取所有插槽
406
+ const slots = useSlots()
407
+ watch(
408
+ () => props.table.data,
409
+ val => {
410
+ // console.log(111, val)
411
+ if (props.useVirtual) {
412
+ saveDATA.value = val
413
+ updateRenderData(0)
414
+ } else {
415
+ state.tableData = val
416
+ }
417
+ },
418
+ { deep: true }
419
+ )
420
+ watch(
421
+ () => props.isRowSort,
422
+ val => {
423
+ if (val) {
424
+ initSort()
425
+ }
426
+ }
427
+ )
428
+ onMounted(() => {
429
+ // console.log('onMounted', props.table.firstColumn)
430
+ // 设置默认选中项(单选)
431
+ if (props.defaultRadioCol) {
432
+ defaultRadioSelect(props.defaultRadioCol)
433
+ }
434
+ initSort()
435
+ if (props.useVirtual) {
436
+ saveDATA.value = props.table.data
437
+ getDom()
438
+ scrollContainerEl.value?.addEventListener("scroll", handleScroll)
439
+ }
440
+ })
441
+ // 更新实际渲染数据
442
+ const updateRenderData = (scrollTop: number) => {
443
+ let startIndex = 0
444
+ let offsetHeight = 0
445
+ for (let i = 0; i < saveDATA.value.length; i++) {
446
+ offsetHeight += getItemHeightFromCache(i)
447
+ if (offsetHeight >= scrollTop) {
448
+ startIndex = i
449
+ break
450
+ }
451
+ }
452
+ // 计算得出的渲染数据
453
+ state.tableData = saveDATA.value.slice(startIndex, startIndex + props.virtualShowSize)
454
+ // 缓存最新的列表项高度
455
+ updateRenderedItemCache(startIndex)
456
+ // 更新偏移值
457
+ updateOffset(offsetHeight - getItemHeightFromCache(startIndex))
458
+ }
459
+ // 滚动事件
460
+ const handleScroll = (e: any) => {
461
+ // 渲染正确的数据
462
+ updateRenderData(e.target.scrollTop)
463
+ // console.log("滚动事件---handleScroll")
464
+ }
465
+ // 移除滚动事件
466
+ onBeforeUnmount(() => {
467
+ // console.log("移除滚动事件")
468
+ if (props.useVirtual) {
469
+ scrollContainerEl.value?.removeEventListener("scroll", handleScroll)
470
+ }
471
+ })
472
+ onUpdated(() => {
473
+ TTable.value.doLayout()
474
+ })
475
+ // 默认选中(单选项)---index必须是大于等于1(且只能默认选中第一页的数据)
476
+ const defaultRadioSelect = (index: number | any) => {
477
+ radioVal.value = index
478
+ emits("radioChange", state.tableData[index - 1], radioVal.value)
479
+ }
480
+ // 行拖拽
481
+ const initSort = () => {
482
+ if (!props.isRowSort) return
483
+ const el = TTableBox.value?.querySelector(".el-table__body-wrapper tbody")
484
+ // console.log('3333', el)
485
+ const handle = props.isRowSortIcon ? ".row_drag" : ".el-table__row"
486
+ Sortable.create(el, {
487
+ animation: 150, // 动画
488
+ handle, // 指定拖拽目标,点击此目标才可拖拽元素(此例中设置操作按钮拖拽)
489
+ // filter: '.disabled', // 指定不可拖动的类名(el-table中可通过row-class-name设置行的class)
490
+ // dragClass: 'dragClass', // 设置拖拽样式类名
491
+ // ghostClass: 'ghostClass', // 设置拖拽停靠样式类名
492
+ // chosenClass: 'chosenClass', // 设置选中样式类名
493
+ onEnd: (evt: { oldIndex: any; newIndex: any }) => {
494
+ // console.log("拖拽结束---11", evt.oldIndex, evt.newIndex)
495
+ const curRow = state.tableData.splice(evt.oldIndex, 1)[0]
496
+ state.tableData.splice(evt.newIndex, 0, curRow)
497
+ emits("rowSort", state.tableData, evt.oldIndex, evt.newIndex)
498
+ }
499
+ })
500
+ }
501
+
502
+ // 过滤字典
503
+ /**
504
+ * 下拉数据回显中文过滤器
505
+ * @param [String,Number] value 需要转中文的key值
506
+ * @param {String} list 数据源
507
+ * @param [String,Number] key 数据源的key字段(默认:value)
508
+ * @param {String} label 数据源的label字段(默认:label)
509
+ */
510
+ const constantEscape = (value: any, list: any[], key: string | number, label: string | number) => {
511
+ const res = list.find(item => {
512
+ return item[key] === value
513
+ })
514
+ return res && res[label]
515
+ }
516
+ // // 第一列单选显示类
517
+ const radioStyleClass = computed(() => {
518
+ if (Array.isArray(props.table.firstColumn)) {
519
+ return props.table.firstColumn.some((item: { type: string }) => item.type === "radio")
520
+ } else {
521
+ return props.table.firstColumn && props.table.firstColumn.type === "radio"
522
+ }
523
+ })
524
+ // 单元格编辑是否存在校验
525
+ const isEditRules = computed(() => {
526
+ return (
527
+ (props.table.rules && Object.keys(props.table.rules).length > 0) ||
528
+ props.columns.some((item: any) => item?.configEdit?.rules)
529
+ )
530
+ })
531
+ // 所有列(表头数据)
532
+ const renderColumns = computed(() => {
533
+ if (state.columnSet.length === 0) {
534
+ return props.columns
535
+ }
536
+ const columnByProp: any = props.columns.reduce((acc: any, cur: any) => {
537
+ acc[cur.prop] = cur
538
+ return acc
539
+ }, {})
540
+ return state.columnSet.filter((cur: any) => !cur.hidden).map((cur: any) => columnByProp[cur.prop])
541
+ })
542
+
543
+ // 判断是否是多级表头
544
+ const isTableHeader = computed(() => {
545
+ return renderColumns.value.some((item: any) => item.children)
546
+ })
547
+ // 判断如果有表头合并就自动开启单元格缩放
548
+ const isTableBorder = computed(() => {
549
+ return props.columns.some((item: any) => item.children)
550
+ })
551
+ // 单元格编辑键盘事件
552
+ const handleKeyup = (event: { keyCode: number }, index: number, key: string) => {
553
+ if (!props.isKeyup) return
554
+ const copyTableData = JSON.parse(JSON.stringify(state.tableData))
555
+ const doms = document.getElementsByClassName(key)
556
+ const focusNextElement = (nextIndex: number) => {
557
+ const nextDom =
558
+ doms[nextIndex]?.getElementsByTagName("input")[0] ||
559
+ doms[nextIndex]?.getElementsByTagName("textarea")[0]
560
+ if (nextDom) nextDom.focus()
561
+ }
562
+ switch (event.keyCode) {
563
+ case 38: // 向上键
564
+ if (!index) index = copyTableData.length
565
+ focusNextElement(index - 1)
566
+ break
567
+ case 40: // 向下键
568
+ if (index === copyTableData.length - 1) index = -1
569
+ focusNextElement(index + 1)
570
+ break
571
+ case 13: // 回车键
572
+ let keyName = props.columns.map((val: any) => val.prop)
573
+ let num = keyName.indexOf(key)
574
+ if (num === -1) {
575
+ num = 0
576
+ } else if (num === keyName.length - 1) {
577
+ if (index === state.copyTableData.length - 1) {
578
+ index = 0
579
+ } else {
580
+ ++index
581
+ }
582
+ } else {
583
+ ++num
584
+ }
585
+ let doms = document.getElementsByClassName(keyName[num])
586
+ if (doms.length) {
587
+ let dom =
588
+ doms[index].getElementsByTagName("input")[0] ||
589
+ doms[index].getElementsByTagName("textarea")[0]
590
+ dom.focus()
591
+ }
592
+ break
593
+ }
594
+ }
595
+
596
+ // forbidden取值(选择单选或取消单选)
597
+ const isForbidden = () => {
598
+ forbidden.value = false
599
+ setTimeout(() => {
600
+ forbidden.value = true
601
+ }, 0)
602
+ }
603
+ // 单选抛出事件radioChange
604
+ const radioClick = (row: any, index: any) => {
605
+ forbidden.value = !forbidden.value
606
+ const isCurrentlySelected = radioVal.value === index
607
+ if (isCurrentlySelected) {
608
+ radioVal.value = null
609
+ } else {
610
+ radioVal.value = index
611
+ }
612
+ isForbidden()
613
+ emits("radioChange", radioVal.value ? row : null, radioVal.value)
614
+ }
615
+
616
+ // 点击单选框单元格触发事件
617
+ const radioHandleChange = (row: any, index: any) => {
618
+ if (row?.isRadioDisabled) return
619
+ if (props.rowClickRadio) {
620
+ return
621
+ }
622
+ if (radioVal.value === index) {
623
+ emits("radioChange", row, index)
624
+ return
625
+ }
626
+
627
+ radioClick(row, index)
628
+ }
629
+ // 点击某行事件
630
+ const rowClick = (row: any) => {
631
+ if (row.isRadioDisabled) return
632
+ // 单选框点击事件
633
+ if (props.rowClickRadio) {
634
+ radioClick(row, state.tableData.indexOf(row) + 1)
635
+ } else {
636
+ return false
637
+ }
638
+ // 多选框点击事件
639
+ if (props.rowClickCheckbox) {
640
+ TTable.value.toggleRowSelection(row)
641
+ } else {
642
+ return false
643
+ }
644
+ }
645
+ // 清除单选框选中状态
646
+ const clearRadioHandle = () => {
647
+ radioVal.value = null
648
+ TTable.value.setCurrentRow(-1)
649
+ }
650
+ // 密度
651
+ const handleClickDensity = (size: ComponentSize) => {
652
+ state.size = size
653
+ }
654
+ // 复制内容到剪切板
655
+ const copyToClipboard = async (text: any) => {
656
+ // 确保传入的内容是字符串类型
657
+ if (typeof text !== "string" || text.trim() === "") {
658
+ throw new Error(t("plus.copy.invalidCopyContent"))
659
+ }
660
+ try {
661
+ // 使用现代剪贴板 API 进行复制
662
+ await navigator.clipboard.writeText(text)
663
+ } catch (error) {
664
+ throw new Error(t("plus.copy.copyFail"))
665
+ }
666
+ }
667
+
668
+ // 显示消息提示
669
+ const showMessage = (type: "success" | "error", message: string) => {
670
+ if (type === "success") {
671
+ ElMessage.success(message)
672
+ } else {
673
+ ElMessage.error(message)
674
+ }
675
+ }
676
+
677
+ // 双击复制单元格内容
678
+ const cellDblclick = async (row: { [x: string]: any }, column: { property: string | number }) => {
679
+ if (!props.isCopy) {
680
+ return false
681
+ }
682
+ const value = row[column.property]
683
+ try {
684
+ // 调用复制函数
685
+ await copyToClipboard(String(value)) // 确保值转换为字符串
686
+ showMessage("success", t("plus.copy.copySuccess"))
687
+ } catch (error: any) {
688
+ // 捕获并显示错误信息
689
+ showMessage("error", error.message || t("plus.copy.copyFail"))
690
+ }
691
+ }
692
+ // 判断是否使用了某个插槽
693
+ const isShow = (name: string) => {
694
+ return Object.keys(slots).includes(name)
695
+ }
696
+ const save = (): Promise<any> => {
697
+ return new Promise(resolve => {
698
+ if (!isEditRules.value) {
699
+ emits("save", state.tableData)
700
+ resolve(state.tableData)
701
+ return
702
+ }
703
+
704
+ // 表单规则校验
705
+ let successLength = 0
706
+ let rulesList: string[] = []
707
+ let rulesError: (string | number)[] = []
708
+ let propError: string[] = []
709
+ let propLabelError = [] as any
710
+
711
+ // 获取所有的form ref
712
+ const refList = Object.keys(formRef.value).filter(item => item.includes("formRef"))
713
+
714
+ // 获取单独设置规则项
715
+ const arr = renderColumns.value
716
+ .filter((val: { configEdit: { rules: any } }) => {
717
+ if (val.configEdit?.rules) {
718
+ return val
719
+ }
720
+ })
721
+ .map((item: { prop: any }) => item.prop)
722
+
723
+ // 获取整体设置规则
724
+ const arr1 = (props.table.rules && Object.keys(props.table.rules)) ?? []
725
+
726
+ // 获取最终设置了哪些规则(其值是设置的--prop)
727
+ const newArr = [...arr, ...arr1]
728
+
729
+ // 最终需要校验的ref
730
+ newArr.map(val => {
731
+ refList.map((item: any) => {
732
+ if (typeof item === "string" && item.includes(val)) {
733
+ rulesList.push(item)
734
+ }
735
+ })
736
+ })
737
+
738
+ // 表单都校验
739
+ rulesList.map((val: string | number) => {
740
+ formRef.value[val].validate((valid: boolean) => {
741
+ if (valid) {
742
+ successLength = successLength + 1
743
+ } else {
744
+ rulesError.push(val)
745
+ }
746
+ })
747
+ })
748
+
749
+ setTimeout(() => {
750
+ // 所有表单都校验成功
751
+ if (successLength == rulesList.length) {
752
+ if (isEditRules.value) {
753
+ emits("save", state.tableData)
754
+ resolve(state.tableData)
755
+ }
756
+ } else {
757
+ // 校验未通过的prop
758
+ rulesError.map(item => {
759
+ newArr.map(val => {
760
+ if (typeof item === "string" && item.includes(val)) {
761
+ propError.push(val)
762
+ }
763
+ })
764
+ })
765
+
766
+ // 去重获取校验未通过的prop--label
767
+ Array.from(new Set(propError)).map(item => {
768
+ renderColumns.value.map((val: { prop: string; label: string }) => {
769
+ if (item === val.prop) {
770
+ propLabelError.push(val.label)
771
+ }
772
+ })
773
+ })
774
+ // console.log("校验未通过的prop--label", propLabelError)
775
+ emits("validateError", propLabelError)
776
+ }
777
+ }, 300)
778
+ })
779
+ }
780
+ // 单个编辑事件
781
+ const handleEvent = ({ type, val }: any, index: any) => {
782
+ emits("handleEvent", type, val, index)
783
+ }
784
+ // 当前页码
785
+ const handlesCurrentChange = (val: any) => {
786
+ emits("page-change", val)
787
+ }
788
+ /**
789
+ * 公共方法
790
+ */
791
+ // 单元格编辑调用save方法返回数据
792
+ const saveMethod = (callback: (arg0: any) => any) => {
793
+ if (!isEditRules.value) {
794
+ callback && callback(state.tableData)
795
+ return
796
+ }
797
+ // 表单规则校验
798
+ let successLength = 0
799
+ let rulesList: any = []
800
+ let rulesError: any = []
801
+ let propError: any = []
802
+ let propLabelError: any = []
803
+ // 获取所有的form ref
804
+ const refList = Object.keys(formRef.value).filter(item => item.includes("formRef"))
805
+ // 获取单独设置规则项
806
+ const arr = renderColumns.value
807
+ .filter((val: { configEdit: { rules: any } }) => {
808
+ if (val.configEdit?.rules) {
809
+ return val
810
+ }
811
+ })
812
+ .map((item: { prop: any }) => item.prop)
813
+ // 获取整体设置规则
814
+ const arr1 = (props.table.rules && Object.keys(props.table.rules)) ?? []
815
+ // 获取最终设置了哪些规则(其值是设置的--prop)
816
+ const newArr = [...arr, ...arr1]
817
+ // 最终需要校验的ref
818
+ newArr.map(val => {
819
+ refList.map((item: any) => {
820
+ if (item.includes(val)) {
821
+ rulesList.push(item)
822
+ }
823
+ })
824
+ })
825
+ // console.log('最终需要校验的数据', rulesList, formRef.value)
826
+ // 表单都校验
827
+ rulesList.map((val: string | number) => {
828
+ formRef.value[val].validate((valid: any) => {
829
+ if (valid) {
830
+ successLength = successLength + 1
831
+ } else {
832
+ rulesError.push(val)
833
+ }
834
+ })
835
+ })
836
+ setTimeout(() => {
837
+ // 所有表单都校验成功
838
+ if (successLength == rulesList.length) {
839
+ if (isEditRules.value) {
840
+ // console.log('所有表单都校验成功--', state.tableData)
841
+ callback && callback(state.tableData)
842
+ }
843
+ } else {
844
+ // 校验未通过的prop
845
+ rulesError.map((item: string | any[]) => {
846
+ newArr.map(val => {
847
+ if (item.includes(val)) {
848
+ propError.push(val)
849
+ }
850
+ })
851
+ })
852
+ // 去重获取校验未通过的prop--label
853
+ Array.from(new Set(propError)).map(item => {
854
+ renderColumns.value.map((val: { prop: unknown; label: any }) => {
855
+ if (item === val.prop) {
856
+ propLabelError.push(val.label)
857
+ }
858
+ })
859
+ })
860
+ // console.log("校验未通过的prop--label", propLabelError)
861
+ emits("validateError", propLabelError)
862
+ }
863
+ }, 300)
864
+ }
865
+ // 清空校验规则
866
+ const clearValidate = () => {
867
+ const refList = Object.keys(formRef.value).filter(item => item.includes("formRef"))
868
+ refList.length > 0 &&
869
+ refList.map(val => {
870
+ formRef.value[val].clearValidate()
871
+ })
872
+ }
873
+ // 表单进行重置并移除校验结果
874
+ const resetFields = () => {
875
+ const refList = Object.keys(formRef.value).filter(item => item.includes("formRef"))
876
+ refList.length > 0 &&
877
+ refList.map(val => {
878
+ formRef.value[val].resetFields()
879
+ })
880
+ // 重置下拉表格
881
+ const refEditList = Object.keys(editTableRef.value).filter(item => item.includes("singleEditRef"))
882
+ refEditList.length > 0 &&
883
+ refEditList.map(val => {
884
+ editTableRef.value[val].resetTselectTableFields()
885
+ })
886
+ }
887
+ // 重置下拉表格--单元格编辑
888
+ const resetTselectTable = () => {
889
+ // 重置下拉表格
890
+ const refEditList = Object.keys(editTableRef.value).filter(item => item.includes("singleEditRef"))
891
+ refEditList.length > 0 &&
892
+ refEditList.map(val => {
893
+ editTableRef.value[val].resetTselectTableFields()
894
+ })
895
+ }
896
+ // 获取columnSet缓存数据
897
+ const reSetColumnSet = () => {
898
+ return columnSetRef.value?.reSetColumnSet()
899
+ }
900
+ // 暴露方法出去
901
+ defineExpose({
902
+ defaultRadioSelect,
903
+ clearSelection,
904
+ getSelectionRows,
905
+ toggleRowSelection,
906
+ toggleAllSelection,
907
+ toggleRowExpansion,
908
+ setCurrentRow,
909
+ clearSort,
910
+ clearFilter,
911
+ doLayout,
912
+ sort,
913
+ scrollTo,
914
+ setScrollTop,
915
+ setScrollLeft,
916
+ state,
917
+ radioVal,
918
+ clearValidate,
919
+ resetFields,
920
+ save,
921
+ saveMethod,
922
+ reSetColumnSet,
923
+ clearRadioHandle,
924
+ resetTselectTable
925
+ })
926
+ </script>