vue2-client 1.22.2 → 1.22.3

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 (170) hide show
  1. package/.claude/settings.local.json +30 -30
  2. package/.env.his +19 -19
  3. package/.eslintrc.js +74 -74
  4. package/.history/.eslintrc_20260521171150.js +74 -0
  5. package/.history/.eslintrc_20260521171213.js +74 -0
  6. package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154443.vue +726 -0
  7. package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154700.vue +478 -0
  8. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175435.vue +706 -0
  9. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175450.vue +694 -0
  10. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260611152602.vue +755 -0
  11. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513145941.vue +524 -0
  12. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513153133.vue +731 -0
  13. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513160316.vue +525 -0
  14. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260601144150.vue +1046 -0
  15. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310142713.vue +512 -0
  16. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310145118.vue +511 -0
  17. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260311094834.vue +696 -0
  18. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260320143028.vue +693 -0
  19. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260409101450.vue +677 -0
  20. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508164645.vue +758 -0
  21. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508164714.vue +693 -0
  22. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508171651.vue +716 -0
  23. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260509133717.vue +695 -0
  24. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260509171115.vue +664 -0
  25. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140637.vue +1455 -0
  26. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140935.vue +1441 -0
  27. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513150818.vue +1441 -0
  28. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153119.vue +1442 -0
  29. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153126.vue +1486 -0
  30. package/.history/src/base-client/components/common/XForm/XFormItem_20260513140854.vue +1607 -0
  31. package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140403.vue +643 -0
  32. package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140829.vue +628 -0
  33. package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519142824.vue +104 -0
  34. package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519143155.vue +102 -0
  35. package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171231.vue +1241 -0
  36. package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171441.vue +1223 -0
  37. package/.history/src/base-client/components/his/HAi/HAi_20260612174826.vue +472 -0
  38. package/.history/src/base-client/components/his/HAi/HAi_20260612175839.vue +538 -0
  39. package/.history/src/base-client/components/his/HAi/HAi_20260615103331.vue +650 -0
  40. package/.history/src/base-client/components/his/XHDescriptions/XHDescriptions_20260424134504.vue +1469 -0
  41. package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171133.vue +788 -0
  42. package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171151.vue +780 -0
  43. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511170841.vue +585 -0
  44. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511171138.vue +787 -0
  45. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260512141830.vue +739 -0
  46. package/.history/src/components/STable/index_20260409155138.js +806 -0
  47. package/.history/src/components/STable/index_20260409155218.js +814 -0
  48. package/.history/src/expression/core/Expression_20260305164427.js +1371 -0
  49. package/.history/src/expression/core/Expression_20260305170258.js +1358 -0
  50. package/.history/src/expression/core/Program_20260305111830.js +944 -0
  51. package/.history/src/expression/core/Program_20260305112041.js +931 -0
  52. package/.history/src/logic/LogicRunner_20260304154306.js +170 -0
  53. package/.history/src/logic/LogicRunner_20260304155553.js +112 -0
  54. package/.history/src/logic/LogicRunner_20260305105834.js +112 -0
  55. package/.history/src/logic/LogicRunner_20260305112718.js +129 -0
  56. package/.history/src/logic/LogicRunner_20260305182436.js +133 -0
  57. package/.history/src/logic/LogicRunner_20260306151301.js +213 -0
  58. package/.history/src/logic/LogicRunner_20260306152419.js +213 -0
  59. package/.history/src/logic/plugins/common/DateTools_20260305154159.js +61 -0
  60. package/.history/src/logic/plugins/common/DateTools_20260305154217.js +44 -0
  61. package/.history/src/logic/plugins/common/DateTools_20260305161014.js +44 -0
  62. package/.history/src/logic/plugins/common/HttpTools_20260305164352.js +80 -0
  63. package/.history/src/logic/plugins/common/HttpTools_20260305170258.js +75 -0
  64. package/.history/src/logic/plugins/common/HttpTools_20260305171634.js +75 -0
  65. package/.history/src/logic/plugins/common/HttpTools_20260306152419.js +72 -0
  66. package/.history/src/services/api/restTools_20260427142149.js +245 -0
  67. package/.history/src/services/api/restTools_20260427142853.js +230 -0
  68. package/.history/src/services/api/restTools_20260519135558.js +230 -0
  69. package/.history/src/services/api/restTools_20260519140825.js +230 -0
  70. package/.history/src/services/api/restTools_20260519151223.js +230 -0
  71. package/.history/src/utils/indexedDB_20260306150918.js +593 -0
  72. package/.history/src/utils/indexedDB_20260306151301.js +586 -0
  73. package/.idea/af-vue2-client.iml +9 -0
  74. package/.idea/codeStyles/Project.xml +62 -0
  75. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  76. package/.idea/misc.xml +6 -0
  77. package/.idea/modules.xml +1 -1
  78. package/Components.md +60 -60
  79. package/index.js +31 -31
  80. package/jest-transform-stub.js +8 -8
  81. package/jest.setup.js +7 -7
  82. package/package.json +1 -1
  83. package/preview-input-box.html +180 -0
  84. package/src/assets/img/querySlotDemo.svg +15 -15
  85. package/src/base-client/components/common/AmapMarker/AmapPointRendering.vue +120 -120
  86. package/src/base-client/components/common/CitySelect/index.js +3 -3
  87. package/src/base-client/components/common/CitySelect/index.md +109 -109
  88. package/src/base-client/components/common/FormGroupEdit/index.js +3 -3
  89. package/src/base-client/components/common/FormGroupEdit/index.md +43 -43
  90. package/src/base-client/components/common/HIS/HButtons/HButtons.vue +55 -1
  91. package/src/base-client/components/common/HIS/HForm/HForm.vue +1186 -1186
  92. package/src/base-client/components/common/HIS/HTab/HTab.vue +88 -1
  93. package/src/base-client/components/common/JSONToTree/jsontotree.vue +271 -271
  94. package/src/base-client/components/common/PersonSetting/index.js +3 -3
  95. package/src/base-client/components/common/Tree/index.js +2 -2
  96. package/src/base-client/components/common/Upload/index.js +3 -3
  97. package/src/base-client/components/common/XAddNativeForm/index.md +146 -146
  98. package/src/base-client/components/common/XAddReport/XAddReport.vue +16 -1
  99. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  100. package/src/base-client/components/common/XDataDrawer/XDataDrawer.vue +180 -180
  101. package/src/base-client/components/common/XDataDrawer/index.js +3 -3
  102. package/src/base-client/components/common/XDataDrawer/index.md +41 -41
  103. package/src/base-client/components/common/XDescriptions/index.js +3 -3
  104. package/src/base-client/components/common/XDescriptions/index.md +382 -382
  105. package/src/base-client/components/common/XForm/index.md +178 -178
  106. package/src/base-client/components/common/XInput/XInput.vue +32 -1
  107. package/src/base-client/components/common/XInspectionDetailDrawer/index.vue +1 -1
  108. package/src/base-client/components/common/XMarkdownViewer/demo.vue +102 -102
  109. package/src/base-client/components/common/XStepView/XStepView.vue +252 -252
  110. package/src/base-client/components/common/XStepView/index.js +3 -3
  111. package/src/base-client/components/common/XStepView/index.md +31 -31
  112. package/src/base-client/components/common/XTable/index.md +255 -255
  113. package/src/base-client/components/his/HAi/HAi.vue +1177 -436
  114. package/src/base-client/components/his/XList/XList.vue +337 -58
  115. package/src/base-client/components/his/XSidebar/XSidebar.vue +36 -12
  116. package/src/base-client/components/his/XTransfer/index.md +327 -327
  117. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
  118. package/src/base-client/plugins/Config.js +19 -19
  119. package/src/base-client/plugins/tabs-page-plugin.js +39 -39
  120. package/src/components/Charts/Bar.vue +62 -62
  121. package/src/components/Charts/ChartCard.vue +134 -134
  122. package/src/components/Charts/Liquid.vue +67 -67
  123. package/src/components/Charts/MiniArea.vue +39 -39
  124. package/src/components/Charts/MiniBar.vue +39 -39
  125. package/src/components/Charts/MiniProgress.vue +75 -75
  126. package/src/components/Charts/MiniSmoothArea.vue +40 -40
  127. package/src/components/Charts/Radar.vue +68 -68
  128. package/src/components/Charts/RankList.vue +77 -77
  129. package/src/components/Charts/TagCloud.vue +113 -113
  130. package/src/components/Charts/TransferBar.vue +64 -64
  131. package/src/components/Charts/Trend.vue +82 -82
  132. package/src/components/Charts/chart.less +12 -12
  133. package/src/components/Charts/smooth.area.less +13 -13
  134. package/src/components/NumberInfo/NumberInfo.vue +54 -54
  135. package/src/components/NumberInfo/index.js +3 -3
  136. package/src/components/NumberInfo/index.less +54 -54
  137. package/src/components/NumberInfo/index.md +43 -43
  138. package/src/components/STable/index.js +953 -953
  139. package/src/components/card/ChartCard.vue +79 -79
  140. package/src/components/chart/Bar.vue +60 -60
  141. package/src/components/chart/MiniArea.vue +67 -67
  142. package/src/components/chart/MiniBar.vue +59 -59
  143. package/src/components/chart/MiniProgress.vue +57 -57
  144. package/src/components/chart/Radar.vue +80 -80
  145. package/src/components/chart/RankingList.vue +60 -60
  146. package/src/components/chart/Trend.vue +79 -79
  147. package/src/components/chart/index.less +9 -9
  148. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  149. package/src/components/input/IInput.vue +66 -66
  150. package/src/components/menu/SideMenu.vue +75 -75
  151. package/src/components/menu/menu.js +273 -273
  152. package/src/components/tool/AStepItem.vue +60 -60
  153. package/src/layouts/CommonLayout.vue +56 -56
  154. package/src/lib.js +1 -1
  155. package/src/mock/extend/index.js +84 -84
  156. package/src/mock/goods/index.js +108 -108
  157. package/src/pages/dashboard/workplace/WorkPlace.vue +141 -141
  158. package/src/pages/system/dictionary/index.vue +44 -44
  159. package/src/pages/system/monitor/loginInfor/index.vue +37 -37
  160. package/src/pages/system/monitor/operLog/index.vue +37 -37
  161. package/src/services/api/cas.js +79 -79
  162. package/src/store/modules/setting.js +119 -119
  163. package/src/utils/errorCode.js +6 -6
  164. package//350/277/201/347/247/273/346/227/245/345/277/227.md +15 -15
  165. package/.idea/MarsCodeWorkspaceAppSettings.xml +0 -7
  166. package/.idea/google-java-format.xml +0 -6
  167. package/.idea/inspectionProfiles/Project_Default.xml +0 -24
  168. package/.idea/jsLinters/eslint.xml +0 -6
  169. package/.idea/vue2-client.iml +0 -12
  170. package/.vscode/settings.json +0 -28
