@jari-ace/element-plus-component 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/flowShell/FlowFormShell.vue.d.ts +6 -0
- package/dist/components/flowShell/FlowFormShell.vue.d.ts.map +1 -1
- package/dist/components/flowShell/FlowFormShell.vue.js +329 -96
- package/dist/components/flowShell/FlowFormShell.vue.js.map +1 -1
- package/dist/components/upload/JaUploader.vue.d.ts +6 -0
- package/dist/components/upload/JaUploader.vue.d.ts.map +1 -1
- package/dist/components/upload/index.d.ts +8 -0
- package/dist/components/upload/index.d.ts.map +1 -1
- package/dist/components/upload/uploader.vue.d.ts +2 -0
- package/dist/components/upload/uploader.vue.d.ts.map +1 -1
- package/dist/components/upload/uploader.vue.js +28 -8
- package/dist/components/upload/uploader.vue.js.map +1 -1
- package/lib/index.css +1 -1
- package/lib/index.js +9265 -9134
- package/lib/index.umd.cjs +37 -37
- package/package.json +2 -2
- package/packages/components/flowShell/FlowFormShell.vue +238 -30
- package/packages/components/upload/uploader.vue +35 -9
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jari-ace/element-plus-component",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.3",
|
|
5
5
|
"main": "lib/index.umd.cjs",
|
|
6
6
|
"module": "lib/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"pretty-bytes": "^7.1.0",
|
|
28
28
|
"vue-pdf-embed": "^2.1.3",
|
|
29
29
|
"vue-router": "^5.0.1",
|
|
30
|
-
"@jari-ace/app-bolts": "0.7.
|
|
30
|
+
"@jari-ace/app-bolts": "0.7.11"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/lodash-es": "^4.17.12",
|
|
@@ -52,12 +52,9 @@
|
|
|
52
52
|
</template>
|
|
53
53
|
</el-result>
|
|
54
54
|
</div>
|
|
55
|
-
<div v-else
|
|
55
|
+
<div v-else>
|
|
56
56
|
<slot name="default" :flowParam="flowFormParam"></slot>
|
|
57
57
|
</div>
|
|
58
|
-
<div class="no-form-tip" v-else>
|
|
59
|
-
<el-empty description="暂无表单内容" />
|
|
60
|
-
</div>
|
|
61
58
|
</div>
|
|
62
59
|
</section>
|
|
63
60
|
|
|
@@ -107,19 +104,53 @@
|
|
|
107
104
|
<ja-button @click="handleForward" type="danger" shortcut="Ctrl+F" v-if="showForwardButton"
|
|
108
105
|
:tooltip="'保存并' + (flowFormParam?.taskInstance ? '结束当前工作步骤办理' : '发起工作')" :loading="saving"
|
|
109
106
|
:disabled="saving">{{
|
|
110
|
-
flowFormParam?.taskInstance ? "办理结束" : "
|
|
107
|
+
flowFormParam?.taskInstance ? "办理结束" : "发起流程" }}</ja-button>
|
|
111
108
|
<slot name="footer" :flowParam="flowFormParam"></slot>
|
|
112
109
|
</footer>
|
|
113
110
|
</div>
|
|
111
|
+
|
|
112
|
+
<!-- 流程选择对话框 -->
|
|
113
|
+
<el-dialog
|
|
114
|
+
v-model="flowSelectionDialogVisible"
|
|
115
|
+
title="选择流程"
|
|
116
|
+
width="500px"
|
|
117
|
+
:close-on-click-modal="false"
|
|
118
|
+
:show-close="false"
|
|
119
|
+
align-center
|
|
120
|
+
append-to-body
|
|
121
|
+
>
|
|
122
|
+
<el-scrollbar max-height="50vh">
|
|
123
|
+
<div class="flow-selection-list">
|
|
124
|
+
<el-card
|
|
125
|
+
v-for="flow in selectableFlows"
|
|
126
|
+
:key="flow.flowKey"
|
|
127
|
+
class="flow-selection-card"
|
|
128
|
+
shadow="hover"
|
|
129
|
+
@click="handleSelectFlow(flow)"
|
|
130
|
+
>
|
|
131
|
+
<div class="flow-card-content">
|
|
132
|
+
<div class="flow-caption">{{ flow.flowCaption }}</div>
|
|
133
|
+
<div class="flow-key">{{ flow.flowKey }}</div>
|
|
134
|
+
</div>
|
|
135
|
+
<el-icon><ArrowRight /></el-icon>
|
|
136
|
+
</el-card>
|
|
137
|
+
</div>
|
|
138
|
+
</el-scrollbar>
|
|
139
|
+
<template #footer>
|
|
140
|
+
<span class="dialog-footer">
|
|
141
|
+
<el-button @click="handleCancelFlowSelection">取消</el-button>
|
|
142
|
+
</span>
|
|
143
|
+
</template>
|
|
144
|
+
</el-dialog>
|
|
114
145
|
</div>
|
|
115
146
|
</template>
|
|
116
147
|
|
|
117
148
|
<script setup lang="ts" generic="T extends Record<string, any>">
|
|
118
149
|
import { ref, watch, computed, nextTick } from 'vue'
|
|
119
|
-
import { useTaskQueryApi, useFlowDefinitionApi, type FlowFormParamDto } from '@jari-ace/app-bolts'
|
|
150
|
+
import { useTaskQueryApi, useFlowDefinitionApi, type FlowFormParamDto, type ProjectedFlowDefinitionDto } from '@jari-ace/app-bolts'
|
|
120
151
|
import type { FlowProcessRequest, TaskInstanceDto } from '@jari-ace/app-bolts'
|
|
121
152
|
import { createAxiosWithoutCache, useLoading } from '@jari-ace/app-bolts'
|
|
122
|
-
import { ElMessage, ElTag, ElCard, ElButton, ElTimeline, ElTimelineItem, ElEmpty, ElIcon, ElResult } from 'element-plus'
|
|
153
|
+
import { ElMessage, ElTag, ElCard, ElButton, ElTimeline, ElTimelineItem, ElEmpty, ElIcon, ElResult, ElDialog, ElScrollbar } from 'element-plus'
|
|
123
154
|
import { JaButton } from '../button'
|
|
124
155
|
import { JaUserInfoTag } from '../userTag'
|
|
125
156
|
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue'
|
|
@@ -141,6 +172,10 @@ const props = withDefaults(defineProps<{
|
|
|
141
172
|
* 流程定义Key
|
|
142
173
|
*/
|
|
143
174
|
flowKey?: string
|
|
175
|
+
/**
|
|
176
|
+
* 业务标签,当 flowKey 为空时,根据 bizTag 查找流程
|
|
177
|
+
*/
|
|
178
|
+
bizTag?: string
|
|
144
179
|
/**
|
|
145
180
|
* 开始节点Key
|
|
146
181
|
*/
|
|
@@ -169,14 +204,20 @@ const props = withDefaults(defineProps<{
|
|
|
169
204
|
* 侧边栏默认是否收起
|
|
170
205
|
*/
|
|
171
206
|
defaultCollapsed?: boolean
|
|
207
|
+
/**
|
|
208
|
+
* 是否是新表单,如果为 true,则不等待 formId,直接加载流程定义。如果为 false,且没有 taskId,则会等待 formData.flowFormId 有值后再加载。
|
|
209
|
+
*/
|
|
210
|
+
isNewForm: boolean
|
|
172
211
|
}>(), {
|
|
173
212
|
appName: undefined,
|
|
174
213
|
flowKey: undefined,
|
|
214
|
+
bizTag: undefined,
|
|
175
215
|
startNodeKey: undefined,
|
|
176
216
|
taskInstanceId: undefined,
|
|
177
217
|
width: undefined,
|
|
178
218
|
height: undefined,
|
|
179
|
-
defaultCollapsed: false
|
|
219
|
+
defaultCollapsed: false,
|
|
220
|
+
isNewForm: false
|
|
180
221
|
})
|
|
181
222
|
|
|
182
223
|
// 内部状态
|
|
@@ -308,26 +349,59 @@ const getTaskStatus = (state?: number) => {
|
|
|
308
349
|
}
|
|
309
350
|
}
|
|
310
351
|
|
|
352
|
+
const actualFlowKey = ref(props.flowKey)
|
|
353
|
+
const flowSelectionDialogVisible = ref(false)
|
|
354
|
+
const selectableFlows = ref<ProjectedFlowDefinitionDto[]>([])
|
|
355
|
+
const selectableFlowParams = ref<FlowFormParamDto[]>([])
|
|
356
|
+
|
|
311
357
|
// 监听dialogVisible变化
|
|
312
358
|
watch(
|
|
313
359
|
() => dialogVisible.value,
|
|
314
360
|
async (newValue) => {
|
|
315
361
|
resetState()
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
362
|
+
actualFlowKey.value = props.flowKey
|
|
363
|
+
if (newValue) {
|
|
364
|
+
emits('open')
|
|
365
|
+
//等待状态同步
|
|
319
366
|
await nextTick()
|
|
320
|
-
|
|
367
|
+
if (props.taskId) {
|
|
368
|
+
// 场景一:通过 taskId 打开,直接加载
|
|
369
|
+
loadFlowFormParam()
|
|
370
|
+
} else if (props.isNewForm) {
|
|
371
|
+
// 场景二:明确是新表单发起流程,不等待 formId,直接加载流程定义
|
|
372
|
+
loadFlowFormParam()
|
|
373
|
+
} else if (props.formData?.flowFormId) {
|
|
374
|
+
// 场景三:非新表单,且一开始就已经有 formId,直接加载
|
|
375
|
+
loadFlowFormParam()
|
|
376
|
+
}
|
|
377
|
+
// 场景四:非新表单且没有 formId,什么都不做,等待 formData.flowFormId 的 watcher 触发
|
|
321
378
|
} else {
|
|
322
379
|
emits('closed')
|
|
323
380
|
}
|
|
324
381
|
}
|
|
325
382
|
)
|
|
326
383
|
|
|
384
|
+
// 监听 formData 的 flowFormId 变化,用于处理异步加载表单数据的场景
|
|
385
|
+
watch(
|
|
386
|
+
() => props.formData?.flowFormId,
|
|
387
|
+
(newFormId, oldFormId) => {
|
|
388
|
+
// 只有在 dialog 打开的情况下,且从无到有,或者发生了变化,且没有 taskId 的时候,才重新加载流程参数
|
|
389
|
+
if (dialogVisible.value && !props.taskId && !props.isNewForm && newFormId && newFormId !== oldFormId) {
|
|
390
|
+
// 避免重复加载,可以先重置
|
|
391
|
+
resetState()
|
|
392
|
+
actualFlowKey.value = props.flowKey
|
|
393
|
+
loadFlowFormParam()
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
)
|
|
397
|
+
|
|
327
398
|
// 重置状态
|
|
328
399
|
const resetState = () => {
|
|
329
400
|
error.value = ''
|
|
330
401
|
flowFormParam.value = undefined
|
|
402
|
+
selectableFlows.value = []
|
|
403
|
+
selectableFlowParams.value = []
|
|
404
|
+
actualFlowKey.value = undefined
|
|
331
405
|
}
|
|
332
406
|
|
|
333
407
|
// 加载流程表单参数
|
|
@@ -335,28 +409,45 @@ const loadFlowFormParam = async () => {
|
|
|
335
409
|
resetState()
|
|
336
410
|
const formId = props.formData?.flowFormId;
|
|
337
411
|
// 检查参数
|
|
338
|
-
// 必须提供 taskId,或者 appName 和 flowKey
|
|
339
|
-
if (!props.taskId && !(props.appName && props.flowKey)) {
|
|
340
|
-
ElMessage.error('参数错误: 必须提供taskId或appName、flowKey和flowFormId')
|
|
412
|
+
// 必须提供 taskId,或者 appName 和 (flowKey 或 bizTag)
|
|
413
|
+
if (!props.taskId && !(props.appName && (props.flowKey || props.bizTag))) {
|
|
414
|
+
ElMessage.error('参数错误: 必须提供taskId或appName、flowKey/bizTag和flowFormId')
|
|
341
415
|
return
|
|
342
416
|
}
|
|
343
|
-
|
|
344
|
-
try {
|
|
417
|
+
try {
|
|
345
418
|
if (props.taskId) {
|
|
346
419
|
// 优先使用Id
|
|
347
420
|
flowFormParam.value = await taskQueryApi.getTaskInstanceById(props.taskId)
|
|
348
|
-
} else if (formId) {
|
|
421
|
+
} else if (formId && props.flowKey) {
|
|
349
422
|
// 使用appName、flowKey、formId
|
|
350
|
-
|
|
423
|
+
const param = await taskQueryApi.getTaskByFormIdAndAppAndFlowKey(formId, props.appName!, props.flowKey!)
|
|
424
|
+
if (param && param.flowDefinition) {
|
|
425
|
+
flowFormParam.value = param
|
|
426
|
+
} else {
|
|
427
|
+
// 兜底:如果没查到流程参数或者只有表单数据没有流程实例,按照新建模式加载流程定义
|
|
428
|
+
const flowDefinition = await flowDefinitionApi.getEffectiveDefinition(props.appName!, props.flowKey!)
|
|
429
|
+
flowFormParam.value = {
|
|
430
|
+
flowDefinition: flowDefinition,
|
|
431
|
+
} as FlowFormParamDto
|
|
432
|
+
}
|
|
433
|
+
} else if (formId && props.bizTag) {
|
|
434
|
+
// formId 存在,但没有 flowKey,有 bizTag,查询可能存在的多个流程参数
|
|
435
|
+
const params = await taskQueryApi.getTasksByFormIdAndAppAndBizTag(formId, props.appName!, props.bizTag)
|
|
436
|
+
if (!params || params.length === 0 || !params.some(p => p.flowDefinition)) {
|
|
437
|
+
// 兜底:如果没查到,或者查出来的都没有流程定义,直接按照没有formId走新建模式处理
|
|
438
|
+
await loadNewFlowParamWithBizTag()
|
|
439
|
+
} else if (params.length === 1) {
|
|
440
|
+
flowFormParam.value = params[0]
|
|
441
|
+
actualFlowKey.value = params[0].flowDefinition?.flowKey
|
|
442
|
+
} else {
|
|
443
|
+
// 多于1个,不立即弹出选择框,先存起来,留到点击"发起工作"时再选
|
|
444
|
+
selectableFlowParams.value = params
|
|
445
|
+
selectableFlows.value = params.map(p => p.flowDefinition as ProjectedFlowDefinitionDto)
|
|
446
|
+
return
|
|
447
|
+
}
|
|
351
448
|
} else {
|
|
352
|
-
//
|
|
353
|
-
|
|
354
|
-
const flowDefinition = await flowDefinitionApi.getEffectiveDefinition(props.appName!, props.flowKey!)
|
|
355
|
-
// 构造部分 flowFormParam
|
|
356
|
-
flowFormParam.value = {
|
|
357
|
-
flowDefinition: flowDefinition,
|
|
358
|
-
// 其他字段为空
|
|
359
|
-
} as FlowFormParamDto
|
|
449
|
+
// 新建模式
|
|
450
|
+
await loadNewFlowParamWithBizTag()
|
|
360
451
|
}
|
|
361
452
|
} catch (e: any) {
|
|
362
453
|
ElMessage.error(e.message || '加载流程信息失败')
|
|
@@ -364,6 +455,68 @@ const loadFlowFormParam = async () => {
|
|
|
364
455
|
}
|
|
365
456
|
}
|
|
366
457
|
|
|
458
|
+
const loadNewFlowParamWithBizTag = async () => {
|
|
459
|
+
let keyToUse = props.flowKey
|
|
460
|
+
if (!keyToUse && props.bizTag) {
|
|
461
|
+
// 根据 bizTag 查询当前生效的可用流程
|
|
462
|
+
const res = await flowDefinitionApi.getEffectiveDefinitionsByBizTag(props.appName!, props.bizTag)
|
|
463
|
+
|
|
464
|
+
if (!res || res.length === 0) {
|
|
465
|
+
throw new Error(`未找到业务标签为 ${props.bizTag} 的生效可用流程定义`)
|
|
466
|
+
} else if (res.length === 1) {
|
|
467
|
+
keyToUse = res[0].flowKey
|
|
468
|
+
} else {
|
|
469
|
+
// 弹出选择对话框的动作延迟到点击发起工作
|
|
470
|
+
selectableFlows.value = res
|
|
471
|
+
return
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
actualFlowKey.value = keyToUse
|
|
476
|
+
|
|
477
|
+
// 获取流程定义
|
|
478
|
+
const flowDefinition = await flowDefinitionApi.getEffectiveDefinition(props.appName!, keyToUse!)
|
|
479
|
+
// 构造部分 flowFormParam
|
|
480
|
+
flowFormParam.value = {
|
|
481
|
+
flowDefinition: flowDefinition,
|
|
482
|
+
// 其他字段为空
|
|
483
|
+
} as FlowFormParamDto
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
const handleSelectFlow = async (flow: ProjectedFlowDefinitionDto) => {
|
|
487
|
+
flowSelectionDialogVisible.value = false
|
|
488
|
+
actualFlowKey.value = flow.flowKey
|
|
489
|
+
|
|
490
|
+
try {
|
|
491
|
+
if (selectableFlowParams.value.length > 0) {
|
|
492
|
+
// 已经有完整的流程参数了,直接使用
|
|
493
|
+
const param = selectableFlowParams.value.find(p => p.flowDefinition?.flowKey === flow.flowKey)
|
|
494
|
+
if (param) {
|
|
495
|
+
flowFormParam.value = param
|
|
496
|
+
// 选择了之后,直接执行原先因为需要选择而暂停的 发起/提交流程 操作
|
|
497
|
+
await executeForward()
|
|
498
|
+
return
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// 否则作为新建模式加载最新流程定义
|
|
503
|
+
const flowDefinition = await flowDefinitionApi.getEffectiveDefinition(props.appName!, flow.flowKey!)
|
|
504
|
+
flowFormParam.value = {
|
|
505
|
+
flowDefinition: flowDefinition,
|
|
506
|
+
} as FlowFormParamDto
|
|
507
|
+
// 选择了之后,直接执行原先因为需要选择而暂停的 发起/提交流程 操作
|
|
508
|
+
await executeForward()
|
|
509
|
+
} catch (e: any) {
|
|
510
|
+
ElMessage.error(e.message || '加载流程信息失败')
|
|
511
|
+
error.value = e.message
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const handleCancelFlowSelection = () => {
|
|
516
|
+
flowSelectionDialogVisible.value = false
|
|
517
|
+
// 取消选择不再关闭整个表单,只是取消本次的发起动作
|
|
518
|
+
}
|
|
519
|
+
|
|
367
520
|
// 底部按钮处理
|
|
368
521
|
const handleSave = async () => {
|
|
369
522
|
saving.value = true
|
|
@@ -373,7 +526,7 @@ const handleSave = async () => {
|
|
|
373
526
|
taskId: flowFormParam.value?.taskInstance?.id || '',
|
|
374
527
|
processRequestType: "SAVE_FORM",
|
|
375
528
|
appName: props.appName || '',
|
|
376
|
-
flowKey:
|
|
529
|
+
flowKey: actualFlowKey.value || '',
|
|
377
530
|
startNodeKey: props.startNodeKey || '',
|
|
378
531
|
forwardTo: []
|
|
379
532
|
},
|
|
@@ -384,7 +537,8 @@ const handleSave = async () => {
|
|
|
384
537
|
}
|
|
385
538
|
}
|
|
386
539
|
|
|
387
|
-
|
|
540
|
+
// 实际执行保存并转发的核心逻辑
|
|
541
|
+
const executeForward = async () => {
|
|
388
542
|
saving.value = true
|
|
389
543
|
try {
|
|
390
544
|
const p = flowFormParam.value
|
|
@@ -393,7 +547,7 @@ const handleForward = async () => {
|
|
|
393
547
|
taskId: p?.taskInstance?.id || '',
|
|
394
548
|
processRequestType: p?.taskInstance ? "FORWARD" : "INITIATE",
|
|
395
549
|
appName: props.appName || '',
|
|
396
|
-
flowKey:
|
|
550
|
+
flowKey: actualFlowKey.value || '',
|
|
397
551
|
startNodeKey: props.startNodeKey || '',
|
|
398
552
|
forwardTo: []
|
|
399
553
|
},
|
|
@@ -406,6 +560,16 @@ const handleForward = async () => {
|
|
|
406
560
|
}
|
|
407
561
|
}
|
|
408
562
|
|
|
563
|
+
const handleForward = async () => {
|
|
564
|
+
// 如果需要选择流程,并且还没有确定实际使用的 flowKey,则弹出选择对话框
|
|
565
|
+
if (selectableFlows.value.length > 1 && !actualFlowKey.value) {
|
|
566
|
+
flowSelectionDialogVisible.value = true
|
|
567
|
+
return
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
await executeForward()
|
|
571
|
+
}
|
|
572
|
+
|
|
409
573
|
</script>
|
|
410
574
|
|
|
411
575
|
<style>
|
|
@@ -715,4 +879,48 @@ const handleForward = async () => {
|
|
|
715
879
|
box-shadow: 0 -1px 4px rgba(0, 0, 0, 0.05);
|
|
716
880
|
z-index: 100;
|
|
717
881
|
}
|
|
882
|
+
|
|
883
|
+
/* 流程选择弹窗样式 */
|
|
884
|
+
.flow-selection-list {
|
|
885
|
+
display: flex;
|
|
886
|
+
flex-direction: column;
|
|
887
|
+
gap: 12px;
|
|
888
|
+
padding: 4px;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
.flow-selection-card {
|
|
892
|
+
cursor: pointer;
|
|
893
|
+
transition: all 0.3s;
|
|
894
|
+
border: 1px solid #e4e7ed;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
.flow-selection-card:hover {
|
|
898
|
+
border-color: var(--el-color-primary);
|
|
899
|
+
transform: translateY(-2px);
|
|
900
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
.flow-selection-card :deep(.el-card__body) {
|
|
904
|
+
display: flex;
|
|
905
|
+
justify-content: space-between;
|
|
906
|
+
align-items: center;
|
|
907
|
+
padding: 16px;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
.flow-card-content {
|
|
911
|
+
display: flex;
|
|
912
|
+
flex-direction: column;
|
|
913
|
+
gap: 4px;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
.flow-caption {
|
|
917
|
+
font-size: 16px;
|
|
918
|
+
font-weight: 500;
|
|
919
|
+
color: #303133;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
.flow-key {
|
|
923
|
+
font-size: 13px;
|
|
924
|
+
color: #909399;
|
|
925
|
+
}
|
|
718
926
|
</style>
|
|
@@ -175,6 +175,10 @@ const emits = defineEmits<{
|
|
|
175
175
|
* 单个文件上传失败事件
|
|
176
176
|
*/
|
|
177
177
|
uploadError: [file: AceFile, error: Error]
|
|
178
|
+
/**
|
|
179
|
+
* 获取平台记录的文件信息,当文件列表加载、上传、删除时会触发此事件,向外传递文件信息
|
|
180
|
+
*/
|
|
181
|
+
fileInfosChanged: [files: FileInfo[]]
|
|
178
182
|
/**
|
|
179
183
|
* 下载完成事件
|
|
180
184
|
*/
|
|
@@ -211,8 +215,11 @@ async function updateAllowedClassificationLevels() {
|
|
|
211
215
|
async function loadFileInfos() {
|
|
212
216
|
if (!curAttachToken.value) {
|
|
213
217
|
files.value = [];
|
|
218
|
+
emits('fileInfosChanged', files.value)
|
|
219
|
+
return;
|
|
214
220
|
}
|
|
215
221
|
files.value = await api.getFileList(curAttachToken.value!);
|
|
222
|
+
emits('fileInfosChanged', files.value)
|
|
216
223
|
}
|
|
217
224
|
|
|
218
225
|
function createUppyInstance() {
|
|
@@ -224,13 +231,12 @@ function createUppyInstance() {
|
|
|
224
231
|
autoProceed: true,
|
|
225
232
|
locale: zhCN
|
|
226
233
|
}).on("progress", progress => {
|
|
227
|
-
if (progress == 100) {
|
|
228
|
-
loadFileInfos();
|
|
229
|
-
}
|
|
230
234
|
uploadingProgress.value = progress;
|
|
231
235
|
});
|
|
232
|
-
|
|
233
|
-
|
|
236
|
+
|
|
237
|
+
let urlPrefix = getUrlPrefix();
|
|
238
|
+
uppy.use(Tus, {
|
|
239
|
+
endpoint: new URL(urlPrefix + "/uploads", location.origin).toString(),
|
|
234
240
|
withCredentials: true,
|
|
235
241
|
retryDelays: undefined,
|
|
236
242
|
chunkSize: !uploadInitParams.value?.chunkSize || uploadInitParams.value?.chunkSize
|
|
@@ -238,7 +244,8 @@ function createUppyInstance() {
|
|
|
238
244
|
parallelUploads: 1,
|
|
239
245
|
headers: {
|
|
240
246
|
aceAttachId: attachId.value!,
|
|
241
|
-
aceNewForm: isNewForm.value ? "yes" : "no"
|
|
247
|
+
aceNewForm: isNewForm.value ? "yes" : "no",
|
|
248
|
+
'X-Forwarded-Prefix': urlPrefix
|
|
242
249
|
},
|
|
243
250
|
metadata: {
|
|
244
251
|
attachId: attachId.value!,
|
|
@@ -251,7 +258,7 @@ function createUppyInstance() {
|
|
|
251
258
|
configKey: props.configKey,
|
|
252
259
|
appServiceName: props.serviceName,
|
|
253
260
|
classifiedLevel: selectedFileClassificationLevel.value.toString()
|
|
254
|
-
}
|
|
261
|
+
},
|
|
255
262
|
});
|
|
256
263
|
if (cfg.enableWebcam) {
|
|
257
264
|
uppy.use(Webcam, {
|
|
@@ -317,6 +324,10 @@ function createUppyInstance() {
|
|
|
317
324
|
}).on('upload-success', file => {
|
|
318
325
|
emits('uploadSuccess', file)
|
|
319
326
|
}).on('complete', (result) => {
|
|
327
|
+
if (result.failed || result.failed.length == 0) {
|
|
328
|
+
uppy.clear()
|
|
329
|
+
}
|
|
330
|
+
loadFileInfos()
|
|
320
331
|
emits('complete', result.successful, result.failed)
|
|
321
332
|
}).on('error', (error) => {
|
|
322
333
|
emits('error', error)
|
|
@@ -325,6 +336,18 @@ function createUppyInstance() {
|
|
|
325
336
|
})
|
|
326
337
|
}
|
|
327
338
|
|
|
339
|
+
function getUrlPrefix() {
|
|
340
|
+
let isDev = window.appDescriptor?.env.isDevMode();
|
|
341
|
+
if (window.rawWindow) {
|
|
342
|
+
isDev = window.rawWindow.appDescriptor.env.isDevMode();
|
|
343
|
+
}
|
|
344
|
+
let urlPrefix = "/ace-file-service";
|
|
345
|
+
if (isDev) {
|
|
346
|
+
urlPrefix = "/ace/ace-file-service";
|
|
347
|
+
}
|
|
348
|
+
return urlPrefix;
|
|
349
|
+
}
|
|
350
|
+
|
|
328
351
|
async function onUploadBtnClick() {
|
|
329
352
|
console.log('upload btn clicked')
|
|
330
353
|
const cfg = uploadInitParams.value?.fileConfig;
|
|
@@ -376,6 +399,7 @@ function handleClassificationLevelSelCmd(level: number) {
|
|
|
376
399
|
async function initLoad() {
|
|
377
400
|
uploadInitParams.value = await api.initLoad(props.serviceName, props.configKey, props.attachToken!);
|
|
378
401
|
files.value = uploadInitParams.value.files;
|
|
402
|
+
emits('fileInfosChanged', files.value)
|
|
379
403
|
attachId.value = uploadInitParams.value?.attachId;
|
|
380
404
|
curAttachToken.value = uploadInitParams.value?.attachId;
|
|
381
405
|
isNewForm.value = false;
|
|
@@ -386,6 +410,7 @@ async function initLoad() {
|
|
|
386
410
|
async function initNew() {
|
|
387
411
|
uploadInitParams.value = await api.initNew(props.serviceName, props.configKey);
|
|
388
412
|
files.value = uploadInitParams.value.files;
|
|
413
|
+
emits('fileInfosChanged', files.value)
|
|
389
414
|
attachId.value = uploadInitParams.value?.attachId;
|
|
390
415
|
curAttachToken.value = uploadInitParams.value?.attachToken;
|
|
391
416
|
isNewForm.value = true;
|
|
@@ -397,10 +422,11 @@ async function initNew() {
|
|
|
397
422
|
async function delUploadedFile(file: FileInfo) {
|
|
398
423
|
await api.deleteFile(file.token || file.id);
|
|
399
424
|
files.value = files.value.filter(f => f.id !== file.id);
|
|
425
|
+
emits('fileInfosChanged', files.value)
|
|
400
426
|
}
|
|
401
427
|
|
|
402
428
|
function previewFile(fileToken: string) {
|
|
403
|
-
pdfSrc.value = new URL("uploads/preview/" + fileToken, location.origin).toString()
|
|
429
|
+
pdfSrc.value = new URL(getUrlPrefix() + "/uploads/preview/" + fileToken, location.origin).toString()
|
|
404
430
|
pdfViewerVisible.value = true;
|
|
405
431
|
}
|
|
406
432
|
|
|
@@ -634,7 +660,7 @@ function getFileIcon(fileName: string) {
|
|
|
634
660
|
</div>
|
|
635
661
|
<div v-if="layout === 'list'" class="file-list"
|
|
636
662
|
:style="{ height: typeof props.height === 'number' ? props.height + 'px' : props.height, maxHeight: typeof props.maxHeight === 'number' ? props.maxHeight + 'px' : props.maxHeight }">
|
|
637
|
-
<div v-if="files?.length
|
|
663
|
+
<div v-if="!files || files?.length == 0" class="empty-text">暂无文件</div>
|
|
638
664
|
<div v-for="file in files" :key="file.id" class="file-item">
|
|
639
665
|
<div class="file-main">
|
|
640
666
|
<el-icon class="file-icon">
|