@utogether/udp-core 1.0.1-beta.9 → 1.0.2

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 (168) hide show
  1. package/build/plugins.ts +37 -39
  2. package/dist/{403-BOzKHdlm.js → 403-B1rIjAAu.js} +6 -6
  3. package/dist/{404-uwgt4Nll.js → 404-mBqc2y4t.js} +4 -4
  4. package/dist/{500-4HBf6V9m.js → 500-BoI45Zdh.js} +2 -2
  5. package/dist/{AuthorityInfo-DvbIh1vT.js → AuthorityInfo-B08NBIIn.js} +1 -1
  6. package/dist/{AuthorityInfo.vue_vue_type_style_index_0_lang-BlCPvwXU.js → AuthorityInfo.vue_vue_type_style_index_0_lang-BLP1SaiH.js} +3 -3
  7. package/dist/{Company-D7Q9BFmr.js → Company-JGGyWEWH.js} +3 -3
  8. package/dist/{CompanyPanel-C0-PJlrt.js → CompanyPanel-BQ_cCmDx.js} +7 -7
  9. package/dist/{Department-h2hlXACv.js → Department-z2iO6hwM.js} +10 -10
  10. package/dist/{DepartmentPanel-B6hDEQpG.js → DepartmentPanel-BtQe7zwU.js} +108 -78
  11. package/dist/{DesignPanel-cS58-1v9.js → DesignPanel-7mhtVWas.js} +1 -1
  12. package/dist/{DesignPanel.vue_vue_type_style_index_0_lang-LdvLC8VU.js → DesignPanel.vue_vue_type_style_index_0_lang-4EsHemj_.js} +6 -6
  13. package/dist/{DictView-T3TmpBa8.js → DictView-CjchV2Yk.js} +15 -16
  14. package/dist/InvOrganization-Pn1O_XP0.js +74 -0
  15. package/dist/{Org-CnCBDGKF.js → Org-BqytV_vi.js} +1 -1
  16. package/dist/{Preview-BaktKXB1.js → Preview-CLpUUMay.js} +2 -2
  17. package/dist/{ReportDefine-5Rb0PO9A.js → ReportDefine-Cz1KtEUF.js} +1 -1
  18. package/dist/{ReportDesign-DYdkVREA.js → ReportDesign-BaORYud4.js} +13 -13
  19. package/dist/{ReportQuery-BwhzIXMt.js → ReportQuery-CPCPXiXz.js} +1 -1
  20. package/dist/{ReportQueryFrom-PHtWwlOe.js → ReportQueryFrom-C_AcrfkJ.js} +1 -1
  21. package/dist/{ReportQueryFrom.vue_vue_type_style_index_0_lang-BE5yZNPM.js → ReportQueryFrom.vue_vue_type_style_index_0_lang-Bm67ejay.js} +1 -1
  22. package/dist/{ReportTemplate-DaadVXIi.js → ReportTemplate-CFiNMz79.js} +11 -11
  23. package/dist/{Role-Dtg3nAmG.js → Role-B-XDoJd5.js} +3 -3
  24. package/dist/{RoleAssign-DEGtLssH.js → RoleAssign-BolW8YVs.js} +8 -8
  25. package/dist/{RolePanel-DpUzfE_o.js → RolePanel-2kfs5tw9.js} +1 -1
  26. package/dist/{RolePanel-CT7BTPmy.js → RolePanel-HilSuYns.js} +1 -1
  27. package/dist/{RolePanel.vue_vue_type_script_setup_true_lang-Xyo0YEI0.js → RolePanel.vue_vue_type_script_setup_true_lang-CE4gApUY.js} +7 -7
  28. package/dist/{RolePanel.vue_vue_type_script_setup_true_lang-Dg2A6DJu.js → RolePanel.vue_vue_type_script_setup_true_lang-DPzgfAyV.js} +13 -13
  29. package/dist/{ScrollPanel.vue_vue_type_style_index_0_lang-CyutzDZS.js → ScrollPanel.vue_vue_type_style_index_0_lang-CCTH4RkH.js} +4 -4
  30. package/dist/{Staff-_NlAGkrh.js → Staff-BTk3whFC.js} +3 -3
  31. package/dist/{StaffInfo-DVgUvVgd.js → StaffInfo-d3AuSzlA.js} +1 -1
  32. package/dist/{StaffInfo.vue_vue_type_script_setup_true_lang-C8hmlFgX.js → StaffInfo.vue_vue_type_script_setup_true_lang-eOL4VlfE.js} +5 -5
  33. package/dist/{StaffPanel-DKNZE3IE.js → StaffPanel-DV-D4jjz.js} +1 -1
  34. package/dist/StaffPanel.vue_vue_type_script_setup_true_lang-4sFq3CEo.js +135 -0
  35. package/dist/{SysUser-kQUf7XKz.js → SysUser-BnjYytws.js} +2 -2
  36. package/dist/{SysUserPanel-C191uX3U.js → SysUserPanel-CBoyD-Qi.js} +1 -1
  37. package/dist/SysUserPanel.vue_vue_type_script_setup_true_lang-PrTlTZR-.js +341 -0
  38. package/dist/{SystemMenu-DwuSvHnj.js → SystemMenu-kYB_ZaUt.js} +36 -36
  39. package/dist/{UserInfo-DIsInFld.js → UserInfo-4dx97VBL.js} +1 -1
  40. package/dist/{UserInfo.vue_vue_type_style_index_0_lang-CnvGdbej.js → UserInfo.vue_vue_type_style_index_0_lang-BpbC_ZDm.js} +10 -10
  41. package/dist/{childView-3Bs2UBEw.js → childView-CHPNfTEb.js} +1 -1
  42. package/dist/{childView-BawyULD7.js → childView-CKA_JgVZ.js} +1 -1
  43. package/dist/{childView.vue_vue_type_style_index_0_lang-YpWF-p2F.js → childView.vue_vue_type_style_index_0_lang-Bym2fQRd.js} +7 -7
  44. package/dist/childView.vue_vue_type_style_index_0_lang-W7bCtXeu.js +177 -0
  45. package/dist/{code-rule-DVaYcn8S.js → code-rule-CbxuZg0-.js} +40 -38
  46. package/dist/core.es.js +18 -12
  47. package/dist/{cron-task-xuzP-BpE.js → cron-task-nTOpqQYf.js} +7 -7
  48. package/dist/flow-task-B07st2aD.js +10 -0
  49. package/dist/{frameView-Cudt06qS.js → frameView-Z1tPUyCh.js} +1 -1
  50. package/dist/index-C3q8HoJM.js +4650 -0
  51. package/dist/{layoutView-BlFTV2jX.js → layoutView--MGA9zUB.js} +1766 -1760
  52. package/dist/{log-in-e7D5Ss1P.js → log-in-CSYJDA6m.js} +36 -29
  53. package/dist/log-out-DiwGCg7p.js +130 -0
  54. package/dist/login-C6Y0ajDp.js +251 -0
  55. package/dist/{login-log-kqKzKTto.js → login-log-C0V-_l3F.js} +5 -3
  56. package/dist/{lov-view-B2HaxyMs.js → lov-view-Cmv7wZZ9.js} +6 -6
  57. package/dist/{menuInfo-BxCTJ1VW.js → menuInfo-UeutJpOa.js} +1 -1
  58. package/dist/{menuInfo.vue_vue_type_style_index_0_lang-CLOPNeUW.js → menuInfo.vue_vue_type_style_index_0_lang-CWX4Mu67.js} +118 -98
  59. package/dist/{pda-app-DPsAFNiw.js → pda-app-B6w99SJo.js} +10 -10
  60. package/dist/{resource-Dibb7t8u.js → resource-BybJvUv0.js} +4 -4
  61. package/dist/{su-welcome-DejR0KkM.js → su-welcome-C1bmxHoY.js} +119 -121
  62. package/dist/sys-config-BnmIDnCj.js +370 -0
  63. package/dist/udp-core.css +1 -9
  64. package/dist/utogether-MlnyYtNS.js +4 -0
  65. package/index.ts +49 -40
  66. package/package.json +18 -18
  67. package/src/App.vue +65 -65
  68. package/src/api/http.ts +1 -4
  69. package/src/api/index.ts +4 -2
  70. package/src/api/user.ts +2 -2
  71. package/src/components/SuCharts/src/UserInfo.vue +78 -78
  72. package/src/components/SuScrollTree/ScrollPanel.vue +1 -6
  73. package/src/components/udp/content/index.vue +88 -0
  74. package/src/components/udp/{form.vue → form/form.vue} +13 -16
  75. package/src/components/udp/{grid.vue → grid/index.vue} +56 -27
  76. package/src/components/udp/index.ts +4 -9
  77. package/src/components/udp/ut-stamp-badge/index.vue +271 -0
  78. package/src/components/udp/utils.ts +66 -105
  79. package/src/layout/components/lay-navbar/index.vue +8 -6
  80. package/src/layout/components/lay-panel/index.vue +150 -150
  81. package/src/layout/components/lay-search/index.vue +25 -25
  82. package/src/layout/components/lay-select-org/index.vue +4 -9
  83. package/src/layout/components/lay-setting/index.vue +503 -510
  84. package/src/layout/components/lay-sidebar/horizontal.vue +8 -6
  85. package/src/layout/components/lay-sidebar/mixNav.vue +260 -258
  86. package/src/layout/components/lay-sidebar/sidebar-logo.vue +101 -98
  87. package/src/layout/components/lay-tag/index.vue +24 -51
  88. package/src/layout/hooks/useDataThemeChange.ts +1 -1
  89. package/src/layout/hooks/useNav.ts +176 -173
  90. package/src/layout/hooks/useTag.ts +227 -233
  91. package/src/layout/types.ts +93 -92
  92. package/src/main.ts +115 -119
  93. package/src/plugins/i18n/en.ts +302 -302
  94. package/src/plugins/i18n/module/u-workflow.ts +1 -1
  95. package/src/plugins/i18n/zh.ts +21 -6
  96. package/src/plugins/vxe-table/index.ts +116 -53
  97. package/src/plugins/vxe-table/render.tsx +945 -956
  98. package/src/router/index.ts +17 -17
  99. package/src/router/modules/flow.ts +35 -0
  100. package/src/router/modules/home.ts +32 -32
  101. package/src/router/modules/remaining.ts +58 -58
  102. package/src/router/utils.ts +420 -377
  103. package/src/store/modules/app.ts +2 -4
  104. package/src/store/modules/epTheme.ts +48 -49
  105. package/src/store/modules/multiTags.ts +15 -14
  106. package/src/store/modules/permission.ts +25 -15
  107. package/src/store/modules/system.ts +1 -3
  108. package/src/style/button.scss +85 -85
  109. package/src/style/login.css +1 -1
  110. package/src/style/vxetable.scss +61 -2
  111. package/src/utils/dataFormat/index.ts +223 -223
  112. package/src/utils/index.ts +3 -1
  113. package/src/utils/lifecycle.ts +39 -20
  114. package/src/utils/propTypes.ts +1 -6
  115. package/src/utils/storage/index.ts +2 -2
  116. package/src/utils/udp/http/index.ts +24 -11
  117. package/src/utils/udp/http/types.d.ts +3 -10
  118. package/src/views/login/login-view.vue +4 -18
  119. package/src/views/organization/company/CompanyPanel.vue +259 -259
  120. package/src/views/organization/department/Department.vue +58 -58
  121. package/src/views/organization/department/DepartmentPanel.vue +303 -283
  122. package/src/views/organization/inv-org/InvOrganization.vue +22 -7
  123. package/src/views/organization/staff/StaffInfo.vue +127 -133
  124. package/src/views/organization/staff/StaffPanel.vue +162 -145
  125. package/src/views/system/cron/cron-task.vue +2 -12
  126. package/src/views/system/menu/SystemMenu.vue +185 -183
  127. package/src/views/system/menu/menuInfo.vue +384 -363
  128. package/src/views/system/role/UserInfo.vue +195 -195
  129. package/src/views/system/role-assign/RoleAssign.vue +57 -57
  130. package/src/views/system/role-assign/RolePanel.vue +139 -139
  131. package/src/views/system/sys/sys-config.vue +69 -20
  132. package/src/views/system/sysUser/SysUserPanel.vue +97 -28
  133. package/src/views/uapp/pda/pda-app.vue +208 -208
  134. package/src/views/udev/coderule/code-rule.vue +132 -121
  135. package/src/views/udev/dict/DictView.vue +2 -2
  136. package/src/views/udev/dict/childView.vue +183 -222
  137. package/src/views/udev/lov/childView.vue +1 -7
  138. package/src/views/udev/lov/lov-view.vue +91 -91
  139. package/src/views/uhome/components/menu-favorite.vue +314 -331
  140. package/src/views/uhome/su-welcome.vue +319 -339
  141. package/src/views/ulogin/login.vue +325 -321
  142. package/src/views/upms/interface/log-in.vue +100 -106
  143. package/src/views/upms/interface/log-out.vue +104 -107
  144. package/src/views/upms/user/login-log.vue +54 -60
  145. package/src/views/urpt/design/DesignPanel.vue +507 -507
  146. package/src/views/urpt/design/Preview.vue +1 -0
  147. package/src/views/urpt/design/ReportDesign.vue +2 -4
  148. package/src/views/utask/flow-task.vue +18 -0
  149. package/types/global.d.ts +231 -236
  150. package/dist/InvOrganization-BVuOhzbt.js +0 -66
  151. package/dist/StaffPanel.vue_vue_type_script_setup_true_lang-BOOO6Cek.js +0 -111
  152. package/dist/SysUserPanel.vue_vue_type_script_setup_true_lang-SwNbAEvW.js +0 -294
  153. package/dist/childView.vue_vue_type_style_index_0_lang-DWIFCX3X.js +0 -187
  154. package/dist/index-CKnq5xIa.js +0 -2623
  155. package/dist/log-out--RRncZhN.js +0 -120
  156. package/dist/login-CpKykfdf.js +0 -253
  157. package/dist/sys-config-DiySRWns.js +0 -277
  158. package/dist/utogether-Dct_14Zk.js +0 -182
  159. package/src/components/udp/count-down.vue +0 -536
  160. package/src/components/udp/flip-down/FlipCard/flip-card.vue +0 -251
  161. package/src/components/udp/flip-down/FlipCard/interfaces.ts +0 -4
  162. package/src/components/udp/flip-down/FlipClock/flip-clock.vue +0 -113
  163. package/src/components/udp/form-upload.vue +0 -482
  164. package/src/components/udp/lov.vue +0 -388
  165. package/src/components/udp/modal-form.vue +0 -189
  166. package/src/components/udp/modal-grid.vue +0 -288
  167. package/src/components/udp/upload.vue +0 -423
  168. package/src/utils/udp/useRender.ts +0 -431
