yxk-20260610-审批历史页面

在审批历史页面增加独立开关 仅看本部门,与现有节点名称 checkbox 筛选叠加。当前登录人的部门信息从 useUserStore().getUserInfo 获取,按用户全部部门口径解析 departIds,再通过部门接口补齐部门编码和名称,用于前端本地过滤审批历史。
This commit is contained in:
ye1023
2026-06-10 09:59:12 +08:00
parent db6c21561a
commit 563f9108e1
2 changed files with 171 additions and 17 deletions
@@ -278,7 +278,7 @@
const feedbackBaseColumns = [
{ title: '责任部门名称', dataIndex: 'responDeptname', align: 'center', width: 160 },
{ title: '反馈人姓名', dataIndex: 'responPersonname', align: 'center', width: 140 },
{ title: '实际执行情况', dataIndex: 'actualExect', align: 'left', width: 280 },
{ title: '实际执行情况', dataIndex: 'actualExect', align: 'center', width: 280 },
{ title: '实际完成时间', dataIndex: 'actualTime', align: 'center', width: 180 },
{ title: '完成状态', dataIndex: 'bpmStatus', align: 'center', width: 120, customRender: ({ record }) => record?.bpmStatus_dictText || record?.bpmStatus },
{ title: '附件', dataIndex: 'id', key: 'attachments', align: 'left', width: 340 },
@@ -1,6 +1,7 @@
<template>
<div class="approval-history-pane">
<div v-if="taskNameOptions.length > 0" class="approval-history-filter">
<div class="approval-history-filter__main">
<span class="approval-history-filter__label">节点名称</span>
<a-checkbox-group v-model:value="selectedTaskNames" class="approval-history-filter__checkboxes" @change="handleTaskNameChange">
<a-checkbox v-for="taskName in taskNameOptions" :key="taskName" :value="taskName">
@@ -8,10 +9,17 @@
</a-checkbox>
</a-checkbox-group>
<div class="approval-history-filter__actions">
<a-button type="link" size="small" :disabled="selectedTaskNames.length === taskNameOptions.length" @click="selectAllTaskNames">全选</a-button>
<a-button type="link" size="small" :disabled="selectedTaskNames.length === taskNameOptions.length" @click="selectAllTaskNames"
>全选</a-button
>
<a-button type="link" size="small" :disabled="selectedTaskNames.length === 0" @click="clearTaskNames">清空</a-button>
</div>
</div>
<div class="approval-history-filter__dept">
<a-switch v-model:checked="onlyCurrentDept" :disabled="currentUserDeptList.length === 0" @change="handleCurrentDeptChange" />
<span class="approval-history-filter__dept-text">仅看本部门审批历史</span>
</div>
</div>
<BasicTable @register="registerTable" />
</div>
</template>
@@ -24,11 +32,22 @@
import { BasicTable, useTable } from '/@/components/Table';
import type { BasicColumn } from '/@/components/Table';
import { onMounted, ref, watch } from 'vue';
import { useUserStore } from '/@/store/modules/user';
import { defHttp } from '/@/utils/http/axios';
import { list as queryApprovalOpinionList } from '/@/views/taskApprovalOpinion/TaskApprovalOpinion.api';
interface ApprovalHistoryRecord {
[key: string]: any;
taskName?: string;
opDeptId?: string;
opDeptName?: string;
opDeptCode?: string;
}
interface CurrentUserDept {
id?: string;
orgCode?: string;
departName?: string;
}
const approvalHistoryColumns: BasicColumn[] = [
@@ -60,9 +79,17 @@
},
},
setup(props) {
const userStore = useUserStore();
const allApprovalHistoryList = ref<ApprovalHistoryRecord[]>([]);
const taskNameOptions = ref<string[]>([]);
const selectedTaskNames = ref<string[]>([]);
const onlyCurrentDept = ref(false);
const currentUserDeptList = ref<CurrentUserDept[]>([]);
const currentUserDeptIdSet = ref<Set<string>>(new Set());
const currentUserDeptCodeSet = ref<Set<string>>(new Set());
const currentUserDeptNameSet = ref<Set<string>>(new Set());
let currentUserDeptLoaded = false;
let currentUserDeptLoadPromise: Promise<void> | null = null;
const [registerTable, { reload, setTableData }] = useTable({
title: '',
@@ -88,6 +115,20 @@
return typeof taskName === 'string' ? taskName.trim() : '';
}
function normalizeText(value: unknown): string {
return typeof value === 'string' ? value.trim() : '';
}
function splitValue(value: unknown): string[] {
if (Array.isArray(value)) {
return value.map((item) => normalizeText(item)).filter(Boolean);
}
return normalizeText(value)
.split(',')
.map((item) => item.trim())
.filter(Boolean);
}
function resolveRecords(res: any): ApprovalHistoryRecord[] {
if (Array.isArray(res)) {
return res;
@@ -95,6 +136,13 @@
return res?.records || res?.result?.records || [];
}
function resolveDeptList(res: any): CurrentUserDept[] {
if (Array.isArray(res)) {
return res;
}
return res?.records || res?.result || [];
}
function resolveTotal(res: any, fallbackTotal: number): number {
return Number(res?.total || res?.result?.total || fallbackTotal || 0);
}
@@ -104,10 +152,27 @@
return [];
}
const selectedNameSet = new Set(selectedTaskNames.value);
return allApprovalHistoryList.value.filter((record) => {
const nodeFilteredRecords = allApprovalHistoryList.value.filter((record) => {
const taskName = normalizeTaskName(record.taskName);
return taskName && selectedNameSet.has(taskName);
});
if (!onlyCurrentDept.value) {
return nodeFilteredRecords;
}
return nodeFilteredRecords.filter(isCurrentUserDeptRecord);
}
function isCurrentUserDeptRecord(record: ApprovalHistoryRecord) {
const deptCode = normalizeText(record.opDeptCode);
if (deptCode) {
return currentUserDeptCodeSet.value.has(deptCode);
}
const deptId = normalizeText(record.opDeptId);
if (deptId) {
return currentUserDeptIdSet.value.has(deptId);
}
const deptName = normalizeText(record.opDeptName);
return deptName ? currentUserDeptNameSet.value.has(deptName) : false;
}
function resetTaskNameFilter(records: ApprovalHistoryRecord[]) {
@@ -116,27 +181,98 @@
selectedTaskNames.value = [...taskNameOptions.value];
}
function applyTaskNameFilter() {
function applyApprovalHistoryFilter() {
setTableData(getFilteredApprovalHistoryList());
}
function handleTaskNameChange(checkedValues: string[]) {
selectedTaskNames.value = checkedValues;
applyTaskNameFilter();
applyApprovalHistoryFilter();
}
function handleCurrentDeptChange(checked: boolean) {
if (typeof checked === 'boolean') {
onlyCurrentDept.value = checked;
}
applyApprovalHistoryFilter();
}
function selectAllTaskNames() {
selectedTaskNames.value = [...taskNameOptions.value];
applyTaskNameFilter();
applyApprovalHistoryFilter();
}
function clearTaskNames() {
selectedTaskNames.value = [];
applyTaskNameFilter();
applyApprovalHistoryFilter();
}
function setCurrentUserDeptList(deptList: CurrentUserDept[]) {
currentUserDeptList.value = deptList;
currentUserDeptIdSet.value = new Set(deptList.map((item) => normalizeText(item.id)).filter(Boolean));
currentUserDeptCodeSet.value = new Set(deptList.map((item) => normalizeText(item.orgCode)).filter(Boolean));
currentUserDeptNameSet.value = new Set(deptList.map((item) => normalizeText(item.departName)).filter(Boolean));
if (deptList.length === 0) {
onlyCurrentDept.value = false;
}
}
async function loadCurrentUserDeptList() {
if (currentUserDeptLoaded) {
return;
}
if (currentUserDeptLoadPromise) {
return currentUserDeptLoadPromise;
}
currentUserDeptLoadPromise = doLoadCurrentUserDeptList()
.then(() => {
currentUserDeptLoaded = true;
})
.finally(() => {
currentUserDeptLoadPromise = null;
});
return currentUserDeptLoadPromise;
}
async function doLoadCurrentUserDeptList() {
const userInfo = (userStore.getUserInfo || {}) as Record<string, any>;
const loginInfo = (userStore.getLoginInfo || {}) as Record<string, any>;
const departIds = splitValue(userInfo.departIds);
const fallbackDeptList = getFallbackCurrentUserDeptList(userInfo, loginInfo);
// 本部门按用户全部部门处理,优先用部门ID批量补齐编码和名称,避免只按当前登录部门筛选。
if (departIds.length > 0) {
try {
const res = await defHttp.get({ url: '/sys/sysDepart/listAll', params: { id: departIds.join(',') } });
const deptList = resolveDeptList(res);
setCurrentUserDeptList(deptList.length > 0 ? deptList : fallbackDeptList);
} catch (e) {
setCurrentUserDeptList(fallbackDeptList);
}
return;
}
setCurrentUserDeptList(fallbackDeptList);
}
function getFallbackCurrentUserDeptList(userInfo: Record<string, any>, loginInfo: Record<string, any>) {
const loginDeparts = Array.isArray(loginInfo.departs) ? loginInfo.departs : [];
if (loginDeparts.length > 0) {
return loginDeparts;
}
const orgCode = normalizeText(userInfo.orgCode);
const departName = normalizeText(userInfo.orgCodeTxt || userInfo.departIds_dictText);
if (orgCode || departName) {
return [{ orgCode, departName }];
}
return [];
}
// 按流程实例查询审批历史,只查 task_approval_opinion 表
async function getApprovalHistoryList() {
await loadCurrentUserDeptList();
const processInstId = getProcessInstId();
if (!processInstId) {
allApprovalHistoryList.value = [];
@@ -197,7 +333,10 @@
reload,
taskNameOptions,
selectedTaskNames,
onlyCurrentDept,
currentUserDeptList,
handleTaskNameChange,
handleCurrentDeptChange,
selectAllTaskNames,
clearTaskNames,
};
@@ -212,11 +351,26 @@
}
.approval-history-filter {
margin-bottom: 8px;
padding: 4px 0;
}
.approval-history-filter__dept {
display: flex;
align-items: center;
gap: 8px;
margin-top: 10px;
line-height: 24px;
}
.approval-history-filter__dept-text {
color: rgba(0, 0, 0, 0.85);
}
.approval-history-filter__main {
display: flex;
align-items: flex-start;
gap: 8px;
margin-bottom: 8px;
padding: 4px 0;
}
.approval-history-filter__label {