@lambo-design-mobile/workflow-approve 1.0.0-beta.2 → 1.0.0-beta.21

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.
@@ -0,0 +1,111 @@
1
+ <template>
2
+ <div>
3
+ <div class="van-nav-bar__content">
4
+ <div class="van-nav-bar__title">{{ title }}</div>
5
+ </div>
6
+ <div v-if="idList.length > 0">
7
+ <van-checkbox-group v-model="result">
8
+ <van-cell-group>
9
+ <van-cell
10
+ v-for="(item, index) in list"
11
+ clickable
12
+ :key="item.id"
13
+ :title="item.name"
14
+ @click="toggle(index)"
15
+ >
16
+ <template #right-icon>
17
+ <van-checkbox :name="item" ref="checkboxes" />
18
+ </template>
19
+ </van-cell>
20
+ </van-cell-group>
21
+ </van-checkbox-group>
22
+ </div>
23
+ <div v-else>
24
+ <van-empty description="流程类型未定义权限范围" />
25
+ </div>
26
+ <div class="custom-bottom-bar">
27
+ <div class="bar-item" @click="selectNormalListHandle('cancel')">取消</div>
28
+ <div class="bar-item approve" @click="selectNormalListHandle('select')">选择</div>
29
+ </div>
30
+ </div>
31
+ </template>
32
+
33
+ <script>
34
+ export default {
35
+ name: "SelectNormalList",
36
+ props: {
37
+ title: {
38
+ type: String,
39
+ default: ''
40
+ },
41
+ idList: {
42
+ type: Array,
43
+ default: () => [],
44
+ required: true,
45
+ },
46
+ parseFunction: {
47
+ type: Function,
48
+ required: true,
49
+ default: (idList) => idList.map(id => ({ id, name: `Name for ${id}` })) // 示例默认解析
50
+ },
51
+ },
52
+ data() {
53
+ return {
54
+ list: [],
55
+ result: [],
56
+ };
57
+ },
58
+ created() {
59
+ // 使用传入的解析函数获取 list 数据
60
+ this.parseFunction(this.idList).then((parsedList) => {
61
+ this.list = parsedList;
62
+ });
63
+ },
64
+ methods: {
65
+ toggle(index) {
66
+ this.$refs.checkboxes[index].toggle();
67
+ },
68
+ selectNormalListHandle(handle) {
69
+ this.$emit('selectNormalListHandle', handle, this.result);
70
+ },
71
+ },
72
+ };
73
+ </script>
74
+
75
+ <style scoped>
76
+ .custom-bottom-bar {
77
+ position: fixed;
78
+ bottom: 0;
79
+ width: 100%;
80
+ display: flex;
81
+ justify-content: space-around;
82
+ background-color: #fff;
83
+ padding: 10px 0;
84
+ border-top: 1px solid #eaeaea;
85
+ box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.05);
86
+ z-index: 1000;
87
+ }
88
+
89
+ .bar-item {
90
+ flex: 1;
91
+ text-align: center;
92
+ padding: 10px 0;
93
+ font-size: 16px;
94
+ border-radius: 4px;
95
+ }
96
+
97
+ .bar-item:active {
98
+ background-color: #e6e6e6;
99
+ }
100
+
101
+ .approve {
102
+ color: #fff;
103
+ background: linear-gradient(90deg, #0096FF, #1677FF);
104
+ border-radius: 9px;
105
+ margin: 0 20px;
106
+ }
107
+
108
+ .approve:active {
109
+ background: linear-gradient(90deg, rgba(0, 150, 255, 0.8), rgba(22, 119, 255, 0.8));
110
+ }
111
+ </style>
@@ -0,0 +1,216 @@
1
+ <template>
2
+ <div>
3
+ <div class="van-nav-bar__content">
4
+ <div class="van-nav-bar__title">选择组织</div>
5
+ </div>
6
+ <div v-if="this.organizeIdList.length > 0 || allOrganize === true">
7
+ <Tree
8
+ :data="data"
9
+ :showCheckBox="showCheckBox"
10
+ @onChecked="handleChecked"
11
+ @onExpand="handleExpand"
12
+ @onSelect="handleSelect"
13
+ :loadData="handleLoadData"
14
+ ref="tree"
15
+ >
16
+ </Tree>
17
+ </div>
18
+ <div v-else>
19
+ <van-empty description="流程类型未定义权限范围"/>
20
+ </div>
21
+ <div class="custom-bottom-bar">
22
+ <div class="bar-item" @click="selectOrganizeHandle('cancel')">取消</div>
23
+ <div class="bar-item approve" @click="selectOrganizeHandle('select')">选择</div>
24
+ </div>
25
+ </div>
26
+ </template>
27
+
28
+ <script>
29
+ import Tree from "./tree/Tree.vue";
30
+ import {getOrgan, getOrgRootTree, getOrgSubNodes} from "../api";
31
+
32
+ export default {
33
+ name: "CustomTree",
34
+ components: {
35
+ Tree
36
+ },
37
+ props: {
38
+ showCheckBox: {
39
+ type: Boolean,
40
+ default: true
41
+ },
42
+ allOrganize: {
43
+ type: Boolean,
44
+ default: false
45
+ },
46
+ organizeIdList: {
47
+ type: Array,
48
+ default: () => []
49
+ }
50
+ },
51
+ data() {
52
+ return {
53
+ organizeData: [] // 初始化为空数组
54
+ };
55
+ },
56
+ methods: {
57
+ getCheckedNodes() {
58
+ return this.$refs.tree.getCheckedNodes();
59
+ },
60
+ getCheckedChildrenNodes() {
61
+ return this.$refs.tree.getCheckedChildrenNodes();
62
+ },
63
+ formatTree(arr) {
64
+ function findParents(arr) {
65
+ const map = arr.reduce((obj, cur) => {
66
+ let id = cur["id"];
67
+ obj[id] = id;
68
+ return obj;
69
+ }, {});
70
+ return arr.filter((item) => !map[item.parentId]);
71
+ }
72
+
73
+ let parents = findParents(arr);
74
+
75
+ function findChildren(parents) {
76
+ if (!parents) return;
77
+ parents.forEach((p) => {
78
+ arr.forEach((item) => {
79
+ if (p.id === item.parentId) {
80
+ if (!p.children) {
81
+ p.children = [];
82
+ }
83
+ p.children.push(item);
84
+ }
85
+ });
86
+ findChildren(p.children);
87
+ });
88
+ }
89
+
90
+ findChildren(parents);
91
+ return parents;
92
+ },
93
+ handleChecked(v) {
94
+ this.$emit('handleChecked', v); // 发射 checked 事件到父组件
95
+ },
96
+ handleExpand(v) {
97
+ this.$emit('handleExpand', v); // 发射 expand 事件到父组件
98
+ },
99
+ handleSelect(v) {
100
+ this.$emit('handleSelect', v); // 发射 select 事件到父组件
101
+ },
102
+ handleLoadData(node, callback) {
103
+ getOrgSubNodes(node.id).then((res) => {
104
+ const result = res.data;
105
+ if (result.code === 1) {
106
+ callback(
107
+ result.data.map((item) => {
108
+ return {
109
+ children: [],
110
+ title: item.organName,
111
+ id: item.organCode,
112
+ parentId: item.parentId,
113
+ checked: false,
114
+ expand: false
115
+ };
116
+ }),
117
+ (res) => {
118
+ console.log(res)
119
+ }
120
+ );
121
+ } else {
122
+ callback(
123
+ [], (res) => {
124
+ console.log(res)
125
+ });
126
+ }
127
+ });
128
+ },
129
+ selectOrganizeHandle(handle) {
130
+ this.$emit('selectOrganizeHandle', handle, this.getCheckedNodes());
131
+ },
132
+
133
+ },
134
+ computed: {
135
+ data() {
136
+ return this.formatTree(this.organizeData);
137
+ }
138
+ },
139
+ created() {
140
+ if (this.organizeIdList.length > 0) {
141
+ this.organizeIdList.forEach((item) => {
142
+ getOrgan(item).then((res) => {
143
+ const result = res.data;
144
+ if (result.code === 1) {
145
+ // 确保 result.data 是一个对象
146
+ const newItem = {
147
+ children: [],
148
+ title: result.data.organName,
149
+ id: result.data.organCode,
150
+ parentId: result.data.parentId,
151
+ checked: false,
152
+ expand: false
153
+ };
154
+ // 添加单个新项到 organizeData 数组
155
+ this.organizeData.push(newItem);
156
+ }
157
+ }).catch((error) => {
158
+ console.error("getOrgan 请求失败:", error);
159
+ });
160
+ });
161
+ } else {
162
+ getOrgRootTree().then((res) => {
163
+ const result = res.data;
164
+ if (result.code === 1) {
165
+ this.organizeData = result.data.map((item) => {
166
+ return {
167
+ children: [],
168
+ title: item.organName,
169
+ id: item.organCode,
170
+ parentId: item.parentId,
171
+ checked: false,
172
+ expand: false
173
+ };
174
+ });
175
+ }
176
+ });
177
+ }
178
+ }
179
+ };
180
+ </script>
181
+ <style scoped>
182
+ .custom-bottom-bar {
183
+ position: fixed;
184
+ bottom: 0;
185
+ width: 100%;
186
+ display: flex;
187
+ justify-content: space-around;
188
+ background-color: #fff;
189
+ padding: 10px 0;
190
+ border-top: 1px solid #eaeaea;
191
+ box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.05);
192
+ z-index: 1000;
193
+ }
194
+
195
+ .bar-item {
196
+ flex: 1;
197
+ text-align: center;
198
+ padding: 10px 0;
199
+ font-size: 16px;
200
+ border-radius: 4px;
201
+ }
202
+
203
+ .bar-item:active {
204
+ background-color: #e6e6e6; /* 点击时的背景颜色 */
205
+ }
206
+
207
+ .approve {
208
+ color: #fff;
209
+ background: linear-gradient(90deg, #0096FF, #1677FF);
210
+ border-radius: 9px;
211
+ }
212
+
213
+ .approve:active {
214
+ background: linear-gradient(90deg, rgba(0, 150, 255, 0.8), rgba(22, 119, 255, 0.8));
215
+ }
216
+ </style>
@@ -16,28 +16,28 @@
16
16
  </template>
17
17
  </van-cell>
18
18
  <van-cell title-class="list-title" value-class="list-value" class="custom-cell" :border="false"
19
- title="样品单号"
19
+ title="申请编号"
20
20
  :value="item.applyId"></van-cell>
21
21
  <van-cell title-class="list-title" value-class="list-value" class="custom-cell" :border="false"
22
22
  title="流程名称" @click="toggleDetails(index)" :is-link="true"
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.handleType === '20' ? '审批' : '办理' }}
40
+ {{ item.handleName || (item.handleType === '20' ? '审批' : '办理') }}
41
41
  </van-button>
