@utogether/udp-core 2.0.0-beta.24 → 2.0.0-beta.26

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 (155) hide show
  1. package/dist/403-D6Wb3JJh.js +72 -0
  2. package/dist/404-B_HNbPNV.js +72 -0
  3. package/dist/500-BMemTTy1.js +77 -0
  4. package/dist/AuthorityInfo-6wHxwiFM.js +91 -0
  5. package/dist/AuthorityPanel-OqF_DvXA.js +98 -0
  6. package/dist/Company-BLXSfow0.js +21 -0
  7. package/dist/CompanyPanel-B4kRZ5Cg.js +199 -0
  8. package/dist/DataSet-CuGZcKC-.js +141 -0
  9. package/dist/Department-oFhsa7cd.js +21 -0
  10. package/dist/DepartmentPanel-B1UGpu-r.js +242 -0
  11. package/dist/DepartmentPanel-BL58AdoT.js +2 -0
  12. package/dist/DesignPanel-DmkFVw1N.js +1196 -0
  13. package/dist/DictView-CC5yMzOq.js +100 -0
  14. package/dist/File-WJXjGYxr.js +89 -0
  15. package/dist/InvOrganization-BwMmD8Ua.js +76 -0
  16. package/dist/Org-HgnOWubi.js +76 -0
  17. package/dist/Preview-CAzWxLmP.js +45 -0
  18. package/dist/ReIcon-DecitXmg.js +413 -0
  19. package/dist/ReportDefine-BgLM-Rjk.js +10 -0
  20. package/dist/ReportDesign-DwchGG2P.js +158 -0
  21. package/dist/ReportQuery-D5jaRJEn.js +101 -0
  22. package/dist/ReportQueryFrom-CNlmtYey.js +198 -0
  23. package/dist/ReportTemplate-CNcTmccs.js +162 -0
  24. package/dist/Role-Be8WfdCA.js +21 -0
  25. package/dist/RoleAssign-CtehGAUf.js +22 -0
  26. package/dist/RolePanel-CAwITg_q.js +131 -0
  27. package/dist/RolePanel-SN0FGFZ7.js +176 -0
  28. package/dist/ScrollPanel-DW30pGz1.js +88 -0
  29. package/dist/Staff-V2YsNKcj.js +22 -0
  30. package/dist/StaffInfo-CKRPW0r4.js +149 -0
  31. package/dist/StaffPanel-BxcgMg7u.js +143 -0
  32. package/dist/SysUser-Dxyj5w5m.js +12 -0
  33. package/dist/SysUserPanel-DI6CWcZo.js +365 -0
  34. package/dist/SystemMenu-BBHREM8T.js +154 -0
  35. package/dist/UserInfo-BMVQ0xwE.js +194 -0
  36. package/dist/_plugin-vue_export-helper-C6QCLu9I.js +8 -0
  37. package/dist/api-BFNxcxSN.js +30 -0
  38. package/dist/authority-BJFEUdrh.js +20 -0
  39. package/dist/await-to-js.es5-DkWYmPXW.js +10 -0
  40. package/dist/childView-BBjPEraB.js +184 -0
  41. package/dist/childView-DNqG2UVm.js +181 -0
  42. package/dist/code-rule-QFrhqFrW.js +151 -0
  43. package/dist/contant-Q77dU_V3.js +4 -0
  44. package/dist/core.es.js +6 -23
  45. package/dist/cron-task-BpUDKEAU.js +131 -0
  46. package/dist/flow-task-DAc2NrDU.js +11 -0
  47. package/dist/frameView-Di0zJZUR.js +39 -0
  48. package/dist/img/v_img.svg +1 -1
  49. package/dist/layout-home-BVp7vYLR.js +239 -0
  50. package/dist/layoutView-B6Mx2ERA.js +2662 -0
  51. package/dist/log-in-BrNB0mLz.js +117 -0
  52. package/dist/log-out-dYfqvzy6.js +111 -0
  53. package/dist/login-D_Hjy3Jd.js +231 -0
  54. package/dist/login-log-CJak-ANA.js +79 -0
  55. package/dist/lov-view-DM5Nm5tW.js +95 -0
  56. package/dist/menuInfo-BlOY1KZW.js +346 -0
  57. package/dist/mitt-CQgI7DYU.js +27 -0
  58. package/dist/pda-app-CA7YI37u.js +589 -0
  59. package/dist/redirect-N0k4tImU.js +16 -0
  60. package/dist/resource-CfQTHFcs.js +94 -0
  61. package/dist/su-welcome-DVD3S_du.js +799 -0
  62. package/dist/sys-config-Ddb3vBpK.js +316 -0
  63. package/dist/system-Cm3lyBas.js +1528 -0
  64. package/dist/udp-core-DaQd5CF1.js +2028 -0
  65. package/dist/udp-core.css +2 -1
  66. package/dist/useDataThemeChange-DJ4K3VGp.js +226 -0
  67. package/dist/useNav-BhOJIdrJ.js +106 -0
  68. package/dist/utogether-l7JXs4Lv.js +4 -0
  69. package/dist/water-mark-WDQZ9YqB.js +119 -0
  70. package/dist/wecom-push-kWkAVRCj.js +77 -0
  71. package/package.json +1 -1
  72. package/src/App.vue +5 -0
  73. package/src/api/index.ts +51 -51
  74. package/src/components/udp/grid/index.vue +9 -11
  75. package/src/components/udp/index.ts +9 -8
  76. package/src/components/udp/lov/index.vue +430 -0
  77. package/src/components/udp/upload/index.vue +444 -444
  78. package/src/components/udp/utils.ts +420 -414
  79. package/src/main.ts +4 -6
  80. package/src/plugins/vxe-table/index.ts +1 -1
  81. package/src/plugins/vxe-table/render.tsx +999 -998
  82. package/src/router/utils.ts +2 -3
  83. package/src/views/login/login-view.vue +297 -301
  84. package/src/views/ulogin/login.vue +3 -32
  85. package/tsconfig.json +1 -1
  86. package/vite.config.ts +8 -3
  87. package/dist/403-DDCAPCYb.js +0 -65
  88. package/dist/404-BclWW4UB.js +0 -65
  89. package/dist/500-BAggMgTl.js +0 -67
  90. package/dist/AuthorityInfo-liCxYVNc.js +0 -4
  91. package/dist/AuthorityInfo.vue_vue_type_style_index_0_lang-Bd5A4CD-.js +0 -100
  92. package/dist/AuthorityPanel-CRlAwbaI.js +0 -4
  93. package/dist/AuthorityPanel.vue_vue_type_style_index_0_lang-DxhZjp1S.js +0 -114
  94. package/dist/Company-DjaOAaWM.js +0 -25
  95. package/dist/CompanyPanel-Dp_2z717.js +0 -206
  96. package/dist/DataSet-DT-rGICv.js +0 -147
  97. package/dist/Department-Bp5RGbl9.js +0 -25
  98. package/dist/DepartmentPanel-Bg4xM4Lx.js +0 -254
  99. package/dist/DesignPanel-BS2ioHd_.js +0 -4
  100. package/dist/DesignPanel.vue_vue_type_style_index_0_lang-DWwfRVCj.js +0 -1013
  101. package/dist/DictView-pYJXt6IS.js +0 -111
  102. package/dist/InvOrganization-D90gRzlN.js +0 -74
  103. package/dist/Org-Dk4KuIx2.js +0 -39
  104. package/dist/Preview-DpZR6uKs.js +0 -48
  105. package/dist/ReportDefine-PtJnfaLw.js +0 -10
  106. package/dist/ReportDesign-4HWkcTtA.js +0 -165
  107. package/dist/ReportQuery-BPY1lWFn.js +0 -75
  108. package/dist/ReportQueryFrom-CHFlkZ42.js +0 -4
  109. package/dist/ReportQueryFrom.vue_vue_type_style_index_0_lang-DbbQydKz.js +0 -178
  110. package/dist/ReportTemplate-C2F3oy8I.js +0 -161
  111. package/dist/Role-iTP6DYOi.js +0 -25
  112. package/dist/RoleAssign-DIYNHQeF.js +0 -26
  113. package/dist/RolePanel-0ojFIz9G.js +0 -4
  114. package/dist/RolePanel-B0Yr5vjo.js +0 -4
  115. package/dist/RolePanel.vue_vue_type_script_setup_true_lang-CHAj3dCD.js +0 -132
  116. package/dist/RolePanel.vue_vue_type_script_setup_true_lang-CXZBxePU.js +0 -154
  117. package/dist/ScrollPanel.vue_vue_type_style_index_0_lang-DtNzPRjS.js +0 -101
  118. package/dist/Staff-sftZ0bIV.js +0 -26
  119. package/dist/StaffInfo-BG2FMXzR.js +0 -4
  120. package/dist/StaffInfo.vue_vue_type_script_setup_true_lang-DzGn0pYY.js +0 -108
  121. package/dist/StaffPanel-BydqiitC.js +0 -4
  122. package/dist/StaffPanel.vue_vue_type_script_setup_true_lang-C42Pnb-b.js +0 -154
  123. package/dist/SysUser-qMGVHpJ_.js +0 -15
  124. package/dist/SysUserPanel-Bh1HgSAr.js +0 -4
  125. package/dist/SysUserPanel.vue_vue_type_script_setup_true_lang-BBEMYLQN.js +0 -356
  126. package/dist/SystemMenu-DUbWmLip.js +0 -156
  127. package/dist/UserInfo-DNkiTdWm.js +0 -4
  128. package/dist/UserInfo.vue_vue_type_style_index_0_lang-B1eNklEd.js +0 -160
  129. package/dist/await-to-js.es5-Bv3Eu4mi.js +0 -10
  130. package/dist/childView-CjUjh8Da.js +0 -4
  131. package/dist/childView-DT9luEEK.js +0 -4
  132. package/dist/childView.vue_vue_type_style_index_0_lang-CgqosFJQ.js +0 -183
  133. package/dist/childView.vue_vue_type_style_index_0_lang-DkXHMFPd.js +0 -143
  134. package/dist/code-rule-uOazxFfn.js +0 -148
  135. package/dist/cron-task-DEykunjo.js +0 -135
  136. package/dist/flow-task-B07st2aD.js +0 -10
  137. package/dist/frameView-FxzlbkeM.js +0 -44
  138. package/dist/index-BnxyUGKa.js +0 -7944
  139. package/dist/layout-home-C0jme8Ju.js +0 -232
  140. package/dist/layoutView-BqMAHIxF.js +0 -3239
  141. package/dist/log-in-skZaWMBY.js +0 -117
  142. package/dist/log-out-BiND7muW.js +0 -130
  143. package/dist/login-C-184YPO.js +0 -235
  144. package/dist/login-log-BEHYT0v0.js +0 -70
  145. package/dist/lov-view-Df-swRfy.js +0 -99
  146. package/dist/menuInfo-CpyjX4a4.js +0 -4
  147. package/dist/menuInfo.vue_vue_type_style_index_0_lang-D09-OKji.js +0 -363
  148. package/dist/pda-app-DP87aTBc.js +0 -710
  149. package/dist/redirect-BqegffKC.js +0 -15
  150. package/dist/resource-CAldbnw4.js +0 -97
  151. package/dist/su-welcome-DoBUqadB.js +0 -42225
  152. package/dist/sys-config-hGuE7DUf.js +0 -385
  153. package/dist/useNav-Cf_e5pBY.js +0 -92
  154. package/dist/utogether-MlnyYtNS.js +0 -4
  155. package/dist/wecom-push-DR7NsNro.js +0 -70
