@lambo-design-mobile/workflow-approve 1.0.0-beta.1 → 1.0.0-beta.11

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.
@@ -2,7 +2,7 @@
2
2
  <div>
3
3
  <div id="headTitle" class="headTitle">
4
4
  <div class="van-nav-bar__content">
5
- <div class="van-nav-bar__title">指定办理人</div>
5
+ <div class="van-nav-bar__title">{{title}}</div>
6
6
  </div>
7
7
  <van-search
8
8
  show-action
@@ -28,8 +28,8 @@
28
28
  :overlay-style="{ position:'absolute',marginTop: '104px'}" transition="none">
29
29
  <div style="padding: 12px">
30
30
  <van-form>
31
- <van-field clearable v-model="searchForm.organId" label="组织ID" readonly />
32
- <van-field clearable v-model="searchForm.organTitle" label="组织名称" readonly />
31
+ <van-field clearable @click="searchOrganShow = true" v-model="searchForm.organId" label="组织ID" readonly />
32
+ <van-field clearable @click="searchOrganShow = true" v-model="searchForm.organTitle" label="组织名称" readonly />
33
33
  <van-field clearable v-model="searchForm.userId" label="用户ID" placeholder="请输入用户ID"/>
34
34
  <van-field name="radio" label="是否管理员">
35
35
  <template #input>
@@ -47,12 +47,12 @@
47
47
  </van-form>
48
48
  </div>
49
49
  </van-popup>
50
- <div id="listContent">
50
+ <div id="listContent" style="background: #f7f8fa">
51
51
  <van-list v-model="loading" style="padding-top: 15px"
52
52
  :finished="finished"
53
53
  finished-text="没有更多了"
54
54
  @load="handleLoad()">
55
- <select-handle-card ref="selectHandleCard" :person-list="personList.rows"
55
+ <select-handle-card ref="selectHandleCard" :multi-select="multiSelect" :person-list="personList.rows"
56
56
  :result.sync="checkResult">
57
57
  </select-handle-card>
58
58
  </van-list>
@@ -61,23 +61,46 @@
61
61
  <div class="bar-item" @click="handleSelect('cancel')">取消</div>
62
62
  <div class="bar-item approve" @click="handleSelect('select')">选择</div>
63
63
  </div>
64
+
65
+ <van-popup v-model="searchOrganShow" closeable round position="bottom" :style="{ height: '80%' }">
66
+ <select-organize :all-organize="true" :show-check-box="false" @handleSelect="onSelect" ></select-organize>
67
+ </van-popup>
64
68
  </div>
65
69
  </template>
66
70
 
67
71
  <script>
68
72
  import SelectHandleCard from "./SelectHandleCard.vue";
69
- import {getOrgRootTree, getUserList} from "../api";
73
+ import {getOrgRootTree, getProcessType, getUserList} from "../api";
74
+ import Tree from "./tree/Tree.vue";
75
+ import SelectOrganize from "./SelectOrganize.vue";
70
76
 
