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

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 (74) hide show
  1. package/dist/{403-Cjzd1bv9.js → 403-BOzKHdlm.js} +1 -1
  2. package/dist/{404-CJ-3SXgP.js → 404-uwgt4Nll.js} +1 -1
  3. package/dist/{500-CQ65MvIK.js → 500-4HBf6V9m.js} +1 -1
  4. package/dist/{AuthorityInfo-BdISFrap.js → AuthorityInfo-DvbIh1vT.js} +1 -1
  5. package/dist/{AuthorityInfo.vue_vue_type_style_index_0_lang-DsLG5slc.js → AuthorityInfo.vue_vue_type_style_index_0_lang-BlCPvwXU.js} +1 -1
  6. package/dist/{Company-Mj-z1hNb.js → Company-D7Q9BFmr.js} +3 -3
  7. package/dist/{CompanyPanel-BNXZ7ER3.js → CompanyPanel-C0-PJlrt.js} +1 -1
  8. package/dist/{Department-C4ygVbSP.js → Department-h2hlXACv.js} +3 -3
  9. package/dist/{DepartmentPanel-Bk96mDlD.js → DepartmentPanel-B6hDEQpG.js} +1 -1
  10. package/dist/{DesignPanel-Bwx2QwMM.js → DesignPanel-cS58-1v9.js} +1 -1
  11. package/dist/{DesignPanel.vue_vue_type_style_index_0_lang-B3OjJTHG.js → DesignPanel.vue_vue_type_style_index_0_lang-LdvLC8VU.js} +2 -2
  12. package/dist/{DictView-DE3jnxnq.js → DictView-T3TmpBa8.js} +57 -44
  13. package/dist/{InvOrganization-Drce3xUC.js → InvOrganization-BVuOhzbt.js} +1 -1
  14. package/dist/{Org-C42D9lDj.js → Org-CnCBDGKF.js} +1 -1
  15. package/dist/{Preview-CCXoRvWF.js → Preview-BaktKXB1.js} +1 -1
  16. package/dist/{ReportDefine-BWsExcQU.js → ReportDefine-5Rb0PO9A.js} +1 -1
  17. package/dist/{ReportDesign-BTzpUpGj.js → ReportDesign-DYdkVREA.js} +2 -2
  18. package/dist/{ReportQuery-eoSmPXzc.js → ReportQuery-BwhzIXMt.js} +1 -1
  19. package/dist/{ReportQueryFrom-D4YlI5jl.js → ReportQueryFrom-PHtWwlOe.js} +1 -1
  20. package/dist/{ReportQueryFrom.vue_vue_type_style_index_0_lang-DPDGKW9a.js → ReportQueryFrom.vue_vue_type_style_index_0_lang-BE5yZNPM.js} +1 -1
  21. package/dist/{ReportTemplate-BTa2YWq0.js → ReportTemplate-DaadVXIi.js} +1 -1
  22. package/dist/{Role-BTGB91P1.js → Role-Dtg3nAmG.js} +3 -3
  23. package/dist/{RoleAssign-BBSY6bYM.js → RoleAssign-DEGtLssH.js} +3 -3
  24. package/dist/{RolePanel-DNDI7e0g.js → RolePanel-CT7BTPmy.js} +1 -1
  25. package/dist/{RolePanel-BaTuyeVC.js → RolePanel-DpUzfE_o.js} +1 -1
  26. package/dist/{RolePanel.vue_vue_type_script_setup_true_lang-QUeAQHrg.js → RolePanel.vue_vue_type_script_setup_true_lang-Dg2A6DJu.js} +3 -3
  27. package/dist/{RolePanel.vue_vue_type_script_setup_true_lang-BCwAp_1a.js → RolePanel.vue_vue_type_script_setup_true_lang-Xyo0YEI0.js} +1 -1
  28. package/dist/{ScrollPanel.vue_vue_type_style_index_0_lang-nqrbOaQP.js → ScrollPanel.vue_vue_type_style_index_0_lang-CyutzDZS.js} +1 -1
  29. package/dist/{Staff-4dbkOqzl.js → Staff-_NlAGkrh.js} +3 -3
  30. package/dist/{StaffInfo-xFAMTWgD.js → StaffInfo-DVgUvVgd.js} +1 -1
  31. package/dist/{StaffInfo.vue_vue_type_script_setup_true_lang-CocRlLsO.js → StaffInfo.vue_vue_type_script_setup_true_lang-C8hmlFgX.js} +1 -1
  32. package/dist/{StaffPanel-Cx-8MHBz.js → StaffPanel-DKNZE3IE.js} +1 -1
  33. package/dist/{StaffPanel.vue_vue_type_script_setup_true_lang-B3wfpxel.js → StaffPanel.vue_vue_type_script_setup_true_lang-BOOO6Cek.js} +2 -2
  34. package/dist/{SysUser-BHpgPXsI.js → SysUser-kQUf7XKz.js} +2 -2
  35. package/dist/{SysUserPanel-DH79Lsnm.js → SysUserPanel-C191uX3U.js} +1 -1
  36. package/dist/{SysUserPanel.vue_vue_type_script_setup_true_lang-BONl2R1a.js → SysUserPanel.vue_vue_type_script_setup_true_lang-SwNbAEvW.js} +1 -1
  37. package/dist/{SystemMenu-C2JbVgyr.js → SystemMenu-DwuSvHnj.js} +2 -2
  38. package/dist/{UserInfo-Efo-_yRo.js → UserInfo-DIsInFld.js} +1 -1
  39. package/dist/{UserInfo.vue_vue_type_style_index_0_lang-DnjjBjMU.js → UserInfo.vue_vue_type_style_index_0_lang-CnvGdbej.js} +1 -1
  40. package/dist/{childView-D7U7qh_A.js → childView-3Bs2UBEw.js} +1 -1
  41. package/dist/{childView-wFMGHGiX.js → childView-BawyULD7.js} +1 -1
  42. package/dist/{childView.vue_vue_type_style_index_0_lang-w2CkZij-.js → childView.vue_vue_type_style_index_0_lang-DWIFCX3X.js} +1 -1
  43. package/dist/{childView.vue_vue_type_style_index_0_lang-Bshn4N8Y.js → childView.vue_vue_type_style_index_0_lang-YpWF-p2F.js} +1 -1
  44. package/dist/{code-rule-B5dIxV6g.js → code-rule-DVaYcn8S.js} +1 -1
  45. package/dist/core.es.js +1 -1
  46. package/dist/{cron-task-DWGtihrw.js → cron-task-xuzP-BpE.js} +1 -1
  47. package/dist/{frameView-DF2mXAwO.js → frameView-Cudt06qS.js} +1 -1
  48. package/dist/index-CKnq5xIa.js +2623 -0
  49. package/dist/{layoutView-DUUKW0KX.js → layoutView-BlFTV2jX.js} +2 -2
  50. package/dist/{login-ByEoQ2HH.js → login-CpKykfdf.js} +2 -2
  51. package/dist/{lov-view-DqD__3-w.js → lov-view-B2HaxyMs.js} +2 -2
  52. package/dist/{menuInfo-a7jPwS1r.js → menuInfo-BxCTJ1VW.js} +1 -1
  53. package/dist/{menuInfo.vue_vue_type_style_index_0_lang-ZzGrkylA.js → menuInfo.vue_vue_type_style_index_0_lang-CLOPNeUW.js} +1 -1
  54. package/dist/{pda-app-EP9d0Ypd.js → pda-app-DPsAFNiw.js} +8 -10
  55. package/dist/{resource-eughqxkP.js → resource-Dibb7t8u.js} +1 -1
  56. package/dist/{su-welcome-98GLKyZM.js → su-welcome-DejR0KkM.js} +1 -1
  57. package/dist/{sys-config-gs16tgwA.js → sys-config-DiySRWns.js} +1 -1
  58. package/dist/udp-core.css +2 -2
  59. package/dist/{utogether-C4Dd2epc.js → utogether-Dct_14Zk.js} +1 -1
  60. package/package.json +1 -1
  61. package/src/components/udp/form-upload.vue +375 -76
  62. package/src/components/udp/form.vue +12 -7
  63. package/src/components/udp/lov.vue +5 -27
  64. package/src/components/udp/upload.vue +1 -3
  65. package/src/components/udp/utils.ts +9 -3
  66. package/src/main.ts +119 -119
  67. package/src/plugins/vxe-table/index.ts +1 -1
  68. package/src/plugins/vxe-table/render.tsx +956 -896
  69. package/src/style/vxetable.scss +6 -10
  70. package/src/utils/udp/useRender.ts +17 -6
  71. package/src/views/uapp/pda/pda-app.vue +208 -207
  72. package/src/views/udev/dict/DictView.vue +7 -0
  73. package/vite.config.ts +2 -1
  74. package/dist/index-VU6c04nN.js +0 -4531
