@ebiz/designer-components 0.1.29 → 0.1.31
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/dist/designer-components.css +1 -1
- package/dist/index.mjs +10586 -10142
- package/package.json +1 -1
- package/src/components/EbizApproval.vue +3 -1
- package/src/components/EbizApprovalForm.vue +482 -0
- package/src/components/EbizEmployeeSelector.vue +22 -18
- package/src/components/EbizSApprovalProcess.vue +9 -43
- package/src/index.js +3 -0
- package/src/router/index.js +6 -0
- package/src/views/EbizApprovalFormDemo.vue +208 -0
- package/src/views/EbizEmployeeSelector.vue +1 -1
- package/src/views/Home.vue +1 -0
package/package.json
CHANGED
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="approval-form">
|
|
3
|
+
<t-form labelWidth="100px" labelAlign="right" class="component-base-style" :data="{}">
|
|
4
|
+
<!-- 添加审批人选择组件 -->
|
|
5
|
+
<div v-if="!isInWhiteList && hasNextApprover" style="margin-bottom: 10px;">
|
|
6
|
+
<ebiz-approval
|
|
7
|
+
:showCC="false"
|
|
8
|
+
type="all"
|
|
9
|
+
:showRootOrg="false"
|
|
10
|
+
class="component-base-style"
|
|
11
|
+
:required="hasNextApprover"
|
|
12
|
+
v-model:approverList="selectedApprover"
|
|
13
|
+
:canEdit="hasNextApprover"
|
|
14
|
+
v-model:ccList="selectedCCList"
|
|
15
|
+
>
|
|
16
|
+
<template #title>
|
|
17
|
+
<div></div>
|
|
18
|
+
</template>
|
|
19
|
+
</ebiz-approval>
|
|
20
|
+
</div>
|
|
21
|
+
<t-form-item label="审批意见">
|
|
22
|
+
<t-textarea placeholder="请输入" :maxLength="200" :maxCharacter="true" class="component-base-style"
|
|
23
|
+
v-model="comments"></t-textarea>
|
|
24
|
+
</t-form-item>
|
|
25
|
+
<t-form-item>
|
|
26
|
+
<div class="button-group">
|
|
27
|
+
<div class="more-actions">
|
|
28
|
+
<t-dropdown :options="actionOptions" @click="onActionSelected">
|
|
29
|
+
<t-button theme="default" variant="outline">
|
|
30
|
+
<template #icon>
|
|
31
|
+
<t-icon name="ellipsis" size="large" class="component-base-style"></t-icon>
|
|
32
|
+
</template>
|
|
33
|
+
</t-button>
|
|
34
|
+
</t-dropdown>
|
|
35
|
+
</div>
|
|
36
|
+
<div>
|
|
37
|
+
<t-button theme="primary" type="submit" content="通过" @click="handlePass">
|
|
38
|
+
<template #icon>
|
|
39
|
+
<t-icon name="check" size="large" class="component-base-style"></t-icon>
|
|
40
|
+
</template>
|
|
41
|
+
</t-button>
|
|
42
|
+
<t-button content="拒绝" the type="reset" style="margin-left: 10px" @click="handleReject">
|
|
43
|
+
<template #icon>
|
|
44
|
+
<t-icon name="close" size="large" class="component-base-style"></t-icon>
|
|
45
|
+
</template>
|
|
46
|
+
</t-button>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</t-form-item>
|
|
50
|
+
</t-form>
|
|
51
|
+
|
|
52
|
+
<!-- 转审人员选择 -->
|
|
53
|
+
<t-dialog header="选择转审人" :visible="showTransferDialog" :confirm-btn="{ content: '确定', theme: 'primary' }"
|
|
54
|
+
:cancel-btn="{ content: '取消', theme: 'default' }" @confirm="confirmTransfer"
|
|
55
|
+
@close="showTransferDialog = false">
|
|
56
|
+
<EbizEmployeeSelector v-model="transferApprover" :single="true"></EbizEmployeeSelector>
|
|
57
|
+
</t-dialog>
|
|
58
|
+
|
|
59
|
+
<!-- 转接待人选择 -->
|
|
60
|
+
<t-dialog header="选择接待人" :visible="showReceiverDialog" :confirm-btn="{ content: '确定', theme: 'primary' }"
|
|
61
|
+
:cancel-btn="{ content: '取消', theme: 'default' }" @confirm="confirmReceiver"
|
|
62
|
+
@close="showReceiverDialog = false">
|
|
63
|
+
<EbizEmployeeSelector v-model="selectedReceiver" :single="true"></EbizEmployeeSelector>
|
|
64
|
+
</t-dialog>
|
|
65
|
+
|
|
66
|
+
<!-- 加签位置选择 -->
|
|
67
|
+
<t-dialog header="选择加签位置" :visible="showPositionDialog" :confirm-btn="{ content: '确定', theme: 'primary' }"
|
|
68
|
+
:cancel-btn="{ content: '取消', theme: 'default' }" @confirm="confirmPosition"
|
|
69
|
+
@close="showPositionDialog = false">
|
|
70
|
+
<t-radio-group v-model="addSignPosition">
|
|
71
|
+
<t-radio value="before">往前加签</t-radio>
|
|
72
|
+
<t-radio value="after">往后加签</t-radio>
|
|
73
|
+
</t-radio-group>
|
|
74
|
+
</t-dialog>
|
|
75
|
+
|
|
76
|
+
<!-- 加签人员选择 -->
|
|
77
|
+
<t-dialog header="选择加签人员" :visible="showAddSignDialog" :confirm-btn="{ content: '确定', theme: 'primary' }"
|
|
78
|
+
:cancel-btn="{ content: '取消', theme: 'default' }" @confirm="confirmAddSign"
|
|
79
|
+
@close="showAddSignDialog = false">
|
|
80
|
+
<EbizEmployeeSelector v-model="selectedAddSignUser" :single="true"></EbizEmployeeSelector>
|
|
81
|
+
</t-dialog>
|
|
82
|
+
|
|
83
|
+
<!-- 退回确认 -->
|
|
84
|
+
<t-dialog header="退回确认" :visible="showReturnDialog" :confirm-btn="{ content: '确定退回', theme: 'danger' }"
|
|
85
|
+
:cancel-btn="{ content: '取消', theme: 'default' }" @confirm="confirmReturn"
|
|
86
|
+
@close="showReturnDialog = false">
|
|
87
|
+
<p>确定要退回该审批吗?</p>
|
|
88
|
+
<t-input v-model="returnReason" placeholder="请输入退回原因" />
|
|
89
|
+
</t-dialog>
|
|
90
|
+
</div>
|
|
91
|
+
</template>
|
|
92
|
+
|
|
93
|
+
<script setup>
|
|
94
|
+
import {
|
|
95
|
+
Form as TForm,
|
|
96
|
+
FormItem as TFormItem,
|
|
97
|
+
Button as TButton,
|
|
98
|
+
Icon as TIcon,
|
|
99
|
+
Textarea as TTextarea,
|
|
100
|
+
Dropdown as TDropdown,
|
|
101
|
+
Dialog as TDialog,
|
|
102
|
+
Select as TSelect,
|
|
103
|
+
RadioGroup as TRadioGroup,
|
|
104
|
+
Radio as TRadio,
|
|
105
|
+
Input as TInput,
|
|
106
|
+
MessagePlugin
|
|
107
|
+
} from 'tdesign-vue-next'
|
|
108
|
+
import { defineProps, defineEmits, ref, reactive, computed, onMounted } from 'vue'
|
|
109
|
+
import { dataService, EbizEmployeeSelector, EbizApproval } from '../index'
|
|
110
|
+
|
|
111
|
+
const request = (params = {}, apiConfig = {}, url = '') => {
|
|
112
|
+
return dataService.fetch(params, apiConfig, url)
|
|
113
|
+
}
|
|
114
|
+
const props = defineProps({
|
|
115
|
+
loading: {
|
|
116
|
+
type: Boolean,
|
|
117
|
+
default: false
|
|
118
|
+
},
|
|
119
|
+
approvalDetail: {
|
|
120
|
+
type: Object,
|
|
121
|
+
default: () => ({})
|
|
122
|
+
},
|
|
123
|
+
taskId: {
|
|
124
|
+
type: String,
|
|
125
|
+
default: ''
|
|
126
|
+
},
|
|
127
|
+
businessKey: {
|
|
128
|
+
type: String,
|
|
129
|
+
default: ''
|
|
130
|
+
},
|
|
131
|
+
processInstanceId: {
|
|
132
|
+
type: String,
|
|
133
|
+
default: ''
|
|
134
|
+
},
|
|
135
|
+
taskDefinitionKey: {
|
|
136
|
+
type: String,
|
|
137
|
+
default: ''
|
|
138
|
+
},
|
|
139
|
+
utils: {
|
|
140
|
+
type: Object,
|
|
141
|
+
default: () => ({})
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
const emit = defineEmits(['pass', 'reject', 'refresh'])
|
|
146
|
+
|
|
147
|
+
// 基础数据
|
|
148
|
+
const comments = ref('')
|
|
149
|
+
const showMoreActions = ref(false)
|
|
150
|
+
const taskType = ref('')
|
|
151
|
+
|
|
152
|
+
// 下一步审批人相关
|
|
153
|
+
const hasNextApprover = ref(false)
|
|
154
|
+
const isInWhiteList = ref(false)
|
|
155
|
+
const selectedApprover = ref([])
|
|
156
|
+
const selectedCCList = ref([])
|
|
157
|
+
|
|
158
|
+
// 转审相关
|
|
159
|
+
const showTransferDialog = ref(false)
|
|
160
|
+
const transferApprover = ref(null)
|
|
161
|
+
|
|
162
|
+
// 转接待人相关
|
|
163
|
+
const showReceiverDialog = ref(false)
|
|
164
|
+
const selectedReceiver = ref(null)
|
|
165
|
+
|
|
166
|
+
// 加签相关
|
|
167
|
+
const showPositionDialog = ref(false)
|
|
168
|
+
const showAddSignDialog = ref(false)
|
|
169
|
+
const addSignPosition = ref('after')
|
|
170
|
+
const selectedAddSignUser = ref(null)
|
|
171
|
+
|
|
172
|
+
// 退回相关
|
|
173
|
+
const showReturnDialog = ref(false)
|
|
174
|
+
const returnReason = ref('')
|
|
175
|
+
|
|
176
|
+
// 员工选择相关
|
|
177
|
+
const employeeLoading = ref(false)
|
|
178
|
+
const employeeOptions = ref([])
|
|
179
|
+
|
|
180
|
+
// 操作选项
|
|
181
|
+
const actionOptions = computed(() => {
|
|
182
|
+
const options = [
|
|
183
|
+
{ content: '转审', value: 'transfer' },
|
|
184
|
+
{ content: '加签', value: 'addSign' },
|
|
185
|
+
{ content: '退回', value: 'return' }
|
|
186
|
+
]
|
|
187
|
+
|
|
188
|
+
// 如果是接待人节点,添加转接待人选项
|
|
189
|
+
if (props.taskDefinitionKey === 'receiver') {
|
|
190
|
+
options.unshift({ content: '转接待人', value: 'changeReceiver' })
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return options
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
// 获取当前任务节点类型
|
|
197
|
+
const getCurrentTaskType = async () => {
|
|
198
|
+
try {
|
|
199
|
+
employeeLoading.value = true
|
|
200
|
+
const res = await request(
|
|
201
|
+
{ taskId: props.taskId },
|
|
202
|
+
{},
|
|
203
|
+
`/tasks/curr-user-task-type`
|
|
204
|
+
)
|
|
205
|
+
taskType.value = res.taskType
|
|
206
|
+
} catch (err) {
|
|
207
|
+
MessagePlugin.error(err.message || '获取任务类型失败')
|
|
208
|
+
} finally {
|
|
209
|
+
employeeLoading.value = false
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// 判断是否需要选择审批人
|
|
214
|
+
const checkHasNextApprover = async () => {
|
|
215
|
+
try {
|
|
216
|
+
const res = await request(
|
|
217
|
+
{ taskId: props.taskId },
|
|
218
|
+
{},
|
|
219
|
+
'/tasks/next-user-task-type'
|
|
220
|
+
)
|
|
221
|
+
hasNextApprover.value = res.hasNextUserTask ? ['sequential', 'parallel'].includes(res.taskType) : false
|
|
222
|
+
} catch (err) {
|
|
223
|
+
MessagePlugin.error(err.message || '获取下一步审批信息失败')
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// 检查是否在白名单中
|
|
228
|
+
const checkIsInWhiteList = async () => {
|
|
229
|
+
if (props.taskDefinitionKey === 'receiver' && props.approvalDetail?.variables?.form?.receiver) {
|
|
230
|
+
try {
|
|
231
|
+
const res = await request(
|
|
232
|
+
{},
|
|
233
|
+
{
|
|
234
|
+
key: 'visitor_whitelist_disenable_pagination',
|
|
235
|
+
apiId: 2282,
|
|
236
|
+
apiType: 0
|
|
237
|
+
},
|
|
238
|
+
''
|
|
239
|
+
)
|
|
240
|
+
isInWhiteList.value = res?.data?.some(item =>
|
|
241
|
+
item.emp_id === Number(props.approvalDetail.variables.form.receiver)
|
|
242
|
+
)
|
|
243
|
+
} catch (err) {
|
|
244
|
+
MessagePlugin.error(err.message || '获取白名单信息失败')
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// 获取员工列表
|
|
250
|
+
const getEmployeeList = async () => {
|
|
251
|
+
try {
|
|
252
|
+
employeeLoading.value = true
|
|
253
|
+
const res = await request(
|
|
254
|
+
{},
|
|
255
|
+
{ key: 'approval_employee_list', apiId: 2269, apiType: '0' },
|
|
256
|
+
''
|
|
257
|
+
)
|
|
258
|
+
employeeOptions.value = (res || []).map(item => ({
|
|
259
|
+
label: item.name,
|
|
260
|
+
value: item.id
|
|
261
|
+
}))
|
|
262
|
+
} catch (err) {
|
|
263
|
+
MessagePlugin.error(err.message || '获取员工列表失败')
|
|
264
|
+
} finally {
|
|
265
|
+
employeeLoading.value = false
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// 显示更多操作菜单
|
|
270
|
+
const onShowMore = () => {
|
|
271
|
+
showMoreActions.value = true
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// 选择操作
|
|
275
|
+
const onActionSelected = ({ value }) => {
|
|
276
|
+
switch (value) {
|
|
277
|
+
case 'transfer':
|
|
278
|
+
showTransferDialog.value = true
|
|
279
|
+
getEmployeeList()
|
|
280
|
+
break
|
|
281
|
+
case 'changeReceiver':
|
|
282
|
+
showReceiverDialog.value = true
|
|
283
|
+
getEmployeeList()
|
|
284
|
+
break
|
|
285
|
+
case 'addSign':
|
|
286
|
+
if (taskType.value === 'sequential') {
|
|
287
|
+
showPositionDialog.value = true
|
|
288
|
+
} else {
|
|
289
|
+
MessagePlugin.warning('加签仅支持会签模式')
|
|
290
|
+
}
|
|
291
|
+
break
|
|
292
|
+
case 'return':
|
|
293
|
+
showReturnDialog.value = true
|
|
294
|
+
break
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// 通过审批
|
|
299
|
+
const handlePass = async () => {
|
|
300
|
+
// 检查是否需要选择下一步审批人
|
|
301
|
+
if (!isInWhiteList.value && hasNextApprover.value && (!Array.isArray(selectedApprover.value) || selectedApprover.value.length === 0)) {
|
|
302
|
+
MessagePlugin.warning('请先选择审批人')
|
|
303
|
+
return
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const params = {
|
|
307
|
+
taskId: props.taskId,
|
|
308
|
+
comment: comments.value,
|
|
309
|
+
approve: true,
|
|
310
|
+
ccList: selectedCCList.value || []
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (Array.isArray(selectedApprover.value) && selectedApprover.value.length > 0) {
|
|
314
|
+
params.approverList = selectedApprover.value
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
try {
|
|
318
|
+
await emit('pass', params)
|
|
319
|
+
comments.value = ''
|
|
320
|
+
} catch (err) {
|
|
321
|
+
MessagePlugin.error(err.message || '操作失败')
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// 拒绝审批
|
|
326
|
+
const handleReject = async () => {
|
|
327
|
+
try {
|
|
328
|
+
await emit('reject', comments.value)
|
|
329
|
+
comments.value = ''
|
|
330
|
+
} catch (err) {
|
|
331
|
+
MessagePlugin.error(err.message || '操作失败')
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// 确认转审
|
|
336
|
+
const confirmTransfer = async () => {
|
|
337
|
+
if (!transferApprover.value) {
|
|
338
|
+
MessagePlugin.warning('请选择转审人')
|
|
339
|
+
return
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
try {
|
|
343
|
+
const res = await request(
|
|
344
|
+
{
|
|
345
|
+
toUserId: String(transferApprover.value),
|
|
346
|
+
rejectReason: '转审'
|
|
347
|
+
},
|
|
348
|
+
{},
|
|
349
|
+
`/tasks/${props.taskId}/transfer`
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
if (res.success) {
|
|
353
|
+
MessagePlugin.success(res.message || '转审成功')
|
|
354
|
+
showTransferDialog.value = false
|
|
355
|
+
transferApprover.value = null
|
|
356
|
+
emit('refresh')
|
|
357
|
+
}
|
|
358
|
+
} catch (err) {
|
|
359
|
+
MessagePlugin.error(err.message || '转审失败')
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// 确认转接待人
|
|
364
|
+
const confirmReceiver = async () => {
|
|
365
|
+
if (!selectedReceiver.value) {
|
|
366
|
+
MessagePlugin.warning('请选择接待人')
|
|
367
|
+
return
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
try {
|
|
371
|
+
const res = await request(
|
|
372
|
+
{
|
|
373
|
+
saveData: {
|
|
374
|
+
id: props.approvalDetail.variables.form.id,
|
|
375
|
+
receiver: String(selectedReceiver.value),
|
|
376
|
+
taskId: props.taskId
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
key: 'out_visitor_apply_update_receiver',
|
|
381
|
+
apiId: 2276,
|
|
382
|
+
apiType: 5
|
|
383
|
+
},
|
|
384
|
+
''
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
MessagePlugin.success('转接待人成功')
|
|
388
|
+
|
|
389
|
+
showReceiverDialog.value = false
|
|
390
|
+
selectedReceiver.value = null
|
|
391
|
+
emit('refresh')
|
|
392
|
+
} catch (err) {
|
|
393
|
+
MessagePlugin.error(err.message || '转接待人失败')
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// 确认加签位置
|
|
398
|
+
const confirmPosition = () => {
|
|
399
|
+
showPositionDialog.value = false
|
|
400
|
+
showAddSignDialog.value = true
|
|
401
|
+
getEmployeeList()
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// 确认加签
|
|
405
|
+
const confirmAddSign = async () => {
|
|
406
|
+
if (!selectedAddSignUser.value) {
|
|
407
|
+
MessagePlugin.warning('请选择加签人员')
|
|
408
|
+
return
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
try {
|
|
412
|
+
const res = await request(
|
|
413
|
+
{
|
|
414
|
+
userIds: [selectedAddSignUser.value],
|
|
415
|
+
position: addSignPosition.value
|
|
416
|
+
},
|
|
417
|
+
{},
|
|
418
|
+
`/tasks/${props.taskId}/addSign`
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
MessagePlugin.success('加签成功')
|
|
422
|
+
|
|
423
|
+
showAddSignDialog.value = false
|
|
424
|
+
selectedAddSignUser.value = null
|
|
425
|
+
|
|
426
|
+
if (addSignPosition.value === 'before') {
|
|
427
|
+
emit('refresh')
|
|
428
|
+
}
|
|
429
|
+
} catch (err) {
|
|
430
|
+
MessagePlugin.error(err.message || '加签失败')
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// 确认退回
|
|
435
|
+
const confirmReturn = async () => {
|
|
436
|
+
try {
|
|
437
|
+
const res = await request(
|
|
438
|
+
{
|
|
439
|
+
reason: returnReason.value || '驳回'
|
|
440
|
+
},
|
|
441
|
+
{},
|
|
442
|
+
`/tasks/${props.taskId}/return`
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
MessagePlugin.success('退回成功')
|
|
446
|
+
|
|
447
|
+
showReturnDialog.value = false
|
|
448
|
+
returnReason.value = ''
|
|
449
|
+
emit('refresh')
|
|
450
|
+
} catch (err) {
|
|
451
|
+
MessagePlugin.error(err.message || '退回失败')
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
onMounted(async () => {
|
|
456
|
+
if (props.taskId) {
|
|
457
|
+
await getCurrentTaskType()
|
|
458
|
+
await checkHasNextApprover()
|
|
459
|
+
await checkIsInWhiteList()
|
|
460
|
+
}
|
|
461
|
+
})
|
|
462
|
+
</script>
|
|
463
|
+
|
|
464
|
+
<style scoped>
|
|
465
|
+
.component-base-style {
|
|
466
|
+
margin: 0px;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.approval-form {
|
|
470
|
+
position: relative;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.button-group {
|
|
474
|
+
display: flex;
|
|
475
|
+
justify-content: space-between;
|
|
476
|
+
align-items: center;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.more-actions {
|
|
480
|
+
margin-right: 10px;
|
|
481
|
+
}
|
|
482
|
+
</style>
|
|
@@ -2,17 +2,20 @@
|
|
|
2
2
|
<div class="ebiz-employee-selector">
|
|
3
3
|
<!-- 选择框展示区 -->
|
|
4
4
|
<div v-if="showDefault" style="display: flex; flex-direction: column; align-items: flex-start; gap: 10px;">
|
|
5
|
-
<
|
|
6
|
-
<div v-
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<span class="item-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
<slot name="selected-items" :event="{ remove: removeItem }" :data="selectedItems">
|
|
6
|
+
<div class="selected-items" v-if="selectedItems && selectedItems.length">
|
|
7
|
+
<div v-for="(item, index) in selectedItems" :key="index" class="selected-item">
|
|
8
|
+
<t-avatar v-if="item.avatar" :image="item.avatar" size="small" />
|
|
9
|
+
<t-avatar v-else size="small">{{ getAvatarText(item.name) }}</t-avatar>
|
|
10
|
+
<span class="item-info">
|
|
11
|
+
<span class="item-code">{{ item.no }} - </span>
|
|
12
|
+
<span class="item-name">{{ item.name }}</span>
|
|
13
|
+
</span>
|
|
14
|
+
<t-icon name="close" class="item-remove" @click="removeItem(index, item.id)"></t-icon>
|
|
15
|
+
</div>
|
|
14
16
|
</div>
|
|
15
|
-
</
|
|
17
|
+
</slot>
|
|
18
|
+
|
|
16
19
|
<t-button @click="showDialog" variant="text" theme="primary">{{ props.content }}</t-button>
|
|
17
20
|
</div>
|
|
18
21
|
|
|
@@ -110,7 +113,8 @@
|
|
|
110
113
|
</div>
|
|
111
114
|
|
|
112
115
|
<div class="employee-list">
|
|
113
|
-
<div v-for="(item, index) in filteredEmployeeList" :key="index" class="employee-item"
|
|
116
|
+
<div v-for="(item, index) in filteredEmployeeList" :key="index" class="employee-item"
|
|
117
|
+
style="cursor: pointer;">
|
|
114
118
|
<t-checkbox v-model="item.checked" @change="handleCheckChange(item)"></t-checkbox>
|
|
115
119
|
<div style="display: flex; align-items: center; gap: 10px; flex: 1;">
|
|
116
120
|
<div class="employee-avatar">
|
|
@@ -275,24 +279,24 @@ const getAvatarText = (name) => {
|
|
|
275
279
|
|
|
276
280
|
const computedModelValue = computed({
|
|
277
281
|
set(val) {
|
|
278
|
-
if(
|
|
279
|
-
if(
|
|
282
|
+
if (props.single) {
|
|
283
|
+
if (val.length > 0) {
|
|
280
284
|
emit("update:modelValue", val[0]);
|
|
281
|
-
}else{
|
|
285
|
+
} else {
|
|
282
286
|
emit("update:modelValue", "");
|
|
283
287
|
}
|
|
284
|
-
return
|
|
288
|
+
return;
|
|
285
289
|
}
|
|
286
290
|
emit("update:modelValue", val);
|
|
287
291
|
},
|
|
288
292
|
get() {
|
|
289
293
|
|
|
290
294
|
let value = props.modelValue
|
|
291
|
-
|
|
295
|
+
|
|
292
296
|
if (props.single) {
|
|
293
297
|
value = props.modelValue ? [props.modelValue] : [];
|
|
294
298
|
}
|
|
295
|
-
value.forEach((val)=>{
|
|
299
|
+
value.forEach((val) => {
|
|
296
300
|
return Number(val);
|
|
297
301
|
})
|
|
298
302
|
|
|
@@ -504,7 +508,7 @@ const fetchEmployeesByIds = async (ids) => {
|
|
|
504
508
|
selectedItems.value = [];
|
|
505
509
|
return;
|
|
506
510
|
}
|
|
507
|
-
if(
|
|
511
|
+
if (!(ids instanceof Array)) {
|
|
508
512
|
ids = [ids];
|
|
509
513
|
}
|
|
510
514
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<span style="display: inline-block" class="component-base-style">加载中</span>
|
|
7
7
|
</ebiz-tdesign-loading>
|
|
8
8
|
|
|
9
|
-
<div
|
|
9
|
+
<div class="card">
|
|
10
10
|
<div style="margin: 10px 0" class="component-base-style">
|
|
11
11
|
<span style="display: inline-block" class="title">审批流程</span>
|
|
12
12
|
</div>
|
|
@@ -120,6 +120,9 @@
|
|
|
120
120
|
defaultTab="organization" class="component-base-style"
|
|
121
121
|
v-model="state.selectedCCList" @click="handleAddCcUser"
|
|
122
122
|
@confirm="onAddCcListConfirm">
|
|
123
|
+
<template #selected-items="{ event, data }">
|
|
124
|
+
<div></div>
|
|
125
|
+
</template>
|
|
123
126
|
</ebiz-employee-selector>
|
|
124
127
|
</div>
|
|
125
128
|
|
|
@@ -268,47 +271,6 @@ const requestApprovalDetail = (businessKey, type) => {
|
|
|
268
271
|
}).catch((err) => {
|
|
269
272
|
handleApprovalDetailError(err)
|
|
270
273
|
})
|
|
271
|
-
|
|
272
|
-
// 临时测试数据(可以删除)
|
|
273
|
-
// const testData = {
|
|
274
|
-
// "processInstanceId": "130953",
|
|
275
|
-
// "businessKey": "357",
|
|
276
|
-
// "processDefinitionKey": "Out_Visitor_Application",
|
|
277
|
-
// "processDefinitionName": "访客自助登记",
|
|
278
|
-
// "processStatus": "ACTIVE",
|
|
279
|
-
// "processStatusDesc": "进行中",
|
|
280
|
-
// "startTime": "2025-06-13 16:04:52",
|
|
281
|
-
// "startUserId": null,
|
|
282
|
-
// "endTime": null,
|
|
283
|
-
// "ccUserList": [
|
|
284
|
-
// {
|
|
285
|
-
// "userId": "3180",
|
|
286
|
-
// "name": "邓强杰",
|
|
287
|
-
// "employeeNo": "4879",
|
|
288
|
-
// "photo": "http://oas.guokeai.cn:9003/upload/20250529/20250529_26f77dfaf1324a96b341e4b9b142ae23.jpg",
|
|
289
|
-
// "deptName": "技术部"
|
|
290
|
-
// }
|
|
291
|
-
// ],
|
|
292
|
-
// "nodes": [
|
|
293
|
-
// {
|
|
294
|
-
// "nodeId": "receiver",
|
|
295
|
-
// "nodeName": "接待人审批",
|
|
296
|
-
// "nodeStatus": "COMPLETED",
|
|
297
|
-
// "isMultiInstance": false,
|
|
298
|
-
// "approvers": [
|
|
299
|
-
// {
|
|
300
|
-
// "userId": "3176",
|
|
301
|
-
// "userName": "吴跃忠",
|
|
302
|
-
// "employeeNo": "LaiRiFangZhang",
|
|
303
|
-
// "deptName": "技术部",
|
|
304
|
-
// "approvalStatus": "COMPLETED",
|
|
305
|
-
// "completedTime": "2025-06-13 16:06:11"
|
|
306
|
-
// }
|
|
307
|
-
// ]
|
|
308
|
-
// }
|
|
309
|
-
// ]
|
|
310
|
-
// }
|
|
311
|
-
// handleApprovalDetailResponse(testData)
|
|
312
274
|
}
|
|
313
275
|
|
|
314
276
|
// 获取操作类型的样式类
|
|
@@ -570,7 +532,11 @@ function onAddCcListConfirm(event) {
|
|
|
570
532
|
{},
|
|
571
533
|
'/tasks/batchAddCcInfo'
|
|
572
534
|
)
|
|
573
|
-
.then((res) => {
|
|
535
|
+
.then((res) => {
|
|
536
|
+
// 重新加载数据
|
|
537
|
+
requestApprovalDetail(String(props.businessKey), props.type)
|
|
538
|
+
message.success("添加成功")
|
|
539
|
+
})
|
|
574
540
|
.catch((err) => {
|
|
575
541
|
message.error(err.message)
|
|
576
542
|
})
|
package/src/index.js
CHANGED
|
@@ -63,6 +63,7 @@ import EbizDepartmentSelector from './components/EbizDepartmentSelector.vue'
|
|
|
63
63
|
import EbizTdesignButtonDialog from './components/EbizTdesignButtonDialog.vue'
|
|
64
64
|
import { MessagePlugin as EbizMessage } from 'tdesign-vue-next'
|
|
65
65
|
import EbizApproval from './components/EbizApproval.vue'
|
|
66
|
+
import EbizApprovalForm from './components/EbizApprovalForm.vue'
|
|
66
67
|
import EbizDiv from './components/EbizDiv.vue'
|
|
67
68
|
import EbizSApprovalProcess from './components/EbizSApprovalProcess.vue'
|
|
68
69
|
|
|
@@ -221,6 +222,8 @@ export {
|
|
|
221
222
|
EbizSDialog,
|
|
222
223
|
// 新增 EbizApproval 组件
|
|
223
224
|
EbizApproval,
|
|
225
|
+
// 审批表单组件
|
|
226
|
+
EbizApprovalForm,
|
|
224
227
|
EbizDiv,
|
|
225
228
|
// 下拉菜单组件
|
|
226
229
|
EbizDropdown,
|
package/src/router/index.js
CHANGED
|
@@ -353,6 +353,12 @@ const routes = [
|
|
|
353
353
|
component:()=>import('../views/EbizApprovalDemo.vue'),
|
|
354
354
|
meta:{title:"Ebiz审批组件示例"}
|
|
355
355
|
},
|
|
356
|
+
{
|
|
357
|
+
path: '/approval-form',
|
|
358
|
+
name: 'EbizApprovalForm',
|
|
359
|
+
component: () => import('../views/EbizApprovalFormDemo.vue'),
|
|
360
|
+
meta: { title: 'Ebiz审批表单组件示例' }
|
|
361
|
+
},
|
|
356
362
|
{
|
|
357
363
|
path:"/vxe-table",
|
|
358
364
|
name:"EbizVxeTable",
|