@lambo-design-mobile/workflow-approve 1.0.0-beta.20 → 1.0.0-beta.22

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/CHANGELOG.md CHANGED
@@ -1,11 +1,25 @@
1
1
  # Changelog
2
- ## [1.0.0-beta.20](http://git.inspur.com/ecbh/lambo-design/lambo-design/-/compare/@lambo-design-mobile/workflow-approve@1.0.0-beta.19...@lambo-design-mobile/workflow-approve@1.0.0-beta.20) (2025-08-21)
2
+ ## [1.0.0-beta.22](http://git.inspur.com/ecbh/lambo-design/lambo-design/-/compare/@lambo-design-mobile/workflow-approve@1.0.0-beta.21...@lambo-design-mobile/workflow-approve@1.0.0-beta.22) (2026-01-29)
3
3
 
4
4
 
5
5
  ### ✨ Features | 新功能
6
6
 
7
- * **workflow-approve:** 发起时间支持范围筛选 ([831f12d](http://git.inspur.com/ecbh/lambo-design/lambo-design/-/commit/831f12dae1b9ecdb7bab2ba666a568183a747ae2))
7
+ * **审批组件:** 功能增加和调整 ([7dff512](http://git.inspur.com/ecbh/lambo-design/lambo-design/-/commit/7dff5124e43a3a7bb9145d4ed518a3507e2603f4))
8
8
 
9
+ ## [1.0.0-beta.21](http://git.inspur.com/ecbh/lambo-design/lambo-design/-/compare/@lambo-design-mobile/workflow-approve@1.0.0-beta.20...@lambo-design-mobile/workflow-approve@1.0.0-beta.21) (2025-10-15)
10
+
11
+
12
+ ### 🐛 Bug Fixes | Bug 修复
13
+
14
+ * **odoListCard:** 更新TodoListCard字段排序&按钮展示逻辑增强 ([1fe525e](http://git.inspur.com/ecbh/lambo-design/lambo-design/-/commit/1fe525e4bec424fe95f4f69e4893a455ce1f7a00))
15
+
16
+ ## [1.0.0-beta.20](http://git.inspur.com/ecbh/lambo-design/lambo-design/-/compare/@lambo-design-mobile/workflow-approve@1.0.0-beta.19...@lambo-design-mobile/workflow-approve@1.0.0-beta.20) (2025-08-21)
17
+
18
+
19
+ ### ✨ Features | 新功能
20
+
21
+ * **workflow-approve:** 发起时间支持范围筛选 ([831f12d](http://git.inspur.com/ecbh/lambo-design/lambo-design/-/commit/831f12dae1b9ecdb7bab2ba666a568183a747ae2))
22
+
9
23
  ## [1.0.0-beta.19](http://git.inspur.com/ecbh/lambo-design/lambo-design/-/compare/@lambo-design-mobile/workflow-approve@1.0.0-beta.18...@lambo-design-mobile/workflow-approve@1.0.0-beta.19) (2025-05-14)
10
24
 
11
25
  ## [1.0.0-beta.18](http://git.inspur.com/ecbh/lambo-design/lambo-design/-/compare/@lambo-design-mobile/workflow-approve@1.0.0-beta.17...@lambo-design-mobile/workflow-approve@1.0.0-beta.18) (2025-04-25)
package/api.js CHANGED
@@ -122,6 +122,19 @@ export const getProcessHis = (applyId, instanceId, procId, taskId) => {
122
122
  })
123
123
  }
124
124
 
125
+ // 获取操作按钮
126
+ export const getHandleButtons = (procId, taskNode) => {
127
+ const params = {
128
+ procId: procId,
129
+ taskNode: taskNode,
130
+ }
131
+ return ajax.request({
132
+ url: config.smartFlowServerContext + "/manage/approvalCenter/getNodeData",
133
+ method: 'post',
134
+ params: params,
135
+ })
136
+ }
137
+
125
138
 
126
139
  // 获取流程图xml
127
140
  export const printData = (applyId, instanceId, procId) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambo-design-mobile/workflow-approve",
3
- "version": "1.0.0-beta.20",
3
+ "version": "1.0.0-beta.22",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "author": "lambo",
@@ -13,9 +13,10 @@
13
13
  "bpmn-js": "^7.3.1"
14
14
  },
15
15
  "devDependencies": {
16
- "@lambo-design-mobile/upload-file": "^1.0.0-beta.14",
16
+ "standard-version": "^9.5.0",
17
17
  "@lambo-design-mobile/lambo-scan-code": "^1.0.0-beta.1",
18
- "@lambo-design-mobile/shared": "^1.0.0-beta.18"
18
+ "@lambo-design-mobile/shared": "^1.0.0-beta.21",
19
+ "@lambo-design-mobile/upload-file": "^1.0.0-beta.16"
19
20
  },
20
21
  "scripts": {
21
22
  "release": "pnpm release-beta && git push --follow-tags && pnpm re-publish",
@@ -17,6 +17,11 @@
17
17
  style="font-size: 16px;font-weight: bold;padding:5px 0;">
18
18
  {{ Array.isArray(item.auditName) ? item.auditName[0] : item.auditName }}
19
19
  </div>
20
+ <div class="organ-detail">
21
+ <span>
22
+ 部门: {{ Array.isArray(item.auditOrganName) ? item.auditOrganName[0] : item.auditOrganName }}
23
+ </span>
24
+ </div>
20
25
  <div>
21
26
  <div v-if="foldingApprovalComments">
22
27
  <span v-if="item.auditComment" @click="showAuditDetail(item.auditComment)">
@@ -109,6 +114,12 @@ export default {
109
114
  border: 0.4rem solid rgb(255, 245, 229); /* 半透明边框,颜色和背景色相同 */
110
115
  }
111
116
 
117
+ .organ-detail {
118
+ font-size: small;
119
+ color: grey;
120
+ margin-bottom: 2px
121
+ }
122
+
112
123
  ::v-deep .van-cell__value {
113
124
  flex: 0 auto;
114
125
  }
@@ -7,7 +7,7 @@
7
7
  <slot name="business-content"/>
8
8
  <van-tab title="流程信息">
9
9
  <div style="padding: 0 10px">
10
- <div v-if="!isDetail">
10
+ <div v-if="!isDetail && showAuditOpinion">
11
11
  <div class="title-info">
12
12
  <van-icon class="info-icon" style="background-color: #0d88ff" name="cluster-o"/>
13
13
  审批信息
@@ -15,6 +15,7 @@
15
15
  <div class="approvalForm-section">
16
16
  <van-cell-group>
17
17
  <van-field
18
+ v-if="handleButtons && handleButtons.includes('auditOpinion')"
18
19
  v-model="approvalForm.auditOpinion"
19
20
  rows="3"
20
21
  autosize
@@ -29,7 +30,7 @@
29
30
  />
30
31
  <div v-if="approvalForm.nextNode!==''">
31
32
  <van-cell title="下一环节" :value="approvalForm.nextNode"/>
32
- <div v-if="handleButtons.includes('appointHandler')">
33
+ <div v-if="handleButtons && handleButtons.includes('appointHandler')">
33
34
  <van-cell @click="nextNodePopupShow = true" title="办理人员" value-class="approvalForm-value"
34
35
  :value="approvalForm.handlingPersonnel">
35
36
  <template #right-icon>
@@ -39,7 +40,7 @@
39
40
  </div>
40
41
  <div class="van-hairline--bottom"></div>
41
42
  </div>
42
- <div v-if="handleButtons.includes('attachmentFile')">
43
+ <div v-if="handleButtons && handleButtons.includes('attachmentFile')">
43
44
  <upload-file :multiple="true"
44
45
  :oss-server-context="config.smartFlowServerContext"
45
46
  :oss-file-put-url="config.ossFilePutUrl"
@@ -69,7 +70,7 @@
69
70
  </van-collapse>
70
71
  </div>
71
72
  </div>
72
- <div v-if="handleButtons.includes('attachmentFile')">
73
+ <div v-if="handleButtons && handleButtons.includes('attachmentFile')">
73
74
  <div class="title-info">
74
75
  <van-icon class="info-icon" style="background-color: #029ea0" name="link-o"/>
75
76
  查看附件
@@ -114,23 +115,23 @@
114
115
  <!-- 底部按钮 等其他内容 -->
115
116
  <div>
116
117
  <van-popup v-model="popupShow" style="padding-top: 40px" closeable round position="bottom">
117
- <div v-if="handleButtons.includes('auditTo70')" class="popup-option" @click="audit('70')">
118
+ <div v-if="handleButtons && handleButtons.includes('auditTo70')" class="popup-option" @click="audit('70')">
118
119
  {{ getAuditButtonStatus(70) }}
119
120
  </div>
120
- <div v-if="handleButtons.includes('auditTo40')" class="popup-option highlighted"
121
+ <div v-if="handleButtons && handleButtons.includes('auditTo40')" class="popup-option highlighted"
121
122
  @click="audit('40')">
122
123
  {{ getAuditButtonStatus(40) }}
123
124
  </div>
124
- <div v-if="handleButtons.includes('auditTo90')" class="popup-option" @click="audit('90')">
125
+ <div v-if="handleButtons && handleButtons.includes('auditTo90')" class="popup-option" @click="audit('90')">
125
126
  {{ getAuditButtonStatus(90) }}
126
127
  </div>
127
- <div v-if="handleButtons.includes('auditTo80')" class="popup-option" @click="audit('80')">
128
+ <div v-if="handleButtons && handleButtons.includes('auditTo80')" class="popup-option" @click="audit('80')">
128
129
  {{ getAuditButtonStatus(80) }}
129
130
  </div>
130
- <div v-if="handleButtons.includes('auditTo82')" class="popup-option" @click="audit('82')">
131
+ <div v-if="handleButtons && handleButtons.includes('auditTo82')" class="popup-option" @click="audit('82')">
131
132
  {{ getAuditButtonStatus(82) }}
132
133
  </div>
133
- <div v-if="handleButtons.includes('auditTo50')" class="popup-option" @click="audit('50')">
134
+ <div v-if="handleButtons && handleButtons.includes('auditTo50')" class="popup-option" @click="audit('50')">
134
135
  {{ getAuditButtonStatus(50) }}
135
136
  </div>
136
137
  </van-popup>
@@ -181,7 +182,7 @@
181
182
  :value="(item.candidateGroups?.organs ?? []).map(organ => organ.name).join(',')">
182
183
  </van-field>
183
184
  </div>
184
- <div v-if="handleButtons.includes('appointTimeoutTime')">
185
+ <div v-if="handleButtons && handleButtons.includes('appointTimeoutTime')">
185
186
  <van-cell center title="停留时间">
186
187
  <template #default>
187
188
  <div style="display: flex; align-items: center;">
@@ -296,6 +297,7 @@ import {
296
297
  getNodesBehind,
297
298
  getPosition,
298
299
  getPreNode,
300
+ getHandleButtons,
299
301
  getProcessHis,
300
302
  getProcessType, getRole
301
303
  } from "../api";
@@ -314,6 +316,9 @@ export default {
314
316
  computed: {
315
317
  config() {
316
318
  return config
319
+ },
320
+ showAuditOpinion(){
321
+ return this.handleButtons && (this.handleButtons.includes('auditOpinion') || this.handleButtons.includes('appointHandler') || this.handleButtons.includes('attachmentFile'))
317
322
  }
318
323
  },
319
324
  components: {ApprovalNodeCell, SelectNormalList, SelectOrganize, Tree, SelectHandle, UploadFile},
@@ -429,6 +434,9 @@ export default {
429
434
  methods: {
430
435
  getAuditStatus,
431
436
  initData() {
437
+ if (!this.handleButtons){
438
+ this.getHandleButtons();
439
+ }
432
440
  this.getProcessHistory();
433
441
  this.getNextNodes();
434
442
  this.getAttachmentList();
@@ -440,14 +448,14 @@ export default {
440
448
  // 计算有多少个可见的handleButtons
441
449
  getVisibleButtonsCount() {
442
450
  return ['auditTo70', 'auditTo40', 'auditTo90', 'auditTo80', 'auditTo82', 'auditTo50']
443
- .filter(btn => this.handleButtons.includes(btn))
451
+ .filter(btn => this.handleButtons && this.handleButtons.includes(btn))
444
452
  .length;
445
453
  },
446
454
 
447
455
  // 获取唯一按钮的文本
448
456
  getSingleButtonText() {
449
457
  const buttonIds = ['auditTo70', 'auditTo40', 'auditTo90', 'auditTo80', 'auditTo82', 'auditTo50'];
450
- const singleButtonId = buttonIds.find(btn => this.handleButtons.includes(btn));
458
+ const singleButtonId = buttonIds.find(btn => this.handleButtons && this.handleButtons.includes(btn));
451
459
  if (singleButtonId) {
452
460
  const statusId = parseInt(singleButtonId.replace('auditTo', ''));
453
461
  return this.getAuditButtonStatus(statusId);
@@ -458,13 +466,20 @@ export default {
458
466
  // 处理唯一按钮的点击
459
467
  handleSingleButton() {
460
468
  const buttonIds = ['auditTo70', 'auditTo40', 'auditTo90', 'auditTo80', 'auditTo82', 'auditTo50'];
461
- const singleButtonId = buttonIds.find(btn => this.handleButtons.includes(btn));
469
+ const singleButtonId = buttonIds.find(btn => this.handleButtons && this.handleButtons.includes(btn));
462
470
  if (singleButtonId) {
463
471
  const statusId = singleButtonId.replace('auditTo', '');
464
472
  this.audit(statusId);
465
473
  }
466
474
  },
467
475
 
476
+ getHandleButtons() {
477
+ getHandleButtons(this.procId, this.taskNode).then(resp => {
478
+ if (resp.data.code === '200') {
479
+ this.handleButtons = resp.data.data[0]?.handleButtons;
480
+ }
481
+ })
482
+ },
468
483
  getProcessHistory() {
469
484
  getProcessHis(this.applyId, this.instanceId, this.procId, this.taskId).then(resp => {
470
485
  if (resp.data.code === '200') {
@@ -741,7 +756,7 @@ export default {
741
756
  Toast({message: '请输入审批意见', duration: '500'});
742
757
  return
743
758
  } else {
744
- this.auditParams.auditOpinion = this.getAuditButtonStatus(self.auditResult);
759
+ this.auditParams.auditOpinion = this.getAuditButtonStatus(this.auditResult);
745
760
  }
746
761
  }
747
762
 
@@ -23,21 +23,21 @@
23
23
  :arrow-direction="detailsVisible[index] ? 'down' : ''"
24
24
  :value="item.procName"></van-cell>
25
25
  <div v-if="detailsVisible[index]">
26
- <van-cell title-class="list-title" value-class="list-value" class="custom-cell" :border="false"
27
- title="当前环节"
28
- :value="item.taskName"></van-cell>
29
26
  <van-cell title-class="list-title" value-class="list-value" class="custom-cell" :border="false" title="申请人"
30
27
  :value="item.applyUser ? item.applyUser.split(':')[1] : '未定义'"></van-cell>
28
+ <van-cell title-class="list-title" value-class="list-value" class="custom-cell" :border="false"
29
+ :title="selectedTask === 'pending' ? '发起时间':'审批时间' "
30
+ :value="selectedTask === 'pending' ? formatDate(item.startDate) :formatDate(item.auditDate)">
31
+ </van-cell>
31
32
  </div>
32
- <van-cell title-class="list-title" value-class="list-value" class="custom-cell"
33
- :title="selectedTask === 'pending' ? '发起时间':'审批时间' "
34
- :value="selectedTask === 'pending' ? formatDate(item.startDate) :formatDate(item.auditDate)">
35
- </van-cell>
33
+ <van-cell title-class="list-title" value-class="list-value" class="custom-cell" :border="false"
34
+ title="当前环节"
35
+ :value="item.taskName"></van-cell>
36
36
  <van-cell v-if="selectedTask === 'pending'" :key="selectedTask" title=" ">
37
37
  <template #right-icon>
38
38
  <div class="button-group">
39
39
  <van-button class="button" size="small" plain type="info" @click="handleItem(item)">
40
- {{ item.handleName || item.handleType === '20' ? '审批' : '办理' }}
40
+ {{ item.handleName || (item.handleType === '20' ? '审批' : '办理') }}
41
41
  </van-button>
42
42
  </div>
43
43
  </template>
@@ -25,24 +25,49 @@
25
25
  <van-empty description="暂无审批记录"/>
26
26
  </div>
27
27
  <!--审批详情弹出框-->
28
- <van-dialog v-model="showTaskNodeDetail" title="审批详情">
29
- <van-cell-group>
30
- <van-field readonly input-align="right" label="审批节点:" :value="nodeDetail.taskName" />
31
- <van-field readonly input-align="right" label="审批人:" :value="nodeDetail.auditName" />
32
- <van-field readonly input-align="right" label="申请人:" :value="nodeDetail.applyUser ? nodeDetail.applyUser.split(':')[1] : '未定义'" />
33
- <van-field readonly input-align="right" :label="nodeDetail.auditDate ? '审批时间:':'发起时间:' "
34
- :value="nodeDetail.auditDate ? nodeDetail.auditDate : nodeDetail.createTime" />
28
+ <van-dialog
29
+ v-model="showTaskNodeDetail"
30
+ :title="nodeDetailTitle"
31
+ :close-on-popstate="true"
32
+ >
33
+ <!-- 当前记录内容 -->
34
+ <van-cell-group inset v-if="currentRecord">
35
+ <van-field readonly input-align="right" label="审批节点:" :value="currentRecord.taskName" />
36
+ <van-field readonly input-align="right" label="审批人:" :value="currentRecord.auditName" />
37
+ <van-field readonly input-align="right" label="申请人:"
38
+ :value="currentRecord.applyUser ? currentRecord.applyUser.split(':')[1] : '未定义'" />
39
+ <van-field readonly input-align="right"
40
+ :label="currentRecord.auditDate ? '审批时间:' : '发起时间:'"
41
+ :value="currentRecord.auditDate || currentRecord.createTime" />
35
42
  <van-cell title="审批结果:" class="custom-cell" :border="false">
36
- <template v-slot:default>
37
- <van-tag :type="getAuditStatus(nodeDetail.auditResult).type">
38
- {{ getAuditStatus(nodeDetail.auditResult).text }}
43
+ <template #default>
44
+ <van-tag :type="getAuditStatus(currentRecord.auditResult).type">
45
+ {{ getAuditStatus(currentRecord.auditResult).text }}
39
46
  </van-tag>
40
47
  </template>
41
48
  </van-cell>
42
- <van-cell v-if="nodeDetail.auditComment" class="custom-cell"
43
- :border="false" title="审批意见:"
44
- :value="nodeDetail.auditComment"></van-cell>
49
+ <van-cell v-if="currentRecord.auditComment" class="custom-cell" :border="false"
50
+ title="审批意见:" :value="currentRecord.auditComment" />
45
51
  </van-cell-group>
52
+
53
+ <!-- 包含多条审批意见时可切换展示 -->
54
+ <div v-show="nodeDetailsList.length > 1" class="dialog-footer-arrows">
55
+ <van-button
56
+ round
57
+ size="small"
58
+ :disabled="currentIndex <= 0"
59
+ @click="prevRecord"
60
+ icon="arrow-left"
61
+ />
62
+ <span class="record-counter">{{ currentIndex + 1 }} / {{ nodeDetailsList.length }}</span>
63
+ <van-button
64
+ round
65
+ size="small"
66
+ :disabled="currentIndex >= nodeDetailsList.length - 1"
67
+ @click="nextRecord"
68
+ icon="arrow"
69
+ />
70
+ </div>
46
71
  </van-dialog>
47
72
  </div>
48
73
  </div>
@@ -76,22 +101,32 @@ export default {
76
101
  },
77
102
  mounted() {
78
103
  this.getPrintData()
79
- this.getHisAudit()
104
+ // this.getHisAudit()
80
105
  this.onTrack()
81
106
  },
82
107
  data() {
83
108
  return {
84
109
  showTaskNodeDetail: false,
85
- nodeDetail: {},
110
+ nodeDetailsList: [],
111
+ currentIndex: 0,
86
112
  auditData: [],
87
113
  }
88
114
  },
115
+ computed: {
116
+ currentRecord() {
117
+ return this.nodeDetailsList[this.currentIndex];
118
+ },
119
+ nodeDetailTitle() {
120
+ return this.nodeDetailsList.length > 1 ? `审批详情( ${this.currentIndex + 1}/ ${this.nodeDetailsList.length})` : '审批详情'
121
+ }
122
+ },
89
123
  methods: {
90
124
  getAuditStatus,
91
125
  getPrintData() {
92
126
  getPrintData(this.applyId, this.procId).then(resp => {
93
127
  if (resp.data.code === '200') {
94
128
  this.tableData = resp.data.data
129
+ this.auditData = resp.data.data
95
130
  }
96
131
  })
97
132
  },
@@ -226,17 +261,32 @@ export default {
226
261
  const eventBus = this.bpmnViewer.get('eventBus');
227
262
  eventBus.on('element.click', (event) => {
228
263
  const elementId = event.element.id;
229
- // 假设 this.tableData 包含了所有节点的详细信息
230
- for (const item of this.tableData) {
231
- if (item.taskNode === elementId) {
232
- console.log(item);
233
- this.showTaskNodeDetail = true;
234
- this.nodeDetail = item;
235
- break;
236
- }
264
+ let matchedRecords = this.tableData.filter(item => item.taskNode === elementId);
265
+
266
+ if (matchedRecords.length > 0) {
267
+ const getTime = (record) => {
268
+ const timeStr = record.auditDate || record.createTime;
269
+ return new Date(timeStr).getTime();
270
+ };
271
+
272
+ matchedRecords.sort((a, b) => getTime(a) - getTime(b));
273
+
274
+ this.nodeDetailsList = matchedRecords;
275
+ this.currentIndex = matchedRecords.length - 1;
276
+ this.showTaskNodeDetail = true;
237
277
  }
238
278
  });
239
279
  },
280
+ prevRecord() {
281
+ if (this.currentIndex > 0) {
282
+ this.currentIndex--;
283
+ }
284
+ },
285
+ nextRecord() {
286
+ if (this.currentIndex < this.nodeDetailsList.length - 1) {
287
+ this.currentIndex++;
288
+ }
289
+ },
240
290
  }
241
291
  }
242
292
  </script>
@@ -320,4 +370,16 @@ export default {
320
370
  flex: 0 auto;
321
371
  }
322
372
 
373
+ .dialog-footer-arrows {
374
+ display: flex;
375
+ justify-content: space-between;
376
+ align-items: center;
377
+ padding: 10px 16px;
378
+ }
379
+
380
+ .dialog-footer-arrows .record-counter {
381
+ font-size: 14px;
382
+ color: #666;
383
+ margin: 0 12px;
384
+ }
323
385
  </style>