@@ -1,6 +1,6 @@
1
1
  import { computed as W, ref as L } from "vue";
2
2
  import { useGlobal as g, storageLocal as u, deviceDetection as H, cookies as C, storageSession as M } from "@utogether/utils";
3
- import { y as P, j as E, s as j, g as h, v as d, z as J, l as K, m as R, n as V, u as S, r as G, o as O, A as x, B as Z } from "./index-VU6c04nN.js";
3
+ import { y as P, j as E, s as j, g as h, v as d, z as J, l as K, m as R, n as V, u as S, r as G, o as O, A as x, B as Z } from "./index-CKnq5xIa.js";
4
4
  import { useI18n as f } from "vue-i18n";
5
5
  import { defineStore as v } from "pinia";
6
6
  function I() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@utogether/udp-core",
3
3
  "private": false,
4
- "version": "1.0.1-beta.8",
4
+ "version": "1.0.1-beta.9",
5
5
  "description": "",
6
6
  "type": "module",
7
7
  "main1": "index.ts",
@@ -2,27 +2,89 @@
2
2
  * @Author: wei.li
3
3
  * @Date: 2022-11-04 14:53:36
4
4
  * @LastEditors: levi7754 levi7754@163.com
5
- * @LastEditTime: 2025-07-20 17:23:11
5
+ * @LastEditTime: 2025-08-18 11:17:57
6
6
  * @Description: form upload
