fix(approval): 待办支持全部待办开关与按任务改派、keywords 与报送人术语
- 有 approval:instance:assign 的用户可切换全租户待办(scope=all) - 详情抽屉展示待办人员并按任务 id 改派 - 查询参数 keyword 改为 keywords;发起人统一为报送人
This commit is contained in:
@@ -9,12 +9,12 @@ export interface ApprovalQueryParam extends PageParam {
|
||||
// 单号
|
||||
bizNo?: string;
|
||||
// 关键词:单号、名称或标题、实施单位
|
||||
keyword?: string;
|
||||
keywords?: string;
|
||||
// 报送部门id
|
||||
reportOrgId?: number;
|
||||
// 受理部门id
|
||||
acceptOrgId?: number;
|
||||
// 发起人id
|
||||
// 报送人id
|
||||
reporterId?: number;
|
||||
// 单据状态
|
||||
status?: string;
|
||||
@@ -93,6 +93,18 @@ export interface ApprovalConfirm {
|
||||
handleTime?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例上的待办任务(PC 按任务改派)
|
||||
*/
|
||||
export interface ApprovalPendingTask {
|
||||
id?: number;
|
||||
nodeKey?: string;
|
||||
nodeName?: string;
|
||||
nodeType?: string;
|
||||
assigneeId?: number;
|
||||
assigneeName?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的待处理任务
|
||||
*/
|
||||
@@ -144,6 +156,7 @@ export interface ApprovalInstance {
|
||||
records?: ApprovalRecord[];
|
||||
confirms?: ApprovalConfirm[];
|
||||
myTask?: ApprovalMyTask | null;
|
||||
pendingTasks?: ApprovalPendingTask[];
|
||||
permissions?: Record<string, boolean>;
|
||||
}
|
||||
|
||||
@@ -191,6 +204,8 @@ export interface ApprovalTodoParam extends PageParam {
|
||||
status?: string;
|
||||
// 单据类型
|
||||
docType?: string;
|
||||
// 查询范围:mine(默认本人待办)/all(全租户待办,需 assign 权限)
|
||||
scope?: 'mine' | 'all';
|
||||
// 关键词:单号、名称或标题、实施单位
|
||||
keywords?: string;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<a-descriptions-item label="当前节点">
|
||||
{{ data.currentNodeName || '-' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="发起人">
|
||||
<a-descriptions-item label="报送人">
|
||||
{{ data.reporterName || '-' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="报送部门">
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
prop:
|
||||
| 'docType'
|
||||
| 'bizNo'
|
||||
| 'keyword'
|
||||
| 'keywords'
|
||||
| 'reportOrgId'
|
||||
| 'acceptOrgId'
|
||||
| 'reporterId'
|
||||
@@ -140,10 +140,10 @@
|
||||
}[] = [
|
||||
{ prop: 'docType', label: '单据类型' },
|
||||
{ prop: 'bizNo', label: '单号' },
|
||||
{ prop: 'keyword', label: '标题或名称' },
|
||||
{ prop: 'keywords', label: '标题或名称' },
|
||||
{ prop: 'reportOrgId', label: '报送部门' },
|
||||
{ prop: 'acceptOrgId', label: '受理部门' },
|
||||
{ prop: 'reporterId', label: '发起人' },
|
||||
{ prop: 'reporterId', label: '报送人' },
|
||||
{ prop: 'status', label: '状态' }
|
||||
];
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
const { form, resetFields } = useFormData<ApprovalQueryParam>({
|
||||
docType: undefined,
|
||||
bizNo: '',
|
||||
keyword: '',
|
||||
keywords: '',
|
||||
reportOrgId: undefined,
|
||||
acceptOrgId: undefined,
|
||||
reporterId: undefined,
|
||||
@@ -182,9 +182,9 @@
|
||||
// 组织下拉选项
|
||||
const organizationOptions = ref<{ label: string; value: number }[]>([]);
|
||||
|
||||
// 发起人下拉选项
|
||||
// 报送人下拉选项
|
||||
const userOptions = ref<{ label: string; value: number }[]>([]);
|
||||
// 发起人请求状态
|
||||
// 报送人请求状态
|
||||
const userLoading = ref(false);
|
||||
|
||||
// 组织远程过滤
|
||||
@@ -192,7 +192,7 @@
|
||||
return (option?.label ?? '').toLowerCase().includes(input.toLowerCase());
|
||||
};
|
||||
|
||||
// 远程搜索发起人
|
||||
// 远程搜索报送人
|
||||
const searchUsers = (keywords?: string) => {
|
||||
userLoading.value = true;
|
||||
searchApprovalUsers({ keywords })
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<a-descriptions-item label="当前节点">
|
||||
{{ detail.currentNodeName || '-' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="发起人">
|
||||
<a-descriptions-item label="报送人">
|
||||
{{ detail.reporterName }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="报送部门">
|
||||
@@ -169,6 +169,14 @@
|
||||
<a-descriptions-item label="节点">
|
||||
{{ detail.currentNodeName || '-' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="待办人员">
|
||||
<template v-if="pendingTasks.length">
|
||||
<a-tag v-for="task in pendingTasks" :key="task.id" color="blue">
|
||||
{{ task.nodeName }}·{{ task.assigneeName }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<span v-else>-</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="存档确认">
|
||||
<template v-if="confirms.length">
|
||||
<a-tag
|
||||
@@ -270,6 +278,13 @@
|
||||
@ok="submitAssign"
|
||||
>
|
||||
<a-form layout="vertical">
|
||||
<a-form-item v-if="pendingTasks.length" label="待办任务" required>
|
||||
<a-select
|
||||
v-model:value="assignTaskId"
|
||||
:options="pendingTaskOptions"
|
||||
placeholder="请选择需要改派的待办任务"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="改派对象" required>
|
||||
<a-select
|
||||
v-model:value="assignForm.targetUserId"
|
||||
@@ -302,6 +317,7 @@
|
||||
import type {
|
||||
ApprovalAttachment,
|
||||
ApprovalInstance,
|
||||
ApprovalPendingTask,
|
||||
ApprovalUser
|
||||
} from '@/api/approval/instance/model';
|
||||
import { getInstance } from '@/api/approval/instance';
|
||||
@@ -346,6 +362,9 @@
|
||||
);
|
||||
const records = computed(() => detail.value?.records ?? []);
|
||||
const confirms = computed(() => detail.value?.confirms ?? []);
|
||||
const pendingTasks = computed<ApprovalPendingTask[]>(
|
||||
() => detail.value?.pendingTasks ?? []
|
||||
);
|
||||
|
||||
const load = async () => {
|
||||
if (!props.instanceId) {
|
||||
@@ -554,6 +573,13 @@
|
||||
targetUserId: undefined,
|
||||
reason: ''
|
||||
});
|
||||
const assignTaskId = ref<number | undefined>(undefined);
|
||||
const pendingTaskOptions = computed(() =>
|
||||
pendingTasks.value.map((task) => ({
|
||||
value: task.id as number,
|
||||
label: `${task.nodeName || task.nodeKey || ''}·${task.assigneeName || ''}`
|
||||
}))
|
||||
);
|
||||
let searchTimer: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
const doSearchUsers = async (keywords?: string) => {
|
||||
@@ -585,14 +611,15 @@
|
||||
const openAssign = () => {
|
||||
assignForm.targetUserId = undefined;
|
||||
assignForm.reason = '';
|
||||
assignTaskId.value = detail.value?.myTask?.id ?? pendingTasks.value[0]?.id;
|
||||
assignVisible.value = true;
|
||||
doSearchUsers();
|
||||
};
|
||||
|
||||
const submitAssign = async () => {
|
||||
const taskId = detail.value?.myTask?.id;
|
||||
const taskId = assignTaskId.value;
|
||||
if (!taskId) {
|
||||
message.error('待办任务不存在,请刷新');
|
||||
message.error('请选择待办任务');
|
||||
return;
|
||||
}
|
||||
if (!assignForm.targetUserId) {
|
||||
@@ -613,8 +640,12 @@
|
||||
message.success('改派成功');
|
||||
assignVisible.value = false;
|
||||
emit('done');
|
||||
// 改派后待办不再属于当前用户,关闭抽屉
|
||||
updateVisible(false);
|
||||
if (detail.value?.myTask?.id === taskId) {
|
||||
// 改派的是当前用户的待办,关闭抽屉回到列表
|
||||
updateVisible(false);
|
||||
} else {
|
||||
await load();
|
||||
}
|
||||
} catch (e: any) {
|
||||
message.error(e.message);
|
||||
} finally {
|
||||
|
||||
@@ -31,6 +31,13 @@
|
||||
@pressEnter="reload"
|
||||
@search="reload"
|
||||
/>
|
||||
<a-checkbox
|
||||
v-if="canAssign"
|
||||
v-model:checked="allScope"
|
||||
@change="reload"
|
||||
>
|
||||
全部待办
|
||||
</a-checkbox>
|
||||
<a-button @click="resetSearch">重置</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
@@ -68,6 +75,7 @@
|
||||
ColumnItem
|
||||
} from 'ele-admin-pro/es/ele-pro-table/types';
|
||||
import useSearch from '@/utils/use-search';
|
||||
import { hasPermission } from '@/utils/permission';
|
||||
import type {
|
||||
ApprovalItem,
|
||||
ApprovalTodoParam
|
||||
@@ -82,6 +90,9 @@
|
||||
const showDetail = ref(false);
|
||||
// 当前单据id
|
||||
const currentId = ref<number | null>(null);
|
||||
// 是否查看全租户待办(仅 assign 权限)
|
||||
const allScope = ref(false);
|
||||
const canAssign = hasPermission('approval:instance:assign');
|
||||
|
||||
// 搜索条件
|
||||
const { where, resetFields } = useSearch<ApprovalTodoParam>({
|
||||
@@ -122,7 +133,7 @@
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '发起人',
|
||||
title: '报送人',
|
||||
dataIndex: 'reporterName',
|
||||
key: 'reporterName',
|
||||
width: 120,
|
||||
@@ -171,6 +182,7 @@
|
||||
return pageApprovalTodo({
|
||||
status: where.status,
|
||||
keywords: where.keywords?.trim() || undefined,
|
||||
scope: allScope.value ? 'all' : undefined,
|
||||
page,
|
||||
limit
|
||||
});
|
||||
@@ -184,6 +196,7 @@
|
||||
// 重置搜索
|
||||
const resetSearch = () => {
|
||||
resetFields();
|
||||
allScope.value = false;
|
||||
reload();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user