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,851 @@
1
+ <template>
2
+ <el-input
3
+ v-if="isShowInput"
4
+ v-model="selectInputVal"
5
+ v-bind="{ clearable: true, ...inputAttr }"
6
+ @focus="() => emits('input-focus')"
7
+ @blur="() => emits('input-blur')"
8
+ @click="() => emits('input-click')"
9
+ @clear="() => emits('input-clear')"
10
+ :style="{ width: inputWidth ? `${inputWidth}px` : '100%' }"
11
+ >
12
+ <template v-for="(_index, name) in slots" v-slot:[name]="data">
13
+ <slot :name="name" v-bind="data" />
14
+ </template>
15
+ </el-input>
16
+ <el-select
17
+ v-else
18
+ ref="selectRef"
19
+ :model-value="multiple ? state.defaultValue : selectDefaultLabel"
20
+ popper-class="t-select-table"
21
+ :style="{ width: selectWidth ? `${selectWidth}px` : '100%' }"
22
+ :value-key="keywords.value"
23
+ :filter-method="filterMethod || filterMethodHandle"
24
+ v-click-outside="closeBox"
25
+ @visible-change="visibleChange"
26
+ @remove-tag="removeTag"
27
+ @clear="clear"
28
+ @keyup="selectKeyup"
29
+ v-bind="{ clearable: true, multiple, filterable, remote, remoteMethod, ...$attrs }"
30
+ >
31
+ <template #empty>
32
+ <div
33
+ class="t-table-select__table"
34
+ :style="{ width: tableWidth ? `${tableWidth}px` : '100%' }"
35
+ >
36
+ <div class="table_query_condition" v-if="isShowQuery">
37
+ <t-query-condition
38
+ ref="tQueryConditionRef"
39
+ :boolEnter="false"
40
+ @handleEvent="handleEvent"
41
+ v-bind="$attrs"
42
+ >
43
+ <template v-for="(_index, name) in slots" v-slot:[name]="data">
44
+ <slot :name="name" v-bind="data"></slot>
45
+ </template>
46
+ <template #querybar v-if="isShowBlurBtn">
47
+ <el-button v-bind="{ type: 'danger', ...computedBtnBind }" @click="blur">
48
+ {{ computedBtnBind.btnTxt }}
49
+ </el-button>
50
+ <slot name="querybar"></slot>
51
+ </template>
52
+ </t-query-condition>
53
+ </div>
54
+ <div class="header_wrap" :style="{ paddingBottom: isShowSlot('toolbar') ? '10px' : 0 }">
55
+ <slot name="toolbar"></slot>
56
+ </div>
57
+ <div class="table_content" v-loading="tableLoading" :element-loading-text="computedLoadingTxt">
58
+ <el-table
59
+ ref="selectTable"
60
+ :data="state.tableData"
61
+ :class="{
62
+ radioStyle: !multiple,
63
+ highlightCurrentRow: isRadio,
64
+ keyUpStyle: isKeyup,
65
+ t_select_table_multiple: useVirtual && multiple,
66
+ t_select_table_radio: useVirtual && !multiple
67
+ }"
68
+ :row-class-name="getRowClassName"
69
+ :row-key="getRowKey"
70
+ @row-click="rowClick"
71
+ @cell-dblclick="cellDblclick"
72
+ @selection-change="handlesSelectionChange"
73
+ v-bind="{ border, size: tableSize, 'highlight-current-row': true, ...$attrs }"
74
+ >
75
+ <el-table-column
76
+ v-if="multiple"
77
+ type="selection"
78
+ :width="tableSize === 'large' ? 65 : 55"
79
+ :align="align || 'center'"
80
+ :reserve-selection="reserveSelection"
81
+ :selectable="selectable"
82
+ :fixed="multipleFixed"
83
+ ></el-table-column>
84
+ <el-table-column
85
+ type="radio"
86
+ :width="tableSize === 'large' ? 65 : 55"
87
+ :label="computedRadioTxt"
88
+ :fixed="radioFixed"
89
+ :align="align || 'center'"
90
+ v-if="!multiple && isShowFirstRadio"
91
+ >
92
+ <template #default="scope">
93
+ <el-radio
94
+ v-model="radioVal"
95
+ :label="scope.$index + 1"
96
+ :disabled="scope.row.isRadioDisabled"
97
+ @click.stop="radioChangeHandle($event, scope.row, scope.$index + 1)"
98
+ ></el-radio>
99
+ </template>
100
+ </el-table-column>
101
+ <el-table-column
102
+ v-for="(item, index) in columns"
103
+ :key="index + 'i'"
104
+ :type="item.type"
105
+ :label="item.label"
106
+ :prop="item.prop"
107
+ :min-width="item['min-width'] || item.minWidth"
108
+ :width="item.width"
109
+ :align="item.align || align || 'center'"
110
+ :fixed="item.fixed"
111
+ v-bind="{ 'show-overflow-tooltip': true, ...item.bind }"
112
+ >
113
+ <template #default="scope">
114
+ <template v-if="item.render">
115
+ <render-col
116
+ :column="item"
117
+ :row="scope.row"
118
+ :render="item.render"
119
+ :index="scope.$index"
120
+ />
121
+ </template>
122
+ <template v-if="item.slotName">
123
+ <slot :name="item.slotName" :scope="scope"></slot>
124
+ </template>
125
+ <div v-if="!item.render && !item.slotName">
126
+ <span>{{ scope.row[item.prop] }}</span>
127
+ </div>
128
+ </template>
129
+ </el-table-column>
130
+ <slot></slot>
131
+ </el-table>
132
+ <div class="t-table-select__page" v-if="isShowPagination">
133
+ <el-pagination
134
+ v-model:current-page="table.currentPage"
135
+ v-model:page-size="table.pageSize"
136
+ @current-change="handlesCurrentChange"
137
+ layout="total, prev, pager, next, jumper"
138
+ :pager-count="table['pager-count'] || 5"
139
+ :total="table.total"
140
+ v-bind="{ background: true, size: paginationSize || 'small', ...$attrs }"
141
+ />
142
+ </div>
143
+ </div>
144
+ <slot name="footer"></slot>
145
+ </div>
146
+ </template>
147
+ </el-select>
148
+ </template>
149
+
150
+ <script setup lang="ts">
151
+ import TQueryCondition from "@ff-ui-plus/components/query-condition/src/index.vue"
152
+ import RenderCol from "@ff-ui-plus/components/select-table/src/renderCol.vue"
153
+ import {
154
+ computed,
155
+ useAttrs,
156
+ useSlots,
157
+ ref,
158
+ watch,
159
+ nextTick,
160
+ reactive,
161
+ onMounted,
162
+ onUpdated,
163
+ onBeforeUnmount
164
+ } from "vue"
165
+ import type { TSelectTableProps } from "./type"
166
+ import { ElMessage } from "element-plus"
167
+ import ClickOutside from "./ClickOutside"
168
+ // 虚拟滚动
169
+ import { useVirtualized } from "./useVirtualized"
170
+ import { useLocale } from "@ff-ui-plus/hooks"
171
+ const { t } = useLocale()
172
+ const {
173
+ scrollContainerEl,
174
+ updateRenderedItemCache,
175
+ updateOffset,
176
+ getDom,
177
+ saveDATA,
178
+ getItemHeightFromCache
179
+ } = useVirtualized()
180
+
181
+ const props = withDefaults(defineProps<TSelectTableProps>(), {
182
+ modelValue: undefined,
183
+ inputValue: undefined,
184
+ defaultSelectVal: () => [],
185
+ radioSelectValLabel: "",
186
+ table: () => ({
187
+ data: [],
188
+ currentPage: 1,
189
+ pageSize: 10,
190
+ total: 0
191
+ }),
192
+ keywords: () => ({
193
+ value: "value",
194
+ label: "label"
195
+ }),
196
+ columns: () => [],
197
+ multiple: false,
198
+ filterable: true,
199
+ remote: false,
200
+ remoteMethod: undefined,
201
+ filterMethod: undefined,
202
+ isShowInput: false,
203
+ inputAttr: () => ({}),
204
+ inputWidth: 550,
205
+ selectWidth: 550,
206
+ tableWidth: 550,
207
+ isShowQuery: false,
208
+ isShowBlurBtn: false,
209
+ btnBind: () => ({ btnTxt: "" }),
210
+ align: "center",
211
+ reserveSelection: true,
212
+ selectable: undefined,
213
+ multipleFixed: true,
214
+ radioTxt: "",
215
+ radioFixed: true,
216
+ tableSize: "default",
217
+ border: true,
218
+ isShowFirstColumn: true,
219
+ useVirtual: false,
220
+ virtualShowSize: 30,
221
+ isShowPagination: false,
222
+ paginationSize: "small",
223
+ selfExpanded: false,
224
+ isClearQuery: false,
225
+ isRadioEchoLabel: true,
226
+ defaultValIsOpenRadioChange: false,
227
+ radioSameIsCancel: true,
228
+ rowClickRadio: true,
229
+ isKeyup: false,
230
+ isExpanded: false,
231
+ multipleDisableDelete: true,
232
+ tableLoading: false,
233
+ loadingTxt: ""
234
+ })
235
+ defineOptions({
236
+ name: "TSelectTable"
237
+ })
238
+ // 自定义指令
239
+ const vClickOutside = ClickOutside
240
+ // 定义 Emits 类型
241
+ export type Emits = {
242
+ (event: "page-change", val: any): void
243
+ (event: "selectionChange", val: any[], ids: any[]): void
244
+ (event: "radioChange", row: any, value: any): void
245
+ (event: "update:inputValue", val: string): void
246
+ (event: "input-focus"): void
247
+ (event: "input-blur"): void
248
+ (event: "input-clear"): void
249
+ (event: "input-click"): void
250
+ }
251
+ // 抛出事件
252
+ const emits = defineEmits<Emits>()
253
+ const slots = useSlots()
254
+ const isDefaultSelectVal = ref(true) // 是否已经重新选择了
255
+ const forbidden = ref(true) // 判断单选选中及取消选中
256
+ const isRadio = ref(false)
257
+ const isQueryVisible = ref(false) // 查询条件是否显示隐藏下拉框
258
+ const isVisible = ref(false) // 是否显示隐藏下拉框
259
+ const radioVal = ref<any>("")
260
+ const isShowFirstRadio = ref(props.isShowFirstColumn) // 是否显示第一列
261
+ const selectDefaultLabel: any = ref(props.modelValue) // 单选赋值
262
+ const scrollTopNum = ref(0) // 滚动条位置
263
+ // input回显值
264
+ let selectInputVal = computed({
265
+ get() {
266
+ return props.inputValue
267
+ },
268
+ set(val) {
269
+ // console.log(777, val)
270
+ emits("update:inputValue", val)
271
+ }
272
+ })
273
+ interface InitState {
274
+ defaultSelectValue: any[]
275
+ tableData: any[]
276
+ defaultValue: any
277
+ ids: any[]
278
+ tabularMap: any
279
+ }
280
+ const state = reactive<InitState>({
281
+ defaultSelectValue: props.defaultSelectVal, // 默认选中
282
+ tableData: props.table.data, // table数据
283
+ defaultValue: props.value,
284
+ ids: [], // 多选id集合
285
+ tabularMap: {} // 存储下拉tale的所有name
286
+ })
287
+ // 国际化文本计算属性
288
+ const computedBtnBind = computed(() => {
289
+ return props.btnBind.btnTxt ? props.btnBind : { btnTxt: t("plus.selectTable.searchBtnTxt") }
290
+ })
291
+ const computedRadioTxt = computed(() => {
292
+ return props.radioTxt || t("plus.selectTable.radioTxt")
293
+ })
294
+ const computedLoadingTxt = computed(() => {
295
+ return props.loadingTxt || t("plus.selectTable.loadingTxt")
296
+ })
297
+
298
+ // 获取ref
299
+ const selectRef = ref<HTMLElement | any>(null)
300
+ const selectTable = ref<HTMLElement | any>(null)
301
+ const tQueryConditionRef = ref<HTMLElement | any>(null)
302
+ const nowIndex = ref(-1)
303
+ // 获取tableData的label
304
+ const tableDataLabelList = computed(() => {
305
+ return state.tableData.map((item: any) => item[props.keywords.label])
306
+ })
307
+ watch(
308
+ () => props.table.data,
309
+ val => {
310
+ if (props.useVirtual) {
311
+ saveDATA.value = val
312
+ updateRenderData(scrollTopNum.value)
313
+ } else {
314
+ state.tableData = val
315
+ // 解决查询后,之前选中的数据若不在查询结果中,则禁用删除
316
+ if (props.multiple && props.multipleDisableDelete) {
317
+ selectRef.value?.$el?.querySelectorAll(".el-tag").forEach(item => {
318
+ if (
319
+ tableDataLabelList.value?.includes(
320
+ item.querySelector(".el-select__tags-text")?.innerText
321
+ )
322
+ ) {
323
+ item.querySelector(".el-tag__close").style = "display: block"
324
+ } else {
325
+ item.querySelector(".el-tag__close").style = "display: none"
326
+ }
327
+ })
328
+ }
329
+ }
330
+ nextTick(() => {
331
+ state.tableData &&
332
+ state.tableData.length > 0 &&
333
+ state.tableData.forEach((item: { [x: string]: any }) => {
334
+ state.tabularMap[item[props.keywords.value]] = item[props.keywords.label]
335
+ })
336
+ })
337
+ },
338
+ { deep: true }
339
+ )
340
+ watch(
341
+ () => props.defaultSelectVal,
342
+ val => {
343
+ // console.log("props.defaultSelectVal---watch", val, isDefaultSelectVal.value)
344
+ state.defaultSelectValue = val
345
+ if (val.length > 0) {
346
+ if (props.multiple) {
347
+ if (isDefaultSelectVal.value) {
348
+ defaultSelect(state.defaultSelectValue)
349
+ }
350
+ } else {
351
+ // console.log("this.defaultSelectValue---watch---1111", state.defaultSelectValue)
352
+ defaultSelect(state.defaultSelectValue)
353
+ }
354
+ }
355
+ },
356
+ { deep: true }
357
+ )
358
+ watch(
359
+ () => props.radioSelectValLabel,
360
+ val => {
361
+ if (val) findLabel()
362
+ },
363
+ { deep: true }
364
+ )
365
+ onMounted(() => {
366
+ // 设置默认选中项(单选)
367
+ if (state.defaultSelectValue && state.defaultSelectValue.length > 0 && isDefaultSelectVal.value) {
368
+ defaultSelect(state.defaultSelectValue)
369
+ }
370
+ if (props.selfExpanded) {
371
+ selectRef.value.expanded = true
372
+ }
373
+ if (props.useVirtual) {
374
+ saveDATA.value = props.table.data
375
+ isShowFirstRadio.value = false
376
+ getDom(props)
377
+ scrollContainerEl.value?.addEventListener("scroll", handleScroll)
378
+ }
379
+ if (props.radioSelectValLabel) findLabel()
380
+ })
381
+
382
+ // 更新实际渲染数据
383
+ const updateRenderData = (scrollTop: number) => {
384
+ // console.log("更新实际渲染数据---scrollTop", scrollTop)
385
+ let startIndex = 0
386
+ let offsetHeight = 0
387
+ for (let i = 0; i < saveDATA.value.length; i++) {
388
+ offsetHeight += getItemHeightFromCache(i)
389
+ if (offsetHeight >= scrollTop) {
390
+ startIndex = i
391
+ break
392
+ }
393
+ }
394
+ // 计算得出的渲染数据
395
+ state.tableData = saveDATA.value.slice(startIndex, startIndex + props.virtualShowSize)
396
+ // 缓存最新的列表项高度
397
+ updateRenderedItemCache(startIndex)
398
+ // 更新偏移值
399
+ updateOffset(offsetHeight - getItemHeightFromCache(startIndex))
400
+ }
401
+ // 滚动事件
402
+ const handleScroll = (e: any) => {
403
+ scrollTopNum.value = e.target.scrollTop
404
+ // 渲染正确的数据
405
+ updateRenderData(scrollTopNum.value)
406
+ // console.log("滚动事件---handleScroll")
407
+ }
408
+ // 移除滚动事件
409
+ onBeforeUnmount(() => {
410
+ // console.log("移除滚动事件")
411
+ if (props.useVirtual) {
412
+ scrollContainerEl.value?.removeEventListener("scroll", handleScroll)
413
+ }
414
+ })
415
+ // 解决查询条件下拉选择table闪烁问题
416
+ onUpdated(() => {
417
+ if (props.isShowQuery) {
418
+ // console.log('onUpdated--22')
419
+ selectTable.value.doLayout()
420
+ }
421
+ })
422
+ // 表格显示隐藏回调
423
+ const visibleChange = (visible: boolean) => {
424
+ // console.log('表格显示隐藏回调', visible)
425
+ isVisible.value = visible
426
+ if (isQueryVisible.value) {
427
+ selectRef.value.expanded = true
428
+ }
429
+ // console.log('表格显示隐藏回调--222', visible)
430
+ if (visible) {
431
+ if (
432
+ state.defaultSelectValue &&
433
+ state.defaultSelectValue.length > 0 &&
434
+ isDefaultSelectVal.value
435
+ ) {
436
+ defaultSelect(state.defaultSelectValue)
437
+ }
438
+ initTableData()
439
+ if (props.useVirtual) {
440
+ saveDATA.value = props.table.data
441
+ updateRenderData(scrollTopNum.value)
442
+ }
443
+ } else {
444
+ if (
445
+ tQueryConditionRef.value &&
446
+ props.isShowQuery &&
447
+ props.isClearQuery &&
448
+ !selectRef.value.expanded &&
449
+ !props.selfExpanded
450
+ ) {
451
+ tQueryConditionRef.value?.resetData()
452
+ }
453
+ findLabel()
454
+ filterMethodHandle("")
455
+ if (props.useVirtual) {
456
+ // console.log("props.useVirtual---清空")
457
+ state.tableData = []
458
+ saveDATA.value = []
459
+ }
460
+ }
461
+ if (props.selfExpanded) {
462
+ selectRef.value.expanded = true
463
+ }
464
+ }
465
+ // 查询条件change事件触发
466
+ const handleEvent = () => {
467
+ // console.log('查询条件change事件触发')
468
+ selectRef.value.expanded = true
469
+ }
470
+ // 条件查询组件的visible-change事件
471
+ const queryVisibleChange = (val: boolean) => {
472
+ isQueryVisible.value = val
473
+ }
474
+ // el-select点击了空白区域
475
+ const closeBox = () => {
476
+ // 获取查询条件组件的项
477
+ if (tQueryConditionRef.value && props.isShowQuery) {
478
+ selectRef.value.expanded = true
479
+ Object.values(tQueryConditionRef.value?.props?.opts).map((val: any) => {
480
+ if (val.comp.includes("select") || val.comp.includes("picker") || val.comp.includes("date")) {
481
+ val.eventHandle = {
482
+ "visible-change": ($event: boolean) => queryVisibleChange($event)
483
+ }
484
+ // queryVisibleChange(true)
485
+ // isQueryVisible.value = true
486
+ selectRef.value.expanded = true
487
+ }
488
+ })
489
+ if (isVisible.value && props.isShowQuery) {
490
+ selectRef.value.expanded = true
491
+ } else {
492
+ selectRef.value.expanded = false
493
+ }
494
+ }
495
+ }
496
+ const attrs: any = useAttrs()
497
+ // 单选键盘事件
498
+ const selectKeyup = (e: { keyCode: any }) => {
499
+ if (!props.multiple && props.isKeyup && state.tableData.length > 0) {
500
+ const newIndex = nowIndex.value * 1
501
+ const nextIndex = e.keyCode === 40 ? newIndex + 1 : e.keyCode === 38 ? newIndex - 1 : newIndex
502
+ // 键盘向上/下滚动条根据移动的选择区域而滚动
503
+ const rowHeight = selectTable.value.$el.querySelectorAll(".el-table__row")[0]?.clientHeight || 0
504
+ const headerHeight =
505
+ selectTable.value.$el.querySelectorAll(".el-table__header")[0]?.clientHeight || 0
506
+ const attrsMaxHeight =
507
+ (typeof (attrs["max-height"] || attrs["maxHeight"]) === "number"
508
+ ? attrs["max-height"] || attrs["maxHeight"]
509
+ : parseFloat(attrs["max-height"] || attrs["maxHeight"])) || 0
510
+ const maxHeight = attrsMaxHeight ? attrsMaxHeight - headerHeight : 0
511
+ const height = rowHeight * (nextIndex + 3)
512
+ const scrollTop = height > maxHeight ? height - maxHeight : 0
513
+ // console.log('attrsMaxHeight---22', attrsMaxHeight)
514
+ if (attrsMaxHeight) {
515
+ selectTable.value.setScrollTop(scrollTop)
516
+ }
517
+
518
+ const validNextIndex = Math.max(0, Math.min(nextIndex, state.tableData.length - 1))
519
+
520
+ selectTable.value.setCurrentRow(state.tableData[validNextIndex])
521
+ nowIndex.value = validNextIndex
522
+
523
+ if (e.keyCode === 13) {
524
+ rowClick(state.tableData[validNextIndex])
525
+ }
526
+ }
527
+ }
528
+
529
+ // 赋值
530
+ const findLabel = () => {
531
+ nextTick(() => {
532
+ if (props.multiple) {
533
+ selectRef.value.selected?.forEach((item: { currentLabel: any; value: any }) => {
534
+ item.currentLabel = item.value
535
+ })
536
+ } else {
537
+ if (props.isRadioEchoLabel) {
538
+ selectDefaultLabel.value =
539
+ (state.defaultValue && state.defaultValue[props.keywords.label]) ||
540
+ props.radioSelectValLabel
541
+ } else {
542
+ selectDefaultLabel.value =
543
+ (state.defaultValue && state.defaultValue[props.keywords.label]) || ""
544
+ }
545
+ }
546
+ })
547
+ }
548
+
549
+ // 当前页码
550
+ const handlesCurrentChange = (val: any) => {
551
+ if (props.multiple) {
552
+ if (!props.reserveSelection) {
553
+ clear()
554
+ }
555
+ } else {
556
+ // clear()
557
+ reset()
558
+ }
559
+ emits("page-change", val)
560
+ }
561
+ // 数据重置后回调
562
+ const reset = () => {
563
+ if (!props.multiple) {
564
+ // 取消高亮
565
+ selectTable.value.setCurrentRow(-1)
566
+ nowIndex.value = -1
567
+ radioVal.value = ""
568
+ isDefaultSelectVal.value = true
569
+ forbidden.value = false
570
+ }
571
+ }
572
+ // 默认选中(且只能默认选中第一页的数据)
573
+ const defaultSelect = (defaultSelectVal: any[]) => {
574
+ if (props.multiple) {
575
+ const multipleList = defaultSelectVal
576
+ .map(val => state.tableData.find(row => row[props.keywords.value] === val))
577
+ .filter(Boolean) as any[]
578
+
579
+ setTimeout(() => {
580
+ state.defaultValue = multipleList.map(item => item[props.keywords.label])
581
+ multipleList.forEach(row => {
582
+ selectTable.value.toggleRowSelection(row, true)
583
+ })
584
+ selectRef.value?.selected?.forEach(item => {
585
+ item.currentLabel = item.value
586
+ })
587
+ }, 0)
588
+ } else {
589
+ setTimeout(() => {
590
+ const row = state.tableData.find(item => item[props.keywords.value] === defaultSelectVal[0])
591
+ if (row) {
592
+ radioVal.value = state.tableData.indexOf(row) + 1
593
+ state.defaultValue = row
594
+ selectDefaultLabel.value = row[props.keywords.label]
595
+ // 是否开启单选事件
596
+ if (!props.defaultValIsOpenRadioChange) {
597
+ emits("radioChange", row, row[props.keywords.value])
598
+ }
599
+ }
600
+ }, 0)
601
+ }
602
+ }
603
+
604
+ // 复选框(多选)
605
+ const handlesSelectionChange = (val: any[]) => {
606
+ // console.log("复选框--组件内--val", val)
607
+ isDefaultSelectVal.value = false
608
+ state.defaultValue = val.map(item => item[props.keywords.label])
609
+ state.ids = val.map(item => item[props.keywords.value])
610
+ if (val.length === 0) {
611
+ isDefaultSelectVal.value = true
612
+ state.defaultSelectValue = []
613
+ }
614
+ emits("selectionChange", val, state.ids)
615
+ }
616
+ // 设置table行class
617
+ const getRowClassName = ({ row }: any) => {
618
+ if (!props.multiple && JSON.stringify(row) === JSON.stringify(state.defaultValue)) {
619
+ return "selected_row_style"
620
+ }
621
+ return ""
622
+ }
623
+ // 搜索后表格勾选不取消
624
+ const getRowKey = (row: { [x: string]: any }) => {
625
+ return row[props.keywords.value]
626
+ }
627
+
628
+ // 搜索过滤
629
+ const filterMethodHandle = (val: string) => {
630
+ if (!props.filterable) return
631
+ if (props.filterable && props.remote && typeof props.remoteMethod === "function") {
632
+ props.remoteMethod(val)
633
+ return
634
+ }
635
+ const tableData = JSON.parse(JSON.stringify(props.table?.data))
636
+ if (!tableData || tableData.length === 0) return
637
+ if (!props.multiple) {
638
+ if (val) {
639
+ radioVal.value = ""
640
+ } else {
641
+ const defaultIndex = tableData.findIndex(
642
+ item => item[props.keywords.label] === selectDefaultLabel.value
643
+ )
644
+ if (defaultIndex !== -1) {
645
+ radioVal.value = defaultIndex + 1
646
+ }
647
+ }
648
+ }
649
+ state.tableData = tableData.filter(item => {
650
+ return item[props.keywords.label]?.includes(val)
651
+ })
652
+ // 解决选中后,在过滤后,没有选中问题
653
+ if (selectDefaultLabel.value) {
654
+ const defaultIndex = state.tableData.findIndex(
655
+ item => item[props.keywords.label] === selectDefaultLabel.value
656
+ )
657
+ if (defaultIndex !== -1) {
658
+ radioVal.value = defaultIndex + 1
659
+ }
660
+ }
661
+ }
662
+
663
+ // 获取表格数据
664
+ const initTableData = () => {
665
+ // 表格默认赋值
666
+ nextTick(() => {
667
+ if (props.multiple) {
668
+ state.defaultValue?.forEach(row => {
669
+ const matchedRow = state.tableData.find(
670
+ item => item[props.keywords.value] === row[props.keywords.value]
671
+ )
672
+ if (matchedRow) {
673
+ selectTable.value.toggleRowSelection(matchedRow, true)
674
+ }
675
+ })
676
+ } else {
677
+ const matchedRow = state.tableData?.find(
678
+ item => item[props.keywords.value] === selectDefaultLabel.value
679
+ )
680
+ if (matchedRow) {
681
+ selectTable.value.setCurrentRow(matchedRow)
682
+ }
683
+ }
684
+ })
685
+ }
686
+
687
+ // 复制内容到剪切板
688
+ const copyToClipboard = async (text: any) => {
689
+ // 确保传入的内容是字符串类型
690
+ if (typeof text !== "string" || text.trim() === "") {
691
+ throw new Error(t("plus.copy.invalidCopyContent"))
692
+ }
693
+ try {
694
+ // 使用现代剪贴板 API 进行复制
695
+ await navigator.clipboard.writeText(text)
696
+ } catch (error) {
697
+ throw new Error(t("plus.copy.copyFail"))
698
+ }
699
+ }
700
+
701
+ // 显示消息提示
702
+ const showMessage = (type: "success" | "error", message: string) => {
703
+ if (type === "success") {
704
+ ElMessage.success(message)
705
+ } else {
706
+ ElMessage.error(message)
707
+ }
708
+ }
709
+
710
+ // 双击复制单元格内容
711
+ const cellDblclick = async (row: { [x: string]: any }, column: { property: string | number }) => {
712
+ const value = row[column.property]
713
+ try {
714
+ // 调用复制函数
715
+ await copyToClipboard(String(value)) // 确保值转换为字符串
716
+ showMessage("success", t("plus.copy.copySuccess"))
717
+ } catch (error: any) {
718
+ // 捕获并显示错误信息
719
+ showMessage("error", error.message || t("plus.copy.copyFail"))
720
+ }
721
+ }
722
+ // 点击单选框单元格触发事件
723
+ const radioChangeHandle = (event: { preventDefault: () => void }, row: any, index: any) => {
724
+ event.preventDefault()
725
+ if (row.isRadioDisabled) return
726
+ isDefaultSelectVal.value = false
727
+ radioClick(row, index)
728
+ }
729
+ // forbidden取值
730
+ const isForbidden = () => {
731
+ forbidden.value = false
732
+ setTimeout(() => {
733
+ forbidden.value = true
734
+ }, 0)
735
+ }
736
+ // 单选抛出事件radioChange
737
+ const radioClick = (row: { [x: string]: any }, index: string | number) => {
738
+ forbidden.value = !forbidden.value
739
+ if (radioVal.value === index) {
740
+ if (!props.radioSameIsCancel) return
741
+ clear()
742
+ } else {
743
+ updateState(row, index)
744
+ }
745
+
746
+ if (props.isExpanded && state.defaultValue) {
747
+ selectDefaultLabel.value = state.defaultValue[props.keywords.label] || ""
748
+ selectRef.value.expanded = true
749
+ } else {
750
+ blur()
751
+ }
752
+ }
753
+
754
+ const updateState = (row: { [x: string]: any }, index: string | number) => {
755
+ isForbidden()
756
+ radioVal.value = index
757
+ state.defaultValue = row
758
+ emits("radioChange", row, row[props.keywords.value])
759
+ }
760
+
761
+ // 单击行
762
+ const rowClick = async (row: { [x: string]: any }) => {
763
+ if (row.isRadioDisabled) return
764
+ if (!props.rowClickRadio) return
765
+ if (!props.multiple) {
766
+ const rowIndex = props.table?.data.findIndex(
767
+ item => item[props.keywords.value] === row[props.keywords.value]
768
+ )
769
+ if (rowIndex !== -1) {
770
+ isDefaultSelectVal.value = false
771
+ await radioClick(row, rowIndex + 1)
772
+ if (radioVal.value) {
773
+ isRadio.value = true
774
+ } else {
775
+ isRadio.value = false
776
+ }
777
+ }
778
+ }
779
+ }
780
+
781
+ // tags删除后回调
782
+ const removeTag = (tag: any) => {
783
+ const row = state.tableData.find(
784
+ (item: { [x: string]: any }) => item[props.keywords.label] === tag
785
+ )
786
+ // console.log("tags删除后回调", row)
787
+ row && selectTable.value.toggleRowSelection(row, false)
788
+ isDefaultSelectVal.value = true
789
+ }
790
+ // 清空后的回调
791
+ const clear = () => {
792
+ // 公共逻辑:重置默认选择状态
793
+ const resetDefaultState = () => {
794
+ isDefaultSelectVal.value = true
795
+ state.defaultSelectValue = []
796
+ state.defaultValue = props.multiple ? [] : null
797
+ }
798
+
799
+ // 安全检查:确保 selectTable.value 存在
800
+ if (!selectTable.value) {
801
+ console.warn("selectTable.value is not initialized")
802
+ return
803
+ }
804
+
805
+ if (props.multiple === true) {
806
+ try {
807
+ selectTable.value.clearSelection()
808
+ } catch (error) {
809
+ console.error("Failed to clear selection:", error)
810
+ }
811
+ resetDefaultState()
812
+ } else if (props.multiple === false) {
813
+ try {
814
+ selectTable.value.setCurrentRow(-1)
815
+ } catch (error) {
816
+ console.error("Failed to set current row:", error)
817
+ }
818
+ nowIndex.value = -1
819
+ radioVal.value = ""
820
+ forbidden.value = false
821
+ selectDefaultLabel.value = null
822
+ resetDefaultState()
823
+ emits("radioChange", null, null)
824
+ } else {
825
+ console.warn("Invalid value for props.multiple:", props.multiple)
826
+ }
827
+ }
828
+ // 触发select隐藏
829
+ const blur = () => {
830
+ selectRef.value.blur()
831
+ }
832
+ // 触发select显示
833
+ const focus = () => {
834
+ selectRef.value.focus()
835
+ }
836
+ // 判断是否使用了某个插槽
837
+ const isShowSlot = (name: string) => {
838
+ return Object.keys(slots).includes(name)
839
+ }
840
+ // 暴露方法出去
841
+ defineExpose({
842
+ focus,
843
+ blur,
844
+ clear,
845
+ props,
846
+ state,
847
+ tQueryConditionRef,
848
+ selectRef,
849
+ selectTable
850
+ })
851
+ </script>