7
7
  -->
8
8
  <template>
9
- <div v-spinning="loading" class="ut-upload-wrapper">
10
- <el-upload
11
- v-model:file-list="fileList"
12
- :action="baseUrl + '/ufil/file/uploadMultipart'"
13
- :disabled="dataStatus === 'detail'"
14
- list-type="picture-card"
15
- :headers="headers"
16
- :before-upload="beforeUpload"
17
- :on-success="onSuccess"
18
- :on-preview="onPreview"
19
- :on-remove="handleRemove"
20
- :http-request="httpRequest"
21
- >
22
- <template #default>
23
- <i v-if="fileList.length < limit && dataStatus !== 'detail'" class="ri-add-line" />
24
- </template>
25
- </el-upload>
9
+ <div class="flex w-full flex-wrap">
10
+ <div class="ut-upload-list flex flex-wrap items-center">
11
+ <div v-for="(item, idx) in fileList" :key="item" :class="'ut-upload-item--' + size">
12
+ <div class="ut-upload--image flex items-center justify-center">
13
+ <img
14
+ v-if="getItemType(item) === 'img'"
15
+ :src="item.url"
16
+ class="ut-image select-none"
17
+ @click="onPreview(item)"
18
+ />
19
+ <div v-else-if="renderMode === 'item' || dataStatus !== 'detail'" class="ut-image-hover">
20
+ <div class="ut-image-file--wrapper">
21
+ <i :class="getItemType(item)" class="ut-image-file ut-image" style="line-height: 1" />
22
+ <div class="px-1 ut-image" :style="{ fontSize: size === 'small' ? '11px' : '10px' }">
23
+ {{ maskFilenameFromPath(item) }}
24
+ </div>
25
+ </div>
26
+ <i
27
+ class="vxe-icon-download ut-download-icon"
28
+ :style="{ fontSize: renderMode === 'item' ? '60px' : '48px' }"
29
+ @click="onDownload(item)"
30
+ />
31
+ </div>
32
+ <vxe-tooltip v-else :content="item.name" class="cursor-pointer">
33
+ <div class="ut-image-hover">
34
+ <div class="ut-image-file--wrapper">
35
+ <i :class="getItemType(item)" class="ut-image-file ut-image" style="font-size: 32px" />
36
+ <div class="px-1 ut-image" :style="{ fontSize: size === 'small' ? '11px' : '10px' }">
37
+ {{ maskFilenameFromPath(item) }}
38
+ </div>
39
+ </div>
40
+ <i
41
+ class="vxe-icon-download ut-download-icon"
42
+ :style="{ fontSize: renderMode === 'item' ? '60px' : '48px' }"
43
+ @click="onDownload(item)"
44
+ />
45
+ </div>
46
+ </vxe-tooltip>
47
+ </div>
48
+ <div v-if="dataStatus !== 'detail'" class="ut-upload--image-item-btn-wrapper">
49
+ <div class="ut-upload-remove--btn"><i class="vxe-icon-close" @click="onRemove(item, idx)" /></div>
50
+ </div>
51
+ </div>
52
+ <div
53
+ v-if="dataStatus !== 'detail'"
54
+ :class="'ut-upload-item--' + size"
55
+ class="ut-upload--btn"
56
+ style="border: 1px dashed var(--vxe-ui-input-border-color)"
57
+ @click="onStartUpload"
58
+ >
59
+ <div class="flex items-center justify-center h-full flex-col cursor-pointer ut-upload--btn">
60
+ <span v-if="!loading" class="vxe-icon-add" style="font-size: 18px" />
61
+ <div v-if="!loading" style="font-size: 11px; padding: 0 1px; text-align: center">点击上传</div>
62
+ <vxe-icon v-if="loading" name="spinner" status="primary" roll style="font-size: 24px" />
63
+ <div v-if="loading" style="font-size: 11px; padding: 0 1px; text-align: center">{{ progressText }}</div>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ <vxe-upload
68
+ ref="xupload"
69
+ v-model="list"
70
+ style="display: none"
71
+ v-bind="$attrs"
72
+ :limit-count="limitCount"
73
+ :limit-size="limitSize"
74
+ :size="size"
75
+ :mode="mode"
76
+ :single-mode="singleMode"
77
+ :image-types="imageTypes"
78
+ :auto-hidden-button="autoHiddenButton"
79
+ :show-error-status="showErrorStatus"
80
+ :remove-method="handleRemove"
81
+ :upload-method="httpRequest"
82
+ :multiple="multiple"
83
+ :show-download-button="showDownloadButton"
84
+ :show-list="false"
85
+ show-progress
86
+ @upload-success="onSuccess"
87
+ />
26
88
  </div>
