@ebiz/designer-components 0.1.49 → 0.1.51
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.
- package/dist/designer-components.css +1 -1
- package/dist/index.mjs +13485 -13211
- package/package.json +1 -1
- package/src/components/EbizApprovalForm.vue +38 -10
- package/src/components/EbizFileList.vue +92 -76
- package/src/components/EbizSApprovalProcess.vue +352 -15
package/package.json
CHANGED
|
@@ -76,7 +76,6 @@
|
|
|
76
76
|
<t-dialog header="退回确认" :visible="showReturnDialog" :confirm-btn="{ content: '确定退回', theme: 'danger' }"
|
|
77
77
|
:cancel-btn="{ content: '取消', theme: 'default' }" @confirm="confirmReturn" @close="showReturnDialog = false">
|
|
78
78
|
<p>确定要退回该审批吗?</p>
|
|
79
|
-
<t-input v-model="returnReason" placeholder="请输入退回原因" />
|
|
80
79
|
</t-dialog>
|
|
81
80
|
</div>
|
|
82
81
|
</template>
|
|
@@ -311,7 +310,19 @@ const handlePass = async () => {
|
|
|
311
310
|
}
|
|
312
311
|
|
|
313
312
|
try {
|
|
314
|
-
await emit('pass', params)
|
|
313
|
+
//await emit('pass', params)
|
|
314
|
+
|
|
315
|
+
//通过审批申请
|
|
316
|
+
await request(
|
|
317
|
+
{
|
|
318
|
+
...params
|
|
319
|
+
},
|
|
320
|
+
{},
|
|
321
|
+
`/tasks/${params.taskId}/complete`
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
emit('pass')
|
|
325
|
+
|
|
315
326
|
comments.value = ''
|
|
316
327
|
attachments.value = []
|
|
317
328
|
} catch (err) {
|
|
@@ -322,7 +333,17 @@ const handlePass = async () => {
|
|
|
322
333
|
// 拒绝审批
|
|
323
334
|
const handleReject = async () => {
|
|
324
335
|
try {
|
|
325
|
-
await emit('reject', comments.value)
|
|
336
|
+
//await emit('reject', comments.value)
|
|
337
|
+
await request(
|
|
338
|
+
{
|
|
339
|
+
taskId: props.taskId,
|
|
340
|
+
comment: comments.value,
|
|
341
|
+
approve: false
|
|
342
|
+
},
|
|
343
|
+
{},
|
|
344
|
+
`/tasks/${props.taskId}/complete`
|
|
345
|
+
)
|
|
346
|
+
emit('reject')
|
|
326
347
|
comments.value = ''
|
|
327
348
|
attachments.value = []
|
|
328
349
|
} catch (err) {
|
|
@@ -341,7 +362,8 @@ const confirmTransfer = async () => {
|
|
|
341
362
|
const res = await request(
|
|
342
363
|
{
|
|
343
364
|
toUserId: String(transferApprover.value),
|
|
344
|
-
|
|
365
|
+
comment: comments.value,
|
|
366
|
+
attachments: attachments.value
|
|
345
367
|
},
|
|
346
368
|
{},
|
|
347
369
|
`/tasks/${props.taskId}/transfer`
|
|
@@ -371,7 +393,9 @@ const confirmReceiver = async () => {
|
|
|
371
393
|
saveData: {
|
|
372
394
|
id: props.approvalDetail.variables.form.id,
|
|
373
395
|
receiver: String(selectedReceiver.value),
|
|
374
|
-
taskId: props.taskId
|
|
396
|
+
taskId: props.taskId,
|
|
397
|
+
comment: comments.value,
|
|
398
|
+
attachments: attachments.value
|
|
375
399
|
}
|
|
376
400
|
},
|
|
377
401
|
{
|
|
@@ -410,7 +434,9 @@ const confirmAddSign = async () => {
|
|
|
410
434
|
const res = await request(
|
|
411
435
|
{
|
|
412
436
|
userIds: [selectedAddSignUser.value],
|
|
413
|
-
position: addSignPosition.value
|
|
437
|
+
position: addSignPosition.value,
|
|
438
|
+
comment: comments.value,
|
|
439
|
+
attachments: attachments.value
|
|
414
440
|
},
|
|
415
441
|
{},
|
|
416
442
|
`/tasks/${props.taskId}/addSign`
|
|
@@ -421,9 +447,10 @@ const confirmAddSign = async () => {
|
|
|
421
447
|
showAddSignDialog.value = false
|
|
422
448
|
selectedAddSignUser.value = null
|
|
423
449
|
|
|
424
|
-
if (addSignPosition.value === 'before') {
|
|
425
|
-
|
|
426
|
-
|
|
450
|
+
/* if (addSignPosition.value === 'before') {
|
|
451
|
+
emit('refresh')
|
|
452
|
+
} */
|
|
453
|
+
emit('refresh')
|
|
427
454
|
} catch (err) {
|
|
428
455
|
MessagePlugin.error(err.message || '加签失败')
|
|
429
456
|
}
|
|
@@ -434,7 +461,8 @@ const confirmReturn = async () => {
|
|
|
434
461
|
try {
|
|
435
462
|
const res = await request(
|
|
436
463
|
{
|
|
437
|
-
|
|
464
|
+
comment: comments.value,
|
|
465
|
+
attachments: attachments.value
|
|
438
466
|
},
|
|
439
467
|
{},
|
|
440
468
|
`/tasks/${props.taskId}/return`
|
|
@@ -1,73 +1,49 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="ebiz-file-list">
|
|
2
|
+
<div class="ebiz-file-list" :class="{ 'mini-mode': size === 'mini' }">
|
|
3
3
|
<div v-if="computedFiles.length === 0" class="empty-state">
|
|
4
4
|
<t-icon name="file" size="48px" />
|
|
5
5
|
<p>暂无文件</p>
|
|
6
6
|
</div>
|
|
7
|
-
<div v-else class="file-list-container">
|
|
8
|
-
<div
|
|
9
|
-
|
|
10
|
-
:key="index"
|
|
11
|
-
class="file-item"
|
|
12
|
-
@click="handleFileClick(file)"
|
|
13
|
-
>
|
|
7
|
+
<div v-else class="file-list-container" :class="{ 'mini-container': size === 'mini' }">
|
|
8
|
+
<div v-for="(file, index) in computedFiles" :key="index" class="file-item"
|
|
9
|
+
:class="{ 'mini-item': size === 'mini' }" @click="handleFileClick(file)">
|
|
14
10
|
<!-- 图片文件直接显示缩略图 -->
|
|
15
11
|
<div v-if="isImage(file.extension)" class="file-icon">
|
|
16
|
-
<t-image
|
|
17
|
-
:
|
|
18
|
-
:alt="file.name"
|
|
19
|
-
fit="cover"
|
|
20
|
-
loading="lazy"
|
|
21
|
-
:style="{ width: imageSize, height: imageSize, borderRadius: '4px' }"
|
|
22
|
-
@error="handleImageError"
|
|
23
|
-
/>
|
|
12
|
+
<t-image :src="file.url" :alt="file.name" fit="cover" loading="lazy"
|
|
13
|
+
:style="{ width: actualImageSize, height: actualImageSize, borderRadius: '4px' }" error="" />
|
|
24
14
|
</div>
|
|
25
|
-
|
|
15
|
+
|
|
26
16
|
<!-- 非图片文件显示图标 -->
|
|
27
17
|
<div v-else class="file-icon">
|
|
28
|
-
<t-icon :name="getFileIcon(file.extension)" :size="
|
|
18
|
+
<t-icon :name="getFileIcon(file.extension)" :size="actualImageSize"
|
|
19
|
+
:style="{ color: getFileColor(file.extension) }" />
|
|
29
20
|
</div>
|
|
30
|
-
|
|
31
|
-
<div class="file-info">
|
|
21
|
+
|
|
22
|
+
<div v-if="size !== 'mini'" class="file-info">
|
|
32
23
|
<div class="file-name" :title="file.name">{{ file.name }}</div>
|
|
33
24
|
<div class="file-meta">
|
|
34
25
|
<span v-if="showFileType" class="file-type">{{ file.extension?.toUpperCase() || '未知' }}</span>
|
|
35
26
|
<span v-if="showFileSize && file.size" class="file-size">{{ formatFileSize(file.size) }}</span>
|
|
36
27
|
</div>
|
|
37
28
|
</div>
|
|
38
|
-
|
|
29
|
+
|
|
39
30
|
<!-- 操作按钮 -->
|
|
40
|
-
<div v-if="showActions" class="file-actions">
|
|
41
|
-
<t-button
|
|
42
|
-
|
|
43
|
-
variant="text"
|
|
44
|
-
@click.stop="handleDownload(file)"
|
|
45
|
-
:title="isImage(file.extension) ? '查看' : '下载'"
|
|
46
|
-
>
|
|
31
|
+
<div v-if="showActions && size !== 'mini'" class="file-actions">
|
|
32
|
+
<t-button size="small" variant="text" @click.stop="handleDownload(file)"
|
|
33
|
+
:title="isImage(file.extension) ? '查看' : '下载'">
|
|
47
34
|
<t-icon :name="isImage(file.extension) ? 'view-list' : 'download'" />
|
|
48
35
|
</t-button>
|
|
49
|
-
<t-button
|
|
50
|
-
|
|
51
|
-
size="small"
|
|
52
|
-
variant="text"
|
|
53
|
-
theme="danger"
|
|
54
|
-
@click.stop="handleDelete(file, index)"
|
|
55
|
-
title="删除"
|
|
56
|
-
>
|
|
36
|
+
<t-button v-if="allowDelete" size="small" variant="text" theme="danger"
|
|
37
|
+
@click.stop="handleDelete(file, index)" title="删除">
|
|
57
38
|
<t-icon name="delete" />
|
|
58
39
|
</t-button>
|
|
59
40
|
</div>
|
|
60
41
|
</div>
|
|
61
42
|
</div>
|
|
62
|
-
|
|
43
|
+
|
|
63
44
|
<!-- 图片预览弹窗 -->
|
|
64
|
-
<t-image-viewer
|
|
65
|
-
|
|
66
|
-
:images="previewImages"
|
|
67
|
-
:index="previewIndex"
|
|
68
|
-
:close-on-esc="true"
|
|
69
|
-
@close="previewVisible = false"
|
|
70
|
-
/>
|
|
45
|
+
<t-image-viewer v-model:visible="previewVisible" :images="previewImages" :index="previewIndex" :close-on-esc="true"
|
|
46
|
+
@close="previewVisible = false" />
|
|
71
47
|
</div>
|
|
72
48
|
</template>
|
|
73
49
|
|
|
@@ -87,6 +63,11 @@ const props = defineProps({
|
|
|
87
63
|
type: [Array, String],
|
|
88
64
|
default: () => []
|
|
89
65
|
},
|
|
66
|
+
// 尺寸大小,支持default和mini
|
|
67
|
+
size: {
|
|
68
|
+
type: String,
|
|
69
|
+
default: 'default'
|
|
70
|
+
},
|
|
90
71
|
// 图片尺寸
|
|
91
72
|
imageSize: {
|
|
92
73
|
type: String,
|
|
@@ -145,18 +126,18 @@ const getFileExtension = (filename) => {
|
|
|
145
126
|
// 提取文件名
|
|
146
127
|
const extractFileName = (url) => {
|
|
147
128
|
if (!url) return '未知文件';
|
|
148
|
-
|
|
129
|
+
|
|
149
130
|
// 移除查询参数和锚点
|
|
150
131
|
const cleanUrl = url.split('?')[0].split('#')[0];
|
|
151
132
|
const parts = cleanUrl.split('/');
|
|
152
133
|
let fileName = parts[parts.length - 1] || '未知文件';
|
|
153
|
-
|
|
134
|
+
|
|
154
135
|
// 如果文件名为空或只是扩展名,生成一个默认名称
|
|
155
136
|
if (!fileName || fileName.startsWith('.')) {
|
|
156
137
|
const extension = getFileExtension(fileName || url);
|
|
157
138
|
fileName = extension ? `文件.${extension}` : '未知文件';
|
|
158
139
|
}
|
|
159
|
-
|
|
140
|
+
|
|
160
141
|
return fileName;
|
|
161
142
|
};
|
|
162
143
|
|
|
@@ -165,7 +146,7 @@ const parseFileInfo = (url) => {
|
|
|
165
146
|
const fullUrl = getFullUrl(url);
|
|
166
147
|
const fileName = extractFileName(url);
|
|
167
148
|
const extension = getFileExtension(fileName);
|
|
168
|
-
|
|
149
|
+
|
|
169
150
|
return {
|
|
170
151
|
name: fileName,
|
|
171
152
|
url: fullUrl,
|
|
@@ -177,12 +158,12 @@ const parseFileInfo = (url) => {
|
|
|
177
158
|
// 计算文件列表
|
|
178
159
|
const computedFiles = computed(() => {
|
|
179
160
|
let fileList = [];
|
|
180
|
-
|
|
161
|
+
|
|
181
162
|
if (typeof props.files === 'string') {
|
|
182
163
|
if (!props.files.trim()) {
|
|
183
164
|
return [];
|
|
184
165
|
}
|
|
185
|
-
|
|
166
|
+
|
|
186
167
|
// 判断是单个URL还是逗号分隔的多个URL
|
|
187
168
|
if (props.files.includes(',')) {
|
|
188
169
|
// 逗号分隔的多个URL
|
|
@@ -219,7 +200,7 @@ const computedFiles = computed(() => {
|
|
|
219
200
|
}
|
|
220
201
|
}).filter(file => file.url); // 过滤掉没有URL的文件
|
|
221
202
|
}
|
|
222
|
-
|
|
203
|
+
|
|
223
204
|
return fileList;
|
|
224
205
|
});
|
|
225
206
|
|
|
@@ -235,7 +216,7 @@ const getFileIcon = (extension) => {
|
|
|
235
216
|
// 文档类
|
|
236
217
|
'pdf': 'file-pdf',
|
|
237
218
|
'doc': 'file-word',
|
|
238
|
-
'docx': 'file-word',
|
|
219
|
+
'docx': 'file-word',
|
|
239
220
|
'xls': 'file-excel',
|
|
240
221
|
'xlsx': 'file-excel',
|
|
241
222
|
'ppt': 'file-powerpoint',
|
|
@@ -263,7 +244,7 @@ const getFileIcon = (extension) => {
|
|
|
263
244
|
'mov': 'file-video',
|
|
264
245
|
'wmv': 'file-video'
|
|
265
246
|
};
|
|
266
|
-
|
|
247
|
+
|
|
267
248
|
return iconMap[extension?.toLowerCase()] || 'file';
|
|
268
249
|
};
|
|
269
250
|
|
|
@@ -283,22 +264,27 @@ const getFileColor = (extension) => {
|
|
|
283
264
|
'mp3': '#FF9800',
|
|
284
265
|
'mp4': '#795548'
|
|
285
266
|
};
|
|
286
|
-
|
|
267
|
+
|
|
287
268
|
return colorMap[extension?.toLowerCase()] || '#666666';
|
|
288
269
|
};
|
|
289
270
|
|
|
271
|
+
// 计算实际使用的图片尺寸
|
|
272
|
+
const actualImageSize = computed(() => {
|
|
273
|
+
return props.size === 'mini' ? '20px' : props.imageSize;
|
|
274
|
+
});
|
|
275
|
+
|
|
290
276
|
// 格式化文件大小
|
|
291
277
|
const formatFileSize = (bytes) => {
|
|
292
278
|
if (!bytes) return '';
|
|
293
279
|
const units = ['B', 'KB', 'MB', 'GB'];
|
|
294
280
|
let size = bytes;
|
|
295
281
|
let unitIndex = 0;
|
|
296
|
-
|
|
282
|
+
|
|
297
283
|
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
298
284
|
size /= 1024;
|
|
299
285
|
unitIndex++;
|
|
300
286
|
}
|
|
301
|
-
|
|
287
|
+
|
|
302
288
|
return `${size.toFixed(1)} ${units[unitIndex]}`;
|
|
303
289
|
};
|
|
304
290
|
|
|
@@ -317,7 +303,7 @@ const handleDownload = (file) => {
|
|
|
317
303
|
document.body.appendChild(link);
|
|
318
304
|
link.click();
|
|
319
305
|
document.body.removeChild(link);
|
|
320
|
-
|
|
306
|
+
|
|
321
307
|
emit('file-download', file);
|
|
322
308
|
};
|
|
323
309
|
|
|
@@ -327,14 +313,14 @@ const handlePreview = (file) => {
|
|
|
327
313
|
previewImages.value = imageFiles.map(f => f.url);
|
|
328
314
|
previewIndex.value = imageFiles.findIndex(f => f.url === file.url);
|
|
329
315
|
previewVisible.value = true;
|
|
330
|
-
|
|
316
|
+
|
|
331
317
|
emit('file-preview', file);
|
|
332
318
|
};
|
|
333
319
|
|
|
334
320
|
// 文件点击处理
|
|
335
321
|
const handleFileClick = (file) => {
|
|
336
322
|
emit('file-click', file);
|
|
337
|
-
|
|
323
|
+
|
|
338
324
|
if (isImage(file.extension)) {
|
|
339
325
|
// 图片文件,显示预览
|
|
340
326
|
handlePreview(file);
|
|
@@ -361,7 +347,16 @@ const handleImageError = () => {
|
|
|
361
347
|
<style lang="less" scoped>
|
|
362
348
|
.ebiz-file-list {
|
|
363
349
|
width: 100%;
|
|
364
|
-
|
|
350
|
+
|
|
351
|
+
&.mini-mode {
|
|
352
|
+
.file-list-container {
|
|
353
|
+
display: flex;
|
|
354
|
+
flex-direction: row;
|
|
355
|
+
flex-wrap: wrap;
|
|
356
|
+
gap: 4px;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
365
360
|
.empty-state {
|
|
366
361
|
display: flex;
|
|
367
362
|
flex-direction: column;
|
|
@@ -369,19 +364,24 @@ const handleImageError = () => {
|
|
|
369
364
|
justify-content: center;
|
|
370
365
|
padding: 40px;
|
|
371
366
|
color: #999;
|
|
372
|
-
|
|
367
|
+
|
|
373
368
|
p {
|
|
374
369
|
margin: 8px 0 0 0;
|
|
375
370
|
font-size: 14px;
|
|
376
371
|
}
|
|
377
372
|
}
|
|
378
|
-
|
|
373
|
+
|
|
379
374
|
.file-list-container {
|
|
380
375
|
display: flex;
|
|
381
376
|
flex-direction: column;
|
|
382
377
|
gap: 8px;
|
|
378
|
+
|
|
379
|
+
&.mini-container {
|
|
380
|
+
flex-direction: row;
|
|
381
|
+
flex-wrap: wrap;
|
|
382
|
+
}
|
|
383
383
|
}
|
|
384
|
-
|
|
384
|
+
|
|
385
385
|
.file-item {
|
|
386
386
|
display: flex;
|
|
387
387
|
align-items: center;
|
|
@@ -391,31 +391,49 @@ const handleImageError = () => {
|
|
|
391
391
|
cursor: pointer;
|
|
392
392
|
transition: all 0.3s;
|
|
393
393
|
background: #fff;
|
|
394
|
-
|
|
394
|
+
|
|
395
|
+
&.mini-item {
|
|
396
|
+
padding: 0;
|
|
397
|
+
border: none;
|
|
398
|
+
background: transparent;
|
|
399
|
+
box-shadow: none;
|
|
400
|
+
margin-right: 8px;
|
|
401
|
+
margin-bottom: 8px;
|
|
402
|
+
|
|
403
|
+
&:hover {
|
|
404
|
+
border-color: transparent;
|
|
405
|
+
box-shadow: none;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
395
409
|
&:hover {
|
|
396
410
|
border-color: #0052d9;
|
|
397
411
|
box-shadow: 0 2px 8px rgba(0, 82, 217, 0.15);
|
|
398
|
-
|
|
412
|
+
|
|
399
413
|
.file-actions {
|
|
400
414
|
opacity: 1;
|
|
401
415
|
}
|
|
402
416
|
}
|
|
403
417
|
}
|
|
404
|
-
|
|
418
|
+
|
|
405
419
|
.file-icon {
|
|
406
420
|
margin-right: 12px;
|
|
407
421
|
flex-shrink: 0;
|
|
408
422
|
display: flex;
|
|
409
423
|
align-items: center;
|
|
410
424
|
justify-content: center;
|
|
411
|
-
width: v-bind(
|
|
412
|
-
height: v-bind(
|
|
425
|
+
width: v-bind(actualImageSize);
|
|
426
|
+
height: v-bind(actualImageSize);
|
|
427
|
+
|
|
428
|
+
.mini-item & {
|
|
429
|
+
margin-right: 0;
|
|
430
|
+
}
|
|
413
431
|
}
|
|
414
|
-
|
|
432
|
+
|
|
415
433
|
.file-info {
|
|
416
434
|
flex: 1;
|
|
417
435
|
min-width: 0;
|
|
418
|
-
|
|
436
|
+
|
|
419
437
|
.file-name {
|
|
420
438
|
font-size: 14px;
|
|
421
439
|
font-weight: 500;
|
|
@@ -425,11 +443,11 @@ const handleImageError = () => {
|
|
|
425
443
|
text-overflow: ellipsis;
|
|
426
444
|
white-space: nowrap;
|
|
427
445
|
}
|
|
428
|
-
|
|
446
|
+
|
|
429
447
|
.file-meta {
|
|
430
448
|
display: flex;
|
|
431
449
|
gap: 8px;
|
|
432
|
-
|
|
450
|
+
|
|
433
451
|
.file-size,
|
|
434
452
|
.file-type {
|
|
435
453
|
font-size: 12px;
|
|
@@ -437,7 +455,7 @@ const handleImageError = () => {
|
|
|
437
455
|
}
|
|
438
456
|
}
|
|
439
457
|
}
|
|
440
|
-
|
|
458
|
+
|
|
441
459
|
.file-actions {
|
|
442
460
|
display: flex;
|
|
443
461
|
gap: 4px;
|
|
@@ -446,6 +464,4 @@ const handleImageError = () => {
|
|
|
446
464
|
flex-shrink: 0;
|
|
447
465
|
}
|
|
448
466
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
</style>
|
|
467
|
+
</style>
|