feat(workbench): 添加待确认tab并调整绩效管理页面标题

This commit is contained in:
dk
2026-07-19 15:02:55 +08:00
parent 7f31bed6f6
commit c2f9c922cf
4 changed files with 65 additions and 18 deletions

View File

@@ -375,7 +375,7 @@
"name": "personal-center_my-performance",
"path": "/personal-center/my-performance",
"component": "view.personal-center_my-performance",
"title": "我的绩效",
"title": "绩效管理",
"routeTitle": "personal-center_my-performance",
"i18nKey": "route.personal-center_my-performance",
"icon": "mdi:trophy-outline",
@@ -389,7 +389,7 @@
"redirect": null,
"props": null,
"meta": {
"title": "我的绩效",
"title": "绩效管理",
"i18nKey": "route.personal-center_my-performance",
"icon": "mdi:trophy-outline",
"localIcon": null,

View File

@@ -173,7 +173,7 @@ const local: App.I18n.Schema = {
'personal-center_work-report_weekly': '个人周报',
'personal-center_work-report_monthly': '个人月报',
'personal-center_work-report_project': '项目半月报',
'personal-center_my-performance': '我的绩效',
'personal-center_my-performance': '绩效管理',
'personal-center_my-application': '我的申请',
'personal-center_overtime-application': '业务学习',
'personal-center_pending-approval': '待我审批',

View File

@@ -1,6 +1,6 @@
import dayjs from 'dayjs';
export type WorkbenchTodoCategory = 'task' | 'ticket' | 'personal' | 'approval';
export type WorkbenchTodoCategory = 'task' | 'ticket' | 'personal' | 'approval' | 'confirm';
export type WorkbenchTodoMainTab = 'all' | WorkbenchTodoCategory;
@@ -68,7 +68,8 @@ const todoCategoryMeta: Record<
task: { label: '任务', tone: 'emerald', icon: 'mdi:checkbox-marked-circle-outline' },
ticket: { label: '工单', tone: 'amber', icon: 'mdi:ticket-confirmation-outline' },
personal: { label: '我的事项', tone: 'violet', icon: 'mdi:notebook-edit-outline' },
approval: { label: '待审批', tone: 'sky', icon: 'mdi:checkbox-multiple-marked-outline' }
approval: { label: '待审批', tone: 'sky', icon: 'mdi:checkbox-multiple-marked-outline' },
confirm: { label: '待确认', tone: 'rose', icon: 'mdi:clipboard-check-outline' }
};
const todoPriorityWeight: Record<WorkbenchTodoPriority, number> = {

View File

@@ -131,7 +131,8 @@ const mainTabs: Array<{ key: WorkbenchTodoMainTab; label: string }> = [
{ key: 'task', label: '任务' },
{ key: 'ticket', label: '工单' },
{ key: 'personal', label: '我的事项' },
{ key: 'approval', label: '待审批' }
{ key: 'approval', label: '待审批' },
{ key: 'confirm', label: '待确认' }
];
const deadlineFilters: Array<{ key: Exclude<WorkbenchTodoDeadlineFilter, null>; label: string }> = [
@@ -144,9 +145,11 @@ const approvalBizTabs: Array<{ key: ApprovalBizType; label: string }> = [
{ key: 'weekly', label: '周报' },
{ key: 'monthly', label: '月报' },
{ key: 'project', label: '项目半月报' },
{ key: 'performance', label: '我的绩效' },
{ key: 'overtime_application', label: '业务学习' }
];
const confirmBizTabs: Array<{ key: Extract<ApprovalBizType, 'performance'>; label: string }> = [
{ key: 'performance', label: '绩效表' }
];
const hasWorkReportApprovePermission = computed(() => hasButtonPermission('project:work-report:approve'));
const hasOvertimeApprovePermission = computed(() => hasButtonPermission('project:overtime-application:approve'));
@@ -154,6 +157,14 @@ const hasPerformanceApprovePermission = computed(
() =>
hasButtonPermission(PerformancePermission.SheetConfirm) && hasButtonPermission(PerformancePermission.SheetReject)
);
const visibleMainTabs = computed(() =>
mainTabs.filter(tab => {
if (tab.key === 'confirm') {
return hasPerformanceApprovePermission.value;
}
return true;
})
);
const visibleApprovalBizTabs = computed(() =>
approvalBizTabs.filter(tab => {
if (tab.key === 'performance') {
@@ -167,6 +178,7 @@ const visibleApprovalBizTabs = computed(() =>
return hasWorkReportApprovePermission.value;
})
);
const visibleConfirmBizTabs = computed(() => (hasPerformanceApprovePermission.value ? confirmBizTabs : []));
const myTaskItems = ref<WorkbenchTodoItem[]>([]);
// 保留任务原始行,供操作图标按 availableActions 渲染并取 projectId / executionId 调状态变更接口
@@ -233,7 +245,7 @@ function getApprovalCategoryLabel(bizType: ApprovalBizType) {
if (bizType === 'weekly') return '周报';
if (bizType === 'monthly') return '月报';
if (bizType === 'project') return '项目半月报';
if (bizType === 'performance') return '我的绩效';
if (bizType === 'performance') return '绩效';
if (bizType === 'overtime_application') return '业务学习';
return '待审批';
}
@@ -549,7 +561,8 @@ const tabCounts = computed(() => {
task: 0,
ticket: 0,
personal: 0,
approval: 0
approval: 0,
confirm: 0
};
mergedItems.value.forEach(item => {
counts[item.category] += 1;
@@ -563,7 +576,8 @@ const tabOverdueCount = computed(() => {
task: 0,
ticket: 0,
personal: 0,
approval: 0
approval: 0,
confirm: 0
};
mergedItems.value.forEach(item => {
if (!isWorkbenchTodoOverdue(item)) return;
@@ -580,6 +594,10 @@ const filteredItems = computed(() => {
return itemsInTab.value.filter(item => item.approvalBizType === activeApprovalBizType.value);
}
if (activeTab.value === 'confirm') {
return itemsInTab.value.filter(item => item.approvalBizType === 'performance');
}
return filterWorkbenchTodoItemsByDeadline(itemsInTab.value, activeDeadlineFilter.value);
});
@@ -650,11 +668,26 @@ watch(
{ immediate: true }
);
watch(
visibleMainTabs,
tabs => {
if (!tabs.some(tab => tab.key === activeTab.value)) {
activeTab.value = tabs[0]?.key ?? 'all';
}
},
{ immediate: true }
);
function handleSelectTab(key: WorkbenchTodoMainTab) {
if (key === 'confirm' && !hasPerformanceApprovePermission.value) return;
if (activeTab.value === key) return;
activeTab.value = key;
if (key === 'approval') activeDeadlineFilter.value = null;
activeDeadlineFilter.value = null;
if (key === 'confirm') {
activeApprovalBizType.value = 'performance';
} else if (key === 'approval' && activeApprovalBizType.value === 'performance') {
activeApprovalBizType.value = visibleApprovalBizTabs.value[0]?.key ?? 'weekly';
}
if (key !== 'task' && activeSort.value === 'priority') {
activeSort.value = 'deadline';
}
@@ -1015,12 +1048,12 @@ async function loadPerformanceApprovalItems() {
performanceApprovalItems.value = buildWorkbenchTodoItems(
data.list.map(item => ({
id: `performance-${item.id}`,
category: 'approval',
categoryLabel: '我的绩效',
title: `${item.periodMonth} 绩效待确认`,
category: 'confirm',
categoryLabel: '绩效',
title: `${item.periodMonth} 绩效待确认`,
createdTime: item.sentTime || item.createTime || item.updateTime || '',
deadline: item.sentTime || item.createTime || item.updateTime || null,
source: `我的绩效 · ${item.managerName || '--'}`,
source: `绩效 · ${item.managerName || '--'}`,
priority: 'mid',
approvalBizType: 'performance',
approvalBizId: item.id
@@ -1124,7 +1157,7 @@ onActivated(refresh);
<div class="workbench-todo__tabs">
<div class="workbench-todo__tabs-group">
<ElTooltip
v-for="tab in mainTabs"
v-for="tab in visibleMainTabs"
:key="tab.key"
:content="`已逾期 ${tabOverdueCount[tab.key]} 项,建议尽快处理`"
:disabled="tabOverdueCount[tab.key] === 0"
@@ -1151,7 +1184,7 @@ onActivated(refresh);
</div>
<div class="workbench-todo__filters">
<div v-if="activeTab !== 'approval'" class="workbench-todo__filters-left">
<div v-if="activeTab !== 'approval' && activeTab !== 'confirm'" class="workbench-todo__filters-left">
<button
v-for="filter in deadlineFilters"
:key="filter.key"
@@ -1163,7 +1196,7 @@ onActivated(refresh);
{{ filter.label }}
</button>
</div>
<div v-else class="workbench-todo__filters-left">
<div v-else-if="activeTab === 'approval'" class="workbench-todo__filters-left">
<button
v-for="tab in visibleApprovalBizTabs"
:key="tab.key"
@@ -1176,6 +1209,19 @@ onActivated(refresh);
<span class="workbench-todo__filter-count">{{ approvalBizTabCounts[tab.key] }}</span>
</button>
</div>
<div v-else class="workbench-todo__filters-left">
<button
v-for="tab in visibleConfirmBizTabs"
:key="tab.key"
type="button"
class="workbench-todo__filter"
:class="{ 'workbench-todo__filter--active': activeApprovalBizType === tab.key }"
@click="handleSelectApprovalBizType(tab.key)"
>
{{ tab.label }}
<span class="workbench-todo__filter-count">{{ approvalBizTabCounts[tab.key] }}</span>
</button>
</div>
<ElDropdown trigger="click" placement="bottom-end" @command="handleSelectSort">
<span class="workbench-todo__sort">