27
89
  </template>
28
90
 
@@ -31,40 +93,63 @@ export default { name: 'FormUpload' };
31
93
  </script>
32
94
 
33
95
  <script setup lang="ts">
34
- import { ref, computed, getCurrentInstance } from 'vue';
96
+ import { ref, computed, onBeforeMount, getCurrentInstance } from 'vue';
35
97
  import { cookies } from '@utogether/utils';
36
98
  import compressorjs from 'compressorjs';
99
+ import { isString, isArray } from 'xe-utils';
100
+ import { VxeUI, VxeUploadPropTypes } from 'vxe-pc-ui';
101
+ import axios from 'axios';
37
102
 
38
103
  export interface IProps {
39
104
  record: object;
105
+ imageTypes?: Array<string>;
40
106
  field: string;
41
- dataStatus: string;
42
- limit?: number;
107
+ dataStatus?: string;
108
+ renderMode?: string;
109
+ size?: VxeUploadPropTypes.Size;
110
+ mode?: VxeUploadPropTypes.Mode;
111
+ limitCount?: number;
112
+ limitSize?: number;
43
113
  compassorSize?: number;
44
114
  quality?: number;
45
- size?: number;
46
- beforeUpload?: Function;
47
- onSuccess?: Function;
48
- onRemove?: Function;
115
+ singleMode?: boolean;
116
+ autoHiddenButton?: boolean;
117
+ showErrorStatus?: boolean;
118
+ showDownloadButton?: boolean;
119
+ multiple?: boolean;
120
+ success?: Function;
121
+ remove?: Function;
49
122
  }
50
123
  const props = withDefaults(defineProps<IProps>(), {
51
124
  record: () => {
52
125
  return {};
53
126
  },
127
+ imageTypes: () => {
128
+ return ['jpg', 'jpeg', 'png', 'gif'];
129
+ },
54
130
  field: '',
131
+ renderMode: 'item',
55
132
  dataStatus: '',
56
- size: 60,
57
- limit: 1,
133
+ size: 'mini',
134
+ mode: '',
135
+ singleMode: false,
136
+ autoHiddenButton: false,
137
+ showDownloadButton: false,
138
+ multiple: false,
139
+ limitSize: 30,
140
+ limitCount: 9,
58
141
  quality: 0.6,
59
142
  compassorSize: 2
60
143
  });
61
144
 
62
145
  const instance = getCurrentInstance()!;
63
146
  const baseUrl = instance.appContext.config.globalProperties.$url;
64
- const viewerApi = instance.appContext.config.globalProperties.$viewerApi;
65
147
  const serviceApi = instance.appContext.config.globalProperties.$serviceApi;
148
+ const progressText = ref('');
149
+ const loading = ref(false);
66
150
 
67
151
  const imgTypes = ['image/gif', 'image/jpeg', 'image/png'];
152
+ const xupload = ref(null);
68
153
 