42
42
  </div>
43
43
  </template>
@@ -131,6 +131,7 @@ export default {
131
131
  taskId: item.taskId,
132
132
  instanceId: item.procInstanceId,
133
133
  procName: item.procName,
134
+ procType: item.procType,
134
135
  procKey: result.data[0].procKey,
135
136
  handleButtons: result.data[0].handleButtons,
136
137
  appFormUrl: item.appFormUrl,
@@ -163,6 +164,7 @@ export default {
163
164
  taskId: item.taskId,
164
165
  instanceId: item.procInstanceId,
165
166
  procName: item.procName,
167
+ procType: item.procType,
166
168
  procKey: result.data[0].procKey,
167
169
  handleButtons: result.data[0].handleButtons,
168
170
  appFormUrl: item.appFormUrl,
@@ -232,4 +234,4 @@ export default {
232
234
  flex: 0 0 auto;
233
235
  }
234
236
 
235
- </style>
237
+ </style>
@@ -18,58 +18,20 @@
18
18
  </div>
19
19
  <div v-if="auditData.length > 0">
20
20
  <div v-for="(item,index) in auditData" :key="index" class="record-item">
21
- <van-cell center>
22
- <template v-slot:icon>
23
- <div
24
- v-if="['通过', '跳转指定节点'].includes(getAuditStatus(item.auditResult).text)"
25
- class="completed-icon">
26
- <van-icon class="iconfont" class-prefix='icon' :name=getAuditStatus(item.auditResult).icon
27
- size="30px" color="#fff"/>
28
- </div>
29
- <div v-else class="pending-icon">
30
- <van-icon class="iconfont" class-prefix='icon' :name=getAuditStatus(item.auditResult).icon
31
- size="30px" color="#fff"/>
32
- </div>
33
- </template>
34
- <template v-slot:title>
35
- <div :style="{ color: getAuditStatus(item.auditResult).color }"
36
- style="font-size: 16px;font-weight: bold;padding:5px 0;">
37
- {{ item.auditName }}
38
- </div>
39
- <div>{{ item.taskName }}
40
- <span v-if="item.auditComment" @click="showAuditDetail(item.auditComment)">
41
- | 审批意见 <van-icon name="comment-circle-o"/>
42
- </span>
43
- </div>
44
- </template>
45
- <template v-slot:label>
46
- <div>{{ item.auditDate }}</div>
47
- </template>
48
- <template v-slot:default>
49
- <span :style="{ color: getAuditStatus(item.auditResult).color }">{{
50
- getAuditStatus(item.auditResult).text
51
- }}</span>
52
- </template>
53
- </van-cell>
21
+ <flow-node-cell :node-detail="item"/>
54
22
  </div>
55
23
  </div>
56
24
  <div v-else>
57
25
  <van-empty description="暂无审批记录"/>
58
26
  </div>
59
-
60
27
  <!--审批详情弹出框-->
61
28
  <van-dialog v-model="showTaskNodeDetail" title="审批详情">
62
29
  <van-cell-group>
63
- <van-cell class="custom-cell" :border="false" title="审批节点:"
64
- :value="nodeDetail.taskName"></van-cell>
65
- <van-cell class="custom-cell" :border="false" title="审批人:"
66
- :value="nodeDetail.auditName"></van-cell>
67
- <van-cell class="custom-cell" :border="false" title="申请人:"
68
- :value="nodeDetail.applyUser ? nodeDetail.applyUser.split(':')[1] : '未定义'"></van-cell>
69
- <van-cell class="custom-cell"
70
- :title="nodeDetail.startDate ? '发起时间:':'审批时间:' "
71
- :value="nodeDetail.startDate ? nodeDetail.startDate : nodeDetail.auditDate">
72
- </van-cell>
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" />
73
35
  <van-cell title="审批结果:" class="custom-cell" :border="false">
74
36
  <template v-slot:default>
75
37
  <van-tag :type="getAuditStatus(nodeDetail.auditResult).type">
@@ -88,9 +50,12 @@
88
50
  <script>
89
51
  import Viewer from "bpmn-js/lib/Viewer";
90
52
  import {getHisAudit, getPrintData, printData} from "../api";
91
- import {Dialog} from "vant";
53
+ import ApprovalNodeCell from "./ApprovalNodeCell.vue";
54
+ import { getAuditStatus } from './js/global';
55
+ import FlowNodeCell from "./FlowNodeCell.vue"; // 根据路径修改
92
56
 
93
57
  export default {
58
+ components: {FlowNodeCell, ApprovalNodeCell},
94
59
  props: {
95
60
  procId: {
96
61
  type: String,
@@ -122,6 +87,7 @@ export default {
122
87
  }
123
88
  },
124
89
  methods: {
90
+ getAuditStatus,
125
91
  getPrintData() {
126
92
  getPrintData(this.applyId, this.procId).then(resp => {
127
93
  if (resp.data.code === '200') {
@@ -270,33 +236,7 @@ export default {
270
236
  }
271
237
  }
272
238
  });
273
-
274
239
  },
275
- getAuditStatus(auditResult) {
276
- const statusMap = {
277
- '30': {text: '通过', icon: "tongguo", color: '#0d88ff', type: 'success'},
278
- '40': {text: '驳回上一节点', icon: "bohui", color: '#ed4014', type: 'danger'},
279
- '50': {text: '驳回到原点', icon: "bohui", color: '#ed4014', type: 'danger'},
280
- '51': {text: '流程作废', icon: "liuchengzuofei", color: '#ed4014', type: 'danger'},
281
- '60': {text: '撤回', icon: "chehui", color: '#ed4014', type: 'warning'},
282
- '80': {text: '跳转指定节点', icon: "tiaozhuan", color: '#0d88ff', type: 'primary'},
283
- '90': {text: '驳回指定节点', icon: "bohui", color: '#ed4014', type: 'primary'},
284
- };
285
- return {
286
- text: (statusMap[auditResult] && statusMap[auditResult].text) || '待审批',
287
- icon: (statusMap[auditResult] && statusMap[auditResult].icon) || 'daishenpi',
288
- color: (statusMap[auditResult] && statusMap[auditResult].color) || '#ff9900',
289
- type: (statusMap[auditResult] && statusMap[auditResult].type) || 'warning',
290
- };
291
- },
292
- showAuditDetail(auditComment) {
293
- Dialog.alert({
294
- title: '审批意见',
295
- message: auditComment,
296
- }).then(() => {
297
- // on close
298
- });
299
- }
300
240
  }
301
241
  }
302
242
  </script>
@@ -338,6 +278,13 @@ export default {
338
278
 
339
279
  }
340
280
 
281
+ ::v-deep .van-dialog__header {
282
+ padding: 10px 0;
283
+ font-weight: 500;
284
+ line-height: 24px;
285
+ text-align: center;
286
+ }
287
+
341
288
  .record-item {
342
289
  position: relative;
343
290
  margin-bottom: 20px;
@@ -353,38 +300,6 @@ export default {
353
300
  background-color: #0d88ff; /* 线条颜色 */
354
301
  }
355
302
 
356
- .completed-icon {
357
- width: 45px; /* 自定义宽度 */
358
- height: 45px; /* 自定义高度 */
359
- background-clip: padding-box; /* 使背景不填充边框 */
360
-
361
- border-radius: 50%;
362
- margin-right: 15px;
363
-
364
- display: flex;
365
- align-items: center;
366
- justify-content: center;
367
-
368
- background: linear-gradient(90deg, #0096FF, #1677FF);
369
- border: 5px solid rgb(229, 244, 255); /* 半透明边框,颜色和背景色相同 */
370
- }
371
-
372
- .pending-icon {
373
- width: 45px; /* 自定义宽度 */
374
- height: 45px; /* 自定义高度 */
375
- background-clip: padding-box; /* 使背景不填充边框 */
376
-
377
- border-radius: 50%;
378
- margin-right: 15px;
379
-
380
- display: flex;
381
- align-items: center;
382
- justify-content: center;
383
-
384
- background: linear-gradient(90deg, #FF7E00, #FFA200);
385
- border: 5px solid rgb(255, 245, 229); /* 半透明边框,颜色和背景色相同 */
386
- }
387
-
388
303
 
389
304
  .title-info {
390
305
  font-weight: bold;
@@ -401,12 +316,8 @@ export default {
401
316
  margin-right: 5px;
402
317
  }
403
318
 
404
- .van-cell__title {
405
- flex: 1 0 auto;
406
- }
407
-
408
319
  .van-cell__value {
409
- flex: 0 1 auto;
320
+ flex: 0 auto;
410
321
  }
411
322
 
412
- </style>
323
+ </style>
@@ -1,8 +1,8 @@
1
1
  @font-face {
2
2
  font-family: "iconfont"; /* Project id 4700118 */
3
- src: url('iconfont.woff2?t=1728522790908') format('woff2'),
4
- url('iconfont.woff?t=1728522790908') format('woff'),
5
- url('iconfont.ttf?t=1728522790908') format('truetype');
3
+ src: url('iconfont.woff2?t=1733205617891') format('woff2'),
4
+ url('iconfont.woff?t=1733205617891') format('woff'),
5
+ url('iconfont.ttf?t=1733205617891') format('truetype');
6
6
  }
7
7
 
8
8
  .icon {
@@ -13,6 +13,14 @@
13
13
  -moz-osx-font-smoothing: grayscale;
14
14
  }
15
15
 
16
+ .icon-faqi:before {
17
+ content: "\e67c";
18
+ }
19
+
20
+ .icon-faqiliuchen:before {
21
+ content: "\e621";
22
+ }
23
+
16
24
  .icon-daiban:before {
17
25
  content: "\e629";
18
26
  }