vue2-client 1.19.59 → 1.19.61
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/package.json
CHANGED
|
@@ -106,7 +106,14 @@
|
|
|
106
106
|
<div v-if="item.showAvatar" class="gender-icon">
|
|
107
107
|
<img :src="maleIcon" alt="male" class="gender-img" />
|
|
108
108
|
</div>
|
|
109
|
-
<span class="label-text">
|
|
109
|
+
<span class="label-text">
|
|
110
|
+
<template v-if="item.type === 'list'">
|
|
111
|
+
<span class="list-label-text">{{ item.label }}</span>
|
|
112
|
+
</template>
|
|
113
|
+
<template v-else>
|
|
114
|
+
{{ item.label }}<span v-if="item.type !== 'list' && getItemColon(item)" class="colon">:</span>
|
|
115
|
+
</template>
|
|
116
|
+
</span>
|
|
110
117
|
</div>
|
|
111
118
|
</template>
|
|
112
119
|
<a-tooltip
|
|
@@ -172,7 +179,14 @@
|
|
|
172
179
|
<div v-if="item.showAvatar" class="gender-icon">
|
|
173
180
|
<img :src="maleIcon" alt="male" class="gender-img" />
|
|
174
181
|
</div>
|
|
175
|
-
<span class="label-text">
|
|
182
|
+
<span class="label-text">
|
|
183
|
+
<template v-if="item.type === 'list'">
|
|
184
|
+
<span class="list-label-text">{{ item.label }}</span>
|
|
185
|
+
</template>
|
|
186
|
+
<template v-else>
|
|
187
|
+
{{ item.label }}
|
|
188
|
+
</template>
|
|
189
|
+
</span>
|
|
176
190
|
</div>
|
|
177
191
|
</template>
|
|
178
192
|
<div
|
|
@@ -458,6 +472,7 @@ export default {
|
|
|
458
472
|
return {
|
|
459
473
|
hiddenConfig: '-1^',
|
|
460
474
|
data: null,
|
|
475
|
+
rawData: null,
|
|
461
476
|
config: null,
|
|
462
477
|
showAllItems: false,
|
|
463
478
|
maleIcon: require('@vue2-client/assets/svg/male.svg')
|
|
@@ -606,20 +621,62 @@ export default {
|
|
|
606
621
|
methods: {
|
|
607
622
|
async getData (data, parameterData) {
|
|
608
623
|
this.data = null
|
|
624
|
+
this.config = null
|
|
609
625
|
this.showAllItems = false
|
|
610
626
|
getConfigByName(data, 'af-his', res => {
|
|
611
627
|
this.config = res
|
|
612
628
|
const hiddenConfig = (this.config && this.config.hiddenConfig) || (0 === 1)
|
|
613
629
|
const parameter = { ...res.parameter, ...this.parameter, ...parameterData }
|
|
614
630
|
runLogic(res.logicName, parameter, 'af-his').then(result => {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
631
|
+
// 如果配置启用 parseList(或 expandList),将 type=list 的父项展开为父项 + 子项(子项来自 result 中对应的数组)
|
|
632
|
+
const expandFlag = Boolean(res.expandList || res.parseList)
|
|
633
|
+
// 不用展开则直接将结果赋值给augmented
|
|
634
|
+
if(!expandFlag){
|
|
635
|
+
if (hiddenConfig) {
|
|
636
|
+
for (const key in result) {
|
|
637
|
+
if (Object.prototype.hasOwnProperty.call(result, key) && result[key] === this.hiddenConfig) {
|
|
638
|
+
delete result[key]
|
|
639
|
+
}
|
|
619
640
|
}
|
|
620
641
|
}
|
|
642
|
+
this.data = result
|
|
643
|
+
}
|
|
644
|
+
const augmented = {}
|
|
645
|
+
if (expandFlag && Array.isArray(res.items)) {
|
|
646
|
+
// 在 expandFlag && Array.isArray(res.items) 的分支内
|
|
647
|
+
const expandedItems = []
|
|
648
|
+
// 用快照遍历,避免遍历被修改过的 res.items
|
|
649
|
+
const originalItems = Array.isArray(res.items) ? res.items.slice() : []
|
|
650
|
+
originalItems.forEach(parentItem => {
|
|
651
|
+
if (!parentItem) return
|
|
652
|
+
if (parentItem.type === 'list') {
|
|
653
|
+
expandedItems.push(parentItem)
|
|
654
|
+
const arr = result ? result[parentItem.field] : null
|
|
655
|
+
if (Array.isArray(arr)) {
|
|
656
|
+
augmented[parentItem.field] = ''
|
|
657
|
+
arr.forEach((sub, idx) => {
|
|
658
|
+
const childItem = {
|
|
659
|
+
field: sub.field || `${parentItem.field}_${idx + 1}`,
|
|
660
|
+
label: sub.label ?? '',
|
|
661
|
+
colon: sub.colon ? sub.colon : parentItem.colon,
|
|
662
|
+
style: parentItem.style ? { ...parentItem.style } : undefined,
|
|
663
|
+
showAvatar: parentItem.showAvatar,
|
|
664
|
+
unit: parentItem.unit,
|
|
665
|
+
}
|
|
666
|
+
if (sub && sub.value !== undefined) augmented[childItem.field] = sub.value
|
|
667
|
+
expandedItems.push(childItem)
|
|
668
|
+
})
|
|
669
|
+
}
|
|
670
|
+
} else {
|
|
671
|
+
// 普通项直接加入
|
|
672
|
+
expandedItems.push(parentItem)
|
|
673
|
+
}
|
|
674
|
+
})
|
|
675
|
+
// 不要改原 res,创建新 config
|
|
676
|
+
this.rawData = result
|
|
677
|
+
this.config = { ...res, items: expandedItems }
|
|
678
|
+
this.data = augmented
|
|
621
679
|
}
|
|
622
|
-
this.data = result
|
|
623
680
|
})
|
|
624
681
|
})
|
|
625
682
|
},
|
|
@@ -797,6 +854,10 @@ export default {
|
|
|
797
854
|
text-decoration: none !important;
|
|
798
855
|
}
|
|
799
856
|
|
|
857
|
+
.list-label-text{
|
|
858
|
+
font-weight: bold;
|
|
859
|
+
}
|
|
860
|
+
|
|
800
861
|
.content-wrapper {
|
|
801
862
|
display: inline-flex;
|
|
802
863
|
align-items: center;
|
|
@@ -80,9 +80,12 @@
|
|
|
80
80
|
slot="extraBeforeTabs"
|
|
81
81
|
key="workFlowTab"
|
|
82
82
|
tab="表单"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
>
|
|
84
|
+
<work-flow-step-files-preview
|
|
85
|
+
v-if="historyFormCompletedDataPreview"
|
|
86
|
+
:preview="historyFormCompletedDataPreview"
|
|
87
|
+
/>
|
|
88
|
+
<a-divider/>
|
|
86
89
|
<x-add-native-form
|
|
87
90
|
ref="xAddForm"
|
|
88
91
|
@x-form-item-emit-func="formItemEmitFunc"
|
|
@@ -90,8 +93,11 @@
|
|
|
90
93
|
</a-tab-pane>
|
|
91
94
|
</x-tab>
|
|
92
95
|
<div v-else>
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
<work-flow-step-files-preview
|
|
97
|
+
v-if="historyFormCompletedDataPreview"
|
|
98
|
+
:preview="historyFormCompletedDataPreview"
|
|
99
|
+
/>
|
|
100
|
+
<a-divider/>
|
|
95
101
|
<x-add-native-form
|
|
96
102
|
ref="xAddForm"
|
|
97
103
|
@x-form-item-emit-func="formItemEmitFunc"
|
|
@@ -287,6 +293,7 @@ import { getConfigByNameAsync, runLogic } from '@vue2-client/services/api/common
|
|
|
287
293
|
import LogicRunner from '@vue2-client/logic/LogicRunner'
|
|
288
294
|
import XTab from '@vue2-client/base-client/components/common/XTab/XTab.vue'
|
|
289
295
|
import WorkFlowPreview from '@vue2-client/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowPreview'
|
|
296
|
+
import WorkFlowStepFilesPreview from '@vue2-client/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowStepFilesPreview.vue'
|
|
290
297
|
import WorkflowPersonSelector from '@vue2-client/pages/WorkflowDetail/WorkflowPageDetail/components/WorkflowPersonSelector.vue'
|
|
291
298
|
|
|
292
299
|
export default {
|
|
@@ -308,6 +315,7 @@ export default {
|
|
|
308
315
|
FileItem,
|
|
309
316
|
ImageItem,
|
|
310
317
|
WorkFlowPreview,
|
|
318
|
+
WorkFlowStepFilesPreview,
|
|
311
319
|
WorkflowPersonSelector
|
|
312
320
|
},
|
|
313
321
|
computed: {
|
|
@@ -962,73 +970,82 @@ export default {
|
|
|
962
970
|
this.historyFormCompletedDataPreview = null
|
|
963
971
|
// 表单的渲染
|
|
964
972
|
if (properties.form && properties.form.formJson) {
|
|
973
|
+
|
|
974
|
+
// 当前处理环节 是否展示历史数据配置
|
|
965
975
|
if (properties.otherProperty && properties.otherProperty.historyFormData) {
|
|
966
976
|
const historyFormDataConfig = properties.otherProperty.historyFormData
|
|
967
977
|
|
|
968
|
-
//
|
|
969
|
-
const
|
|
970
|
-
const
|
|
978
|
+
// 预处理
|
|
979
|
+
const stepIdByName = new Map(this.stepsForChild.map(step => [step.name, step.id]))
|
|
980
|
+
const stepFormJsonByStepId = new Map(
|
|
981
|
+
this.stepsDefine.map(step => [step.id, step?.properties?.form?.formJson])
|
|
982
|
+
)
|
|
971
983
|
|
|
984
|
+
const stepIdSet = new Set()
|
|
972
985
|
for (const historyFormConfig of historyFormDataConfig) {
|
|
973
|
-
const
|
|
974
|
-
if (
|
|
975
|
-
|
|
976
|
-
|
|
986
|
+
const targetStepId = stepIdByName.get(historyFormConfig.stepName)
|
|
987
|
+
if (targetStepId == null) continue
|
|
988
|
+
stepIdSet.add(targetStepId)
|
|
989
|
+
}
|
|
977
990
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
991
|
+
const stepIdS = Array.from(stepIdSet)
|
|
992
|
+
if (stepIdS.length > 0) {
|
|
993
|
+
const allStepData = await postByServiceName('/logic/geWorkFlowCompletedStepDataBySteps', {
|
|
994
|
+
workflowId: this.workflowId,
|
|
995
|
+
stepIdS
|
|
996
|
+
})
|
|
983
997
|
|
|
984
|
-
|
|
985
|
-
const
|
|
998
|
+
// 组装历史表单数据(data 部分)和按步骤分组的附件
|
|
999
|
+
const historyFormData = []
|
|
1000
|
+
const stepAttachmentsMap = new Map()
|
|
986
1001
|
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1002
|
+
for (const historyFormConfig of historyFormDataConfig) {
|
|
1003
|
+
const targetStepId = stepIdByName.get(historyFormConfig.stepName)
|
|
1004
|
+
if (targetStepId == null) continue
|
|
990
1005
|
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
stepId,
|
|
994
|
-
model,
|
|
995
|
-
displayLabel: historyFormConfig.displayLabel
|
|
996
|
-
})
|
|
997
|
-
stepIdSet.add(stepId)
|
|
998
|
-
}
|
|
1006
|
+
const stepFormJson = stepFormJsonByStepId.get(targetStepId)
|
|
1007
|
+
if (!stepFormJson) continue
|
|
999
1008
|
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
const queryPromises = Array.from(stepIdSet).map(async stepId => {
|
|
1003
|
-
try {
|
|
1004
|
-
const formData = await postByServiceName(
|
|
1005
|
-
workFlowViewApi.getWorkFlowCompletedStepData,
|
|
1006
|
-
{ workflowId: this.workflowId, stepId }
|
|
1007
|
-
)
|
|
1008
|
-
formDataCache.set(stepId, formData.data || {})
|
|
1009
|
-
} catch (error) {
|
|
1010
|
-
console.error(`查询步骤 ${stepId} 的数据失败:`, error)
|
|
1011
|
-
formDataCache.set(stepId, {})
|
|
1012
|
-
}
|
|
1013
|
-
})
|
|
1009
|
+
const stepDataRaw = allStepData?.[targetStepId] || allStepData?.[String(targetStepId)]
|
|
1010
|
+
if (!stepDataRaw) continue
|
|
1014
1011
|
|
|
1015
|
-
|
|
1016
|
-
await Promise.all(queryPromises)
|
|
1012
|
+
const isAttachment = historyFormConfig.displayLabel === '附件' && historyFormConfig.formLabel === '附件'
|
|
1017
1013
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1014
|
+
if (isAttachment) {
|
|
1015
|
+
// 仅在配置了附件时才收集对应步骤的附件
|
|
1016
|
+
if (!stepAttachmentsMap.has(targetStepId)) {
|
|
1017
|
+
stepAttachmentsMap.set(targetStepId, {
|
|
1018
|
+
stepId: targetStepId,
|
|
1019
|
+
stepName: historyFormConfig.stepName,
|
|
1020
|
+
data: [],
|
|
1021
|
+
images: [],
|
|
1022
|
+
files: []
|
|
1023
|
+
})
|
|
1024
|
+
}
|
|
1025
|
+
const attachment = stepAttachmentsMap.get(targetStepId)
|
|
1026
|
+
attachment.images = Array.isArray(stepDataRaw.images) ? stepDataRaw.images : []
|
|
1027
|
+
attachment.files = Array.isArray(stepDataRaw.files) ? stepDataRaw.files : []
|
|
1028
|
+
} else {
|
|
1029
|
+
const formItem = stepFormJson.find(item => item.name === historyFormConfig.formLabel)
|
|
1030
|
+
const model = formItem?.model
|
|
1031
|
+
if (!model) continue
|
|
1032
|
+
// 普通字段:从 data 中取值,并按 displayLabel 组织
|
|
1033
|
+
const value = stepDataRaw.data ? stepDataRaw.data[model] : undefined
|
|
1034
|
+
if (value === undefined || value === null) continue
|
|
1035
|
+
historyFormData.push({
|
|
1036
|
+
label: historyFormConfig.displayLabel,
|
|
1037
|
+
value
|
|
1038
|
+
})
|
|
1039
|
+
}
|
|
1024
1040
|
}
|
|
1025
|
-
})
|
|
1026
1041
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1042
|
+
// 聚合所有步骤的附件到统一的 images/files,同时保留按步骤分组的数据
|
|
1043
|
+
const stepAttachments = Array.from(stepAttachmentsMap.values())
|
|
1044
|
+
|
|
1045
|
+
this.historyFormCompletedDataPreview = {
|
|
1046
|
+
data: historyFormData,
|
|
1047
|
+
stepAttachments,
|
|
1048
|
+
}
|
|
1032
1049
|
}
|
|
1033
1050
|
}
|
|
1034
1051
|
this.stepDefine = properties.form.formJson
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="workflow-step-preview">
|
|
3
|
+
<!-- data:不分步骤,直接展示(有就展示,没有就不展示) -->
|
|
4
|
+
<a-descriptions
|
|
5
|
+
v-if="previewData && previewData.length"
|
|
6
|
+
:column="{ xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 }"
|
|
7
|
+
bordered
|
|
8
|
+
size="small"
|
|
9
|
+
class="descriptionPreviewItem"
|
|
10
|
+
>
|
|
11
|
+
<p slot="title" class="descriptionTitle">
|
|
12
|
+
填写历史
|
|
13
|
+
</p>
|
|
14
|
+
<a-descriptions-item
|
|
15
|
+
v-for="(item, idx) in previewData"
|
|
16
|
+
:key="item.label || idx"
|
|
17
|
+
v-if="item.label !== '附件上传' && item.label !== '__expressionRs'"
|
|
18
|
+
>
|
|
19
|
+
<span slot="label" class="label">{{ item.label }}</span>
|
|
20
|
+
<span v-if="(item.type ?? 'default') === 'image'">
|
|
21
|
+
<div class="value">
|
|
22
|
+
<image-item :images="item.value" :width="70" :padding="0"/>
|
|
23
|
+
</div>
|
|
24
|
+
</span>
|
|
25
|
+
<span v-else>
|
|
26
|
+
<div class="value">{{ item.value }}</div>
|
|
27
|
+
</span>
|
|
28
|
+
</a-descriptions-item>
|
|
29
|
+
</a-descriptions>
|
|
30
|
+
|
|
31
|
+
<!-- 附件:按步骤分组展示(有就展示,没有就不展示) -->
|
|
32
|
+
<a-card
|
|
33
|
+
v-for="step in normalizedAttachmentSteps"
|
|
34
|
+
:key="step.stepId"
|
|
35
|
+
size="small"
|
|
36
|
+
class="step-card"
|
|
37
|
+
:bordered="false"
|
|
38
|
+
>
|
|
39
|
+
<template slot="title">
|
|
40
|
+
<span class="step-title">{{ step.stepName }}</span>
|
|
41
|
+
</template>
|
|
42
|
+
|
|
43
|
+
<div v-if="Array.isArray(step.images) && step.images.length" class="attachment-block">
|
|
44
|
+
<image-item :images="step.images" :width="70" :padding="0"/>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div v-if="Array.isArray(step.files) && step.files.length" class="attachment-block">
|
|
48
|
+
<file-item :files="step.files" />
|
|
49
|
+
</div>
|
|
50
|
+
</a-card>
|
|
51
|
+
</div>
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<script>
|
|
55
|
+
import { FileItem, ImageItem } from '@vue2-client/components/FileImageItem'
|
|
56
|
+
|
|
57
|
+
export default {
|
|
58
|
+
name: 'WorkFlowStepFilesPreview',
|
|
59
|
+
components: {
|
|
60
|
+
FileItem,
|
|
61
|
+
ImageItem
|
|
62
|
+
},
|
|
63
|
+
props: {
|
|
64
|
+
preview: {
|
|
65
|
+
type: Object,
|
|
66
|
+
default: null
|
|
67
|
+
},
|
|
68
|
+
stepAttachments: {
|
|
69
|
+
type: Array,
|
|
70
|
+
default: () => []
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
computed: {
|
|
74
|
+
previewData () {
|
|
75
|
+
const data = this.preview?.data
|
|
76
|
+
return Array.isArray(data) ? data : null
|
|
77
|
+
},
|
|
78
|
+
normalizedAttachmentSteps () {
|
|
79
|
+
const steps = (this.preview && Array.isArray(this.preview.stepAttachments))
|
|
80
|
+
? this.preview.stepAttachments
|
|
81
|
+
: this.stepAttachments
|
|
82
|
+
|
|
83
|
+
return (steps || [])
|
|
84
|
+
.filter(step => step && step.stepId != null)
|
|
85
|
+
.map(step => ({
|
|
86
|
+
stepId: step.stepId,
|
|
87
|
+
stepName: step.stepName || `步骤 ${step.stepId}`,
|
|
88
|
+
images: Array.isArray(step.images) ? step.images : [],
|
|
89
|
+
files: Array.isArray(step.files) ? step.files : []
|
|
90
|
+
}))
|
|
91
|
+
.filter(step => step.images.length || step.files.length)
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
</script>
|
|
96
|
+
|
|
97
|
+
<style lang="less" scoped>
|
|
98
|
+
.workflow-step-preview {
|
|
99
|
+
padding: 4px 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.step-card {
|
|
103
|
+
margin-bottom: 14px;
|
|
104
|
+
border-radius: 10px;
|
|
105
|
+
border: 1px solid #f0f0f0;
|
|
106
|
+
box-shadow: 0 4px 10px -6px rgba(0, 0, 0, 0.05);
|
|
107
|
+
|
|
108
|
+
:deep(.ant-card-body) {
|
|
109
|
+
padding: 12px 16px 10px;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.step-title {
|
|
114
|
+
font-weight: 600;
|
|
115
|
+
color: rgba(0, 0, 0, 0.85);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.label {
|
|
119
|
+
color: rgba(0, 0, 0, 0.85);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.value {
|
|
123
|
+
white-space: pre-wrap;
|
|
124
|
+
word-break: break-word;
|
|
125
|
+
color: rgba(0, 0, 0, 0.65);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.attachment-block {
|
|
129
|
+
padding: 8px 0;
|
|
130
|
+
|
|
131
|
+
& + & {
|
|
132
|
+
margin-top: 8px;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
:deep(.file-item),
|
|
136
|
+
:deep(.image-item) {
|
|
137
|
+
margin: 0;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.descriptionPreviewItem {
|
|
142
|
+
margin-bottom: 22px;
|
|
143
|
+
border-radius: 10px;
|
|
144
|
+
overflow: hidden;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.descriptionTitle {
|
|
148
|
+
position: relative;
|
|
149
|
+
padding-left: 12px;
|
|
150
|
+
|
|
151
|
+
&::before {
|
|
152
|
+
content: '';
|
|
153
|
+
position: absolute;
|
|
154
|
+
left: 0;
|
|
155
|
+
top: 50%;
|
|
156
|
+
transform: translateY(-50%);
|
|
157
|
+
width: 4px;
|
|
158
|
+
height: 16px;
|
|
159
|
+
background-color: #1890ff;
|
|
160
|
+
border-radius: 2px;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
</style>
|
|
164
|
+
|
|
165
|
+
|