@@ -0,0 +1,585 @@
1
+ <script setup>
2
+ import { ref, watch, onMounted } from 'vue'
3
+ import { runLogic, getConfigByName } from '@vue2-client/services/api/common'
4
+
5
+ const props = defineProps({
6
+ queryParamsName: { type: String, default: '' },
7
+ configName: { type: String, default: '' },
8
+ serverName: { type: String, default: 'af-his' },
9
+ logicName: { type: String, default: '' },
10
+ parameter: { type: Object, default: () => ({}) },
11
+ rowKey: { type: String, default: 'id' },
12
+ displayKey: { type: String, default: 'itemName' },
13
+ descriptionKey: { type: String, default: 'itemCode' },
14
+ groupKey: { type: String, default: 'category' },
15
+ groupLabelKey: { type: String, default: 'categoryName' },
16
+ groupCountKey: { type: String, default: 'itemCount' },
17
+ groupItemsKey: { type: String, default: 'items' },
18
+ leftTitle: { type: String, default: '' },
19
+ rightTitle: { type: String, default: '' },
20
+ allText: { type: String, default: 'All' },
21
+ leftWidth: { type: String, default: '324px' },
22
+ rightWidth: { type: String, default: '324px' },
23
+ height: { type: String, default: '143px' },
24
+ initialValue: { type: Array, default: () => [] },
25
+ disabled: { type: Boolean, default: false },
26
+ data: { type: Array, default: null },
27
+ config: { type: Object, default: null },
28
+ env: { type: String, default: 'prod' }
29
+ })
30
+
31
+ const emit = defineEmits(['update:value', 'change', 'loaded'])
32
+
33
+ const loading = ref(false)
34
+ const localValue = ref([])
35
+ const localDataSource = ref([])
36
+ const localGroupDataSource = ref([])
37
+
38
+ const isDev = () => props.env !== 'prod'
39
+
40
+ const totalCount = ref(0)
41
+
42
+ watch(() => props.value, (newVal) => {
43
+ if (newVal !== undefined && JSON.stringify(newVal) !== JSON.stringify(localValue.value)) {
44
+ localValue.value = [...newVal]
45
+ }
46
+ }, { immediate: true })
47
+
48
+ watch(localValue, (newVal) => {
49
+ emit('update:value', newVal)
50
+ })
51
+
52
+ const loadData = async () => {
53
+ loading.value = true
54
+ try {
55
+ let data = []
56
+
57
+ if (props.data && Array.isArray(props.data)) {
58
+ data = props.data
59
+ } else if (props.logicName) {
60
+ data = await loadByLogic()
61
+ } else if (props.queryParamsName || props.configName) {
62
+ await loadByConfig()
63
+ return
64
+ }
65
+
66
+ parseData(data)
67
+ if (props.initialValue.length > 0) {
68
+ localValue.value = [...props.initialValue]
69
+ }
70
+ totalCount.value = localDataSource.value.length
71
+ emit('loaded', {
72
+ dataSource: localDataSource.value,
73
+ groupDataSource: localGroupDataSource.value
74
+ })
75
+ } catch (e) {
76
+ console.error('[XTransfer] Load error:', e)
77
+ } finally {
78
+ loading.value = false
79
+ }
80
+ }
81
+
82
+ const loadByConfig = () => {
83
+ return new Promise((resolve) => {
84
+ const configName = props.queryParamsName || props.configName
85
+ getConfigByName(configName, props.serverName, async (config) => {
86
+ if (!config) {
87
+ loading.value = false
88
+ resolve()
89
+ return
90
+ }
91
+
92
+ if (config.logicName) {
93
+ const data = await loadByLogicWithConfig(config)
94
+ parseData(data)
95
+ if (props.initialValue.length > 0) {
96
+ localValue.value = [...props.initialValue]
97
+ }
98
+ totalCount.value = localDataSource.value.length
99
+ emit('loaded', {
100
+ dataSource: localDataSource.value,
101
+ groupDataSource: localGroupDataSource.value
102
+ })
103
+ } else if (config.data && Array.isArray(config.data)) {
104
+ parseData(config.data)
105
+ }
106
+
107
+ loading.value = false
108
+ resolve()
109
+ }, isDev())
110
+ })
111
+ }
112
+
113
+ const loadByLogicWithConfig = async (config) => {
114
+ const logic = config.logicName || props.logicName
115
+ const params = config.parameter || props.parameter
116
+ const server = config.serverName || props.serverName
117
+
118
+ try {
119
+ const res = await runLogic(logic, params, server, isDev())
120
+ if (res) {
121
+ return Array.isArray(res) ? res : (res.data || res.result || [])
122
+ }
123
+ } catch (e) {
124
+ console.error('[XTransfer] logic error:', e)
125
+ }
126
+ return []
127
+ }
128
+
129
+ const loadByLogic = async () => {
130
+ try {
131
+ const res = await runLogic(props.logicName, props.parameter, props.serverName, isDev())
132
+ if (res) {
133
+ return Array.isArray(res) ? res : (res.data || res.result || [])
134
+ }
135
+ } catch (e) {
136
+ console.error('[XTransfer] logic error:', e)
137
+ }
138
+ return []
139
+ }
140
+
141
+ const parseData = (data) => {
142
+ if (!data || !Array.isArray(data)) {
143
+ localDataSource.value = []
144
+ localGroupDataSource.value = []
145
+ return
146
+ }
147
+
148
+ const firstItem = data[0]
149
+ const hasGroup = firstItem && (firstItem[props.groupKey] || firstItem[props.groupLabelKey])
150
+
151
+ if (hasGroup) {
152
+ localGroupDataSource.value = data.map(group => ({
153
+ key: group[props.rowKey] || group.key,
154
+ label: group[props.groupLabelKey] || group.label || '未命名',
155
+ count: group[props.groupCountKey] || (group[props.groupItemsKey]?.length || 0),
156
+ items: transformItems(group[props.groupItemsKey] || group.items || []),
157
+ _rawData: group
158
+ }))
159
+
160
+ localDataSource.value = []
161
+ data.forEach(group => {
162
+ const items = group[props.groupItemsKey] || group.items || []
163
+ localDataSource.value.push(...transformItems(items))
164
+ })
165
+ } else {
166
+ localDataSource.value = transformItems(data)
167
+ localGroupDataSource.value = []
168
+ }
169
+ }
170
+
171
+ const transformItems = (items) => {
172
+ if (!items || !Array.isArray(items)) return []
173
+
174
+ return items.map((item, index) => ({
175
+ key: String(getNestedValue(item, props.rowKey) || item.key || `item-${index}`),
176
+ title: String(getNestedValue(item, props.displayKey) || item.title || `选项${index + 1}`),
177
+ description: props.descriptionKey ? String(getNestedValue(item, props.descriptionKey) || '') : '',
178
+ disabled: item.disabled === true,
179
+ _rawData: item
180
+ }))
181
+ }
182
+
183
+ const getNestedValue = (obj, path) => {
184
+ if (!path || !obj) return null
185
+ return path.split('.').reduce((acc, part) => {
186
+ if (acc === null || acc === undefined) return null
187
+ return acc[part]
188
+ }, obj)
189
+ }
190
+
191
+ const addItem = (key) => {
192
+ if (props.disabled) return
193
+ if (!localValue.value.includes(key)) {
194
+ localValue.value = [...localValue.value, key]
195
+ emitChange()
196
+ }
197
+ }
198
+
199
+ const removeItem = (key) => {
200
+ if (props.disabled) return
201
+ localValue.value = localValue.value.filter(k => k !== key)
202
+ emitChange()
203
+ }
204
+
205
+ const selectAll = () => {
206
+ if (props.disabled) return
207
+ const allKeys = localDataSource.value.map(item => item.key)
208
+ localValue.value = [...allKeys]
209
+ emitChange()
210
+ }
211
+
212
+ const clearAll = () => {
213
+ if (props.disabled) return
214
+ localValue.value = []
215
+ emitChange()
216
+ }
217
+
218
+ const emitChange = () => {
219
+ emit('change', {
220
+ value: localValue.value,
221
+ data: getSelectedData()
222
+ })
223
+ }
224
+
225
+ const getSelectedData = () => {
226
+ return localValue.value.map(key => {
227
+ const item = localDataSource.value.find(d => d.key === key)
228
+ return item?._rawData
229
+ }).filter(Boolean)
230
+ }
231
+
232
+ const getItemTitle = (key) => {
233
+ const item = localDataSource.value.find(d => d.key === key)
234
+ return item?.title || key
235
+ }
236
+
237
+ const getItemDesc = (key) => {
238
+ const item = localDataSource.value.find(d => d.key === key)
239
+ return item?.description || ''
240
+ }
241
+
242
+ defineExpose({
243
+ loadData,
244
+ getSelectedData,
245
+ getSelectedKeys: () => [...localValue.value],
246
+ clear: clearAll,
247
+ setValue: (keys) => { localValue.value = keys }
248
+ })
249
+
250
+ onMounted(() => {
251
+ loadData()
252
+ })
253
+
254
+ watch(() => [props.queryParamsName, props.logicName, props.config, props.data], () => {
255
+ loadData()
256
+ }, { deep: true })
257
+ </script>
258
+
259
+ <template>
260
+ <div class="x-transfer-component">
261
+ <a-spin :spinning="loading">
262
+ <div class="x-transfer-container">
263
+ <div class="transfer-panel" :style="{ width: leftWidth }">
264
+ <div class="panel-header">
265
+ <span v-if="leftTitle" class="panel-title">{{ leftTitle }}</span>
266
+ </div>
267
+ <div class="panel-body" :style="{ maxHeight: height }">
268
+ <template v-if="localGroupDataSource.length > 0">
269
+ <div
270
+ v-for="group in localGroupDataSource"
271
+ :key="group.key"
272
+ class="group-section"
273
+ >
274
+ <div class="group-label-row">
275
+ <span class="group-label">{{ group.label }}</span>
276
+ <span class="group-count" v-if="group.count > 0">{{ group.count }}</span>
277
+ </div>
278
+ <div class="group-items">
279
+ <div
280
+ v-for="item in group.items"
281
+ :key="item.key"
282
+ class="item-row"
283
+ :class="{ selected: localValue.includes(item.key) }"
284
+ :title="item.title"
285
+ @dblclick="addItem(item.key)"
286
+ >
287
+ <span class="item-title">{{ item.title }}</span>
288
+ <span v-if="item.description" class="item-desc">{{ item.description }}</span>
289
+ <span class="item-arrow"></span>
290
+ </div>
291
+ </div>
292
+ </div>
293
+ </template>
294
+ <template v-else>
295
+ <div
296
+ v-for="item in localDataSource"
297
+ :key="item.key"
298
+ class="item-row"
299
+ :class="{ selected: localValue.includes(item.key) }"
300
+ :title="item.title"
301
+ @dblclick="addItem(item.key)"
302
+ >
303
+ <span class="item-title">{{ item.title }}</span>
304
+ <span v-if="item.description" class="item-desc">{{ item.description }}</span>
305
+ <span class="item-arrow"></span>
306
+ </div>
307
+ </template>
308
+ <a-empty v-if="localDataSource.length === 0 && !loading" />
309
+ </div>
310
+ </div>
311
+
312
+ <div class="transfer-actions">
313
+ <div class="transfer-action-right">
314
+ <div class="action-row">
315
+ <span class="action-text">{{ allText }}</span>
316
+ <span
317
+ class="action-arrow"
318
+ :class="{ disabled: disabled || totalCount === 0 }"
319
+ @click="selectAll"
320
+ >
321
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
322
+ <path d="M9 18l6-6-6-6"/>
323
+ </svg>
324
+ </span>
325
+ </div>
326
+ </div>
327
+ <div class="transfer-action-left">
328
+ <div class="action-row">
329
+ <span class="action-text">{{ allText }}</span>
330
+ <span
331
+ class="action-arrow left"
332
+ :class="{ disabled: disabled || localValue.length === 0 }"
333
+ @click="clearAll"
334
+ >
335
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
336
+ <path d="M15 18l-6-6 6-6"/>
337
+ </svg>
338
+ </span>
339
+ </div>
340
+ </div>
341
+ </div>
342
+
343
+ <div class="transfer-panel" :style="{ width: rightWidth }">
344
+ <div class="panel-header">
345
+ <span v-if="rightTitle" class="panel-title">{{ rightTitle }}</span>
346
+ <span class="panel-count selected" v-if="localValue.length > 0">{{ localValue.length }}</span>
347
+ </div>
348
+ <div class="panel-body" :style="{ maxHeight: height }">
349
+ <div
350
+ v-for="key in localValue"
351
+ :key="key"
352
+ class="item-row selected-item"
353
+ :title="getItemTitle(key)"
354
+ @dblclick="removeItem(key)"
355
+ >
356
+ <span class="item-arrow left-arrow"></span>
357
+ <span class="item-title">{{ getItemTitle(key) }}</span>
358
+ <span v-if="getItemDesc(key)" class="item-desc">{{ getItemDesc(key) }}</span>
359
+ </div>
360
+ <a-empty v-if="localValue.length === 0" />
361
+ </div>
362
+ </div>
363
+ </div>
364
+ </a-spin>
365
+ </div>
366
+ </template>
367
+
368
+ <style scoped>
369
+ .x-transfer-component {
370
+ width: 100%;
371
+ }
372
+
373
+ .x-transfer-container {
374
+ display: flex;
375
+ flex-direction: row;
376
+ gap: 12px;
377
+ align-items: flex-start;
378
+ width: 100%;
379
+ }
380
+
381
+ .transfer-panel {
382
+ width: 324px;
383
+ height: 143px;
384
+ border-radius: 6px;
385
+ opacity: 1;
386
+ box-sizing: border-box;
387
+ border: 1px solid #E5E9F0;
388
+ background: #fff;
389
+ flex: 0 0 auto;
390
+ display: flex;
391
+ flex-direction: column;
392
+ overflow: hidden;
393
+ }
394
+
395
+ .panel-header {
396
+ padding: 0 12px;
397
+ background: #fafafa;
398
+ border-bottom: 1px solid #E5E9F0;
399
+ display: flex;
400
+ align-items: center;
401
+ gap: 8px;
402
+ height: 37px;
403
+ box-sizing: border-box;
404
+ flex-shrink: 0;
405
+ }
406
+
407
+ .panel-title {
408
+ font-size: 14px;
409
+ color: #313131;
410
+ }
411
+
412
+ .panel-count {
413
+ font-size: 12px;
414
+ color: #313131;
415
+ background: #f0f0f0;
416
+ padding: 0 8px;
417
+ border-radius: 10px;
418
+ }
419
+
420
+ .panel-count.selected {
421
+ background: #1890ff;
422
+ color: #fff;
423
+ }
424
+
425
+ .panel-body {
426
+ padding: 0;
427
+ overflow-y: auto;
428
+ flex: 1;
429
+ min-height: 0;
430
+ }
431
+
432
+ .item-row {
433
+ padding: 0 12px;
434
+ border-bottom: 1px solid #E5E9F0;
435
+ cursor: pointer;
436
+ display: flex;
437
+ align-items: center;
438
+ transition: background-color 0.15s;
439
+ user-select: none;
440
+ height: 37px;
441
+ box-sizing: border-box;
442
+ }
443
+
444
+ .item-row:last-child {
445
+ border-bottom: none;
446
+ }
447
+
448
+ .item-row:hover {
449
+ background: #f5f5f5;
450
+ }
451
+
452
+ .item-row.selected {
453
+ background: #e6f7ff;
454
+ }
455
+
456
+ .item-row.selected:hover {
457
+ background: #bae7ff;
458
+ }
459
+
460
+ .item-title {
461
+ font-size: 14px;
462
+ color: #313131;
463
+ flex-shrink: 0;
464
+ }
465
+
466
+ .item-desc {
467
+ font-size: 12px;
468
+ color: #94979E;
469
+ margin-left: 8px;
470
+ flex: 1;
471
+ overflow: hidden;
472
+ text-overflow: ellipsis;
473
+ white-space: nowrap;
474
+ }
475
+
476
+ .item-arrow {
477
+ width: 6px;
478
+ height: 10px;
479
+ background: #94979E;
480
+ flex-shrink: 0;
481
+ margin-left: auto;
482
+ }
483
+
484
+ .item-arrow.left-arrow {
485
+ transform: rotate(180deg);
486
+ margin-left: 0;
487
+ margin-right: auto;
488
+ }
489
+
490
+ .selected-item {
491
+ background: #fff;
492
+ }
493
+
494
+ .selected-item:hover {
495
+ background: #f5f5f5;
496
+ }
497
+
498
+ .transfer-actions {
499
+ display: flex;
500
+ flex-direction: column;
501
+ gap: 8px;
502
+ }
503
+
504
+ .transfer-action-right,
505
+ .transfer-action-left {
506
+ width: 68px;
507
+ height: 70px;
508
+ border: 1px solid #E5E9F0;
509
+ border-radius: 6px;
510
+ background: #FFFFFF;
511
+ box-sizing: border-box;
512
+ display: flex;
513
+ flex-direction: column;
514
+ align-items: center;
515
+ justify-content: center;
516
+ }
517
+
518
+ .action-row {
519
+ display: flex;
520
+ align-items: center;
521
+ justify-content: center;
522
+ gap: 6px;
523
+ }
524
+
525
+ .action-text {
526
+ font-size: 14px;
527
+ color: #313131;
528
+ }
529
+
530
+ .action-arrow {
531
+ width: 10px;
532
+ height: 12px;
533
+ color: #94979E;
534
+ flex-shrink: 0;
535
+ cursor: pointer;
536
+ transition: opacity 0.2s;
537
+ }
538
+
539
+ .action-arrow.left {
540
+ transform: rotate(180deg);
541
+ }
542
+
543
+ .action-arrow:hover {
544
+ opacity: 0.7;
545
+ }
546
+
547
+ .action-arrow.disabled {
548
+ opacity: 0.3;
549
+ cursor: not-allowed;
550
+ }
551
+
552
+ .group-section {
553
+ margin-bottom: 12px;
554
+ }
555
+
556
+ .group-section:last-child {
557
+ margin-bottom: 0;
558
+ }
559
+
560
+ .group-label-row {
561
+ display: flex;
562
+ align-items: center;
563
+ gap: 6px;
564
+ padding: 0 12px;
565
+ height: 37px;
566
+ box-sizing: border-box;
567
+ }
568
+
569
+ .group-label {
570
+ font-size: 14px;
571
+ color: #313131;
572
+ }
573
+
574
+ .group-count {
575
+ font-size: 12px;
576
+ color: #94979E;
577
+ }
578
+
579
+ .group-items {
580
+ border: 1px solid #E5E9F0;
581
+ border-radius: 6px;
582
+ overflow: hidden;
583
+ margin: 0 12px 12px 12px;
584
+ }
585
+ </style>