71
77
  export default {
72
78
  name: "SelectHandle",
73
- components: {SelectHandleCard},
79
+ components: {SelectOrganize, Tree, SelectHandleCard},
80
+ props: {
81
+ title: {
82
+ type: String,
83
+ default: ''
84
+ },
85
+ procType: {
86
+ type: String,
87
+ required: true
88
+ },
89
+ multiSelect: { // 新增一个 prop 来控制是否开启多选模式
90
+ type: Boolean,
91
+ default: false
92
+ }
93
+ },
74
94
  data() {
75
95
  return {
96
+ searchOrganShow: false,
76
97
  searchFilterShow: false,
77
98
  searchFilterBadge: false,
78
99
  searchForm: {
79
100
  userId: '',
101
+ orgTreeType: '',
80
102
  userName: '',
103
+ permScopeList: '',
81
104
  organId: '',
82
105
  organTitle: '',
83
106
  directChild: '',
@@ -91,43 +114,65 @@ export default {
91
114
  rows: []
92
115
  },
93
116
  checkResult: [], // 需要传递到子组件的 checkResult
94
- }
117
+ };
118
+ },
119
+ mounted() {
120
+ this.initSearch();
95
121
  },
96
122
  methods: {
97
- handleLoad() {
98
- console.log("触发加载")
123
+ initSearch() {
99
124
  getOrgRootTree().then(res => {
100
125
  const result = res.data;
101
126
  if (result.code === 1) {
102
127
  this.searchForm.organId = result.data[0].organId;
103
128
  this.searchForm.organTitle = result.data[0].organName;
129
+ this.searchForm.userId = '';
130
+ }
131
+ this.handleLoad()
132
+ })
133
+ },
134
+ handleLoad() {
135
+ console.log("触发加载")
136
+ const offset = this.personList.rows.length;
137
+ const limit = 10;
104
138
 
105
- const offset = this.personList.rows.length;
106
- const limit = 10;
107
-
108
- getUserList(offset, limit, this.searchForm).then(res => {
109
-
110
- const result = res.data;
111
- if (result.code === "1") {
139
+ getProcessType(this.procType).then(res => {
112
140
 
113
- //返回的数据添加到 personList
114
- this.personList.rows = this.personList.rows.concat(result.data.rows);
115
- this.personList.total = result.data.total;
141
+ this.searchForm.orgTreeType = res.data.data.rows[0].organTreeType;
142
+ const userArray = this.extractUsers(res.data.data.rows[0].permScope);
143
+ if (userArray.length > 0) {
144
+ this.searchForm.permScopeList = userArray.join(',')
145
+ }
146
+ getUserList(offset, limit, this.searchForm).then(res => {
116
147
 
117
- } else {
118
- console.error('Failed to load data');
119
- }
148
+ const result = res.data;
149
+ if (result.code === "1") {
150
+ //返回的数据添加到 personList 中
151
+ this.personList.rows = this.personList.rows.concat(result.data.rows);
152
+ this.personList.total = result.data.total;
153
+ }
120
154
 
121
- this.loading = false;
122
- this.finished = this.personList.rows.length >= this.personList.total;
155
+ this.loading = false;
156
+ this.finished = this.personList.rows.length >= this.personList.total;
123
157
 
124
- }).catch(error => {
125
- console.error('Error fetching data:', error);
126
- this.loading = false;
127
- });
128
- }
158
+ }).catch(error => {
159
+ console.error('Error fetching data:', error);
160
+ this.loading = false;
161
+ });
162
+ }).catch(error => {
163
+ console.error(error)
129
164
  })
130
165
  },
166
+
167
+ extractUsers(permScope) {
168
+ const match = permScope.match(/U:([^,]+)/);
169
+ if (match && match[1]) {
170
+ return match[1].split(';');
171
+ } else {
172
+ return [];
173
+ }
174
+ },
175
+
131
176
  onSearch() {
132
177
  // 如果搜索弹框是打开的
133
178
  if (this.searchFilterShow) {
@@ -148,15 +193,7 @@ export default {
148
193
  }
149
194
  },
150
195
  resetSearch() {
151
- // 遍历 searchForm 对象的每个属性,将其值置为空
152
- for (let key in this.searchForm) {
153
- // eslint-disable-next-line no-prototype-builtins
154
- if (this.searchForm.hasOwnProperty(key)) {
155
- if (key !== "organId" && key !== "organTitle") {
156
- this.searchForm[key] = '';
157
- }
158
- }
159
- }
196
+ this.initSearch()
160
197
  },
161
198
  resetAndLoadPersonList() {
162
199
  this.personList.total = 0;
@@ -174,6 +211,12 @@ export default {
174
211
  checkSearchForm() {
175
212
  this.searchFilterBadge = Object.values(this.searchForm).some(value => value !== '');
176
213
  },
214
+
215
+ onSelect(v) {
216
+ this.searchForm.organId = v.id;
217
+ this.searchForm.organTitle = v.title;
218
+ this.searchOrganShow = false;
219
+ },
177
220
  },
178
221
  watch: {
179
222
  // 监听 searchForm 的每一个字段的变化
@@ -265,6 +308,7 @@ export default {
265
308
  color: #fff;
266
309
  background: linear-gradient(90deg, #0096FF, #1677FF);
267
310
  border-radius: 9px;
311
+ margin: 0 20px;
268
312
  }
269
313
 
270
314
  .approve:active {
@@ -1,12 +1,12 @@
1
1
  <template>
2
2
  <div>
3
- <van-checkbox-group v-model="localResult" :max="1" ref="checkboxGroup">
3
+ <van-checkbox-group v-model="localResult" :max="multiSelect ? 0 : 1" ref="checkboxGroup">
4
4
  <van-cell-group v-for="(item,index) in personList" :key="index"
5
5
  style="margin-bottom: 10px;" inset>
6
6
  <van-cell value-class="value-status" center size="large"
7
7
  :value="item.userName">
8
8
  <template #icon>
9
- <van-checkbox @click="clearLocalResult(item)" style="padding: 0 5px" :name="item"
9
+ <van-checkbox @click="handleCheckboxClick(item)" style="padding: 0 5px" :name="item"
10
10
  icon-size="18px"></van-checkbox>
11
11
  </template>
12
12
  </van-cell>
@@ -29,8 +29,8 @@
29
29
  </van-checkbox-group>
30
30
  </div>
31
31
  </template>
32
- <script>
33
32
 
33
+ <script>
34
34
  export default {
35
35
  name: 'SelectHandleCard',
36
36
  props: {
@@ -42,6 +42,10 @@ export default {
42
42
  result: {
43
43
  type: Array,
44
44
  default: () => []
45
+ },
46
+ multiSelect: { // 新增一个 prop 来控制是否开启多选模式
47
+ type: Boolean,
48
+ default: false
45
49
  }
46
50
  },
47
51
  data() {
@@ -71,9 +75,19 @@ export default {
71
75
  toggleAll() {
72
76
  this.$refs.checkboxGroup.toggleAll(false);
73
77
  },
78
+ handleCheckboxClick(item) {
79
+ if (this.multiSelect) {
80
+ this.addLocalResult(item); // 如果是多选模式,调用 addLocalResult
81
+ } else {
82
+ this.clearLocalResult(item); // 否则调用 clearLocalResult,保持单选
83
+ }
84
+ },
74
85
  clearLocalResult(item) {
75
86
  this.localResult = [];
76
87
  this.localResult.push(item)
88
+ },
89
+ addLocalResult(item) {
90
+
77
91
  },
78
92
  getStatusText(status) {
79
93
  switch (status) {
@@ -119,8 +133,8 @@ export default {
119
133
  }
120
134
  }
121
135
  </script>
122
- <style scoped>
123
136
 
137
+ <style scoped>
124
138
  /* 自定义 .van-cell 样式 */
125
139
  .custom-cell {
126
140
  padding: 5px 16px;
@@ -131,5 +145,4 @@ export default {
131
145
  font-weight: bold; /* 设置文字加粗 */
132
146
  text-align: right;
133
147
  }
134
-
135
- </style>
148
+ </style>
@@ -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>
@@ -37,7 +37,7 @@
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,9 @@ export default {
131
131
  taskId: item.taskId,
132
132
  instanceId: item.procInstanceId,
133
133
  procName: item.procName,
134
+ procType: item.procType,
135
+ procKey: result.data[0].procKey,
136
+ handleButtons: result.data[0].handleButtons,
134
137
  appFormUrl: item.appFormUrl,
135
138
  appDetailUrl: item.appDetailUrl,
136
139
  }
@@ -161,6 +164,7 @@ export default {
161
164
  taskId: item.taskId,
162
165
  instanceId: item.procInstanceId,
163
166
  procName: item.procName,
167
+ procType: item.procType,
164
168
  procKey: result.data[0].procKey,
165
169
  handleButtons: result.data[0].handleButtons,
166
170
  appFormUrl: item.appFormUrl,
@@ -230,4 +234,4 @@ export default {
230
234
  flex: 0 0 auto;
231
235
  }
232
236
 
233
- </style>
237
+ </style>