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