@@ -1,998 +1,999 @@
1
- /*
2
- * @Author: wei.li
3
- * @Date: 2021-12-01 09:18:50
4
- * @LastEditors: levi7754 levi7754@163.com
5
- * @LastEditTime: 2026-01-30 13:41:29
6
- * @Description: file content
7
- */
8
-
9
- // @ts-nocheck
10
-
11
- import dayjs from 'dayjs';
12
- import { isArray, isEmpty, findTree, isObject, isPlainObject } from 'xe-utils';
13
- import type {
14
- FormItemRenderOptions,
15
- FormItemContentRenderParams,
16
- VxeColumnPropTypes,
17
- VxeGlobalRendererHandles
18
- } from 'vxe-table';
19
-
20
- import { cookies, storageLocal } from '@utogether/utils';
21
-
22
- interface SuFormItemRenderOptions extends FormItemRenderOptions {
23
- sourceData: IRecord;
24
- }
25
- interface SuEditRender extends VxeColumnPropTypes.EditRender {
26
- sourceData: IRecord;
27
- }
28
- interface SuRenderCellOptions extends VxeGlobalRendererHandles.RenderCellOptions {
29
- sourceData: IRecord[];
30
- }
31
-
32
- export const VxetableRender = (VXETable, { serviceApi, i18n }) => {
33
- const dict = storageLocal.getItem('kLov');
34
-
35
- // form render
36
- VXETable.renderer.add('#SuSelect', {
37
- renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
38
- const { row, column } = params;
39
- const { options, props, optionProps = {}, events } = renderOpts;
40
- // @ts-ignore
41
- const { label = 'label', value = 'value' } = optionProps;
42
- const { loading = false, multiple } = props;
43
- const componentHook = useComponent();
44
-
45
- // 多选时
46
- const modelField = multiple ? `_${column.field}` : column.field;
47
- // 默认值
48
- componentHook.setDefaultValue(props, row, column.field);
49
- /**
50
- * @description: 远程搜索对应的函数
51
- * @param {*} val 录入的参数
52
- */
53
- function remoteMethod(query) {
54
- componentHook.remote(query, column.field, renderOpts);
55
- }
56
-
57
- /**
58
- * @description: 选中值发生变化时触发
59
- * @param {*} val 目前的选中值
60
- */
61
- function onChange(val) {
62
- componentHook.selectChange(val, row, column.field, renderOpts, {
63
- column,
64
- datasource: 'row'
65
- });
66
- }
67
-
68
- function onInput(val) {
69
- events?.input && events.input(params, val);
70
- }
71
- /**
72
- * @description: 可清空的单选模式下用户点击清空按钮时触发
73
- */
74
- function onClear() {
75
- componentHook.clear(row, column.field, renderOpts, 'row');
76
- }
77
-
78
- function onFocus() {
79
- !options.length && remoteMethod('');
80
- events?.focus && events.focus(params, column.field);
81
- }
82
-
83
- return [
84
- <el-select
85
- v-model={row[modelField]}
86
- filterable
87
- remote
88
- clearable
89
- placeholder="请录入关键字搜索"
90
- style="width: 100%"
91
- remote-method={remoteMethod}
92
- loading={loading}
93
- {...props}
94
- onFocus={() => onFocus()}
95
- onChange={v => onChange(v)}
96
- onClear={() => onClear()}
97
- onInput={v => onInput(v)}
98
- >
99
- {options.map(item => {
100
- return <el-option key={item[value]} label={item[label]} value={item[value]}></el-option>;
101
- })}
102
- </el-select>
103
- ];
104
- },
105
- // 可编辑显示模板
106
- renderTableCell(renderOpts, params) {
107
- const { row, column } = params;
108
- const { props } = renderOpts;
109
- const { textValue, multiple } = props;
110
- let val = row[column.field];
111
- if (textValue) {
112
- val = eval(`row.${textValue}`) || row[column.field];
113
- }
114
- if (val && multiple && isArray(val)) {
115
- val = val && val.join(',');
116
- }
117
- return [<span>{val}</span>];
118
- },
119
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
120
- const { data, field } = params;
121
- const { options, props, optionProps = {}, events } = renderOpts;
122
- // @ts-ignore
123
- const { label = 'label', value = 'value' } = optionProps;
124
- const { multiple, loading = false } = props;
125
-
126
- const componentHook = useComponent();
127
- // 多选时, model挂载到临时字段上
128
- const modelField = multiple ? `_${field}` : field;
129
- // 默认值
130
- componentHook.setDefaultValue(props, data, field);
131
-
132
- /**
133
- * @description: 远程搜索对应的函数
134
- * @param {*} val 录入的参数
135
- */
136
- async function remoteMethod(query) {
137
- componentHook.remote(query, field, renderOpts);
138
- }
139
-
140
- /**
141
- * @description: 选中值发生变化时触发
142
- * @param {*} val 目前的选中值
143
- */
144
- function onChange(val) {
145
- componentHook.selectChange(val, data, field, renderOpts, {
146
- datasource: 'data'
147
- });
148
- }
149
-
150
- function onInput(val) {
151
- events?.input && events.input(params, val);
152
- }
153
- /**
154
- * @description: 可清空的单选模式下用户点击清空按钮时触发
155
- */
156
- function onClear() {
157
- componentHook.clear(data, field, renderOpts, 'data');
158
- }
159
-
160
- function onFocus() {
161
- !options.length && remoteMethod('');
162
- events?.focus && events.focus(params);
163
- }
164
-
165
- return [
166
- <el-select
167
- v-model={data[modelField]}
168
- filterable
169
- remote
170
- clearable
171
- style="width: 100%"
172
- placeholder="请录入关键字搜索"
173
- loading={loading}
174
- remote-method={remoteMethod}
175
- {...props}
176
- onFocus={() => onFocus()}
177
- onChange={v => onChange(v)}
178
- onClear={() => onClear()}
179
- onInput={() => onInput()}
180
- >
181
- {options.map(item => {
182
- return <el-option key={item[value]} label={item[label]} value={item[value]}></el-option>;
183
- })}
184
- </el-select>
185
- ];
186
- }
187
- });
188
-
189
- // 时间范围
190
- VXETable.renderer.add('#SuDateRange', {
191
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
192
- const { data, field } = params;
193
- const { props } = renderOpts;
194
- if (props?.defaultValue && !data[field]) {
195
- data[field] = props.defaultValue;
196
- props.defaultValue = props.required ? props.defaultValue : null;
197
- }
198
-
199
- const end = new Date();
200
- const shortcuts = [
201
- {
202
- text: i18n('message.udp.today', true),
203
- value: () => [getTime(1, 'day'), end]
204
- },
205
- {
206
- text: i18n('message.udp.yesterday', true),
207
- value: () => [getTime(2, 'day'), getTime(2, 'day')]
208
- },
209
- {
210
- text: i18n('message.udp.lastWeek', true),
211
- value: () => [getTime(7, 'day'), end]
212
- },
213
- {
214
- text: i18n('message.udp.lastMonth', true),
215
- value: () => [getTime(1, 'month'), end]
216
- },
217
- {
218
- text: i18n('message.udp.threeMonth', true),
219
- value: () => [getTime(3, 'month'), end]
220
- },
221
- {
222
- text: i18n('message.udp.halfYear', true),
223
- value: () => [getTime(6, 'month'), end]
224
- },
225
- {
226
- text: i18n('message.udp.anniversary', true),
227
- value: () => [getTime(1, 'year'), end]
228
- }
229
- ];
230
-
231
- const getTime = (offset, type) => {
232
- return dayjs().subtract(offset, type).add('1', 'day').format();
233
- };
234
-
235
- return [
236
- <el-date-picker
237
- v-model={data[field]}
238
- type={props?.type || 'daterange'}
239
- shortcuts={shortcuts}
240
- style="width: 100%"
241
- range-separator={i18n('message.to', true)}
242
- start-placeholder={i18n('message.startDate', true)}
243
- end-placeholder={i18n('message.endDate', true)}
244
- {...props}
245
- />
246
- ];
247
- }
248
- });
249
- // 下拉选择
250
- VXETable.renderer.add('#select', {
251
- renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
252
- const { row, column } = params;
253
- const { options, props, optionProps = {} } = renderOpts;
254
- const { label = 'label', value = 'value' } = optionProps;
255
- const { multiple, isOptionsColumn, optionsColumnField } = props;
256
- console.log('ssssss', renderOpts);
257
- const componentHook = useComponent();
258
-
259
- debugger;
260
-
261
- // 多选时
262
- const modelField = multiple ? `_${column.field}` : column.field;
263
- // 默认值
264
- componentHook.setDefaultValue(props, row, column.field);
265
-
266
- function onChange(val) {
267
- componentHook.selectChange(val, row, column.field, renderOpts, {
268
- column,
269
- datasource: 'row'
270
- });
271
- }
272
-
273
- function onClear() {
274
- componentHook.clear(row, column.field, renderOpts, 'row');
275
- }
276
-
277
- return [
278
- <el-select
279
- v-model={row[modelField]}
280
- filterable
281
- clearable
282
- {...props}
283
- style="width: 100%"
284
- class="udp-select-wrapper"
285
- onChange={v => onChange(v)}
286
- onClear={() => onClear()}
287
- >
288
- {options.map(item => {
289
- return (
290
- <el-option key={item[value]} label={item[label]} value={item[value]}>
291
- {isOptionsColumn ? (
292
- <>
293
- <span style="float: left"> {item[label]} </span>
294
- <span style=" float: right; color: var(--el-text-color-secondary); font-size: 13px">
295
- {item[optionsColumnField] || item[value] || null}
296
- </span>
297
- </>
298
- ) : null}
299
- </el-option>
300
- );
301
- })}
302
- </el-select>
303
- ];
304
- },
305
- renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
306
- const { row, column } = params;
307
- const { options, props, optionProps = {} } = renderOpts;
308
- const { label = 'label', value = 'value' } = optionProps;
309
- const { multiple, isOptionsColumn, optionsColumnField } = props;
310
- console.log('defaultParams');
311
-
312
- const componentHook = useComponent();
313
-
314
- // 多选时
315
- const modelField = multiple ? `_${column.field}` : column.field;
316
- // 默认值
317
- componentHook.setDefaultValue(props, row, column.field);
318
- function onChange(val) {
319
- componentHook.selectChange(val, row, column.field, renderOpts, {
320
- column,
321
- datasource: 'row'
322
- });
323
- }
324
-
325
- function onClear() {
326
- componentHook.clear(row, column.field, renderOpts, 'row');
327
- }
328
-
329
- return [
330
- <el-select
331
- v-model={row[modelField]}
332
- filterable
333
- clearable
334
- {...props}
335
- style="width: 100%"
336
- onChange={v => onChange(v)}
337
- onClear={() => onClear()}
338
- >
339
- {options.map(item => {
340
- return (
341
- <el-option key={item[value]} label={item[label]} value={item[value]}>
342
- {isOptionsColumn ? (
343
- <>
344
- <span style="float: left"> {item[label]} </span>
345
- <span style=" float: right; color: var(--el-text-color-secondary); font-size: 13px">
346
- {item[optionsColumnField || value] || null}
347
- </span>
348
- </>
349
- ) : null}
350
- </el-option>
351
- );
352
- })}
353
- </el-select>
354
- ];
355
- },
356
- // 可编辑显示模板
357
- renderTableCell(renderOpts, params) {
358
- const { row, column } = params;
359
- const { props, options, optionProps } = renderOpts;
360
- // @ts-ignore
361
- const { label = 'label', value = 'value', extLabel } = optionProps;
362
- console.log('defaultParams');
363
- const { textValue } = props;
364
- let val = row[column.field];
365
- const item = options.find(opt => opt[value] === val);
366
- if (textValue) {
367
- val = eval(`row.${textValue}`) || row[column.field];
368
- }
369
- if (item) {
370
- val = extLabel ? item[value] : item[label];
371
- }
372
- if (val && props?.multiple && isArray(val)) {
373
- val = val && val.join(',');
374
- }
375
- return [<span>{val}</span>];
376
- },
377
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
378
- const { data, field } = params;
379
- const { options, props, optionProps = {} } = renderOpts;
380
- const { label = 'label', value = 'value' } = optionProps;
381
-
382
- const { multiple, isOptionsColumn, optionsColumnField } = props;
383
-
384
- const componentHook = useComponent();
385
-
386
- // 多选时, model挂载到临时字段上
387
- const modelField = multiple ? `_${field}` : field;
388
- // 默认值
389
- multiple && componentHook.setDefaultValue(props, data, field);
390
- /**
391
- * @description: 选中值发生变化时触发
392
- * @param {*} val 目前的选中值
393
- */
394
- function onChange(val) {
395
- componentHook.selectChange(val, data, field, renderOpts, {
396
- datasource: 'data'
397
- });
398
- }
399
-
400
- /**
401
- * @description: 可清空的单选模式下用户点击清空按钮时触发
402
- */
403
- function onClear() {
404
- debugger;
405
- componentHook.clear(data, field, renderOpts, 'data');
406
- }
407
-
408
- return [
409
- <el-select
410
- v-model={data[modelField]}
411
- filterable
412
- clearable
413
- style="width: 100%"
414
- {...props}
415
- onChange={v => onChange(v)}
416
- onClear={() => onClear()}
417
- >
418
- {options.map(item => {
419
- return (
420
- <el-option key={item[value]} label={item[label]} value={item[value]}>
421
- {isOptionsColumn ? (
422
- <>
423
- <span style="float: left"> {item[label]} </span>
424
- <span style=" float: right; color: var(--el-text-color-secondary); font-size: 13px">
425
- {item[optionsColumnField || value] || null}
426
- </span>
427
- </>
428
- ) : null}
429
- </el-option>
430
- );
431
- })}
432
- </el-select>
433
- ];
434
- }
435
- });
436
- // 下拉选择
437
- VXETable.renderer.add('#textarea', {
438
- renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
439
- const { row, column } = params;
440
- const { props } = renderOpts;
441
-
442
- const componentHook = useComponent();
443
- function onChange(val) {
444
- componentHook.change(val, row, column.field, renderOpts, { column, datasource: 'row' });
445
- }
446
-
447
- function onClear() {
448
- componentHook.clear(row, column.field, renderOpts, 'row');
449
- }
450
-
451
- return [
452
- <vxe-textarea
453
- v-model={row[column.field]}
454
- {...props}
455
- style="width: 100%"
456
- onChange={v => onChange(v)}
457
- onClear={() => onClear()}
458
- />
459
- ];
460
- },
461
- renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
462
- const { row, column } = params;
463
- const { props } = renderOpts;
464
-
465
- const componentHook = useComponent();
466
-
467
- function onChange(val) {
468
- componentHook.change(val, row, column.field, renderOpts, { column, datasource: 'row' });
469
- }
470
-
471
- function onClear() {
472
- componentHook.clear(row, column.field, renderOpts, 'row');
473
- }
474
-
475
- return [
476
- <vxe-textarea v-model={row[column.field]} {...props} onChange={v => onChange(v)} onClear={() => onClear()} />
477
- ];
478
- },
479
- // 可编辑显示模板
480
- renderTableCell(renderOpts, params) {
481
- const { row, column } = params;
482
- return row[column.field];
483
- },
484
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
485
- const { data, field } = params;
486
- const { props } = renderOpts;
487
- const componentHook = useComponent();
488
-
489
- // 默认值
490
- const { defaultValue } = props;
491
- if (defaultValue) {
492
- data[field] = defaultValue;
493
- }
494
- /**
495
- * @description: 选中值发生变化时触发
496
- * @param {*} val 目前的选中值
497
- */
498
- function onChange(val) {
499
- componentHook.change(val, data, field, renderOpts, { datasource: 'data' });
500
- }
501
-
502
- /**
503
- * @description: 可清空的单选模式下用户点击清空按钮时触发
504
- */
505
- function onClear() {
506
- componentHook.clear(data, field, renderOpts, 'data');
507
- }
508
-
509
- return [<vxe-textarea v-model={data[field]} {...props} onChange={v => onChange(v)} onClear={() => onClear()} />];
510
- }
511
- });
512
- // Lov
513
- VXETable.renderer.add('#lov', {
514
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
515
- const { data, field } = params;
516
- const { props, events } = renderOpts;
517
- const componentHook = useComponent();
518
- // 默认值
519
- const { defaultValues } = props;
520
- if (defaultValues) {
521
- data[field] = defaultValues;
522
- }
523
- /**
524
- * @description: 选中值发生变化时触发
525
- * @param {*} val 目前的选中值
526
- */
527
- function onChange(record, displayField) {
528
- const { mapField, field, displayName, multiple } = props;
529
- if (!multiple) {
530
- const obj = {
531
- [displayName || field]: record[displayField || displayName || field]
532
- };
533
- for (const key in mapField) {
534
- obj[key] = record[mapField[key]];
535
- }
536
- Object.assign(data, obj);
537
- } else if (multiple) {
538
- const obj = {};
539
- data[displayName || field] = record.reduce((curv, prev) => {
540
- for (const key in mapField) {
541
- obj[key] = !curv ? prev[mapField[key]] : obj[key] + ',' + prev[mapField[key]];
542
- }
543
- curv = !curv ? prev[displayName || field] : curv + ',' + prev[displayName || field];
544
- return curv;
545
- }, '');
546
- Object.assign(data, obj);
547
- }
548
- const parm = { data, options: record, field };
549
- events?.change && events.change(parm);
550
- }
551
-
552
- /**
553
- * @description: 点击清空按钮时触发
554
- */
555
- function onClear() {
556
- componentHook.clear(data, field, renderOpts, 'data');
557
- }
558
-
559
- return [
560
- <ut-lov record={data} {...props} mode="vxe" onChange={(v, f) => onChange(v, f)} onClear={() => onClear()} />
561
- ];
562
- },
563
- // 单元格编辑
564
- renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
565
- const { row, column } = params;
566
- const { props, events } = renderOpts;
567
- const componentHook = useComponent();
568
- console.log('lov====');
569
- function onChange(record, displayField) {
570
- const { mapField, field, displayName, multiple } = props;
571
- if (!multiple) {
572
- const obj = {
573
- [displayName || field]: record[displayField || displayName || field]
574
- };
575
- for (const key in mapField) {
576
- obj[key] = record[mapField[key]];
577
- }
578
- Object.assign(row, obj);
579
- }
580
- const params = { row, options: record, field: column.field, column };
581
- events?.change && events.change(params);
582
- }
583
-
584
- function onClear() {
585
- componentHook.clear(row, field, renderOpts, 'row');
586
- }
587
-
588
- return [
589
- <ut-lov
590
- record={row}
591
- mode="vxe"
592
- transfer
593
- {...props}
594
- onChange={(v, f) => onChange(v, f)}
595
- onClear={() => onClear()}
596
- />
597
- ];
598
- },
599
- // 单元格默认
600
- renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
601
- const { row, column } = params;
602
- const { props, events } = renderOpts;
603
- const componentHook = useComponent();
604
- function onChange(record, displayField) {
605
- const { mapField, field, displayName, multiple } = props;
606
- if (!multiple) {
607
- const obj = {
608
- [displayName || field]: record[displayField || displayName || field]
609
- };
610
- for (const key in mapField) {
611
- obj[key] = record[mapField[key]];
612
- }
613
- Object.assign(row, obj);
614
- }
615
- const params = { row, options: record, field: column.field, column };
616
- events?.change && events.change(params);
617
- }
618
- /**
619
- * @description 清空数据
620
- */
621
- function onClear() {
622
- componentHook.clear(row, field, renderOpts, 'row');
623
- }
624
-
625
- return [
626
- <ut-lov record={row} mode="ele" {...props} onChange={(v, f) => onChange(v, f)} onClear={() => onClear()} />
627
- ];
628
- },
629
- // 可编辑显示模板
630
- renderTableCell(renderOpts, params) {
631
- const { row, column } = params;
632
- return [<span>{row[column.field]}</span>];
633
- }
634
- });
635
- // form upload
636
- VXETable.renderer.add('#upload', {
637
- renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
638
- const { row, column } = params;
639
- const { props, events } = renderOpts;
640
- debugger;
641
-
642
- /**
643
- * @description: 点击清空按钮时触发
644
- */
645
- function onClear(file, fielist) {
646
- events?.remove && events?.remove(file, fielist);
647
- }
648
-
649
- return [
650
- <form-upload2
651
- record={row}
652
- field={column.field}
653
- size="mini"
654
- {...props}
655
- render-mode="column"
656
- data-status="edit"
657
- onRemove={(file, fielist) => onClear(file, fielist)}
658
- />
659
- ];
660
- },
661
-
662
- // 可编辑显示模板
663
- renderTableCell(renderOpts, params) {
664
- const { row, column } = params;
665
- const { props } = renderOpts;
666
- debugger;
667
- return [
668
- <form-upload2
669
- record={row}
670
- field={column.field}
671
- size="mini"
672
- {...props}
673
- mode="image"
674
- render-mode="column"
675
- data-status="detail"
676
- />
677
- ];
678
- },
679
- // 默认显示模板
680
- renderDefault(renderOpts, params) {
681
- const { row, column } = params;
682
- const { props } = renderOpts;
683
- return [
684
- <form-upload2
685
- record={row}
686
- field={column.field}
687
- size="mini"
688
- {...props}
689
- mode="image"
690
- render-mode="column"
691
- data-status="detail"
692
- />
693
- ];
694
- },
695
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
696
- const { data, field } = params;
697
- const { props, events } = renderOpts;
698
- /**
699
- * @description: 点击清空按钮时触发
700
- */
701
- function onClear(file, fielist) {
702
- events?.remove && events?.remove(file, fielist);
703
- }
704
-
705
- if (props.singleMode) {
706
- // 单个模式下,限制只能单个上传
707
- Object.assign(props, { multiple: false, limitCount: 1, autoHiddenButton: true });
708
- }
709
- if (!props.mode || props.mode === 'image') {
710
- props.imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'apk'];
711
- }
712
-
713
- console.log({ props });
714
-
715
- return [
716
- <form-upload2
717
- record={data}
718
- field={field}
719
- mode="image"
720
- {...props}
721
- onRemove={(file, fielist) => onClear(file, fielist)}
722
- />
723
- ];
724
- }
725
- });
726
-
727
- // 创建一个简单的超链接渲染
728
- VXETable.renderer.add('#tag', {
729
- // 默认显示模板
730
- renderTableDefault(renderOpts, params) {
731
- const { row, column } = params;
732
- const {
733
- props: { code, tagMap }
734
- } = renderOpts;
735
- function getTagType() {
736
- return row[column.field] ? tagMap[row[column.field]] : null;
737
- }
738
- return [
739
- row[column.field] ? (
740
- <el-tag effect="dark" type={getTagType()}>
741
- {getValue(code, row[column.field])}
742
- </el-tag>
743
- ) : null
744
- ];
745
- }
746
- });
747
-
748
- VXETable.renderer.add('#switch', {
749
- renderTableDefault(renderOpts, params) {
750
- const { row, column } = params;
751
- const {
752
- props: { code, activeValue, inactiveValue },
753
- events
754
- } = renderOpts;
755
- function onChange(value) {
756
- const params = { row, column, value };
757
- events?.change && events.change(params);
758
- }
759
- return [
760
- row[column.field] ? (
761
- <el-switch
762
- v-model={row[column.field]}
763
- inline-prompt
764
- size="large"
765
- style="--el-switch-on-color: #13ce66; --el-switch-off-color: #E6A23C"
766
- {...renderOpts.props}
767
- active-text={getValue(code, activeValue)}
768
- inactive-text={getValue(code, inactiveValue)}
769
- onChange={v => onChange(v)}
770
- />
771
- ) : null
772
- ];
773
- }
774
- });
775
-
776
- VXETable.renderer.add('#iconSelect', {
777
- renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
778
- const { row, column } = params;
779
- return [<SuIconSelect v-model={row[column.field]} teleported={false} />];
780
- },
781
- renderTableCell(renderOpts, params) {
782
- const { row, column } = params;
783
- return [<IconifyIconOffline icon={row[column.field]} style="font-size: 16px;" />];
784
- },
785
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
786
- const { data, field } = params;
787
- return [<SuIconSelect v-model={data[field]} teleported />];
788
- }
789
- });
790
-
791
- VXETable.renderer.add('#treeSelect', {
792
- renderTableEdit(renderOpts: SuEditRender, params) {
793
- const { row, column } = params;
794
- const { props, sourceData, events } = renderOpts;
795
-
796
- return [
797
- <el-tree-select
798
- v-model={row[column.field]}
799
- data={sourceData}
800
- check-strictly
801
- {...props}
802
- filterable
803
- onCheckChange={(node, selected, isLeaf) => onCheckChange(node, selected, isLeaf, events)}
804
- onNodeClick={(data, node, treeNode) => onNodeClick(data, node, treeNode, events)}
805
- onCurrentChange={(data, node) => onCurrentChange(data, node, events)}
806
- />
807
- ];
808
- },
809
- renderTableCell(renderOpts: SuRenderCellOptions, params) {
810
- const { row, column } = params;
811
- const { sourceData, props = {} } = renderOpts;
812
- const { children = 'children', label = 'label' } = props;
813
- const data = findTree(sourceData, item => item['value'] === row[column.field], { children });
814
- return data ? [<span>{data.item[label]}</span>] : null;
815
- },
816
- renderItemContent(renderOpts: SuFormItemRenderOptions, params: FormItemContentRenderParams) {
817
- const { data, field } = params;
818
- const { props, sourceData, events } = renderOpts;
819
- return [
820
- <el-tree-select
821
- v-model={data[field]}
822
- data={sourceData}
823
- check-strictly
824
- {...props}
825
- filterable
826
- onCheckChange={(node, selected, isLeaf) => onCheckChange(node, selected, isLeaf, events)}
827
- onNodeClick={(data, node, treeNode) => onNodeClick(data, node, treeNode, events)}
828
- onCurrentChange={(data, node) => onCurrentChange(data, node, events)}
829
- />
830
- ];
831
- }
832
- });
833
-
834
- /**
835
- * 组件公共方法
836
- * @returns
837
- */
838
- const useComponent = () => {
839
- // 下拉框选择
840
- /**
841
- * select下拉选择change事件
842
- * @param value 选择值
843
- * @param data 数据源
844
- * @param field 字段
845
- * @param renderOpts 渲染参数
846
- * @param opts 数据源类型等
847
- * @return `{ data: 数据源, field: 字段, options?: 选中的选项组, option?: 选中的选项, column?: 列信息 }`
848
- */
849
- const selectChange = (value, data, field, renderOpts, opts) => {
850
- let option = null;
851
-
852
- const { datasource } = opts;
853
- const { options, props, optionProps = {}, events } = renderOpts;
854
-
855
- const callData = { [datasource]: data, field };
856
- // 1、清空原有数据
857
- data[field] = null;
858
- if (!isEmpty(value) && props?.multiple) {
859
- // 2、给实际字段赋值
860
- data[field] = value.join(',');
861
- option = [];
862
- // 多选
863
- value.forEach(item => {
864
- const selectOpt = options.find(opt => item === opt[optionProps?.value]);
865
- if (selectOpt && !isEmpty(props.mapField) && isObject(props.mapField)) {
866
- Object.keys(props.mapField).forEach(key => {
867
- const val = selectOpt[props.mapField[key]];
868
- const ov = data[key] ? data[key].toString() : '';
869
- // 默认用逗号(,)分割
870
- data[key] = ov && !ov.includes(val) ? `${ov},${val}` : val;
871
- });
872
- }
873
- selectOpt && option.push(selectOpt);
874
- });
875
- Object.assign(callData, { options: option });
876
- } else {
877
- // 3、原字段赋值, 多选进来说明必定是空值
878
- data[field] = props?.multiple ? null : value;
879
- option = options.find(opt => value === opt[optionProps?.value]);
880
- if (!isEmpty(props.mapField) && isObject(props.mapField)) {
881
- Object.keys(props.mapField).forEach(key => {
882
- data[key] = option ? option[props.mapField[key]] : null;
883
- });
884
- }
885
- Object.assign(callData, { option });
886
- }
887
- datasource === 'row' && Object.assign(callData, { column: opts.column });
888
- events?.change && events.change(callData);
889
- };
890
- const setDefaultValue = (props, data, field) => {
891
- const { multiple, defaultValue } = props;
892
- // 多选时, model挂载到临时字段上
893
- const modelField = multiple ? `_${field}` : field;
894
- // 默认值
895
- if (!data[field] && defaultValue) {
896
- data[field] = defaultValue;
897
- if (isPlainObject(defaultValue)) {
898
- const keys = Object.keys(defaultValue);
899
- keys.forEach(key => {
900
- data[key] = data[key] || defaultValue[key];
901
- });
902
- }
903
- }
904
- if (!data[modelField] && data[field]) {
905
- data[modelField] = multiple ? data[field]?.split(',') : data[field];
906
- }
907
- };
908
- const remote = async (query, field, renderOpts) => {
909
- const { options, props, events } = renderOpts;
910
- const { fetchField, url, defaultParams = {}, method = 'get' } = props;
911
- const commonParam = getCookieParam();
912
- const params = Object.assign(
913
- { pageSize: 20, pageNum: 1, ...commonParam, ...defaultParams },
914
- { [fetchField || field]: query }
915
- );
916
- if (props.loading) return;
917
- let res;
918
- try {
919
- options.length = 0;
920
- props.loading = true;
921
- res = await serviceApi[method](url, params);
922
- if (events?.filterMethod) {
923
- options.push(...events.filterMethod(res.list || res));
924
- } else if (res) {
925
- res.list ? options.push(...res.list) : options.push(...res);
926
- }
927
- } finally {
928
- props.loading = false;
929
- }
930
- };
931
- // 清除数据
932
- const clear = (data, field, renderOpts, datasource) => {
933
- const { props, events } = renderOpts;
934
- debugger;
935
- const { mapField } = props;
936
- data[field] = null;
937
- if (props?.multiple) {
938
- data[`_${field}`] = [];
939
- }
940
- if (!isEmpty(mapField)) {
941
- for (const key in mapField) {
942
- data[key] = null;
943
- }
944
- }
945
- events?.clear && events.clear({ [datasource]: data, field });
946
- };
947
- const change = (data, field, mapField, events, datasource) => {
948
- data[field] = null;
949
- if (!isEmpty(mapField)) {
950
- for (const key in mapField) {
951
- data[key] = null;
952
- }
953
- }
954
- events?.change && events.change({ [datasource]: data, field });
955
- };
956
- return { clear, change, remote, selectChange, setDefaultValue };
957
- };
958
-
959
- /**
960
- * 当复选框被点击的时候触发
961
- * @param node 传递给 data 属性的数组中该节点所对应的对象
962
- * @param selected 节点本身是否被选中
963
- * @param isLeaf 节点的子树中是否有被选中的节点
964
- */
965
- const onCheckChange = (node, selected, isLeaf, events) => {
966
- console.log(node, selected, isLeaf);
967
- events?.checkChange && events?.checkChange(node, selected, isLeaf);
968
- };
969
- /**
970
- * 节点被点击的时候触发
971
- * @param nodeObject 点击的节点对象
972
- * @param node TreeNode 的 node 属性
973
- * @param treeNode TreeNode
974
- */
975
- const onNodeClick = (nodeObject, node, treeNode, events) => {
976
- events?.checkChange && events?.checkChange(nodeObject, node, treeNode);
977
- };
978
- /**
979
- * 当前选中节点变化时触发的事件
980
- * @param data 当前节点的数据
981
- * @param node 当前节点的 Node 对象
982
- */
983
- const onCurrentChange = (data, node, events) => {
984
- events?.checkChange && events?.checkChange(data, node);
985
- };
986
-
987
- function getValue(code, value) {
988
- if (!value || !code || !dict) return value;
989
- return dict[code]?.children?.find(item => item.dictCode === value)?.dictName;
990
- }
991
-
992
- return VXETable;
993
- };
994
-
995
- const getCookieParam = () => {
996
- const kCOOKIES = 'kCookies_param';
997
- return cookies.get(kCOOKIES) ? JSON.parse(cookies.get(kCOOKIES)) : {};
998
- };
1
+ /*
2
+ * @Author: wei.li
3
+ * @Date: 2021-12-01 09:18:50
4
+ * @LastEditors: levi7754 levi7754@163.com
5
+ * @LastEditTime: 2026-04-07 13:49:25
6
+ * @Description: file content
7
+ */
8
+
9
+ // @ts-nocheck
10
+
11
+ import dayjs from 'dayjs';
12
+ import { isArray, isEmpty, findTree, isObject, isPlainObject } from 'xe-utils';
13
+ import type {
14
+ FormItemRenderOptions,
15
+ FormItemContentRenderParams,
16
+ VxeColumnPropTypes,
17
+ VxeGlobalRendererHandles
18
+ } from 'vxe-table';
19
+
20
+ import { cookies, storageLocal } from '@utogether/utils';
21
+
22
+ interface SuFormItemRenderOptions extends FormItemRenderOptions {
23
+ sourceData: IRecord;
24
+ }
25
+ interface SuEditRender extends VxeColumnPropTypes.EditRender {
26
+ sourceData: IRecord;
27
+ }
28
+ interface SuRenderCellOptions extends VxeGlobalRendererHandles.RenderCellOptions {
29
+ sourceData: IRecord[];
30
+ }
31
+
32
+ export const VxetableRender = (VXETable, { serviceApi, i18n }) => {
33
+ const dict = storageLocal.getItem('kLov');
34
+
35
+ // form render
36
+ VXETable.renderer.add('#SuSelect', {
37
+ renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
38
+ const { row, column } = params;
39
+ const { options, props, optionProps = {}, events } = renderOpts;
40
+ // @ts-ignore
41
+ const { label = 'label', value = 'value' } = optionProps;
42
+ const { loading = false, multiple } = props;
43
+ const componentHook = useComponent();
44
+
45
+ // 多选时
46
+ const modelField = multiple ? `_${column.field}` : column.field;
47
+ // 默认值
48
+ componentHook.setDefaultValue(props, row, column.field);
49
+ /**
50
+ * @description: 远程搜索对应的函数
51
+ * @param {*} val 录入的参数
52
+ */
53
+ function remoteMethod(query) {
54
+ componentHook.remote(query, column.field, renderOpts);
55
+ }
56
+
57
+ /**
58
+ * @description: 选中值发生变化时触发
59
+ * @param {*} val 目前的选中值
60
+ */
61
+ function onChange(val) {
62
+ componentHook.selectChange(val, row, column.field, renderOpts, {
63
+ column,
64
+ datasource: 'row'
65
+ });
66
+ }
67
+
68
+ function onInput(val) {
69
+ events?.input && events.input(params, val);
70
+ }
71
+ /**
72
+ * @description: 可清空的单选模式下用户点击清空按钮时触发
73
+ */
74
+ function onClear() {
75
+ componentHook.clear(row, column.field, renderOpts, 'row');
76
+ }
77
+
78
+ function onFocus() {
79
+ !options.length && remoteMethod('');
80
+ events?.focus && events.focus(params, column.field);
81
+ }
82
+
83
+ return [
84
+ <el-select
85
+ v-model={row[modelField]}
86
+ filterable
87
+ remote
88
+ clearable
89
+ placeholder="请录入关键字搜索"
90
+ style="width: 100%"
91
+ remote-method={remoteMethod}
92
+ loading={loading}
93
+ {...props}
94
+ onFocus={() => onFocus()}
95
+ onChange={v => onChange(v)}
96
+ onClear={() => onClear()}
97
+ onInput={v => onInput(v)}
98
+ >
99
+ {options.map(item => {
100
+ return <el-option key={item[value]} label={item[label]} value={item[value]}></el-option>;
101
+ })}
102
+ </el-select>
103
+ ];
104
+ },
105
+ // 可编辑显示模板
106
+ renderTableCell(renderOpts, params) {
107
+ const { row, column } = params;
108
+ const { props } = renderOpts;
109
+ const { textValue, multiple } = props;
110
+ let val = row[column.field];
111
+ if (textValue) {
112
+ val = eval(`row.${textValue}`) || row[column.field];
113
+ }
114
+ if (val && multiple && isArray(val)) {
115
+ val = val && val.join(',');
116
+ }
117
+ return [<span>{val}</span>];
118
+ },
119
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
120
+ const { data, field } = params;
121
+ const { options, props, optionProps = {}, events } = renderOpts;
122
+ // @ts-ignore
123
+ const { label = 'label', value = 'value' } = optionProps;
124
+ const { multiple, loading = false } = props;
125
+
126
+ const componentHook = useComponent();
127
+ // 多选时, model挂载到临时字段上
128
+ const modelField = multiple ? `_${field}` : field;
129
+ // 默认值
130
+ componentHook.setDefaultValue(props, data, field);
131
+
132
+ /**
133
+ * @description: 远程搜索对应的函数
134
+ * @param {*} val 录入的参数
135
+ */
136
+ async function remoteMethod(query) {
137
+ componentHook.remote(query, field, renderOpts);
138
+ }
139
+
140
+ /**
141
+ * @description: 选中值发生变化时触发
142
+ * @param {*} val 目前的选中值
143
+ */
144
+ function onChange(val) {
145
+ componentHook.selectChange(val, data, field, renderOpts, {
146
+ datasource: 'data'
147
+ });
148
+ }
149
+
150
+ function onInput(val) {
151
+ events?.input && events.input(params, val);
152
+ }
153
+ /**
154
+ * @description: 可清空的单选模式下用户点击清空按钮时触发
155
+ */
156
+ function onClear() {
157
+ componentHook.clear(data, field, renderOpts, 'data');
158
+ }
159
+
160
+ function onFocus() {
161
+ !options.length && remoteMethod('');
162
+ events?.focus && events.focus(params);
163
+ }
164
+
165
+ return [
166
+ <el-select
167
+ v-model={data[modelField]}
168
+ filterable
169
+ remote
170
+ clearable
171
+ style="width: 100%"
172
+ placeholder="请录入关键字搜索"
173
+ loading={loading}
174
+ remote-method={remoteMethod}
175
+ {...props}
176
+ onFocus={() => onFocus()}
177
+ onChange={v => onChange(v)}
178
+ onClear={() => onClear()}
179
+ onInput={() => onInput()}
180
+ >
181
+ {options.map(item => {
182
+ return <el-option key={item[value]} label={item[label]} value={item[value]}></el-option>;
183
+ })}
184
+ </el-select>
185
+ ];
186
+ }
187
+ });
188
+
189
+ // 时间范围
190
+ VXETable.renderer.add('#SuDateRange', {
191
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
192
+ const { data, field } = params;
193
+ const { props } = renderOpts;
194
+ if (props?.defaultValue && !data[field]) {
195
+ data[field] = props.defaultValue;
196
+ props.defaultValue = props.required ? props.defaultValue : null;
197
+ }
198
+
199
+ const end = new Date();
200
+ const shortcuts = [
201
+ {
202
+ text: i18n('message.udp.today', true),
203
+ value: () => [getTime(1, 'day'), end]
204
+ },
205
+ {
206
+ text: i18n('message.udp.yesterday', true),
207
+ value: () => [getTime(2, 'day'), getTime(2, 'day')]
208
+ },
209
+ {
210
+ text: i18n('message.udp.lastWeek', true),
211
+ value: () => [getTime(7, 'day'), end]
212
+ },
213
+ {
214
+ text: i18n('message.udp.lastMonth', true),
215
+ value: () => [getTime(1, 'month'), end]
216
+ },
217
+ {
218
+ text: i18n('message.udp.threeMonth', true),
219
+ value: () => [getTime(3, 'month'), end]
220
+ },
221
+ {
222
+ text: i18n('message.udp.halfYear', true),
223
+ value: () => [getTime(6, 'month'), end]
224
+ },
225
+ {
226
+ text: i18n('message.udp.anniversary', true),
227
+ value: () => [getTime(1, 'year'), end]
228
+ }
229
+ ];
230
+
231
+ const getTime = (offset, type) => {
232
+ return dayjs().subtract(offset, type).add('1', 'day').format();
233
+ };
234
+
235
+ return [
236
+ <el-date-picker
237
+ v-model={data[field]}
238
+ type={props?.type || 'daterange'}
239
+ shortcuts={shortcuts}
240
+ style="width: 100%"
241
+ range-separator={i18n('message.to', true)}
242
+ start-placeholder={i18n('message.startDate', true)}
243
+ end-placeholder={i18n('message.endDate', true)}
244
+ {...props}
245
+ />
246
+ ];
247
+ }
248
+ });
249
+ // 下拉选择
250
+ VXETable.renderer.add('#select', {
251
+ renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
252
+ const { row, column } = params;
253
+ const { options, props, optionProps = {} } = renderOpts;
254
+ const { label = 'label', value = 'value' } = optionProps;
255
+ const { multiple, isOptionsColumn, optionsColumnField } = props;
256
+ console.log('ssssss', renderOpts);
257
+ const componentHook = useComponent();
258
+
259
+ debugger;
260
+
261
+ // 多选时
262
+ const modelField = multiple ? `_${column.field}` : column.field;
263
+ // 默认值
264
+ componentHook.setDefaultValue(props, row, column.field);
265
+
266
+ function onChange(val) {
267
+ componentHook.selectChange(val, row, column.field, renderOpts, {
268
+ column,
269
+ datasource: 'row'
270
+ });
271
+ }
272
+
273
+ function onClear() {
274
+ componentHook.clear(row, column.field, renderOpts, 'row');
275
+ }
276
+
277
+ return [
278
+ <el-select
279
+ v-model={row[modelField]}
280
+ filterable
281
+ clearable
282
+ {...props}
283
+ style="width: 100%"
284
+ class="udp-select-wrapper"
285
+ onChange={v => onChange(v)}
286
+ onClear={() => onClear()}
287
+ >
288
+ {options.map(item => {
289
+ return (
290
+ <el-option key={item[value]} label={item[label]} value={item[value]}>
291
+ {isOptionsColumn ? (
292
+ <>
293
+ <span style="float: left"> {item[label]} </span>
294
+ <span style=" float: right; color: var(--el-text-color-secondary); font-size: 13px">
295
+ {item[optionsColumnField] || item[value] || null}
296
+ </span>
297
+ </>
298
+ ) : null}
299
+ </el-option>
300
+ );
301
+ })}
302
+ </el-select>
303
+ ];
304
+ },
305
+ renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
306
+ const { row, column } = params;
307
+ const { options, props, optionProps = {} } = renderOpts;
308
+ const { label = 'label', value = 'value' } = optionProps;
309
+ const { multiple, isOptionsColumn, optionsColumnField } = props;
310
+ console.log('defaultParams');
311
+
312
+ const componentHook = useComponent();
313
+
314
+ // 多选时
315
+ const modelField = multiple ? `_${column.field}` : column.field;
316
+ // 默认值
317
+ componentHook.setDefaultValue(props, row, column.field);
318
+ function onChange(val) {
319
+ componentHook.selectChange(val, row, column.field, renderOpts, {
320
+ column,
321
+ datasource: 'row'
322
+ });
323
+ }
324
+
325
+ function onClear() {
326
+ componentHook.clear(row, column.field, renderOpts, 'row');
327
+ }
328
+
329
+ return [
330
+ <el-select
331
+ v-model={row[modelField]}
332
+ filterable
333
+ clearable
334
+ {...props}
335
+ style="width: 100%"
336
+ onChange={v => onChange(v)}
337
+ onClear={() => onClear()}
338
+ >
339
+ {options.map(item => {
340
+ return (
341
+ <el-option key={item[value]} label={item[label]} value={item[value]}>
342
+ {isOptionsColumn ? (
343
+ <>
344
+ <span style="float: left"> {item[label]} </span>
345
+ <span style=" float: right; color: var(--el-text-color-secondary); font-size: 13px">
346
+ {item[optionsColumnField || value] || null}
347
+ </span>
348
+ </>
349
+ ) : null}
350
+ </el-option>
351
+ );
352
+ })}
353
+ </el-select>
354
+ ];
355
+ },
356
+ // 可编辑显示模板
357
+ renderTableCell(renderOpts, params) {
358
+ const { row, column } = params;
359
+ const { props, options, optionProps } = renderOpts;
360
+ // @ts-ignore
361
+ const { label = 'label', value = 'value', extLabel } = optionProps;
362
+ console.log('defaultParams');
363
+ const { textValue } = props;
364
+ let val = row[column.field];
365
+ const item = options.find(opt => opt[value] === val);
366
+ if (textValue) {
367
+ val = eval(`row.${textValue}`) || row[column.field];
368
+ }
369
+ if (item) {
370
+ val = extLabel ? item[value] : item[label];
371
+ }
372
+ if (val && props?.multiple && isArray(val)) {
373
+ val = val && val.join(',');
374
+ }
375
+ return [<span>{val}</span>];
376
+ },
377
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
378
+ const { data, field } = params;
379
+ const { options, props, optionProps = {} } = renderOpts;
380
+ const { label = 'label', value = 'value' } = optionProps;
381
+
382
+ const { multiple, isOptionsColumn, optionsColumnField } = props;
383
+
384
+ const componentHook = useComponent();
385
+
386
+ // 多选时, model挂载到临时字段上
387
+ const modelField = multiple ? `_${field}` : field;
388
+ // 默认值
389
+ multiple && componentHook.setDefaultValue(props, data, field);
390
+ /**
391
+ * @description: 选中值发生变化时触发
392
+ * @param {*} val 目前的选中值
393
+ */
394
+ function onChange(val) {
395
+ componentHook.selectChange(val, data, field, renderOpts, {
396
+ datasource: 'data'
397
+ });
398
+ }
399
+
400
+ /**
401
+ * @description: 可清空的单选模式下用户点击清空按钮时触发
402
+ */
403
+ function onClear() {
404
+ debugger;
405
+ componentHook.clear(data, field, renderOpts, 'data');
406
+ }
407
+
408
+ return [
409
+ <el-select
410
+ v-model={data[modelField]}
411
+ filterable
412
+ clearable
413
+ style="width: 100%"
414
+ {...props}
415
+ onChange={v => onChange(v)}
416
+ onClear={() => onClear()}
417
+ >
418
+ {options.map(item => {
419
+ return (
420
+ <el-option key={item[value]} label={item[label]} value={item[value]}>
421
+ {isOptionsColumn ? (
422
+ <>
423
+ <span style="float: left"> {item[label]} </span>
424
+ <span style=" float: right; color: var(--el-text-color-secondary); font-size: 13px">
425
+ {item[optionsColumnField || value] || null}
426
+ </span>
427
+ </>
428
+ ) : null}
429
+ </el-option>
430
+ );
431
+ })}
432
+ </el-select>
433
+ ];
434
+ }
435
+ });
436
+ // 下拉选择
437
+ VXETable.renderer.add('#textarea', {
438
+ renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
439
+ const { row, column } = params;
440
+ const { props } = renderOpts;
441
+
442
+ const componentHook = useComponent();
443
+ function onChange(val) {
444
+ componentHook.change(val, row, column.field, renderOpts, { column, datasource: 'row' });
445
+ }
446
+
447
+ function onClear() {
448
+ componentHook.clear(row, column.field, renderOpts, 'row');
449
+ }
450
+
451
+ return [
452
+ <vxe-textarea
453
+ v-model={row[column.field]}
454
+ {...props}
455
+ style="width: 100%"
456
+ onChange={v => onChange(v)}
457
+ onClear={() => onClear()}
458
+ />
459
+ ];
460
+ },
461
+ renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
462
+ const { row, column } = params;
463
+ const { props } = renderOpts;
464
+
465
+ const componentHook = useComponent();
466
+
467
+ function onChange(val) {
468
+ componentHook.change(val, row, column.field, renderOpts, { column, datasource: 'row' });
469
+ }
470
+
471
+ function onClear() {
472
+ componentHook.clear(row, column.field, renderOpts, 'row');
473
+ }
474
+
475
+ return [
476
+ <vxe-textarea v-model={row[column.field]} {...props} onChange={v => onChange(v)} onClear={() => onClear()} />
477
+ ];
478
+ },
479
+ // 可编辑显示模板
480
+ renderTableCell(renderOpts, params) {
481
+ const { row, column } = params;
482
+ return row[column.field];
483
+ },
484
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
485
+ const { data, field } = params;
486
+ const { props } = renderOpts;
487
+ const componentHook = useComponent();
488
+
489
+ // 默认值
490
+ const { defaultValue } = props;
491
+ if (defaultValue) {
492
+ data[field] = defaultValue;
493
+ }
494
+ /**
495
+ * @description: 选中值发生变化时触发
496
+ * @param {*} val 目前的选中值
497
+ */
498
+ function onChange(val) {
499
+ componentHook.change(val, data, field, renderOpts, { datasource: 'data' });
500
+ }
501
+
502
+ /**
503
+ * @description: 可清空的单选模式下用户点击清空按钮时触发
504
+ */
505
+ function onClear() {
506
+ componentHook.clear(data, field, renderOpts, 'data');
507
+ }
508
+
509
+ return [<vxe-textarea v-model={data[field]} {...props} onChange={v => onChange(v)} onClear={() => onClear()} />];
510
+ }
511
+ });
512
+ // Lov
513
+ VXETable.renderer.add('#lov', {
514
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
515
+ const { data, field } = params;
516
+ const { props, events } = renderOpts;
517
+ const componentHook = useComponent();
518
+ console.log('renderItemContent');
519
+ // 默认值
520
+ const { defaultValues } = props;
521
+ if (defaultValues) {
522
+ data[field] = defaultValues;
523
+ }
524
+ /**
525
+ * @description: 选中值发生变化时触发
526
+ * @param {*} val 目前的选中值
527
+ */
528
+ function onChange(record, displayField) {
529
+ const { mapField, field, displayName, multiple } = props;
530
+ if (!multiple) {
531
+ const obj = {
532
+ [displayName || field]: record[displayField || displayName || field]
533
+ };
534
+ for (const key in mapField) {
535
+ obj[key] = record[mapField[key]];
536
+ }
537
+ Object.assign(data, obj);
538
+ } else if (multiple) {
539
+ const obj = {};
540
+ data[displayName || field] = record.reduce((curv, prev) => {
541
+ for (const key in mapField) {
542
+ obj[key] = !curv ? prev[mapField[key]] : obj[key] + ',' + prev[mapField[key]];
543
+ }
544
+ curv = !curv ? prev[displayName || field] : curv + ',' + prev[displayName || field];
545
+ return curv;
546
+ }, '');
547
+ Object.assign(data, obj);
548
+ }
549
+ const parm = { data, options: record, field };
550
+ events?.change && events.change(parm);
551
+ }
552
+
553
+ /**
554
+ * @description: 点击清空按钮时触发
555
+ */
556
+ function onClear() {
557
+ componentHook.clear(data, field, renderOpts, 'data');
558
+ }
559
+
560
+ return [
561
+ <ut-lov record={data} {...props} mode="vxe" onChange={(v, f) => onChange(v, f)} onClear={() => onClear()} />
562
+ ];
563
+ },
564
+ // 单元格编辑
565
+ renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
566
+ const { row, column } = params;
567
+ const { props, events } = renderOpts;
568
+ const componentHook = useComponent();
569
+ console.log('lov====');
570
+ function onChange(record, displayField) {
571
+ const { mapField, field, displayName, multiple } = props;
572
+ if (!multiple) {
573
+ const obj = {
574
+ [displayName || field]: record[displayField || displayName || field]
575
+ };
576
+ for (const key in mapField) {
577
+ obj[key] = record[mapField[key]];
578
+ }
579
+ Object.assign(row, obj);
580
+ }
581
+ const params = { row, options: record, field: column.field, column };
582
+ events?.change && events.change(params);
583
+ }
584
+
585
+ function onClear() {
586
+ componentHook.clear(row, field, renderOpts, 'row');
587
+ }
588
+
589
+ return [
590
+ <ut-lov
591
+ record={row}
592
+ mode="vxe"
593
+ transfer
594
+ {...props}
595
+ onChange={(v, f) => onChange(v, f)}
596
+ onClear={() => onClear()}
597
+ />
598
+ ];
599
+ },
600
+ // 单元格默认
601
+ renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
602
+ const { row, column } = params;
603
+ const { props, events } = renderOpts;
604
+ const componentHook = useComponent();
605
+ function onChange(record, displayField) {
606
+ const { mapField, field, displayName, multiple } = props;
607
+ if (!multiple) {
608
+ const obj = {
609
+ [displayName || field]: record[displayField || displayName || field]
610
+ };
611
+ for (const key in mapField) {
612
+ obj[key] = record[mapField[key]];
613
+ }
614
+ Object.assign(row, obj);
615
+ }
616
+ const params = { row, options: record, field: column.field, column };
617
+ events?.change && events.change(params);
618
+ }
619
+ /**
620
+ * @description 清空数据
621
+ */
622
+ function onClear() {
623
+ componentHook.clear(row, field, renderOpts, 'row');
624
+ }
625
+
626
+ return [
627
+ <ut-lov record={row} mode="ele" {...props} onChange={(v, f) => onChange(v, f)} onClear={() => onClear()} />
628
+ ];
629
+ },
630
+ // 可编辑显示模板
631
+ renderTableCell(renderOpts, params) {
632
+ const { row, column } = params;
633
+ return [<span>{row[column.field]}</span>];
634
+ }
635
+ });
636
+ // form upload
637
+ VXETable.renderer.add('#upload', {
638
+ renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
639
+ const { row, column } = params;
640
+ const { props, events } = renderOpts;
641
+ debugger;
642
+
643
+ /**
644
+ * @description: 点击清空按钮时触发
645
+ */
646
+ function onClear(file, fielist) {
647
+ events?.remove && events?.remove(file, fielist);
648
+ }
649
+
650
+ return [
651
+ <form-upload2
652
+ record={row}
653
+ field={column.field}
654
+ size="mini"
655
+ {...props}
656
+ render-mode="column"
657
+ data-status="edit"
658
+ onRemove={(file, fielist) => onClear(file, fielist)}
659
+ />
660
+ ];
661
+ },
662
+
663
+ // 可编辑显示模板
664
+ renderTableCell(renderOpts, params) {
665
+ const { row, column } = params;
666
+ const { props } = renderOpts;
667
+ debugger;
668
+ return [
669
+ <form-upload2
670
+ record={row}
671
+ field={column.field}
672
+ size="mini"
673
+ {...props}
674
+ mode="image"
675
+ render-mode="column"
676
+ data-status="detail"
677
+ />
678
+ ];
679
+ },
680
+ // 默认显示模板
681
+ renderDefault(renderOpts, params) {
682
+ const { row, column } = params;
683
+ const { props } = renderOpts;
684
+ return [
685
+ <form-upload2
686
+ record={row}
687
+ field={column.field}
688
+ size="mini"
689
+ {...props}
690
+ mode="image"
691
+ render-mode="column"
692
+ data-status="detail"
693
+ />
694
+ ];
695
+ },
696
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
697
+ const { data, field } = params;
698
+ const { props, events } = renderOpts;
699
+ /**
700
+ * @description: 点击清空按钮时触发
701
+ */
702
+ function onClear(file, fielist) {
703
+ events?.remove && events?.remove(file, fielist);
704
+ }
705
+
706
+ if (props.singleMode) {
707
+ // 单个模式下,限制只能单个上传
708
+ Object.assign(props, { multiple: false, limitCount: 1, autoHiddenButton: true });
709
+ }
710
+ if (!props.mode || props.mode === 'image') {
711
+ props.imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'apk'];
712
+ }
713
+
714
+ console.log({ props });
715
+
716
+ return [
717
+ <form-upload2
718
+ record={data}
719
+ field={field}
720
+ mode="image"
721
+ {...props}
722
+ onRemove={(file, fielist) => onClear(file, fielist)}
723
+ />
724
+ ];
725
+ }
726
+ });
727
+
728
+ // 创建一个简单的超链接渲染
729
+ VXETable.renderer.add('#tag', {
730
+ // 默认显示模板
731
+ renderTableDefault(renderOpts, params) {
732
+ const { row, column } = params;
733
+ const {
734
+ props: { code, tagMap }
735
+ } = renderOpts;
736
+ function getTagType() {
737
+ return row[column.field] ? tagMap[row[column.field]] : null;
738
+ }
739
+ return [
740
+ row[column.field] ? (
741
+ <el-tag effect="dark" type={getTagType()}>
742
+ {getValue(code, row[column.field])}
743
+ </el-tag>
744
+ ) : null
745
+ ];
746
+ }
747
+ });
748
+
749
+ VXETable.renderer.add('#switch', {
750
+ renderTableDefault(renderOpts, params) {
751
+ const { row, column } = params;
752
+ const {
753
+ props: { code, activeValue, inactiveValue },
754
+ events
755
+ } = renderOpts;
756
+ function onChange(value) {
757
+ const params = { row, column, value };
758
+ events?.change && events.change(params);
759
+ }
760
+ return [
761
+ row[column.field] ? (
762
+ <el-switch
763
+ v-model={row[column.field]}
764
+ inline-prompt
765
+ size="large"
766
+ style="--el-switch-on-color: #13ce66; --el-switch-off-color: #E6A23C"
767
+ {...renderOpts.props}
768
+ active-text={getValue(code, activeValue)}
769
+ inactive-text={getValue(code, inactiveValue)}
770
+ onChange={v => onChange(v)}
771
+ />
772
+ ) : null
773
+ ];
774
+ }
775
+ });
776
+
777
+ VXETable.renderer.add('#iconSelect', {
778
+ renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
779
+ const { row, column } = params;
780
+ return [<SuIconSelect v-model={row[column.field]} teleported={false} />];
781
+ },
782
+ renderTableCell(renderOpts, params) {
783
+ const { row, column } = params;
784
+ return [<IconifyIconOffline icon={row[column.field]} style="font-size: 16px;" />];
785
+ },
786
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
787
+ const { data, field } = params;
788
+ return [<SuIconSelect v-model={data[field]} teleported />];
789
+ }
790
+ });
791
+
792
+ VXETable.renderer.add('#treeSelect', {
793
+ renderTableEdit(renderOpts: SuEditRender, params) {
794
+ const { row, column } = params;
795
+ const { props, sourceData, events } = renderOpts;
796
+
797
+ return [
798
+ <el-tree-select
799
+ v-model={row[column.field]}
800
+ data={sourceData}
801
+ check-strictly
802
+ {...props}
803
+ filterable
804
+ onCheckChange={(node, selected, isLeaf) => onCheckChange(node, selected, isLeaf, events)}
805
+ onNodeClick={(data, node, treeNode) => onNodeClick(data, node, treeNode, events)}
806
+ onCurrentChange={(data, node) => onCurrentChange(data, node, events)}
807
+ />
808
+ ];
809
+ },
810
+ renderTableCell(renderOpts: SuRenderCellOptions, params) {
811
+ const { row, column } = params;
812
+ const { sourceData, props = {} } = renderOpts;
813
+ const { children = 'children', label = 'label' } = props;
814
+ const data = findTree(sourceData, item => item['value'] === row[column.field], { children });
815
+ return data ? [<span>{data.item[label]}</span>] : null;
816
+ },
817
+ renderItemContent(renderOpts: SuFormItemRenderOptions, params: FormItemContentRenderParams) {
818
+ const { data, field } = params;
819
+ const { props, sourceData, events } = renderOpts;
820
+ return [
821
+ <el-tree-select
822
+ v-model={data[field]}
823
+ data={sourceData}
824
+ check-strictly
825
+ {...props}
826
+ filterable
827
+ onCheckChange={(node, selected, isLeaf) => onCheckChange(node, selected, isLeaf, events)}
828
+ onNodeClick={(data, node, treeNode) => onNodeClick(data, node, treeNode, events)}
829
+ onCurrentChange={(data, node) => onCurrentChange(data, node, events)}
830
+ />
831
+ ];
832
+ }
833
+ });
834
+
835
+ /**
836
+ * 组件公共方法
837
+ * @returns
838
+ */
839
+ const useComponent = () => {
840
+ // 下拉框选择
841
+ /**
842
+ * select下拉选择change事件
843
+ * @param value 选择值
844
+ * @param data 数据源
845
+ * @param field 字段
846
+ * @param renderOpts 渲染参数
847
+ * @param opts 数据源类型等
848
+ * @return `{ data: 数据源, field: 字段, options?: 选中的选项组, option?: 选中的选项, column?: 列信息 }`
849
+ */
850
+ const selectChange = (value, data, field, renderOpts, opts) => {
851
+ let option = null;
852
+
853
+ const { datasource } = opts;
854
+ const { options, props, optionProps = {}, events } = renderOpts;
855
+
856
+ const callData = { [datasource]: data, field };
857
+ // 1、清空原有数据
858
+ data[field] = null;
859
+ if (!isEmpty(value) && props?.multiple) {
860
+ // 2、给实际字段赋值
861
+ data[field] = value.join(',');
862
+ option = [];
863
+ // 多选
864
+ value.forEach(item => {
865
+ const selectOpt = options.find(opt => item === opt[optionProps?.value]);
866
+ if (selectOpt && !isEmpty(props.mapField) && isObject(props.mapField)) {
867
+ Object.keys(props.mapField).forEach(key => {
868
+ const val = selectOpt[props.mapField[key]];
869
+ const ov = data[key] ? data[key].toString() : '';
870
+ // 默认用逗号(,)分割
871
+ data[key] = ov && !ov.includes(val) ? `${ov},${val}` : val;
872
+ });
873
+ }
874
+ selectOpt && option.push(selectOpt);
875
+ });
876
+ Object.assign(callData, { options: option });
877
+ } else {
878
+ // 3、原字段赋值, 多选进来说明必定是空值
879
+ data[field] = props?.multiple ? null : value;
880
+ option = options.find(opt => value === opt[optionProps?.value]);
881
+ if (!isEmpty(props.mapField) && isObject(props.mapField)) {
882
+ Object.keys(props.mapField).forEach(key => {
883
+ data[key] = option ? option[props.mapField[key]] : null;
884
+ });
885
+ }
886
+ Object.assign(callData, { option });
887
+ }
888
+ datasource === 'row' && Object.assign(callData, { column: opts.column });
889
+ events?.change && events.change(callData);
890
+ };
891
+ const setDefaultValue = (props, data, field) => {
892
+ const { multiple, defaultValue } = props;
893
+ // 多选时, model挂载到临时字段上
894
+ const modelField = multiple ? `_${field}` : field;
895
+ // 默认值
896
+ if (!data[field] && defaultValue) {
897
+ data[field] = defaultValue;
898
+ if (isPlainObject(defaultValue)) {
899
+ const keys = Object.keys(defaultValue);
900
+ keys.forEach(key => {
901
+ data[key] = data[key] || defaultValue[key];
902
+ });
903
+ }
904
+ }
905
+ if (!data[modelField] && data[field]) {
906
+ data[modelField] = multiple ? data[field]?.split(',') : data[field];
907
+ }
908
+ };
909
+ const remote = async (query, field, renderOpts) => {
910
+ const { options, props, events } = renderOpts;
911
+ const { fetchField, url, defaultParams = {}, method = 'get' } = props;
912
+ const commonParam = getCookieParam();
913
+ const params = Object.assign(
914
+ { pageSize: 20, pageNum: 1, ...commonParam, ...defaultParams },
915
+ { [fetchField || field]: query }
916
+ );
917
+ if (props.loading) return;
918
+ let res;
919
+ try {
920
+ options.length = 0;
921
+ props.loading = true;
922
+ res = await serviceApi[method](url, params);
923
+ if (events?.filterMethod) {
924
+ options.push(...events.filterMethod(res.list || res));
925
+ } else if (res) {
926
+ res.list ? options.push(...res.list) : options.push(...res);
927
+ }
928
+ } finally {
929
+ props.loading = false;
930
+ }
931
+ };
932
+ // 清除数据
933
+ const clear = (data, field, renderOpts, datasource) => {
934
+ const { props, events } = renderOpts;
935
+ debugger;
936
+ const { mapField } = props;
937
+ data[field] = null;
938
+ if (props?.multiple) {
939
+ data[`_${field}`] = [];
940
+ }
941
+ if (!isEmpty(mapField)) {
942
+ for (const key in mapField) {
943
+ data[key] = null;
944
+ }
945
+ }
946
+ events?.clear && events.clear({ [datasource]: data, field });
947
+ };
948
+ const change = (data, field, mapField, events, datasource) => {
949
+ data[field] = null;
950
+ if (!isEmpty(mapField)) {
951
+ for (const key in mapField) {
952
+ data[key] = null;
953
+ }
954
+ }
955
+ events?.change && events.change({ [datasource]: data, field });
956
+ };
957
+ return { clear, change, remote, selectChange, setDefaultValue };
958
+ };
959
+
960
+ /**
961
+ * 当复选框被点击的时候触发
962
+ * @param node 传递给 data 属性的数组中该节点所对应的对象
963
+ * @param selected 节点本身是否被选中
964
+ * @param isLeaf 节点的子树中是否有被选中的节点
965
+ */
966
+ const onCheckChange = (node, selected, isLeaf, events) => {
967
+ console.log(node, selected, isLeaf);
968
+ events?.checkChange && events?.checkChange(node, selected, isLeaf);
969
+ };
970
+ /**
971
+ * 节点被点击的时候触发
972
+ * @param nodeObject 点击的节点对象
973
+ * @param node TreeNode 的 node 属性
974
+ * @param treeNode TreeNode
975
+ */
976
+ const onNodeClick = (nodeObject, node, treeNode, events) => {
977
+ events?.checkChange && events?.checkChange(nodeObject, node, treeNode);
978
+ };
979
+ /**
980
+ * 当前选中节点变化时触发的事件
981
+ * @param data 当前节点的数据
982
+ * @param node 当前节点的 Node 对象
983
+ */
984
+ const onCurrentChange = (data, node, events) => {
985
+ events?.checkChange && events?.checkChange(data, node);
986
+ };
987
+
988
+ function getValue(code, value) {
989
+ if (!value || !code || !dict) return value;
990
+ return dict[code]?.children?.find(item => item.dictCode === value)?.dictName;
991
+ }
992
+
993
+ return VXETable;
994
+ };
995
+
996
+ const getCookieParam = () => {
997
+ const kCOOKIES = 'kCookies_param';
998
+ return cookies.get(kCOOKIES) ? JSON.parse(cookies.get(kCOOKIES)) : {};
999
+ };