merge: t24 待办派单/转办

This commit is contained in:
2026-10-30 21:48:38 +08:00
2 changed files with 133 additions and 2 deletions
+29 -1
View File
@@ -3,7 +3,8 @@ import type { ApiResult } from '@/api';
import { THINK_API_URL } from '@/config/setting';
import type {
ApprovalAssignParam,
ApprovalAssignResult
ApprovalAssignResult,
ApprovalUser
} from '../instance/model';
/**
@@ -60,6 +61,33 @@ export async function archiveApprovalTask(id: number) {
return Promise.reject(new Error(res.data.message));
}
/**
* 派单候选池(仅派单节点、本人待办)
*/
export async function listDispatchCandidates(id: number) {
const res = await request.get<ApiResult<ApprovalUser[]>>(
THINK_API_URL + '/approval/task/' + id + '/candidates'
);
if (res.data.code === 0) {
return res.data.data ?? [];
}
return Promise.reject(new Error(res.data.message));
}
/**
* 派单(选定 1 人即完成派单节点)
*/
export async function dispatchApprovalTask(id: number, targetUserId: number) {
const res = await request.post<ApiResult<unknown>>(
THINK_API_URL + '/approval/task/' + id + '/dispatch',
{ targetUserId }
);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 改派待办
*/
@@ -21,6 +21,14 @@
>
通过
</a-button>
<a-button
v-if="detail.permissions?.canDispatch"
v-permission="'approval:instance:approve'"
type="primary"
@click="openDispatch"
>
派单
</a-button>
<a-button
v-if="detail.permissions?.canReject"
v-permission="'approval:instance:approve'"
@@ -227,6 +235,32 @@
/>
</a-modal>
<!-- 派单 -->
<a-modal
v-model:visible="dispatchVisible"
title="派单"
:confirm-loading="submitting"
:mask-closable="false"
@ok="submitDispatch"
>
<a-form layout="vertical">
<a-form-item label="派单对象" required>
<a-select
v-model:value="dispatchTargetUserId"
show-search
:filter-option="filterCandidate"
:options="candidateOptions"
:loading="candidateLoading"
placeholder="请选择受理部门成员"
not-found-content="暂无可派单人员,请联系管理员维护部门成员"
/>
</a-form-item>
<div class="ele-text-secondary">
派单后由报送人与被派单人分别存档,选定后不可更改。
</div>
</a-form>
</a-modal>
<!-- 改派 -->
<a-modal
v-model:visible="assignVisible"
@@ -267,7 +301,8 @@
import { Empty, Modal, message } from 'ant-design-vue';
import type {
ApprovalAttachment,
ApprovalInstance
ApprovalInstance,
ApprovalUser
} from '@/api/approval/instance/model';
import { getInstance } from '@/api/approval/instance';
import { searchApprovalUsers } from '@/api/approval/directory';
@@ -276,6 +311,8 @@
archiveApprovalTask,
assignApprovalTask,
confirmApprovalTask,
dispatchApprovalTask,
listDispatchCandidates,
rejectApprovalTask
} from '@/api/approval/task';
import {
@@ -443,6 +480,72 @@
});
};
/* 派单 */
const dispatchVisible = ref(false);
const candidateLoading = ref(false);
const dispatchTargetUserId = ref<number | undefined>(undefined);
const candidateOptions = ref<{ label: string; value: number }[]>([]);
const candidateLabel = (user: ApprovalUser) =>
(user.realName || user.nickname || user.username || '') +
(user.username ? '(' + user.username + ')' : '') +
(user.organizationName ? ' · ' + user.organizationName : '');
const filterCandidate = (input: string, option: any) =>
String(option?.label ?? '')
.toLowerCase()
.includes(input.toLowerCase());
const openDispatch = async () => {
const taskId = detail.value?.myTask?.id;
if (!taskId) {
message.error('待办任务不存在,请刷新');
return;
}
dispatchTargetUserId.value = undefined;
candidateOptions.value = [];
dispatchVisible.value = true;
candidateLoading.value = true;
try {
const users = await listDispatchCandidates(taskId);
candidateOptions.value = users.map((user) => ({
value: user.userId as number,
label: candidateLabel(user)
}));
if (!candidateOptions.value.length) {
message.warning('暂无可派单人员,请联系管理员维护部门成员');
}
} catch (e: any) {
message.error(e.message);
} finally {
candidateLoading.value = false;
}
};
const submitDispatch = async () => {
const taskId = detail.value?.myTask?.id;
if (!taskId) {
message.error('待办任务不存在,请刷新');
return;
}
if (!dispatchTargetUserId.value) {
message.error('请选择派单对象');
return;
}
submitting.value = true;
try {
await dispatchApprovalTask(taskId, dispatchTargetUserId.value);
message.success('派单成功');
dispatchVisible.value = false;
await load();
emit('done');
} catch (e: any) {
message.error(e.message);
} finally {
submitting.value = false;
}
};
/* 改派 */
const assignVisible = ref(false);
const userLoading = ref(false);