yxk-20260610-审批历史页面
在审批历史页面增加独立开关 仅看本部门,与现有节点名称 checkbox 筛选叠加。当前登录人的部门信息从 useUserStore().getUserInfo 获取,按用户全部部门口径解析 departIds,再通过部门接口补齐部门编码和名称,用于前端本地过滤审批历史。
This commit is contained in:
@@ -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 },
|
||||
|
||||
+170
-16
@@ -1,15 +1,23 @@
|
||||
<template>
|
||||
<div class="approval-history-pane">
|
||||
<div v-if="taskNameOptions.length > 0" class="approval-history-filter">
|
||||
<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">
|
||||
{{ taskName }}
|
||||
</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 === 0" @click="clearTaskNames">清空</a-button>
|
||||
<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">
|
||||
{{ taskName }}
|
||||
</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 === 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" />
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user