@lambo-design/workflow-approve 1.0.0-beta.76 → 1.0.0-beta.78
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 +1 -1
- package/src/components/history.vue +546 -126
package/package.json
CHANGED
|
@@ -1,120 +1,305 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
+
<!-- 添加排序和分组切换按钮 -->
|
|
4
|
+
<div class="history-controls" style="margin-bottom: 16px;">
|
|
5
|
+
<ButtonGroup>
|
|
6
|
+
<Button
|
|
7
|
+
:type="sortBy === 'time' ? 'primary' : 'default'"
|
|
8
|
+
size="small"
|
|
9
|
+
@click="toggleSortBy('time')">
|
|
10
|
+
<Icon type="md-time" />
|
|
11
|
+
按时间排序
|
|
12
|
+
</Button>
|
|
13
|
+
<Button
|
|
14
|
+
:type="sortBy === 'node' ? 'primary' : 'default'"
|
|
15
|
+
size="small"
|
|
16
|
+
@click="toggleSortBy('node')">
|
|
17
|
+
<Icon type="md-git-network" />
|
|
18
|
+
按节点分组
|
|
19
|
+
</Button>
|
|
20
|
+
</ButtonGroup>
|
|
21
|
+
</div>
|
|
3
22
|
|
|
4
23
|
<Timeline class="portrait-timeline">
|
|
5
|
-
<TimelineItem v-for="(items,index) in
|
|
24
|
+
<TimelineItem v-for="(items,index) in processedItemList" :key="index" class="portrait-timeline-item">
|
|
6
25
|
<template #dot>
|
|
7
|
-
<div
|
|
8
|
-
<div v-else-if="items[0].auditResult === '40' || items[0].auditResult === '50'" class="cicle" style="background-color: #ffcc66"></div>
|
|
9
|
-
<div v-else-if="items[0].auditResult === '60' || items[0].auditResult === '62' || items[0].auditResult === '83'" class="cicle" style="background-color: #ed4014"></div>
|
|
10
|
-
<div v-else class="cicle" style="background-color: #ff9900"></div>
|
|
26
|
+
<div class="cicle" :style="{backgroundColor: getTimelineDotColor(items[0].auditResult)}"></div>
|
|
11
27
|
</template>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
type="vertical"/>
|
|
40
|
-
<tooltip v-if="item.auditOrganName">
|
|
41
|
-
<span class="audit-name-style"> {{ item.auditOrganName[itemListIndex] }}</span>
|
|
42
|
-
<div slot="content" style="white-space: normal"> {{ item.auditOrganName[itemListIndex] }}</div>
|
|
43
|
-
</tooltip>
|
|
44
|
-
<span v-if="portraitWidth === 0 || portraitWidth >= 600" class="audit-date-style">
|
|
45
|
-
{{showDate(item)}}
|
|
46
|
-
</span>
|
|
47
|
-
</Row>
|
|
48
|
-
<Row v-if="item.auditComment">
|
|
49
|
-
<tooltip max-width="200px" placement="bottom-start">
|
|
50
|
-
<span class="audit-comment-style">{{ item.auditComment }}</span>
|
|
51
|
-
<div slot="content" style="white-space: normal"> {{ item.auditComment }}</div>
|
|
52
|
-
</tooltip>
|
|
53
|
-
</Row>
|
|
54
|
-
<Row v-if="portraitWidth < 600" class="portrait-audit-date-style">{{showDate(item)}}</Row>
|
|
55
|
-
<Row style="margin-top: 10px">
|
|
56
|
-
<Col span="12">
|
|
57
|
-
<span style="color: #005aff;; font-size: 13px;"
|
|
58
|
-
v-if="item.auditResult === '00'">流程发起</span>
|
|
59
|
-
<span style="color: #005aff;; font-size: 13px;"
|
|
60
|
-
v-else-if="item.auditResult === '10'">自动跳过</span>
|
|
61
|
-
<span style="color: #005aff;; font-size: 13px;"
|
|
62
|
-
v-else-if="item.auditResult === '11'">与上一环节办理人相同自动跳过</span>
|
|
63
|
-
<span style="color: #005aff;; font-size: 13px;"
|
|
64
|
-
v-else-if="item.auditResult === '12'">与发起人相同自动跳过</span>
|
|
65
|
-
<span style="color: #005aff;; font-size: 13px;"
|
|
66
|
-
v-else-if="item.auditResult === '13'">办理人为空自动跳过</span>
|
|
67
|
-
<span style="color: #005aff;; font-size: 13px;"
|
|
68
|
-
v-else-if="item.auditResult === '14'">符合流程变量条件自动跳过</span>
|
|
69
|
-
<span style="color: #005aff;; font-size: 13px;"
|
|
70
|
-
v-else-if="item.auditResult === '30'">通过</span>
|
|
71
|
-
<span style="color: #ed4014; font-size: 13px;"
|
|
72
|
-
v-else-if="item.auditResult === '40'">{{item.rejectName ? item.rejectName : '驳回'}}上一节点</span>
|
|
73
|
-
<span style="color: #ed4014; font-size: 13px;"
|
|
74
|
-
v-else-if="item.auditResult === '50'">{{item.rejectName ? item.rejectName : '驳回'}}到原点</span>
|
|
75
|
-
<span style="color: #ed4014; font-size: 13px;"
|
|
76
|
-
v-else-if="item.auditResult === '51'">流程终止</span>
|
|
77
|
-
<span style="color: #ed4014; font-size: 13px;"
|
|
78
|
-
v-else-if="item.auditResult === '60'">撤回</span>
|
|
79
|
-
<span style="color: #005aff; font-size: 13px;"
|
|
80
|
-
v-else-if="item.auditResult === '61'">交回委派任务</span>
|
|
81
|
-
<span style="color: #ed4014; font-size: 13px;"
|
|
82
|
-
v-else-if="item.auditResult === '62'">委派任务被撤回</span>
|
|
83
|
-
<span style="color: #19be6b; font-size: 13px;"
|
|
84
|
-
v-else-if="item.auditResult === '80'">跳转指定节点</span>
|
|
85
|
-
<span style="color: #005aff; font-size: 13px;"
|
|
86
|
-
v-else-if="item.auditResult === '82'">指定他人处理</span>
|
|
87
|
-
<span style="color: #ed4014; font-size: 13px;"
|
|
88
|
-
v-else-if="item.auditResult === '83'">会签减签</span>
|
|
89
|
-
<span style="color: #19be6b; font-size: 13px;"
|
|
90
|
-
v-else-if="item.auditResult === '90'">{{item.rejectName ? item.rejectName : '驳回'}}指定节点</span>
|
|
91
|
-
<span style="color: #ff9900; font-size: 13px;" v-else>{{ '待' + handleName }}</span>
|
|
28
|
+
<!-- 按时间排序时:不显示标题,自动展开 -->
|
|
29
|
+
<template v-if="sortBy === 'time'">
|
|
30
|
+
<!-- 检查是否有待审批记录 -->
|
|
31
|
+
<template v-if="items.some(item => isPendingAudit(item))">
|
|
32
|
+
<!-- 待审批的记录:使用折叠面板 -->
|
|
33
|
+
<Collapse v-model="pendingActiveName" simple style="margin: -10px 0 0 20px;border: none">
|
|
34
|
+
<Panel :name="'pending-panel' + index" hide-arrow>
|
|
35
|
+
<span class="pending-audit-title">
|
|
36
|
+
<Icon type="md-time" style="color: #ff9900; margin-right: 5px;" />
|
|
37
|
+
待{{ handleName }}
|
|
38
|
+
</span>
|
|
39
|
+
<template #content>
|
|
40
|
+
<!-- 遍历所有待审批的记录 -->
|
|
41
|
+
<div v-for="(item, itemIndex) in items.filter(item => isPendingAudit(item))" :key="itemIndex">
|
|
42
|
+
<div v-for="(itemListItem, itemListIndex) in item.auditName" :key="itemListIndex">
|
|
43
|
+
<Card dis-hover
|
|
44
|
+
class="portrait-card portrait-card-time"
|
|
45
|
+
:bordered="false">
|
|
46
|
+
<List item-layout="vertical">
|
|
47
|
+
<ListItem>
|
|
48
|
+
<Row style="display: flex; align-items: center;">
|
|
49
|
+
<!-- 左边:Avatar -->
|
|
50
|
+
<Col>
|
|
51
|
+
<avatar
|
|
52
|
+
:class="portraitWidth >= 600 ? 'portrait-avatar-large' : 'portrait-avatar-small'"
|
|
53
|
+
size="small">
|
|
54
|
+
{{ getFirstName(itemListItem) }}</avatar>
|
|
92
55
|
</Col>
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
<
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
56
|
+
<!-- 右边:审批信息 -->
|
|
57
|
+
<Col span="17">
|
|
58
|
+
<Row>
|
|
59
|
+
<tooltip>
|
|
60
|
+
<span class="audit-name-style"> {{ itemListItem }}</span>
|
|
61
|
+
<div slot="content" style="white-space: normal"> {{ itemListItem }}</div>
|
|
62
|
+
</tooltip>
|
|
63
|
+
<Divider style="background-color:#808695;height: 1em;margin: 4px 9px 0 6px;"
|
|
64
|
+
type="vertical"/>
|
|
65
|
+
<tooltip v-if="item.auditOrganName">
|
|
66
|
+
<span class="audit-name-style"> {{ item.auditOrganName[itemListIndex] }}</span>
|
|
67
|
+
<div slot="content" style="white-space: normal"> {{ item.auditOrganName[itemListIndex] }}</div>
|
|
68
|
+
</tooltip>
|
|
69
|
+
<span v-if="portraitWidth === 0 || portraitWidth >= 600" class="audit-date-style">
|
|
70
|
+
{{showDate(item)}}
|
|
71
|
+
</span>
|
|
72
|
+
</Row>
|
|
73
|
+
<Row v-if="item.auditComment">
|
|
74
|
+
<tooltip max-width="200px" placement="bottom-start">
|
|
75
|
+
<span class="audit-comment-style">{{ item.auditComment }}</span>
|
|
76
|
+
<div slot="content" style="white-space: normal"> {{ item.auditComment }}</div>
|
|
77
|
+
</tooltip>
|
|
78
|
+
</Row>
|
|
79
|
+
<Row v-if="portraitWidth < 600" class="portrait-audit-date-style">{{showDate(item)}}</Row>
|
|
80
|
+
<Row style="margin-top: 10px">
|
|
81
|
+
<Col span="12">
|
|
82
|
+
<span style="color: #ff9900; font-size: 13px;">{{ '待' + handleName }}</span>
|
|
83
|
+
</Col>
|
|
84
|
+
<Col span="12" style="text-align: right">
|
|
85
|
+
<Button v-if="item.fileList && item.fileList.length > 0" size="small" type="primary" ghost class="urging" @click="openModal(item)">查看附件</Button>
|
|
86
|
+
<Button v-if="displayPushButton"
|
|
87
|
+
size="small" type="primary" ghost class="urging"
|
|
88
|
+
@click="pushHim(item,itemListItem,itemListIndex)">催一下
|
|
89
|
+
</Button>
|
|
90
|
+
</Col>
|
|
91
|
+
</Row>
|
|
99
92
|
</Col>
|
|
100
93
|
</Row>
|
|
94
|
+
</ListItem>
|
|
95
|
+
</List>
|
|
96
|
+
</Card>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</template>
|
|
100
|
+
</Panel>
|
|
101
|
+
</Collapse>
|
|
102
|
+
</template>
|
|
103
|
+
|
|
104
|
+
<!-- 已审批的记录:直接显示 -->
|
|
105
|
+
<div v-for="(item, itemIndex) in items.filter(item => !isPendingAudit(item))" :key="'approved-' + itemIndex">
|
|
106
|
+
<div v-for="(itemListItem, itemListIndex) in item.auditName" :key="itemListIndex">
|
|
107
|
+
<Card dis-hover
|
|
108
|
+
class="portrait-card portrait-card-time"
|
|
109
|
+
:bordered="false">
|
|
110
|
+
<List item-layout="vertical">
|
|
111
|
+
<ListItem>
|
|
112
|
+
<Row style="display: flex; align-items: center;">
|
|
113
|
+
<!-- 左边:Avatar -->
|
|
114
|
+
<Col>
|
|
115
|
+
<avatar
|
|
116
|
+
:class="portraitWidth >= 600 ? 'portrait-avatar-large' : 'portrait-avatar-small'"
|
|
117
|
+
size="small">
|
|
118
|
+
{{ getFirstName(itemListItem) }}</avatar>
|
|
119
|
+
</Col>
|
|
120
|
+
<!-- 右边:审批信息 -->
|
|
121
|
+
<Col span="17">
|
|
122
|
+
<Row>
|
|
123
|
+
<tooltip>
|
|
124
|
+
<span class="audit-name-style"> {{ itemListItem }}</span>
|
|
125
|
+
<div slot="content" style="white-space: normal"> {{ itemListItem }}</div>
|
|
126
|
+
</tooltip>
|
|
127
|
+
<Divider style="background-color:#808695;height: 1em;margin: 4px 9px 0 6px;"
|
|
128
|
+
type="vertical"/>
|
|
129
|
+
<tooltip v-if="item.auditOrganName">
|
|
130
|
+
<span class="audit-name-style"> {{ item.auditOrganName[itemListIndex] }}</span>
|
|
131
|
+
<div slot="content" style="white-space: normal"> {{ item.auditOrganName[itemListIndex] }}</div>
|
|
132
|
+
</tooltip>
|
|
133
|
+
<span v-if="portraitWidth === 0 || portraitWidth >= 600" class="audit-date-style">
|
|
134
|
+
{{showDate(item)}}
|
|
135
|
+
</span>
|
|
136
|
+
</Row>
|
|
137
|
+
<Row v-if="item.auditComment">
|
|
138
|
+
<tooltip max-width="200px" placement="bottom-start">
|
|
139
|
+
<span class="audit-comment-style">{{ item.auditComment }}</span>
|
|
140
|
+
<div slot="content" style="white-space: normal"> {{ item.auditComment }}</div>
|
|
141
|
+
</tooltip>
|
|
142
|
+
</Row>
|
|
143
|
+
<Row v-if="portraitWidth < 600" class="portrait-audit-date-style">{{showDate(item)}}</Row>
|
|
144
|
+
<Row style="margin-top: 10px">
|
|
145
|
+
<Col span="12">
|
|
146
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
147
|
+
v-if="item.auditResult === '00'">流程发起</span>
|
|
148
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
149
|
+
v-else-if="item.auditResult === '10'">自动跳过</span>
|
|
150
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
151
|
+
v-else-if="item.auditResult === '11'">与上一环节办理人相同自动跳过</span>
|
|
152
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
153
|
+
v-else-if="item.auditResult === '12'">与发起人相同自动跳过</span>
|
|
154
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
155
|
+
v-else-if="item.auditResult === '13'">办理人为空自动跳过</span>
|
|
156
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
157
|
+
v-else-if="item.auditResult === '14'">符合流程变量条件自动跳过</span>
|
|
158
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
159
|
+
v-else-if="item.auditResult === '30'">通过</span>
|
|
160
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
161
|
+
v-else-if="item.auditResult === '40'">{{item.rejectName ? item.rejectName : '驳回'}}上一节点</span>
|
|
162
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
163
|
+
v-else-if="item.auditResult === '50'">{{item.rejectName ? item.rejectName : '驳回'}}到原点</span>
|
|
164
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
165
|
+
v-else-if="item.auditResult === '51'">流程终止</span>
|
|
166
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
167
|
+
v-else-if="item.auditResult === '60'">撤回</span>
|
|
168
|
+
<span style="color: #005aff; font-size: 13px;"
|
|
169
|
+
v-else-if="item.auditResult === '61'">交回委派任务</span>
|
|
170
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
171
|
+
v-else-if="item.auditResult === '62'">委派任务被撤回</span>
|
|
172
|
+
<span style="color: #19be6b; font-size: 13px;"
|
|
173
|
+
v-else-if="item.auditResult === '80'">跳转指定节点</span>
|
|
174
|
+
<span style="color: #005aff; font-size: 13px;"
|
|
175
|
+
v-else-if="item.auditResult === '82'">指定他人处理</span>
|
|
176
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
177
|
+
v-else-if="item.auditResult === '83'">会签减签</span>
|
|
178
|
+
<span style="color: #19be6b; font-size: 13px;"
|
|
179
|
+
v-else-if="item.auditResult === '90'">{{item.rejectName ? item.rejectName : '驳回'}}指定节点</span>
|
|
180
|
+
</Col>
|
|
181
|
+
<Col span="12" style="text-align: right">
|
|
182
|
+
<Button v-if="item.fileList && item.fileList.length > 0" size="small" type="primary" ghost class="urging" @click="openModal(item)">查看附件</Button>
|
|
101
183
|
</Col>
|
|
102
184
|
</Row>
|
|
185
|
+
</Col>
|
|
186
|
+
</Row>
|
|
187
|
+
</ListItem>
|
|
188
|
+
</List>
|
|
189
|
+
</Card>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
</template>
|
|
193
|
+
|
|
194
|
+
<!-- 按节点分组时:显示折叠面板 -->
|
|
195
|
+
<template v-else>
|
|
196
|
+
<Collapse v-model="activeName" simple style="margin: -10px 0 0 -2px;border: none">
|
|
197
|
+
<Panel :name="'panel' + index" hide-arrow>
|
|
198
|
+
<span class="history-title">{{ items[0].taskName }}</span>
|
|
199
|
+
<template #content>
|
|
200
|
+
<div v-for="(item, index) in items" :key="index">
|
|
201
|
+
<div v-for="(itemListItem, itemListIndex) in item.auditName" :key="itemListIndex">
|
|
202
|
+
<Card dis-hover
|
|
203
|
+
class="portrait-card"
|
|
204
|
+
:bordered="false">
|
|
205
|
+
<List item-layout="vertical">
|
|
206
|
+
<ListItem>
|
|
207
|
+
<Row style="display: flex; align-items: center;">
|
|
208
|
+
<!-- 左边:Avatar -->
|
|
209
|
+
<Col>
|
|
210
|
+
<avatar
|
|
211
|
+
:class="portraitWidth >= 600 ? 'portrait-avatar-large' : 'portrait-avatar-small'"
|
|
212
|
+
size="small">
|
|
213
|
+
{{ getFirstName(itemListItem) }}</avatar>
|
|
214
|
+
</Col>
|
|
215
|
+
<!-- 右边:审批信息 -->
|
|
216
|
+
<Col span="17">
|
|
217
|
+
<Row>
|
|
218
|
+
<tooltip>
|
|
219
|
+
<span class="audit-name-style"> {{ itemListItem }}</span>
|
|
220
|
+
<div slot="content" style="white-space: normal"> {{ itemListItem }}</div>
|
|
221
|
+
</tooltip>
|
|
222
|
+
<Divider style="background-color:#808695;height: 1em;margin: 4px 9px 0 6px;"
|
|
223
|
+
type="vertical"/>
|
|
224
|
+
<tooltip v-if="item.auditOrganName">
|
|
225
|
+
<span class="audit-name-style"> {{ item.auditOrganName[itemListIndex] }}</span>
|
|
226
|
+
<div slot="content" style="white-space: normal"> {{ item.auditOrganName[itemListIndex] }}</div>
|
|
227
|
+
</tooltip>
|
|
228
|
+
<span v-if="portraitWidth === 0 || portraitWidth >= 600" class="audit-date-style">
|
|
229
|
+
{{showDate(item)}}
|
|
230
|
+
</span>
|
|
231
|
+
</Row>
|
|
232
|
+
<Row v-if="item.auditComment">
|
|
233
|
+
<tooltip max-width="200px" placement="bottom-start">
|
|
234
|
+
<span class="audit-comment-style">{{ item.auditComment }}</span>
|
|
235
|
+
<div slot="content" style="white-space: normal"> {{ item.auditComment }}</div>
|
|
236
|
+
</tooltip>
|
|
237
|
+
</Row>
|
|
238
|
+
<Row v-if="portraitWidth < 600" class="portrait-audit-date-style">{{showDate(item)}}</Row>
|
|
239
|
+
<Row style="margin-top: 10px">
|
|
240
|
+
<Col span="12">
|
|
241
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
242
|
+
v-if="item.auditResult === '00'">流程发起</span>
|
|
243
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
244
|
+
v-else-if="item.auditResult === '10'">自动跳过</span>
|
|
245
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
246
|
+
v-else-if="item.auditResult === '11'">与上一环节办理人相同自动跳过</span>
|
|
247
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
248
|
+
v-else-if="item.auditResult === '12'">与发起人相同自动跳过</span>
|
|
249
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
250
|
+
v-else-if="item.auditResult === '13'">办理人为空自动跳过</span>
|
|
251
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
252
|
+
v-else-if="item.auditResult === '14'">符合流程变量条件自动跳过</span>
|
|
253
|
+
<span style="color: #005aff;; font-size: 13px;"
|
|
254
|
+
v-else-if="item.auditResult === '30'">通过</span>
|
|
255
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
256
|
+
v-else-if="item.auditResult === '40'">{{item.rejectName ? item.rejectName : '驳回'}}上一节点</span>
|
|
257
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
258
|
+
v-else-if="item.auditResult === '50'">{{item.rejectName ? item.rejectName : '驳回'}}到原点</span>
|
|
259
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
260
|
+
v-else-if="item.auditResult === '51'">流程终止</span>
|
|
261
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
262
|
+
v-else-if="item.auditResult === '60'">撤回</span>
|
|
263
|
+
<span style="color: #005aff; font-size: 13px;"
|
|
264
|
+
v-else-if="item.auditResult === '61'">交回委派任务</span>
|
|
265
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
266
|
+
v-else-if="item.auditResult === '62'">委派任务被撤回</span>
|
|
267
|
+
<span style="color: #19be6b; font-size: 13px;"
|
|
268
|
+
v-else-if="item.auditResult === '80'">跳转指定节点</span>
|
|
269
|
+
<span style="color: #005aff; font-size: 13px;"
|
|
270
|
+
v-else-if="item.auditResult === '82'">指定他人处理</span>
|
|
271
|
+
<span style="color: #ed4014; font-size: 13px;"
|
|
272
|
+
v-else-if="item.auditResult === '83'">会签减签</span>
|
|
273
|
+
<span style="color: #19be6b; font-size: 13px;"
|
|
274
|
+
v-else-if="item.auditResult === '90'">{{item.rejectName ? item.rejectName : '驳回'}}指定节点</span>
|
|
275
|
+
<span style="color: #ff9900; font-size: 13px;" v-else>{{ '待' + handleName }}</span>
|
|
276
|
+
</Col>
|
|
277
|
+
<Col span="12" style="text-align: right">
|
|
278
|
+
<Button v-if="item.fileList && item.fileList.length > 0" size="small" type="primary" ghost class="urging" @click="openModal(item)">查看附件</Button>
|
|
279
|
+
<Button v-if="displayPushButton && !auditPassStatus.includes(item.auditResult) && item.auditResult !== '40'&&item.auditResult !== '50'&&item.auditResult !== '60'&&item.auditResult !== '62'&&item.auditResult!=='83'&&item.auditResult!=='90'"
|
|
280
|
+
size="small" type="primary" ghost class="urging"
|
|
281
|
+
@click="pushHim(item,itemListItem,itemListIndex)">催一下
|
|
282
|
+
</Button>
|
|
283
|
+
</Col>
|
|
284
|
+
</Row>
|
|
285
|
+
</Col>
|
|
286
|
+
</Row>
|
|
103
287
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
288
|
+
</ListItem>
|
|
289
|
+
</List>
|
|
290
|
+
</Card>
|
|
291
|
+
</div>
|
|
107
292
|
</div>
|
|
108
|
-
</
|
|
109
|
-
</
|
|
110
|
-
</
|
|
111
|
-
</
|
|
293
|
+
</template>
|
|
294
|
+
</Panel>
|
|
295
|
+
</Collapse>
|
|
296
|
+
</template>
|
|
112
297
|
</TimelineItem>
|
|
113
298
|
</Timeline>
|
|
114
299
|
|
|
115
300
|
<Modal
|
|
116
|
-
|
|
117
|
-
|
|
301
|
+
v-model="showModal"
|
|
302
|
+
title="查看附件"
|
|
118
303
|
>
|
|
119
304
|
<Table border
|
|
120
305
|
:columns="attachmentColumn"
|
|
@@ -197,17 +382,138 @@ export default {
|
|
|
197
382
|
setModals: {
|
|
198
383
|
modals: []
|
|
199
384
|
},
|
|
200
|
-
auditPassStatus:['00', '10', '11', '12', '13', '14', '30', '61', '80'],
|
|
385
|
+
auditPassStatus:['00', '10', '11', '12', '13', '14', '30', '40', '50', '51', '60', '61', '62', '80', '82', '83', '90'],
|
|
201
386
|
showModal: false,
|
|
202
387
|
fileList: [],
|
|
203
388
|
modalImg: false,
|
|
204
389
|
image: "",
|
|
205
|
-
itemList:
|
|
390
|
+
itemList: [],
|
|
206
391
|
auditNameList: [],
|
|
207
392
|
displayPushButton: false,
|
|
393
|
+
sortBy: 'time',
|
|
394
|
+
pendingActiveName: [], // 控制待审批折叠面板的展开状态
|
|
208
395
|
}
|
|
209
396
|
},
|
|
210
397
|
computed: {
|
|
398
|
+
processedItemList() {
|
|
399
|
+
// 确保 itemList 存在且是数组
|
|
400
|
+
if (!this.itemList || !Array.isArray(this.itemList) || this.itemList.length === 0) {
|
|
401
|
+
return [];
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (this.sortBy === 'time') {
|
|
405
|
+
// 按时间排序:将所有审批记录平铺,按时间排序,然后重新分组
|
|
406
|
+
let allRecords = [];
|
|
407
|
+
|
|
408
|
+
// 平铺所有审批记录
|
|
409
|
+
this.itemList.forEach(nodeGroup => {
|
|
410
|
+
// 确保 nodeGroup 是数组
|
|
411
|
+
if (Array.isArray(nodeGroup)) {
|
|
412
|
+
nodeGroup.forEach(record => {
|
|
413
|
+
if (record && typeof record === 'object') {
|
|
414
|
+
// 获取准确的时间用于排序
|
|
415
|
+
let sortTime = this.getRecordTime(record);
|
|
416
|
+
let timestamp = new Date(sortTime).getTime();
|
|
417
|
+
|
|
418
|
+
// 验证时间戳是否有效
|
|
419
|
+
if (isNaN(timestamp)) {
|
|
420
|
+
console.warn('时间戳解析失败:', {
|
|
421
|
+
record: record,
|
|
422
|
+
sortTime: sortTime,
|
|
423
|
+
auditDate: record.auditDate,
|
|
424
|
+
createTime: record.createTime
|
|
425
|
+
});
|
|
426
|
+
// 使用当前时间作为后备
|
|
427
|
+
timestamp = new Date().getTime();
|
|
428
|
+
sortTime = new Date().toISOString();
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
allRecords.push({
|
|
432
|
+
record: record,
|
|
433
|
+
sortTime: sortTime,
|
|
434
|
+
timestamp: timestamp
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
// 调试信息:打印排序前的数据
|
|
442
|
+
console.log('排序前的记录:', allRecords.map(item => ({
|
|
443
|
+
auditResult: item.record.auditResult,
|
|
444
|
+
auditDate: item.record.auditDate,
|
|
445
|
+
createTime: item.record.createTime,
|
|
446
|
+
sortTime: item.sortTime,
|
|
447
|
+
timestamp: item.timestamp,
|
|
448
|
+
date: new Date(item.timestamp)
|
|
449
|
+
})));
|
|
450
|
+
|
|
451
|
+
// 按时间戳排序(倒序,最新在前)
|
|
452
|
+
allRecords.sort((a, b) => {
|
|
453
|
+
// 使用时间戳进行排序,避免字符串比较问题
|
|
454
|
+
return b.timestamp - a.timestamp;
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
// 调试信息:打印排序后的数据
|
|
458
|
+
console.log('排序后的记录:', allRecords.map(item => ({
|
|
459
|
+
auditResult: item.record.auditResult,
|
|
460
|
+
auditDate: item.record.auditDate,
|
|
461
|
+
createTime: item.record.createTime,
|
|
462
|
+
sortTime: item.sortTime,
|
|
463
|
+
timestamp: item.timestamp,
|
|
464
|
+
date: new Date(item.timestamp)
|
|
465
|
+
})));
|
|
466
|
+
|
|
467
|
+
// 重新分组:相同状态且时间相近的记录分为一组
|
|
468
|
+
let groupedRecords = [];
|
|
469
|
+
let currentGroup = [];
|
|
470
|
+
|
|
471
|
+
allRecords.forEach((item, index) => {
|
|
472
|
+
if (currentGroup.length === 0) {
|
|
473
|
+
// 第一个记录,直接加入
|
|
474
|
+
currentGroup.push(item.record);
|
|
475
|
+
} else {
|
|
476
|
+
// 检查是否应该与当前组合并
|
|
477
|
+
let shouldGroup = false;
|
|
478
|
+
|
|
479
|
+
// 如果都是待审批状态且是同一个节点,则分为一组
|
|
480
|
+
if (this.isPendingAudit(item.record) &&
|
|
481
|
+
currentGroup.some(r => this.isPendingAudit(r) && r.taskName === item.record.taskName)) {
|
|
482
|
+
shouldGroup = true;
|
|
483
|
+
}
|
|
484
|
+
// 如果都是已审批状态且时间非常接近(同一天或几分钟内),可以考虑分组,但通常按个人分组
|
|
485
|
+
else if (!this.isPendingAudit(item.record) &&
|
|
486
|
+
currentGroup.length === 1 &&
|
|
487
|
+
!this.isPendingAudit(currentGroup[0]) &&
|
|
488
|
+
currentGroup[0].taskName === item.record.taskName) {
|
|
489
|
+
// 暂时不分组已审批记录,每个人一组
|
|
490
|
+
shouldGroup = false;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
if (shouldGroup) {
|
|
494
|
+
currentGroup.push(item.record);
|
|
495
|
+
} else {
|
|
496
|
+
// 开始新的分组
|
|
497
|
+
if (currentGroup.length > 0) {
|
|
498
|
+
groupedRecords.push([...currentGroup]);
|
|
499
|
+
}
|
|
500
|
+
currentGroup = [item.record];
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
// 添加最后一组
|
|
506
|
+
if (currentGroup.length > 0) {
|
|
507
|
+
groupedRecords.push(currentGroup);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return groupedRecords;
|
|
511
|
+
} else {
|
|
512
|
+
// 按节点分组:保持原有的节点分组结构
|
|
513
|
+
return this.itemList;
|
|
514
|
+
}
|
|
515
|
+
},
|
|
516
|
+
|
|
211
517
|
attachmentColumn: function () {
|
|
212
518
|
let column = [];
|
|
213
519
|
column.push({title: '序号', type: 'index', width: 70, align: 'center', fixed: 'left'});
|
|
@@ -310,22 +616,22 @@ export default {
|
|
|
310
616
|
responseType: 'blob', // 因为是流文件,所以要指定blob类型
|
|
311
617
|
url: this.smartFlowServerContext + "/manage/oss/file/get/" + row.fileId// 一个word下载文件的接口
|
|
312
618
|
}).then(({data}) => {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
619
|
+
docx.renderAsync(data, this.$refs.file, null, {
|
|
620
|
+
className: "docx", //默认和文档样式类的类名/前缀
|
|
621
|
+
inWrapper: true, //启用围绕文档内容呈现包装器
|
|
622
|
+
ignoreWidth: false, //禁用页面的渲染宽度
|
|
623
|
+
ignoreHeight: false, //禁用页面的渲染高度
|
|
624
|
+
ignoreFonts: false, //禁用字体渲染
|
|
625
|
+
breakPages: true, //在分页符上启用分页
|
|
626
|
+
ignoreLastRenderedPageBreak: true, //在lastRenderedPageBreak元素上禁用分页
|
|
627
|
+
experimental: false, //启用实验功能(制表符停止计算)
|
|
628
|
+
trimXmlDeclaration: true, //如果为true,则在解析之前将从xml文档中删除xml声明
|
|
629
|
+
useBase64URL: false, //如果为true,图像、字体等将转换为base 64 URL,否则使用URL.createObjectURL
|
|
630
|
+
useMathMLPolyfill: false, //包括用于铬、边等的MathML多填充。
|
|
631
|
+
showChanges: false, //启用文档更改的实验渲染(插入/删除)
|
|
632
|
+
debug: false, //启用额外的日志记录
|
|
633
|
+
})
|
|
634
|
+
}
|
|
329
635
|
)
|
|
330
636
|
}
|
|
331
637
|
},
|
|
@@ -362,13 +668,83 @@ export default {
|
|
|
362
668
|
return `处理时间:${item.auditDate}`
|
|
363
669
|
}
|
|
364
670
|
return `接收时间:${item.createTime}`
|
|
671
|
+
},
|
|
672
|
+
getRecordTime(item) {
|
|
673
|
+
// 获取记录的时间用于排序
|
|
674
|
+
let timeStr = '';
|
|
675
|
+
|
|
676
|
+
if (item.auditResult && item.auditResult !== '') {
|
|
677
|
+
// 已审批记录:优先使用审批时间
|
|
678
|
+
timeStr = item.auditDate || item.createTime;
|
|
679
|
+
} else {
|
|
680
|
+
// 待审批记录:使用创建时间
|
|
681
|
+
timeStr = item.createTime || item.auditDate;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// 如果没有时间,使用当前时间
|
|
685
|
+
if (!timeStr) {
|
|
686
|
+
return new Date().toISOString();
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// 标准化时间格式
|
|
690
|
+
try {
|
|
691
|
+
// 处理中国标准时间格式 "YYYY-MM-DD HH:mm:ss"
|
|
692
|
+
if (typeof timeStr === 'string') {
|
|
693
|
+
// 移除可能的多余空格
|
|
694
|
+
timeStr = timeStr.trim();
|
|
695
|
+
|
|
696
|
+
// 检查是否是标准格式 "YYYY-MM-DD HH:mm:ss"
|
|
697
|
+
if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(timeStr)) {
|
|
698
|
+
// 直接使用 new Date() 解析,这样会按本地时区处理
|
|
699
|
+
let date = new Date(timeStr);
|
|
700
|
+
if (!isNaN(date.getTime())) {
|
|
701
|
+
return date.toISOString();
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// 如果包含 T 但没有时区信息,添加本地时区
|
|
706
|
+
if (timeStr.includes('T') && !timeStr.includes('Z') && !timeStr.includes('+')) {
|
|
707
|
+
timeStr += 'Z';
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// 验证时间是否有效
|
|
712
|
+
let date = new Date(timeStr);
|
|
713
|
+
if (isNaN(date.getTime())) {
|
|
714
|
+
console.warn('Invalid date format:', timeStr);
|
|
715
|
+
return new Date().toISOString();
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
return date.toISOString();
|
|
719
|
+
} catch (error) {
|
|
720
|
+
console.warn('Error parsing date:', timeStr, error);
|
|
721
|
+
return new Date().toISOString();
|
|
722
|
+
}
|
|
723
|
+
},
|
|
724
|
+
getTimelineDotColor(auditResult) {
|
|
725
|
+
if (this.auditPassStatus.includes(auditResult)) {
|
|
726
|
+
return '#005aff'; // 蓝色:通过状态
|
|
727
|
+
} else if (auditResult === '40' || auditResult === '50') {
|
|
728
|
+
return '#ffcc66'; // 黄色:驳回状态
|
|
729
|
+
} else if (auditResult === '60' || auditResult === '62' || auditResult === '83') {
|
|
730
|
+
return '#ed4014'; // 红色:撤回/委派状态
|
|
731
|
+
} else {
|
|
732
|
+
return '#ff9900'; // 橙色:其他状态
|
|
733
|
+
}
|
|
734
|
+
},
|
|
735
|
+
toggleSortBy(by) {
|
|
736
|
+
this.sortBy = by;
|
|
737
|
+
},
|
|
738
|
+
isPendingAudit(item) {
|
|
739
|
+
// 判断是否为待审批状态
|
|
740
|
+
// auditResult为空、null、undefined或者不在已审批状态列表中时,认为是待审批
|
|
741
|
+
return !item.auditResult || !this.auditPassStatus.includes(item.auditResult);
|
|
365
742
|
}
|
|
366
743
|
},
|
|
367
744
|
mounted() {
|
|
368
745
|
this.displayPushButton = this.donePage && this.pushButton;
|
|
369
746
|
this.itemList = this.list;
|
|
370
747
|
if (this.itemList.length > 0) {
|
|
371
|
-
this.displayedList = this.itemList.slice(0, 2);
|
|
372
748
|
// 初始化modals
|
|
373
749
|
this.setModals.modals = this.itemList.map(() => ({value: false}));
|
|
374
750
|
this.activeName = 'panel0';
|
|
@@ -379,10 +755,8 @@ export default {
|
|
|
379
755
|
this.$nextTick(() => {
|
|
380
756
|
this.itemList = newValue;
|
|
381
757
|
if (this.itemList.length > 0) {
|
|
382
|
-
this.displayedList = this.itemList.slice(0, 2);
|
|
383
758
|
this.setModals.modals = this.itemList.map(() => ({value: false}));
|
|
384
759
|
}
|
|
385
|
-
|
|
386
760
|
});
|
|
387
761
|
}
|
|
388
762
|
}
|
|
@@ -393,26 +767,72 @@ export default {
|
|
|
393
767
|
|
|
394
768
|
<style scoped>
|
|
395
769
|
@import "../styles/css/index.less";
|
|
396
|
-
|
|
770
|
+
|
|
771
|
+
.history-controls {
|
|
772
|
+
padding: 12px;
|
|
773
|
+
background-color: #f8f9fa;
|
|
774
|
+
border-radius: 6px;
|
|
775
|
+
border: 1px solid #e8eaec;
|
|
776
|
+
text-align: center;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
.history-controls .ivu-btn-group .ivu-btn {
|
|
780
|
+
margin-right: 0;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
.history-controls .ivu-btn-group .ivu-btn + .ivu-btn {
|
|
784
|
+
margin-left: -1px;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
.history-title {
|
|
788
|
+
font-weight: 600;
|
|
789
|
+
color: #2c3e50;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
.pending-audit-title {
|
|
793
|
+
font-weight: 600;
|
|
794
|
+
color: #ff9900;
|
|
795
|
+
font-size: 14px;
|
|
796
|
+
display: flex;
|
|
797
|
+
align-items: center;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/* 按时间排序的卡片样式 - 更小,不遮挡时间轴圆点 */
|
|
801
|
+
.portrait-card-time {
|
|
802
|
+
margin-left: 20px !important;
|
|
803
|
+
margin-right: 10px !important;
|
|
804
|
+
margin-bottom: 8px !important;
|
|
805
|
+
background-color: #fafafa !important;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
:deep(.portrait-card-time .ivu-card-body) {
|
|
809
|
+
padding: 8px 12px !important;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
:deep(.portrait-card-time .ivu-list-item) {
|
|
813
|
+
padding: 6px 0 !important;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
:deep(.docx) {
|
|
397
817
|
width: 100% !important;
|
|
398
818
|
}
|
|
399
819
|
|
|
400
|
-
|
|
820
|
+
:deep(.ivu-timeline-item-tail) {
|
|
401
821
|
border-style: solid;
|
|
402
822
|
border-left: none;
|
|
403
823
|
border-color: #005aff;
|
|
404
824
|
border-width: thin;
|
|
405
825
|
}
|
|
406
826
|
|
|
407
|
-
|
|
827
|
+
:deep(.ivu-list-item) {
|
|
408
828
|
padding-bottom: 0 !important;
|
|
409
829
|
}
|
|
410
830
|
|
|
411
|
-
|
|
831
|
+
:deep(.ivu-collapse-content-box) {
|
|
412
832
|
padding: 0 !important;
|
|
413
833
|
}
|
|
414
834
|
|
|
415
|
-
|
|
835
|
+
:deep(.ivu-card-body) {
|
|
416
836
|
padding: 5px !important;
|
|
417
837
|
}
|
|
418
838
|
|