69
154
  const headers = computed(() => {
70
155
  const kTOKENKEY = 'authorized-token';
@@ -75,20 +160,8 @@ const headers = computed(() => {
75
160
  };
76
161
  return headers;
77
162
  });
78
-
79
- const fileList = ref([]);
80
- const loading = ref(false);
81
- const display = ref('flex');
82
- const image_size = ref(props.size + 'px');
83
- const process_size = ref(props.size - 10 + 'px');
84
-
85
- const beforeUpload = file => {
86
- if (props.beforeUpload) {
87
- return props.beforeUpload(file);
88
- }
89
- loading.value = true;
90
- return true;
91
- };
163
+ const list = [];
164
+ const fileList = ref<any>([]);
92
165
 
93
166
  const httpRequest = options => {
94
167
  if (imgTypes.includes(options.file.type) && options.file.size > 1024 * 1024 * props.compassorSize) {
@@ -111,73 +184,299 @@ const httpRequest = options => {
111
184
  const uploadProcess = (resolve, reject, file) => {
112
185
  const formBody = new FormData();
113
186
  formBody.append('file', file);
187
+ const url = baseUrl + '/ufil/file/uploadMultipart';
188
+ loading.value = true;
189
+ return axios
190
+ .post(url, formBody, {
191
+ headers: Object.assign({ 'Content-Type': 'multipart/form-data' }, headers.value),
192
+ onUploadProgress(progressEvent) {
193
+ const progress = Math.round((progressEvent.loaded * 100) / (progressEvent.total || 0));
194
+ progressText.value = `进度${progress}%`;
195
+ }
196
+ })
197
+ .then(async response => {
198
+ progressText.value = `处理中...`;
199
+ file.path = response.data.data;
200
+ file.url = `${baseUrl}/ufil${file.path}`;
201
+ fileList.value.push(file);
202
+ console.log(file);
203
+ loading.value = false;
204
+ resolve(file);
205
+ })
206
+ .catch(() => {
207
+ loading.value = false;
208
+ reject(null);
209
+ });
114
210
 
115
211
  return serviceApi
116
212
  .post('/ufil/file/uploadMultipart', formBody, { headers })
117
213
  .then(async data => {
118
- loading.value = false;
119
214
  file.path = data;
215
+ file.url = `${baseUrl}/ufil${file.path}`;
216
+ fileList.value.push(file);
217
+ console.log(file);
120
218
  resolve(file);
121
219
  })
122
220
  .catch(() => {
123
- loading.value = false;
124
221
  reject(null);
125
222
  });
126
223
  };
127
224
 
128
- const onSuccess = file => {
129
- loading.value = false;
130
- if (props.onSuccess) {
131
- return props.onSuccess(file);
225
+ const onStartUpload = () => {
226
+ xupload.value.choose();
227
+ };
228
+
229
+ const onSuccess = ({ data }) => {
230
+ if (props.success) {
231
+ return props.success(data);
132
232
  } else {
133
233
  const field = props.field;
134
- Object.assign(props.record, { [field]: file.path });
135
- display.value = props.limit > fileList.value.length ? 'flex' : 'none';
234
+ Object.assign(props.record, { [field]: data.path });
136
235
  }
236
+ console.log(props.record, fileList);
137
237
  };
138
238
 
139
- const handleRemove = (uploadFile, uploadFiles) => {
140
- if (props.onRemove) {
141
- return props.onRemove(uploadFile, fileList);
239
+ const handleRemove: VxeUploadPropTypes.RemoveMethod = ({ option }) => {
240
+ if (props.remove) {
241
+ return props.remove(option, fileList);
142
242
  }
143
- loading.value = false;
144
- console.log(uploadFile, uploadFiles);
145
- display.value = 'flex';
146
- emit('remove', uploadFile, fileList);
243
+ emit('remove', option, fileList);
147
244
  };
148
245
 
149
- const onPreview = file => {
150
- if (imgTypes.includes(file.raw.type)) {
151
- const src = `${baseUrl}/ufil${file.response.path}`;
152
- viewerApi({ options: { toolbar: true, url: 'data-source' }, images: [{ src, 'data-source': src }] });
153
- } else {
246
+ const onRemove = (file, idx) => {
247
+ fileList.value.splice(idx, 1);
248
+ emit('remove', file, fileList);
249
+ };
250
+
251
+ const onPreview = item => {
252
+ // console.log(item.url);
253
+ VxeUI.previewImage({ activeIndex: 0, urlList: [item.url] });
254
+ };
255
+
256
+ const getItemType = item => {
257
+ const type = item.type || item.url.split('.').pop();
258
+ let icon = '';
259
+ switch (type) {
260
+ case 'jpg':
261
+ case 'png':
262
+ case 'jpeg':
263
+ case 'webp':
264
+ case 'image/jpeg':
265
+ case 'image/png':
266
+ case 'image/gif':
267
+ icon = 'img';
268
+ break;
269
+ case 'doc':
270
+ case 'docx':
271
+ icon = 'vxe-icon-file-word';
272
+ break;
273
+ case 'xlsx':
274
+ case 'xls':
275
+ icon = 'vxe-icon-file-excel';
276
+ break;
277
+ case 'pdf':
278
+ icon = 'vxe-icon-file-pdf';
279
+ break;
280
+ case 'txt':
281
+ icon = 'vxe-icon-file-txt';
282
+ break;
283
+ case 'ppt':
284
+ icon = 'vxe-icon-file-ppt';
285
+ break;
286
+ case 'markdown':
287
+ icon = 'vxe-icon-file-markdown';
288
+ break;
289
+ case 'apk':
290
+ icon = 'ri-android-fill';
291
+ break;
292
+ case 'ipa':
293
+ icon = 'ri-apple-line';
294
+ break;
295
+
296
+ default:
297
+ icon = 'vxe-icon-file';
298
+ break;
154
299
  }
300
+ return icon;
301
+ };
302
+
303
+ const maskFilenameFromPath = file => {
304
+ let total = props.size === 'small' ? 10 : 9;
305
+ // 提取纯文件名(含扩展名)
306
+ const extractFilename = file => {
307
+ if (file.name) return file.name;
308
+ const path = file.url;
309
+ const separator = path.includes('\\') ? '\\' : '/';
310
+ return path.split(separator).pop();
311
+ };
312
+
313
+ // 处理文件名脱敏
314
+ const maskFilename = filename => {
315
+ const dotPos = filename.lastIndexOf('.');
316
+ const name = dotPos > 0 ? filename.substring(0, dotPos) : filename;
317
+ const ext = dotPos > 0 ? filename.substring(dotPos) : '';
318
+
319
+ if (name.length <= total) return filename;
320
+
321
+ const prefix = props.renderMode === 'item' ? name.substring(0, total - 5) : '';
322
+ const suffix = name.substring(name.length - (total - 6));
323
+ return `${prefix}...${suffix}${ext}`;
324
+ };
325
+
326
+ return maskFilename(extractFilename(file));
327
+ };
328
+
329
+ const onDownload = file => {
330
+ console.log(file);
155
331
  };
156
332
  const emit = defineEmits<{
157
- (e: 'remove', file: File, fileList: any): void;
333
+ (e: 'remove', file: any, fileList: any): void;
158
334
  }>();
335
+
336
+ onBeforeMount(() => {
337
+ const fileUrl = props.record[props.field];
338
+ fileList.value = [
339
+ // { name: '深圳友聚信息技术开发文档.doc', url: `xxx.pdf`, _X_KEY: '1111e' },
340
+ // { name: '深圳友聚信息技术开发文档.doc', url: `xxx.xlsx`, _X_KEY: '111122' },
341
+ // {
342
+ // name: '15806d21e3f445dcae0e2e0825c76a79.apk',
343
+ // url: `${baseUrl}/ufil/resource/image/20250817/15806d21e3f445dcae0e2e0825c76a79.apk`
344
+ // }
345
+ ];
346
+ if (fileUrl) {
347
+ if (fileUrl && isString(fileUrl)) {
348
+ const name = fileUrl.match(/[^\/\\]+$/)[0];
349
+ const file = { name, url: `${baseUrl}/ufil${fileUrl}` };
350
+ if (props.singleMode) {
351
+ fileList.value = file;
352
+ } else {
353
+ fileList.value.push(file);
354
+ }
355
+ } else if (isArray(fileUrl)) {
356
+ fileUrl.forEach(url => {
357
+ const name = url.match(/[^\/\\]+$/)[0];
358
+ fileList.value.push({ name, url: `${baseUrl}/ufil${url}` });
359
+ });
360
+ }
361
+ }
362
+ console.log('fileList');
363
+ });
159
364
  </script>
160
365
 
161
366
  <style lang="scss">
162
- .ut-upload-wrapper {
163
- .el-upload--picture-card {
164
- display: v-bind(display);
165
- width: v-bind(image_size) !important;
166
- height: v-bind(image_size) !important;
367
+ .ut-upload-item--small {
368
+ position: relative;
369
+ width: var(--vxe-ui-upload-image-wh-small);
370
+ height: var(--vxe-ui-upload-image-wh-small);
371
+
372
+ margin: var(--vxe-ui-layout-padding-half);
373
+ border: 1px solid var(--vxe-ui-input-border-color);
374
+ border-radius: var(--vxe-ui-base-border-radius);
375
+ .ut-upload--image {
376
+ position: relative;
377
+ border-radius: var(--vxe-ui-base-border-radius);
378
+ width: var(--vxe-ui-upload-image-wh-small);
379
+ height: var(--vxe-ui-upload-image-wh-small);
380
+ .ut-image-file--wrapper {
381
+ display: flex;
382
+ flex-direction: column;
383
+ align-items: center;
384
+ .ut-image-file {
385
+ font-size: 48px;
386
+ }
387
+ }
167
388
  }
389
+ }
168
390
 
169
- .el-upload-list--picture-card .el-upload-list__item {
170
- width: v-bind(image_size) !important;
171
- height: v-bind(image_size) !important;
391
+ .ut-upload-item--mini {
392
+ position: relative;
393
+ width: var(--vxe-ui-upload-image-wh-mini);
394
+ height: var(--vxe-ui-upload-image-wh-mini);
395
+
396
+ margin: var(--vxe-ui-layout-padding-half);
397
+ border: 1px solid var(--vxe-ui-input-border-color);
398
+ border-radius: var(--vxe-ui-base-border-radius);
399
+ .ut-upload--image {
400
+ position: relative;
401
+ border-radius: var(--vxe-ui-base-border-radius);
402
+ width: var(--vxe-ui-upload-image-wh-mini);
403
+ height: var(--vxe-ui-upload-image-wh-mini);
404
+ .ut-image-file--wrapper {
405
+ display: flex;
406
+ flex-direction: column;
407
+ align-items: center;
408
+ .ut-image-file {
409
+ font-size: 42px;
410
+ }
411
+ }
172
412
  }
413
+ }
173
414
 
174
- .el-upload-list--picture-card .el-progress {
175
- width: v-bind(process_size) !important;
415
+ .ut-upload-item--xs {
416
+ position: relative;
417
+ width: 48px;
418
+ height: 48px;
176
419
 
177
- .el-progress-circle {
178
- width: v-bind(process_size) !important;
179
- height: v-bind(process_size) !important;
420
+ margin: var(--vxe-ui-layout-padding-half);
421
+ border: 1px solid var(--vxe-ui-input-border-color);
422
+ border-radius: var(--vxe-ui-base-border-radius);
423
+ .ut-upload--image {
424
+ position: relative;
425
+ border-radius: var(--vxe-ui-base-border-radius);
426
+ width: 48px;
427
+ height: 48px;
428
+ .ut-image-file--wrapper {
429
+ display: flex;
430
+ flex-direction: column;
431
+ align-items: center;
432
+ .ut-image-file {
433
+ font-size: 32px;
434
+ }
180
435
  }
181
436
  }
182
437
  }
438
+
439
+ .ut-upload--btn:hover {
440
+ border: 1px dashed var(--udp-theme-vxeColor);
441
+ color: var(--udp-theme-vxeColor);
442
+ }
443
+
444
+ .ut-upload--image-item-btn-wrapper {
445
+ display: inline-flex;
446
+ justify-content: center;
447
+ position: absolute;
448
+ top: calc(var(--vxe-ui-layout-padding-half) * -1);
449
+ right: calc(var(--vxe-ui-layout-padding-half) * -1);
450
+ .ut-upload-remove--btn {
451
+ display: flex;
452
+ flex-direction: row;
453
+ justify-content: center;
454
+ align-items: center;
455
+ width: 1.8em;
456
+ height: 1.8em;
457
+ font-size: 0.8em;
458
+ border-radius: 50%;
459
+ color: #fff;
460
+ background-color: var(--vxe-ui-status-error-color);
461
+ z-index: 3;
462
+ cursor: pointer;
463
+ }
464
+ }
465
+
466
+ .ut-image {
467
+ height: 100%;
468
+ border-radius: var(--vxe-ui-base-border-radius);
469
+ }
470
+
471
+ .ut-image-hover:hover > .ut-image-file--wrapper {
472
+ display: none;
473
+ }
474
+
475
+ .ut-image-hover:hover > .ut-download-icon {
476
+ display: block;
477
+ }
478
+ .ut-download-icon {
479
+ display: none;
480
+ cursor: pointer;
481
+ }
183
482
  </style>
@@ -2,7 +2,7 @@
2
2
  * @Author: wei.li
3
3
  * @Date: 2022-03-02 17:07:59
4
4
  * @LastEditors: levi7754 levi7754@163.com
5
- * @LastEditTime: 2025-07-30 18:57:09
5
+ * @LastEditTime: 2025-08-19 10:19:16
6
6
  * @Description: SuForm
7
7
  -->
8
8
 
@@ -10,18 +10,18 @@
10
10
  <div class="width: 100%">
11
11
  <vxe-form
12
12
  ref="xForm"
13
- v-model:collapse-status="collapseStatus"
14
13
  :data="record"
15
14
  :items="formItems"
16
15
  :rules="rules"
17
16
  :loading="loading"
18
17
  :vertical="vertical"
19
- title-align="right"
20
18
  :title-width="titleWidth"
19
+ :disabled="dataStatus === 'detail'"
20
+ title-align="right"
21
+ title-bold
22
+ v-bind="$attrs"
21
23
  >
22
- <template #dividerPrefix>
23
- <div class="w-2 h-4 bg-amber-600">5555</div>
24
- </template>
24
+ <template #dividerPrefix />
25
25
  <template #collapseNode>
26
26
  <div class="flex justify-start">
27
27
  <vxe-checkbox
@@ -30,6 +30,7 @@
30
30
  :checked-value="false"
31
31
  :unchecked-value="true"
32
32
  class="pl-10"
33
+ @change="onChange"
33
34
  />
34
35
  </div>
35
36
  </template>
@@ -83,9 +84,13 @@ const rules = computed(() => {
83
84
 
84
85
  const formItems = computed(() => {
85
86
  if (!props.items.length) return props.items;
86
- return formatItems(props.items, props.dataStatus, 6);
87
+ return formatItems(props.items, 'edit', 6);
87
88
  });
88
89
 
90
+ const onChange = () => {
91
+ xForm.value.toggleCollapse();
92
+ };
93
+
89
94
  /**
90
95
  * @deprecated
91
96
  * @description 使用validate替换
@@ -18,18 +18,8 @@
18
18
  <vxe-grid ref="xgrid" v-bind="data" resizable @cell-dblclick="onCellClick" />
19
19
  </template>
20
20
  <template #footer>
21
- <vxe-button
22
- :content="$t('message.btn.cancel')"
23
- icon="ri-close-line"
24
- status="warning"
25
- @click="onClose"
26
- />
27
- <vxe-button
28
- :content="$t('message.btn.confirm')"
29
- icon="ri-save-3-line"
30
- status="primary"
31
- @click="onConfirm"
32
- />
21
+ <vxe-button :content="$t('message.btn.cancel')" icon="ri-close-line" status="warning" @click="onClose" />
22
+ <vxe-button :content="$t('message.btn.confirm')" icon="ri-save-3-line" status="primary" @click="onConfirm" />
33
23
  </template>
34
24
  </vxe-modal>
35
25
  <el-dialog
@@ -49,18 +39,8 @@
49
39
  </div>
50
40
  </template>
51
41
  <template #footer>
52
- <vxe-button
53
- :content="$t('message.btn.cancel')"
54
- icon="ri-close-line"
55
- status="warning"
56
- @click="onClose"
57
- />
58
- <vxe-button
59
- :content="$t('message.btn.confirm')"
60
- icon="ri-save-3-line"
61
- status="primary"
62
- @click="onConfirm"
63
- />
42
+ <vxe-button :content="$t('message.btn.cancel')" icon="ri-close-line" status="warning" @click="onClose" />
43
+ <vxe-button :content="$t('message.btn.confirm')" icon="ri-save-3-line" status="primary" @click="onConfirm" />
64
44
  </template>
65
45
  </el-dialog>
66
46
  <vxe-input
@@ -150,9 +130,7 @@ const data = reactive<VxeGridProps>({
150
130
  },
151
131
  ajax: {
152
132
  query: ({ page, form }) => {
153
- const commonParam = cookies.get('kCookies_param')
154
- ? JSON.parse(cookies.get('kCookies_param'))
155
- : {};
133
+ const commonParam = cookies.get('kCookies_param') ? JSON.parse(cookies.get('kCookies_param')) : {};
156
134
  let queryParams = Object.assign({}, form, commonParam, props.defaultParams);
157
135
  queryParams.pageNum = page?.currentPage || 1;
158
136
  queryParams.pageSize = page?.pageSize || 20;
@@ -361,9 +361,7 @@ const setErrorMessage = (array: ITableColProps[]) => {
361
361
  const formatterData = (formatterType: string) => {
362
362
  gridOptions.columns!.forEach((col: any) => {
363
363
  if (formatterType === 'toSave') {
364
- const commonParam = cookies.get('kCookies_param')
365
- ? JSON.parse(cookies.get('kCookies_param')!)
366
- : {};
364
+ const commonParam = cookies.get('kCookies_param') ? JSON.parse(cookies.get('kCookies_param')!) : {};
367
365
  dataList.forEach(data => {
368
366
  data[col.mapField] = data[col.field];
369
367
  Object.assign(data, commonParam, props.defaultParams);