@@ -1,956 +1,945 @@
1
- /*
2
- * @Author: wei.li
3
- * @Date: 2021-12-01 09:18:50
4
- * @LastEditors: levi7754 levi7754@163.com
5
- * @LastEditTime: 2025-08-17 19:04:49
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, mapField } = 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, mapField, events, '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 { mapField, 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, mapField, events, '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 = {}, events } = renderOpts;
254
- const { label = 'label', value = 'value', extLabel } = optionProps;
255
- const { mapField } = props;
256
-
257
- const componentHook = useComponent();
258
-
259
- if (props.multiple && row[column.field] && !isArray(row[column.field])) {
260
- row[column.field].split(',').forEach(dv => {
261
- const isExit = options.some(option => option[label] === dv);
262
- !isExit && options.push({ [value]: dv, [label]: dv });
263
- });
264
- }
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, mapField, events, 'row');
275
- }
276
-
277
- return [
278
- <el-select
279
- v-model={row[column.field]}
280
- filterable
281
- clearable
282
- {...props}
283
- style="width: 100%"
284
- onChange={v => onChange(v)}
285
- onClear={() => onClear()}
286
- >
287
- {options.map(item => {
288
- return (
289
- <el-option
290
- key={item[value]}
291
- label={extLabel && item[extLabel] ? item[value] : item[label]}
292
- value={item[value]}
293
- ></el-option>
294
- );
295
- })}
296
- </el-select>
297
- ];
298
- },
299
- renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
300
- const { row, column } = params;
301
- const { options, props, optionProps = {}, events } = renderOpts;
302
- const { label = 'label', value = 'value', extLabel } = optionProps;
303
- const { mapField } = props;
304
-
305
- const componentHook = useComponent();
306
-
307
- if (props.multiple && row[column.field] && !isArray(row[column.field])) {
308
- row[column.field].split(',').forEach(dv => {
309
- const isExit = options.some(option => option[label] === dv);
310
- !isExit && options.push({ [value]: dv, [label]: dv });
311
- });
312
- }
313
-
314
- function onChange(val) {
315
- componentHook.selectChange(val, row, column.field, renderOpts, {
316
- column,
317
- datasource: 'row'
318
- });
319
- }
320
-
321
- function onClear() {
322
- componentHook.clear(row, column.field, mapField, events, 'row');
323
- }
324
-
325
- return [
326
- <el-select
327
- v-model={row[column.field]}
328
- filterable
329
- clearable
330
- {...props}
331
- style="width: 100%"
332
- onChange={v => onChange(v)}
333
- onClear={() => onClear()}
334
- >
335
- {options.map(item => {
336
- return (
337
- <el-option
338
- key={item[value]}
339
- label={extLabel && item[extLabel] ? item[value] : item[label]}
340
- value={item[value]}
341
- ></el-option>
342
- );
343
- })}
344
- </el-select>
345
- ];
346
- },
347
- // 可编辑显示模板
348
- renderTableCell(renderOpts, params) {
349
- const { row, column } = params;
350
- const { props, options, optionProps } = renderOpts;
351
- // @ts-ignore
352
- const { label = 'label', value = 'value', extLabel } = optionProps;
353
- const { textValue } = props;
354
- let val = row[column.field];
355
- const item = options.find(opt => opt[value] === val);
356
- if (textValue) {
357
- val = eval(`row.${textValue}`) || row[column.field];
358
- }
359
- if (item) {
360
- val = extLabel ? item[value] : item[label];
361
- }
362
- if (val && props?.multiple && isArray(val)) {
363
- val = val && val.join(',');
364
- }
365
- return [<span>{val}</span>];
366
- },
367
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
368
- const { data, field } = params;
369
- const { options, props, optionProps = {}, events } = renderOpts;
370
- const { label = 'label', value = 'value' } = optionProps;
371
-
372
- const { mapField, multiple } = props;
373
-
374
- const componentHook = useComponent();
375
-
376
- // 多选时, model挂载到临时字段上
377
- const modelField = multiple ? `_${field}` : field;
378
- // 默认值
379
- componentHook.setDefaultValue(props, data, field);
380
- /**
381
- * @description: 选中值发生变化时触发
382
- * @param {*} val 目前的选中值
383
- */
384
- function onChange(val) {
385
- componentHook.selectChange(val, data, field, renderOpts, {
386
- datasource: 'data'
387
- });
388
- }
389
-
390
- /**
391
- * @description: 可清空的单选模式下用户点击清空按钮时触发
392
- */
393
- function onClear() {
394
- componentHook.clear(data, field, mapField, events, 'data');
395
- }
396
-
397
- return [
398
- <el-select
399
- v-model={data[modelField]}
400
- filterable
401
- clearable
402
- style="width: 100%"
403
- {...props}
404
- onChange={v => onChange(v)}
405
- onClear={() => onClear()}
406
- >
407
- {options.map(item => {
408
- return <el-option key={item[value]} label={item[label]} value={item[value]}></el-option>;
409
- })}
410
- </el-select>
411
- ];
412
- }
413
- });
414
- // 下拉选择
415
- VXETable.renderer.add('#textarea', {
416
- renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
417
- const { row, column } = params;
418
- const { props, events } = renderOpts;
419
- const { mapField } = props;
420
-
421
- const componentHook = useComponent();
422
- function onChange(val) {
423
- componentHook.change(val, row, column.field, renderOpts, { column, datasource: 'row' });
424
- }
425
-
426
- function onClear() {
427
- componentHook.clear(row, column.field, mapField, events, 'row');
428
- }
429
-
430
- return [
431
- <vxe-textarea
432
- v-model={row[column.field]}
433
- {...props}
434
- style="width: 100%"
435
- onChange={v => onChange(v)}
436
- onClear={() => onClear()}
437
- />
438
- ];
439
- },
440
- renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
441
- const { row, column } = params;
442
- const { props, events } = renderOpts;
443
- const { mapField } = props;
444
-
445
- const componentHook = useComponent();
446
-
447
- function onChange(val) {
448
- componentHook.change(val, row, column.field, renderOpts, { column, datasource: 'row' });
449
- }
450
-
451
- function onClear() {
452
- componentHook.clear(row, column.field, mapField, events, 'row');
453
- }
454
-
455
- return [
456
- <vxe-textarea v-model={row[column.field]} {...props} onChange={v => onChange(v)} onClear={() => onClear()} />
457
- ];
458
- },
459
- // 可编辑显示模板
460
- renderTableCell(renderOpts, params) {
461
- const { row, column } = params;
462
- return row[column.field];
463
- },
464
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
465
- const { data, field } = params;
466
- const { props, events } = renderOpts;
467
- const componentHook = useComponent();
468
-
469
- // 默认值
470
- const { defaultValue, mapField } = props;
471
- if (defaultValue) {
472
- data[field] = defaultValue;
473
- }
474
- /**
475
- * @description: 选中值发生变化时触发
476
- * @param {*} val 目前的选中值
477
- */
478
- function onChange(val) {
479
- componentHook.change(val, data, field, renderOpts, { datasource: 'data' });
480
- }
481
-
482
- /**
483
- * @description: 可清空的单选模式下用户点击清空按钮时触发
484
- */
485
- function onClear() {
486
- componentHook.clear(data, field, mapField, events, 'data');
487
- }
488
-
489
- return [<vxe-textarea v-model={data[field]} {...props} onChange={v => onChange(v)} onClear={() => onClear()} />];
490
- }
491
- });
492
- // Lov
493
- VXETable.renderer.add('#lov', {
494
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
495
- const { data, field } = params;
496
- const { props, events } = renderOpts;
497
- const componentHook = useComponent();
498
- // 默认值
499
- const { defaultValues, mapField } = props;
500
- if (defaultValues) {
501
- data[field] = defaultValues;
502
- }
503
- /**
504
- * @description: 选中值发生变化时触发
505
- * @param {*} val 目前的选中值
506
- */
507
- function onChange(record, displayField) {
508
- const { mapField, field, displayName, multiple } = props;
509
- if (!multiple) {
510
- const obj = {
511
- [displayName || field]: record[displayField || displayName || field]
512
- };
513
- for (const key in mapField) {
514
- obj[key] = record[mapField[key]];
515
- }
516
- Object.assign(data, obj);
517
- } else if (multiple) {
518
- const obj = {};
519
- data[displayName || field] = record.reduce((curv, prev) => {
520
- for (const key in mapField) {
521
- obj[key] = !curv ? prev[mapField[key]] : obj[key] + ',' + prev[mapField[key]];
522
- }
523
- curv = !curv ? prev[displayName || field] : curv + ',' + prev[displayName || field];
524
- return curv;
525
- }, '');
526
- Object.assign(data, obj);
527
- }
528
- const parm = { data, options: record, field };
529
- events?.change && events.change(parm);
530
- }
531
-
532
- /**
533
- * @description: 点击清空按钮时触发
534
- */
535
- function onClear() {
536
- componentHook.clear(data, field, mapField, events, 'data');
537
- }
538
-
539
- return [
540
- <ut-lov record={data} {...props} mode="vxe" onChange={(v, f) => onChange(v, f)} onClear={() => onClear()} />
541
- ];
542
- },
543
- // 单元格编辑
544
- renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
545
- const { row, column } = params;
546
- const { props, events } = renderOpts;
547
- const componentHook = useComponent();
548
- console.log('lov====');
549
- function onChange(record, displayField) {
550
- const { mapField, field, displayName, multiple } = props;
551
- if (!multiple) {
552
- const obj = {
553
- [displayName || field]: record[displayField || displayName || field]
554
- };
555
- for (const key in mapField) {
556
- obj[key] = record[mapField[key]];
557
- }
558
- Object.assign(row, obj);
559
- }
560
- const params = { row, options: record, field: column.field, column };
561
- events?.change && events.change(params);
562
- }
563
-
564
- function onClear() {
565
- componentHook.clear(row, field, mapField, events, 'row');
566
- }
567
-
568
- return [
569
- <ut-lov
570
- record={row}
571
- mode="vxe"
572
- transfer
573
- {...props}
574
- onChange={(v, f) => onChange(v, f)}
575
- onClear={() => onClear()}
576
- />
577
- ];
578
- },
579
- // 单元格默认
580
- renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
581
- const { row, column } = params;
582
- const { props, events } = renderOpts;
583
- const componentHook = useComponent();
584
- function onChange(record, displayField) {
585
- const { mapField, field, displayName, multiple } = props;
586
- if (!multiple) {
587
- const obj = {
588
- [displayName || field]: record[displayField || displayName || field]
589
- };
590
- for (const key in mapField) {
591
- obj[key] = record[mapField[key]];
592
- }
593
- Object.assign(row, obj);
594
- }
595
- const params = { row, options: record, field: column.field, column };
596
- events?.change && events.change(params);
597
- }
598
- /**
599
- * @description 清空数据
600
- */
601
- function onClear() {
602
- componentHook.clear(row, field, mapField, events, 'row');
603
- }
604
-
605
- return [
606
- <ut-lov record={row} mode="ele" {...props} onChange={(v, f) => onChange(v, f)} onClear={() => onClear()} />
607
- ];
608
- },
609
- // 可编辑显示模板
610
- renderTableCell(renderOpts, params) {
611
- const { row, column } = params;
612
- return [<span>{row[column.field]}</span>];
613
- }
614
- });
615
- // form upload
616
- VXETable.renderer.add('#upload', {
617
- renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
618
- const { row, column } = params;
619
- const { props, events } = renderOpts;
620
-
621
- /**
622
- * @description: 点击清空按钮时触发
623
- */
624
- function onClear(file, fielist) {
625
- row[column.field] = '';
626
- events?.remove && events?.remove(file, fielist);
627
- }
628
-
629
- return [
630
- <form-upload2
631
- record={row}
632
- field={column.field}
633
- size="mini"
634
- {...props}
635
- render-mode="column"
636
- data-status="edit"
637
- onRemove={(file, fielist) => onClear(file, fielist)}
638
- />
639
- ];
640
- },
641
-
642
- // 可编辑显示模板
643
- renderTableCell(renderOpts, params) {
644
- const { row, column } = params;
645
- const { props } = renderOpts;
646
- return [
647
- <form-upload2
648
- record={row}
649
- field={column.field}
650
- size="mini"
651
- {...props}
652
- mode="image"
653
- render-mode="column"
654
- data-status="detail"
655
- />
656
- ];
657
- },
658
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
659
- const { data, field } = params;
660
- const { props, events } = renderOpts;
661
- /**
662
- * @description: 点击清空按钮时触发
663
- */
664
- function onClear(file, fielist) {
665
- data[field] = '';
666
- events?.remove && events?.remove(file, fielist);
667
- }
668
-
669
- if (props.singleMode) {
670
- // 单个模式下,限制只能单个上传
671
- Object.assign(props, { multiple: false, limitCount: 1, autoHiddenButton: true });
672
- }
673
- if (!props.mode || props.mode === 'image') {
674
- props.imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'apk'];
675
- }
676
-
677
- console.log({ props });
678
-
679
- return [
680
- <form-upload2
681
- record={data}
682
- field={field}
683
- mode="image"
684
- {...props}
685
- onRemove={(file, fielist) => onClear(file, fielist)}
686
- />
687
- ];
688
- }
689
- });
690
-
691
- // 创建一个简单的超链接渲染
692
- VXETable.renderer.add('#tag', {
693
- // 默认显示模板
694
- renderTableDefault(renderOpts, params) {
695
- const { row, column } = params;
696
- const {
697
- props: { code, tagMap }
698
- } = renderOpts;
699
- function getTagType() {
700
- return row[column.field] ? tagMap[row[column.field]] : null;
701
- }
702
- return [
703
- row[column.field] ? (
704
- <el-tag effect="dark" type={getTagType()}>
705
- {getValue(code, row[column.field])}
706
- </el-tag>
707
- ) : null
708
- ];
709
- }
710
- });
711
-
712
- VXETable.renderer.add('#switch', {
713
- renderTableDefault(renderOpts, params) {
714
- const { row, column } = params;
715
- const {
716
- props: { code, activeValue, inactiveValue },
717
- events
718
- } = renderOpts;
719
- function onChange(value) {
720
- const params = { row, column, value };
721
- events?.change && events.change(params);
722
- }
723
- return [
724
- row[column.field] ? (
725
- <el-switch
726
- v-model={row[column.field]}
727
- inline-prompt
728
- size="large"
729
- style="--el-switch-on-color: #13ce66; --el-switch-off-color: #E6A23C"
730
- {...renderOpts.props}
731
- active-text={getValue(code, activeValue)}
732
- inactive-text={getValue(code, inactiveValue)}
733
- onChange={v => onChange(v)}
734
- />
735
- ) : null
736
- ];
737
- }
738
- });
739
-
740
- VXETable.renderer.add('#iconSelect', {
741
- renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
742
- const { row, column } = params;
743
- return [<SuIconSelect v-model={row[column.field]} teleported={false} />];
744
- },
745
- renderTableCell(renderOpts, params) {
746
- const { row, column } = params;
747
- return [<IconifyIconOffline icon={row[column.field]} style="font-size: 16px;" />];
748
- },
749
- renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
750
- const { data, field } = params;
751
- return [<SuIconSelect v-model={data[field]} teleported />];
752
- }
753
- });
754
-
755
- VXETable.renderer.add('#treeSelect', {
756
- renderTableEdit(renderOpts: SuEditRender, params) {
757
- const { row, column } = params;
758
- const { props, sourceData, events } = renderOpts;
759
-
760
- return [
761
- <el-tree-select
762
- v-model={row[column.field]}
763
- data={sourceData}
764
- check-strictly
765
- {...props}
766
- filterable
767
- onCheckChange={(node, selected, isLeaf) => onCheckChange(node, selected, isLeaf, events)}
768
- onNodeClick={(data, node, treeNode) => onNodeClick(data, node, treeNode, events)}
769
- onCurrentChange={(data, node) => onCurrentChange(data, node, events)}
770
- />
771
- ];
772
- },
773
- renderTableCell(renderOpts: SuRenderCellOptions, params) {
774
- const { row, column } = params;
775
- const { sourceData, props = {} } = renderOpts;
776
- const { children = 'children', label = 'label' } = props;
777
- const data = findTree(sourceData, item => item['value'] === row[column.field], { children });
778
- return data ? [<span>{data.item[label]}</span>] : null;
779
- },
780
- renderItemContent(renderOpts: SuFormItemRenderOptions, params: FormItemContentRenderParams) {
781
- const { data, field } = params;
782
- const { props, sourceData, events } = renderOpts;
783
- return [
784
- <el-tree-select
785
- v-model={data[field]}
786
- data={sourceData}
787
- check-strictly
788
- {...props}
789
- filterable
790
- onCheckChange={(node, selected, isLeaf) => onCheckChange(node, selected, isLeaf, events)}
791
- onNodeClick={(data, node, treeNode) => onNodeClick(data, node, treeNode, events)}
792
- onCurrentChange={(data, node) => onCurrentChange(data, node, events)}
793
- />
794
- ];
795
- }
796
- });
797
-
798
- /**
799
- * 组件公共方法
800
- * @returns
801
- */
802
- const useComponent = () => {
803
- // 下拉框选择
804
- /**
805
- * select下拉选择change事件
806
- * @param value 选择值
807
- * @param data 数据源
808
- * @param field 字段
809
- * @param renderOpts 渲染参数
810
- * @param opts 数据源类型等
811
- * @return `{ data: 数据源, field: 字段, options?: 选中的选项组, option?: 选中的选项, column?: 列信息 }`
812
- */
813
- const selectChange = (value, data, field, renderOpts, opts) => {
814
- let option = null;
815
-
816
- const { datasource } = opts;
817
- const { options, props, optionProps = {}, events } = renderOpts;
818
-
819
- const callData = { [datasource]: data, field };
820
- // 1、清空原有数据
821
- data[field] = null;
822
- if (!isEmpty(value) && props?.multiple) {
823
- // 2、给实际字段赋值
824
- data[field] = value.join(',');
825
- option = [];
826
- // 多选
827
- value.forEach(item => {
828
- const selectOpt = options.find(opt => item === opt[optionProps?.value]);
829
- if (selectOpt && !isEmpty(props.mapField) && isObject(props.mapField)) {
830
- Object.keys(props.mapField).forEach(key => {
831
- const val = selectOpt[props.mapField[key]];
832
- const ov = data[key] ? data[key].toString() : '';
833
- // 默认用逗号(,)分割
834
- data[key] = ov && !ov.includes(val) ? `${ov},${val}` : val;
835
- });
836
- }
837
- selectOpt && option.push(selectOpt);
838
- });
839
- Object.assign(callData, { options: option });
840
- } else {
841
- // 3、原字段赋值, 多选进来说明必定是空值
842
- data[field] = props?.multiple ? null : value;
843
- option = options.find(opt => value === opt[optionProps?.value]);
844
- if (!isEmpty(props.mapField) && isObject(props.mapField)) {
845
- Object.keys(props.mapField).forEach(key => {
846
- data[key] = option ? option[props.mapField[key]] : null;
847
- });
848
- }
849
- Object.assign(callData, { option });
850
- }
851
- datasource === 'row' && Object.assign(callData, { column: opts.column });
852
- events?.change && events.change(callData);
853
- };
854
- const setDefaultValue = (props, data, field) => {
855
- const { multiple, defaultValue } = props;
856
- // 多选时, model挂载到临时字段上
857
- const modelField = multiple ? `_${field}` : field;
858
- // 默认值
859
- if (!data[field] && defaultValue) {
860
- data[field] = defaultValue;
861
- if (isPlainObject(defaultValue)) {
862
- const keys = Object.keys(defaultValue);
863
- keys.forEach(key => {
864
- data[key] = data[key] || defaultValue[key];
865
- });
866
- }
867
- }
868
- if (!data[modelField] && data[field]) {
869
- data[modelField] = multiple ? data[field]?.split(',') : data[field];
870
- }
871
- };
872
- const remote = async (query, field, renderOpts) => {
873
- const { options, props, events } = renderOpts;
874
- const { fetchField, url, defaultParams = {}, method = 'get' } = props;
875
- const commonParam = getCookieParam();
876
- const params = Object.assign(
877
- { pageSize: 20, pageNum: 1, ...commonParam, ...defaultParams },
878
- { [fetchField || field]: query }
879
- );
880
- if (props.loading) return;
881
- let res;
882
- try {
883
- options.length = 0;
884
- props.loading = true;
885
- res = await serviceApi[method](url, params);
886
- if (events?.filterMethod) {
887
- options.push(...events.filterMethod(res.list || res));
888
- } else if (res) {
889
- res.list ? options.push(...res.list) : options.push(...res);
890
- }
891
- } finally {
892
- props.loading = false;
893
- }
894
- };
895
- // 清除数据
896
- const clear = (data, field, mapField, events, datasource) => {
897
- data[field] = null;
898
- if (!isEmpty(mapField)) {
899
- for (const key in mapField) {
900
- data[key] = null;
901
- }
902
- }
903
- events?.clear && events.clear({ [datasource]: data, field });
904
- };
905
- const change = (data, field, mapField, events, datasource) => {
906
- data[field] = null;
907
- if (!isEmpty(mapField)) {
908
- for (const key in mapField) {
909
- data[key] = null;
910
- }
911
- }
912
- events?.change && events.change({ [datasource]: data, field });
913
- };
914
- return { clear, change, remote, selectChange, setDefaultValue };
915
- };
916
-
917
- /**
918
- * 当复选框被点击的时候触发
919
- * @param node 传递给 data 属性的数组中该节点所对应的对象
920
- * @param selected 节点本身是否被选中
921
- * @param isLeaf 节点的子树中是否有被选中的节点
922
- */
923
- const onCheckChange = (node, selected, isLeaf, events) => {
924
- console.log(node, selected, isLeaf);
925
- events?.checkChange && events?.checkChange(node, selected, isLeaf);
926
- };
927
- /**
928
- * 节点被点击的时候触发
929
- * @param nodeObject 点击的节点对象
930
- * @param node TreeNode node 属性
931
- * @param treeNode TreeNode
932
- */
933
- const onNodeClick = (nodeObject, node, treeNode, events) => {
934
- events?.checkChange && events?.checkChange(nodeObject, node, treeNode);
935
- };
936
- /**
937
- * 当前选中节点变化时触发的事件
938
- * @param data 当前节点的数据
939
- * @param node 当前节点的 Node 对象
940
- */
941
- const onCurrentChange = (data, node, events) => {
942
- events?.checkChange && events?.checkChange(data, node);
943
- };
944
-
945
- function getValue(code, value) {
946
- if (!value || !code || !dict) return value;
947
- return dict[code]?.children?.find(item => item.dictCode === value)?.dictName;
948
- }
949
-
950
- return VXETable;
951
- };
952
-
953
- const getCookieParam = () => {
954
- const kCOOKIES = 'kCookies_param';
955
- return cookies.get(kCOOKIES) ? JSON.parse(cookies.get(kCOOKIES)) : {};
956
- };
1
+ /*
2
+ * @Author: wei.li
3
+ * @Date: 2021-12-01 09:18:50
4
+ * @LastEditors: levi7754 levi7754@163.com
5
+ * @LastEditTime: 2025-10-29 16:48:47
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, mapField } = 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, mapField, events, '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 { mapField, 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, mapField, events, '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 = {}, events } = renderOpts;
254
+ const { label = 'label', value = 'value' } = optionProps;
255
+ const { mapField, multiple } = props;
256
+ console.log('ssssss');
257
+ const componentHook = useComponent();
258
+
259
+ // 多选时
260
+ const modelField = multiple ? `_${column.field}` : column.field;
261
+ // 默认值
262
+ componentHook.setDefaultValue(props, row, column.field);
263
+
264
+ function onChange(val) {
265
+ componentHook.selectChange(val, row, column.field, renderOpts, {
266
+ column,
267
+ datasource: 'row'
268
+ });
269
+ }
270
+
271
+ function onClear() {
272
+ componentHook.clear(row, column.field, mapField, events, 'row');
273
+ }
274
+
275
+ return [
276
+ <el-select
277
+ v-model={row[modelField]}
278
+ filterable
279
+ clearable
280
+ {...props}
281
+ style="width: 100%"
282
+ class="udp-select-wrapper"
283
+ onChange={v => onChange(v)}
284
+ onClear={() => onClear()}
285
+ >
286
+ {options.map(item => {
287
+ return <el-option key={item[value]} label={item[label]} value={item[value]}></el-option>;
288
+ })}
289
+ </el-select>
290
+ ];
291
+ },
292
+ renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
293
+ const { row, column } = params;
294
+ const { options, props, optionProps = {}, events } = renderOpts;
295
+ const { label = 'label', value = 'value', extLabel } = optionProps;
296
+ const { mapField, multiple } = props;
297
+ console.log('defaultParams');
298
+ // 多选时
299
+ const modelField = multiple ? `_${column.field}` : column.field;
300
+ // 默认值
301
+ componentHook.setDefaultValue(props, row, column.field);
302
+ function onChange(val) {
303
+ componentHook.selectChange(val, row, column.field, renderOpts, {
304
+ column,
305
+ datasource: 'row'
306
+ });
307
+ }
308
+
309
+ function onClear() {
310
+ componentHook.clear(row, column.field, mapField, events, 'row');
311
+ }
312
+
313
+ return [
314
+ <el-select
315
+ v-model={row[modelField]}
316
+ filterable
317
+ clearable
318
+ {...props}
319
+ style="width: 100%"
320
+ onChange={v => onChange(v)}
321
+ onClear={() => onClear()}
322
+ >
323
+ {options.map(item => {
324
+ return (
325
+ <el-option
326
+ key={item[value]}
327
+ label={extLabel && item[extLabel] ? item[value] : item[label]}
328
+ value={item[value]}
329
+ ></el-option>
330
+ );
331
+ })}
332
+ </el-select>
333
+ ];
334
+ },
335
+ // 可编辑显示模板
336
+ renderTableCell(renderOpts, params) {
337
+ const { row, column } = params;
338
+ const { props, options, optionProps } = renderOpts;
339
+ // @ts-ignore
340
+ const { label = 'label', value = 'value', extLabel } = optionProps;
341
+ console.log('defaultParams');
342
+ const { textValue } = props;
343
+ let val = row[column.field];
344
+ const item = options.find(opt => opt[value] === val);
345
+ if (textValue) {
346
+ val = eval(`row.${textValue}`) || row[column.field];
347
+ }
348
+ if (item) {
349
+ val = extLabel ? item[value] : item[label];
350
+ }
351
+ if (val && props?.multiple && isArray(val)) {
352
+ val = val && val.join(',');
353
+ }
354
+ return [<span>{val}</span>];
355
+ },
356
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
357
+ const { data, field } = params;
358
+ const { options, props, optionProps = {}, events } = renderOpts;
359
+ const { label = 'label', value = 'value' } = optionProps;
360
+
361
+ const { mapField, multiple } = props;
362
+
363
+ const componentHook = useComponent();
364
+
365
+ // 多选时, model挂载到临时字段上
366
+ const modelField = multiple ? `_${field}` : field;
367
+ // 默认值
368
+ componentHook.setDefaultValue(props, data, field);
369
+ /**
370
+ * @description: 选中值发生变化时触发
371
+ * @param {*} val 目前的选中值
372
+ */
373
+ function onChange(val) {
374
+ componentHook.selectChange(val, data, field, renderOpts, {
375
+ datasource: 'data'
376
+ });
377
+ }
378
+
379
+ /**
380
+ * @description: 可清空的单选模式下用户点击清空按钮时触发
381
+ */
382
+ function onClear() {
383
+ componentHook.clear(data, field, mapField, events, 'data');
384
+ }
385
+
386
+ return [
387
+ <el-select
388
+ v-model={data[modelField]}
389
+ filterable
390
+ clearable
391
+ style="width: 100%"
392
+ {...props}
393
+ onChange={v => onChange(v)}
394
+ onClear={() => onClear()}
395
+ >
396
+ {options.map(item => {
397
+ return <el-option key={item[value]} label={item[label]} value={item[value]}></el-option>;
398
+ })}
399
+ </el-select>
400
+ ];
401
+ }
402
+ });
403
+ // 下拉选择
404
+ VXETable.renderer.add('#textarea', {
405
+ renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
406
+ const { row, column } = params;
407
+ const { props, events } = renderOpts;
408
+ const { mapField } = props;
409
+
410
+ const componentHook = useComponent();
411
+ function onChange(val) {
412
+ componentHook.change(val, row, column.field, renderOpts, { column, datasource: 'row' });
413
+ }
414
+
415
+ function onClear() {
416
+ componentHook.clear(row, column.field, mapField, events, 'row');
417
+ }
418
+
419
+ return [
420
+ <vxe-textarea
421
+ v-model={row[column.field]}
422
+ {...props}
423
+ style="width: 100%"
424
+ onChange={v => onChange(v)}
425
+ onClear={() => onClear()}
426
+ />
427
+ ];
428
+ },
429
+ renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
430
+ const { row, column } = params;
431
+ const { props, events } = renderOpts;
432
+ const { mapField } = props;
433
+
434
+ const componentHook = useComponent();
435
+
436
+ function onChange(val) {
437
+ componentHook.change(val, row, column.field, renderOpts, { column, datasource: 'row' });
438
+ }
439
+
440
+ function onClear() {
441
+ componentHook.clear(row, column.field, mapField, events, 'row');
442
+ }
443
+
444
+ return [
445
+ <vxe-textarea v-model={row[column.field]} {...props} onChange={v => onChange(v)} onClear={() => onClear()} />
446
+ ];
447
+ },
448
+ // 可编辑显示模板
449
+ renderTableCell(renderOpts, params) {
450
+ const { row, column } = params;
451
+ return row[column.field];
452
+ },
453
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
454
+ const { data, field } = params;
455
+ const { props, events } = renderOpts;
456
+ const componentHook = useComponent();
457
+
458
+ // 默认值
459
+ const { defaultValue, mapField } = props;
460
+ if (defaultValue) {
461
+ data[field] = defaultValue;
462
+ }
463
+ /**
464
+ * @description: 选中值发生变化时触发
465
+ * @param {*} val 目前的选中值
466
+ */
467
+ function onChange(val) {
468
+ componentHook.change(val, data, field, renderOpts, { datasource: 'data' });
469
+ }
470
+
471
+ /**
472
+ * @description: 可清空的单选模式下用户点击清空按钮时触发
473
+ */
474
+ function onClear() {
475
+ componentHook.clear(data, field, mapField, events, 'data');
476
+ }
477
+
478
+ return [<vxe-textarea v-model={data[field]} {...props} onChange={v => onChange(v)} onClear={() => onClear()} />];
479
+ }
480
+ });
481
+ // Lov
482
+ VXETable.renderer.add('#lov', {
483
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
484
+ const { data, field } = params;
485
+ const { props, events } = renderOpts;
486
+ const componentHook = useComponent();
487
+ // 默认值
488
+ const { defaultValues, mapField } = props;
489
+ if (defaultValues) {
490
+ data[field] = defaultValues;
491
+ }
492
+ /**
493
+ * @description: 选中值发生变化时触发
494
+ * @param {*} val 目前的选中值
495
+ */
496
+ function onChange(record, displayField) {
497
+ const { mapField, field, displayName, multiple } = props;
498
+ if (!multiple) {
499
+ const obj = {
500
+ [displayName || field]: record[displayField || displayName || field]
501
+ };
502
+ for (const key in mapField) {
503
+ obj[key] = record[mapField[key]];
504
+ }
505
+ Object.assign(data, obj);
506
+ } else if (multiple) {
507
+ const obj = {};
508
+ data[displayName || field] = record.reduce((curv, prev) => {
509
+ for (const key in mapField) {
510
+ obj[key] = !curv ? prev[mapField[key]] : obj[key] + ',' + prev[mapField[key]];
511
+ }
512
+ curv = !curv ? prev[displayName || field] : curv + ',' + prev[displayName || field];
513
+ return curv;
514
+ }, '');
515
+ Object.assign(data, obj);
516
+ }
517
+ const parm = { data, options: record, field };
518
+ events?.change && events.change(parm);
519
+ }
520
+
521
+ /**
522
+ * @description: 点击清空按钮时触发
523
+ */
524
+ function onClear() {
525
+ componentHook.clear(data, field, mapField, events, 'data');
526
+ }
527
+
528
+ return [
529
+ <ut-lov record={data} {...props} mode="vxe" onChange={(v, f) => onChange(v, f)} onClear={() => onClear()} />
530
+ ];
531
+ },
532
+ // 单元格编辑
533
+ renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
534
+ const { row, column } = params;
535
+ const { props, events } = renderOpts;
536
+ const componentHook = useComponent();
537
+ console.log('lov====');
538
+ function onChange(record, displayField) {
539
+ const { mapField, field, displayName, multiple } = props;
540
+ if (!multiple) {
541
+ const obj = {
542
+ [displayName || field]: record[displayField || displayName || field]
543
+ };
544
+ for (const key in mapField) {
545
+ obj[key] = record[mapField[key]];
546
+ }
547
+ Object.assign(row, obj);
548
+ }
549
+ const params = { row, options: record, field: column.field, column };
550
+ events?.change && events.change(params);
551
+ }
552
+
553
+ function onClear() {
554
+ componentHook.clear(row, field, mapField, events, 'row');
555
+ }
556
+
557
+ return [
558
+ <ut-lov
559
+ record={row}
560
+ mode="vxe"
561
+ transfer
562
+ {...props}
563
+ onChange={(v, f) => onChange(v, f)}
564
+ onClear={() => onClear()}
565
+ />
566
+ ];
567
+ },
568
+ // 单元格默认
569
+ renderTableDefault(renderOpts: VxeColumnPropTypes.EditRender, params) {
570
+ const { row, column } = params;
571
+ const { props, events } = renderOpts;
572
+ const componentHook = useComponent();
573
+ function onChange(record, displayField) {
574
+ const { mapField, field, displayName, multiple } = props;
575
+ if (!multiple) {
576
+ const obj = {
577
+ [displayName || field]: record[displayField || displayName || field]
578
+ };
579
+ for (const key in mapField) {
580
+ obj[key] = record[mapField[key]];
581
+ }
582
+ Object.assign(row, obj);
583
+ }
584
+ const params = { row, options: record, field: column.field, column };
585
+ events?.change && events.change(params);
586
+ }
587
+ /**
588
+ * @description 清空数据
589
+ */
590
+ function onClear() {
591
+ componentHook.clear(row, field, mapField, events, 'row');
592
+ }
593
+
594
+ return [
595
+ <ut-lov record={row} mode="ele" {...props} onChange={(v, f) => onChange(v, f)} onClear={() => onClear()} />
596
+ ];
597
+ },
598
+ // 可编辑显示模板
599
+ renderTableCell(renderOpts, params) {
600
+ const { row, column } = params;
601
+ return [<span>{row[column.field]}</span>];
602
+ }
603
+ });
604
+ // form upload
605
+ VXETable.renderer.add('#upload', {
606
+ renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
607
+ const { row, column } = params;
608
+ const { props, events } = renderOpts;
609
+
610
+ /**
611
+ * @description: 点击清空按钮时触发
612
+ */
613
+ function onClear(file, fielist) {
614
+ row[column.field] = '';
615
+ events?.remove && events?.remove(file, fielist);
616
+ }
617
+
618
+ return [
619
+ <form-upload2
620
+ record={row}
621
+ field={column.field}
622
+ size="mini"
623
+ {...props}
624
+ render-mode="column"
625
+ data-status="edit"
626
+ onRemove={(file, fielist) => onClear(file, fielist)}
627
+ />
628
+ ];
629
+ },
630
+
631
+ // 可编辑显示模板
632
+ renderTableCell(renderOpts, params) {
633
+ const { row, column } = params;
634
+ const { props } = renderOpts;
635
+ return [
636
+ <form-upload2
637
+ record={row}
638
+ field={column.field}
639
+ size="mini"
640
+ {...props}
641
+ mode="image"
642
+ render-mode="column"
643
+ data-status="detail"
644
+ />
645
+ ];
646
+ },
647
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
648
+ const { data, field } = params;
649
+ const { props, events } = renderOpts;
650
+ /**
651
+ * @description: 点击清空按钮时触发
652
+ */
653
+ function onClear(file, fielist) {
654
+ data[field] = '';
655
+ events?.remove && events?.remove(file, fielist);
656
+ }
657
+
658
+ if (props.singleMode) {
659
+ // 单个模式下,限制只能单个上传
660
+ Object.assign(props, { multiple: false, limitCount: 1, autoHiddenButton: true });
661
+ }
662
+ if (!props.mode || props.mode === 'image') {
663
+ props.imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'apk'];
664
+ }
665
+
666
+ console.log({ props });
667
+
668
+ return [
669
+ <form-upload2
670
+ record={data}
671
+ field={field}
672
+ mode="image"
673
+ {...props}
674
+ onRemove={(file, fielist) => onClear(file, fielist)}
675
+ />
676
+ ];
677
+ }
678
+ });
679
+
680
+ // 创建一个简单的超链接渲染
681
+ VXETable.renderer.add('#tag', {
682
+ // 默认显示模板
683
+ renderTableDefault(renderOpts, params) {
684
+ const { row, column } = params;
685
+ const {
686
+ props: { code, tagMap }
687
+ } = renderOpts;
688
+ function getTagType() {
689
+ return row[column.field] ? tagMap[row[column.field]] : null;
690
+ }
691
+ return [
692
+ row[column.field] ? (
693
+ <el-tag effect="dark" type={getTagType()}>
694
+ {getValue(code, row[column.field])}
695
+ </el-tag>
696
+ ) : null
697
+ ];
698
+ }
699
+ });
700
+
701
+ VXETable.renderer.add('#switch', {
702
+ renderTableDefault(renderOpts, params) {
703
+ const { row, column } = params;
704
+ const {
705
+ props: { code, activeValue, inactiveValue },
706
+ events
707
+ } = renderOpts;
708
+ function onChange(value) {
709
+ const params = { row, column, value };
710
+ events?.change && events.change(params);
711
+ }
712
+ return [
713
+ row[column.field] ? (
714
+ <el-switch
715
+ v-model={row[column.field]}
716
+ inline-prompt
717
+ size="large"
718
+ style="--el-switch-on-color: #13ce66; --el-switch-off-color: #E6A23C"
719
+ {...renderOpts.props}
720
+ active-text={getValue(code, activeValue)}
721
+ inactive-text={getValue(code, inactiveValue)}
722
+ onChange={v => onChange(v)}
723
+ />
724
+ ) : null
725
+ ];
726
+ }
727
+ });
728
+
729
+ VXETable.renderer.add('#iconSelect', {
730
+ renderTableEdit(renderOpts: VxeColumnPropTypes.EditRender, params) {
731
+ const { row, column } = params;
732
+ return [<SuIconSelect v-model={row[column.field]} teleported={false} />];
733
+ },
734
+ renderTableCell(renderOpts, params) {
735
+ const { row, column } = params;
736
+ return [<IconifyIconOffline icon={row[column.field]} style="font-size: 16px;" />];
737
+ },
738
+ renderItemContent(renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
739
+ const { data, field } = params;
740
+ return [<SuIconSelect v-model={data[field]} teleported />];
741
+ }
742
+ });
743
+
744
+ VXETable.renderer.add('#treeSelect', {
745
+ renderTableEdit(renderOpts: SuEditRender, params) {
746
+ const { row, column } = params;
747
+ const { props, sourceData, events } = renderOpts;
748
+
749
+ return [
750
+ <el-tree-select
751
+ v-model={row[column.field]}
752
+ data={sourceData}
753
+ check-strictly
754
+ {...props}
755
+ filterable
756
+ onCheckChange={(node, selected, isLeaf) => onCheckChange(node, selected, isLeaf, events)}
757
+ onNodeClick={(data, node, treeNode) => onNodeClick(data, node, treeNode, events)}
758
+ onCurrentChange={(data, node) => onCurrentChange(data, node, events)}
759
+ />
760
+ ];
761
+ },
762
+ renderTableCell(renderOpts: SuRenderCellOptions, params) {
763
+ const { row, column } = params;
764
+ const { sourceData, props = {} } = renderOpts;
765
+ const { children = 'children', label = 'label' } = props;
766
+ const data = findTree(sourceData, item => item['value'] === row[column.field], { children });
767
+ return data ? [<span>{data.item[label]}</span>] : null;
768
+ },
769
+ renderItemContent(renderOpts: SuFormItemRenderOptions, params: FormItemContentRenderParams) {
770
+ const { data, field } = params;
771
+ const { props, sourceData, events } = renderOpts;
772
+ return [
773
+ <el-tree-select
774
+ v-model={data[field]}
775
+ data={sourceData}
776
+ check-strictly
777
+ {...props}
778
+ filterable
779
+ onCheckChange={(node, selected, isLeaf) => onCheckChange(node, selected, isLeaf, events)}
780
+ onNodeClick={(data, node, treeNode) => onNodeClick(data, node, treeNode, events)}
781
+ onCurrentChange={(data, node) => onCurrentChange(data, node, events)}
782
+ />
783
+ ];
784
+ }
785
+ });
786
+
787
+ /**
788
+ * 组件公共方法
789
+ * @returns
790
+ */
791
+ const useComponent = () => {
792
+ // 下拉框选择
793
+ /**
794
+ * select下拉选择change事件
795
+ * @param value 选择值
796
+ * @param data 数据源
797
+ * @param field 字段
798
+ * @param renderOpts 渲染参数
799
+ * @param opts 数据源类型等
800
+ * @return `{ data: 数据源, field: 字段, options?: 选中的选项组, option?: 选中的选项, column?: 列信息 }`
801
+ */
802
+ const selectChange = (value, data, field, renderOpts, opts) => {
803
+ let option = null;
804
+
805
+ const { datasource } = opts;
806
+ const { options, props, optionProps = {}, events } = renderOpts;
807
+
808
+ const callData = { [datasource]: data, field };
809
+ // 1、清空原有数据
810
+ data[field] = null;
811
+ if (!isEmpty(value) && props?.multiple) {
812
+ // 2、给实际字段赋值
813
+ data[field] = value.join(',');
814
+ option = [];
815
+ // 多选
816
+ value.forEach(item => {
817
+ const selectOpt = options.find(opt => item === opt[optionProps?.value]);
818
+ if (selectOpt && !isEmpty(props.mapField) && isObject(props.mapField)) {
819
+ Object.keys(props.mapField).forEach(key => {
820
+ const val = selectOpt[props.mapField[key]];
821
+ const ov = data[key] ? data[key].toString() : '';
822
+ // 默认用逗号(,)分割
823
+ data[key] = ov && !ov.includes(val) ? `${ov},${val}` : val;
824
+ });
825
+ }
826
+ selectOpt && option.push(selectOpt);
827
+ });
828
+ Object.assign(callData, { options: option });
829
+ } else {
830
+ // 3、原字段赋值, 多选进来说明必定是空值
831
+ data[field] = props?.multiple ? null : value;
832
+ option = options.find(opt => value === opt[optionProps?.value]);
833
+ if (!isEmpty(props.mapField) && isObject(props.mapField)) {
834
+ Object.keys(props.mapField).forEach(key => {
835
+ data[key] = option ? option[props.mapField[key]] : null;
836
+ });
837
+ }
838
+ Object.assign(callData, { option });
839
+ }
840
+ datasource === 'row' && Object.assign(callData, { column: opts.column });
841
+ events?.change && events.change(callData);
842
+ };
843
+ const setDefaultValue = (props, data, field) => {
844
+ const { multiple, defaultValue } = props;
845
+ // 多选时, model挂载到临时字段上
846
+ const modelField = multiple ? `_${field}` : field;
847
+ // 默认值
848
+ if (!data[field] && defaultValue) {
849
+ data[field] = defaultValue;
850
+ if (isPlainObject(defaultValue)) {
851
+ const keys = Object.keys(defaultValue);
852
+ keys.forEach(key => {
853
+ data[key] = data[key] || defaultValue[key];
854
+ });
855
+ }
856
+ }
857
+ if (!data[modelField] && data[field]) {
858
+ data[modelField] = multiple ? data[field]?.split(',') : data[field];
859
+ }
860
+ };
861
+ const remote = async (query, field, renderOpts) => {
862
+ const { options, props, events } = renderOpts;
863
+ const { fetchField, url, defaultParams = {}, method = 'get' } = props;
864
+ const commonParam = getCookieParam();
865
+ const params = Object.assign(
866
+ { pageSize: 20, pageNum: 1, ...commonParam, ...defaultParams },
867
+ { [fetchField || field]: query }
868
+ );
869
+ if (props.loading) return;
870
+ let res;
871
+ try {
872
+ options.length = 0;
873
+ props.loading = true;
874
+ res = await serviceApi[method](url, params);
875
+ if (events?.filterMethod) {
876
+ options.push(...events.filterMethod(res.list || res));
877
+ } else if (res) {
878
+ res.list ? options.push(...res.list) : options.push(...res);
879
+ }
880
+ } finally {
881
+ props.loading = false;
882
+ }
883
+ };
884
+ // 清除数据
885
+ const clear = (data, field, mapField, events, datasource) => {
886
+ data[field] = null;
887
+ if (!isEmpty(mapField)) {
888
+ for (const key in mapField) {
889
+ data[key] = null;
890
+ }
891
+ }
892
+ events?.clear && events.clear({ [datasource]: data, field });
893
+ };
894
+ const change = (data, field, mapField, events, datasource) => {
895
+ data[field] = null;
896
+ if (!isEmpty(mapField)) {
897
+ for (const key in mapField) {
898
+ data[key] = null;
899
+ }
900
+ }
901
+ events?.change && events.change({ [datasource]: data, field });
902
+ };
903
+ return { clear, change, remote, selectChange, setDefaultValue };
904
+ };
905
+
906
+ /**
907
+ * 当复选框被点击的时候触发
908
+ * @param node 传递给 data 属性的数组中该节点所对应的对象
909
+ * @param selected 节点本身是否被选中
910
+ * @param isLeaf 节点的子树中是否有被选中的节点
911
+ */
912
+ const onCheckChange = (node, selected, isLeaf, events) => {
913
+ console.log(node, selected, isLeaf);
914
+ events?.checkChange && events?.checkChange(node, selected, isLeaf);
915
+ };
916
+ /**
917
+ * 节点被点击的时候触发
918
+ * @param nodeObject 点击的节点对象
919
+ * @param node TreeNode node 属性
920
+ * @param treeNode TreeNode
921
+ */
922
+ const onNodeClick = (nodeObject, node, treeNode, events) => {
923
+ events?.checkChange && events?.checkChange(nodeObject, node, treeNode);
924
+ };
925
+ /**
926
+ * 当前选中节点变化时触发的事件
927
+ * @param data 当前节点的数据
928
+ * @param node 当前节点的 Node 对象
929
+ */
930
+ const onCurrentChange = (data, node, events) => {
931
+ events?.checkChange && events?.checkChange(data, node);
932
+ };
933
+
934
+ function getValue(code, value) {
935
+ if (!value || !code || !dict) return value;
936
+ return dict[code]?.children?.find(item => item.dictCode === value)?.dictName;
937
+ }
938
+
939
+ return VXETable;
940
+ };
941
+
942
+ const getCookieParam = () => {
943
+ const kCOOKIES = 'kCookies_param';
944
+ return cookies.get(kCOOKIES) ? JSON.parse(cookies.get(kCOOKIES)) : {};
945
+ };