fix(产品需求、项目需求、工作报告、我的绩效、加班申请): 1、修复搜索区域的下拉框,无法搜索的问题。2、修复工作报告内容溢出的问题。3、修复我的待办 - 待审批,里面的二级tabs没有加权限的问题。4、优化周报里工作日志展示时的分隔符。5、优化项目需求池、我的绩效请求重复发送、影响效率的问题。
feat(我的绩效): 1、增加我的绩效在工作台可以直接处理的功能。2、增加我的绩效全部导出时,合并多个excel的sheet为一个excel的功能。
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
fetchGetProjectReportApprovalPage,
|
||||
fetchGetProjectTask,
|
||||
fetchGetWeeklyReportApprovalPage,
|
||||
fetchPerformanceSheetPage,
|
||||
fetchRejectOvertimeApplication
|
||||
} from '@/service/api';
|
||||
import { useAuthStore } from '@/store/modules/auth';
|
||||
@@ -29,6 +30,9 @@ import TaskWorklogDialog from '@/views/project/project/execution/modules/task-wo
|
||||
import PersonalItemDetailDialog from '@/views/personal-center/my-item/modules/personal-item-detail-dialog.vue';
|
||||
import PersonalItemOperateDialog from '@/views/personal-center/my-item/modules/personal-item-operate-dialog.vue';
|
||||
import PersonalItemStatusActionDialog from '@/views/personal-center/my-item/modules/personal-item-status-action-dialog.vue';
|
||||
import PerformanceActionDialog from '@/views/personal-center/my-performance/modules/performance-action-dialog.vue';
|
||||
import PerformanceExcelEditorDrawer from '@/views/personal-center/my-performance/modules/performance-excel-editor-drawer.vue';
|
||||
import { PerformancePermission } from '@/views/personal-center/my-performance/modules/performance-shared';
|
||||
import OvertimeApplicationBatchDetailDialog from '@/views/personal-center/overtime-application/modules/overtime-application-batch-detail-dialog.vue';
|
||||
import OvertimeApplicationDetailDialog from '@/views/personal-center/overtime-application/modules/overtime-application-detail-dialog.vue';
|
||||
import WorkReportPrototypePageDialog from '@/views/personal-center/work-report/shared/components/prototype-page-dialog.vue';
|
||||
@@ -61,7 +65,8 @@ import IconMdiPlayCircleOutline from '~icons/mdi/play-circle-outline';
|
||||
|
||||
type SortKey = 'created' | 'priority' | 'deadline';
|
||||
type OvertimeApprovalActionType = 'approve' | 'reject';
|
||||
type ApprovalBizType = 'overtime_application' | WorkReportType;
|
||||
type PerformanceApprovalActionType = 'confirm' | 'reject';
|
||||
type ApprovalBizType = 'overtime_application' | 'performance' | WorkReportType;
|
||||
|
||||
defineOptions({ name: 'WorkbenchTodoPanel' });
|
||||
|
||||
@@ -80,6 +85,11 @@ const { routerPushByKey } = useRouterPush();
|
||||
|
||||
const authStore = useAuthStore();
|
||||
const currentUserId = computed(() => authStore.userInfo.userId || '');
|
||||
const buttonPermissions = computed(() => new Set(authStore.userInfo.buttons || []));
|
||||
|
||||
function hasButtonPermission(permission: string) {
|
||||
return buttonPermissions.value.has(permission);
|
||||
}
|
||||
|
||||
// 工时填报在工作台内弹层完成(不切路由),需广播给「我的工时」widget 重拉
|
||||
const { notify: notifyWorklogChanged } = useWorkbenchWorklogSignal();
|
||||
@@ -89,6 +99,7 @@ const { loading, refresh } = useWorkbenchRefresh(async () => {
|
||||
loadMyTaskItems(),
|
||||
loadPersonalTodoItems(),
|
||||
loadOvertimeApprovalItems(),
|
||||
loadPerformanceApprovalItems(),
|
||||
loadWorkReportApprovalItems()
|
||||
]);
|
||||
});
|
||||
@@ -130,9 +141,30 @@ const approvalBizTabs: Array<{ key: ApprovalBizType; label: string }> = [
|
||||
{ key: 'weekly', label: '周报' },
|
||||
{ key: 'monthly', label: '月报' },
|
||||
{ key: 'project', label: '项目半月报' },
|
||||
{ key: 'performance', label: '我的绩效' },
|
||||
{ key: 'overtime_application', label: '加班申请' }
|
||||
];
|
||||
|
||||
const hasWorkReportApprovePermission = computed(() => hasButtonPermission('project:work-report:approve'));
|
||||
const hasOvertimeApprovePermission = computed(() => hasButtonPermission('project:overtime-application:approve'));
|
||||
const hasPerformanceApprovePermission = computed(
|
||||
() =>
|
||||
hasButtonPermission(PerformancePermission.SheetConfirm) && hasButtonPermission(PerformancePermission.SheetReject)
|
||||
);
|
||||
const visibleApprovalBizTabs = computed(() =>
|
||||
approvalBizTabs.filter(tab => {
|
||||
if (tab.key === 'performance') {
|
||||
return hasPerformanceApprovePermission.value;
|
||||
}
|
||||
|
||||
if (tab.key === 'overtime_application') {
|
||||
return hasOvertimeApprovePermission.value;
|
||||
}
|
||||
|
||||
return hasWorkReportApprovePermission.value;
|
||||
})
|
||||
);
|
||||
|
||||
const myTaskItems = ref<WorkbenchTodoItem[]>([]);
|
||||
// 保留任务原始行,供操作图标按 availableActions 渲染并取 projectId / executionId 调状态变更接口
|
||||
const myTaskRows = ref<Api.Project.MyTaskItem[]>([]);
|
||||
@@ -141,6 +173,8 @@ const personalTodoItems = ref<WorkbenchTodoItem[]>([]);
|
||||
const personalItemRows = ref<Api.PersonalItem.PersonalItem[]>([]);
|
||||
const overtimeApprovalItems = ref<WorkbenchTodoItem[]>([]);
|
||||
const overtimeApprovalRows = ref<Api.OvertimeApplication.OvertimeApplication[]>([]);
|
||||
const performanceApprovalItems = ref<WorkbenchTodoItem[]>([]);
|
||||
const performanceApprovalRows = ref<Api.Performance.Sheet.Sheet[]>([]);
|
||||
const workReportApprovalItems = ref<WorkbenchTodoItem[]>([]);
|
||||
const weeklyApprovalRows = ref<Api.WorkReport.Weekly.WeeklyReport[]>([]);
|
||||
const monthlyApprovalRows = ref<Api.WorkReport.Monthly.MonthlyReport[]>([]);
|
||||
@@ -150,6 +184,7 @@ const mergedItems = computed(() => [
|
||||
...myTaskItems.value,
|
||||
...personalTodoItems.value,
|
||||
...overtimeApprovalItems.value,
|
||||
...performanceApprovalItems.value,
|
||||
...workReportApprovalItems.value
|
||||
]);
|
||||
|
||||
@@ -179,6 +214,10 @@ const batchSubmitting = ref(false);
|
||||
const workReportDetailVisible = ref(false);
|
||||
const currentWorkReport = ref<WorkReportRow | null>(null);
|
||||
const currentWorkReportType = ref<WorkReportType>('weekly');
|
||||
const performanceDetailVisible = ref(false);
|
||||
const performanceActionVisible = ref(false);
|
||||
const currentPerformanceSheet = ref<Api.Performance.Sheet.Sheet | null>(null);
|
||||
const currentPerformanceActionType = ref<PerformanceApprovalActionType>('confirm');
|
||||
|
||||
// 批量审批选中状态(存原始加班申请 id,避免映射转换)
|
||||
const selectedOvertimeIds = ref<Set<string>>(new Set());
|
||||
@@ -191,6 +230,7 @@ function getApprovalCategoryLabel(bizType: ApprovalBizType) {
|
||||
if (bizType === 'weekly') return '周报';
|
||||
if (bizType === 'monthly') return '月报';
|
||||
if (bizType === 'project') return '项目半月报';
|
||||
if (bizType === 'performance') return '我的绩效';
|
||||
if (bizType === 'overtime_application') return '加班申请';
|
||||
return '待审批';
|
||||
}
|
||||
@@ -464,6 +504,7 @@ const filteredItems = computed(() => {
|
||||
const approvalBizTabCounts = computed(() => {
|
||||
const counts: Record<ApprovalBizType, number> = {
|
||||
overtime_application: 0,
|
||||
performance: 0,
|
||||
weekly: 0,
|
||||
monthly: 0,
|
||||
project: 0
|
||||
@@ -472,6 +513,12 @@ const approvalBizTabCounts = computed(() => {
|
||||
itemsInTab.value.forEach(item => {
|
||||
if (item.approvalBizType === 'overtime_application') {
|
||||
counts.overtime_application += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.approvalBizType === 'performance') {
|
||||
counts.performance += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isWorkReportApprovalBizType(item.approvalBizType)) {
|
||||
@@ -510,6 +557,17 @@ watch([activeTab, activeDeadlineFilter, activeSort], () => {
|
||||
currentPage.value = 1;
|
||||
});
|
||||
|
||||
watch(
|
||||
visibleApprovalBizTabs,
|
||||
tabs => {
|
||||
if (!tabs.length) return;
|
||||
if (!tabs.some(tab => tab.key === activeApprovalBizType.value)) {
|
||||
activeApprovalBizType.value = tabs[0].key;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
function handleSelectTab(key: WorkbenchTodoMainTab) {
|
||||
if (activeTab.value === key) return;
|
||||
activeTab.value = key;
|
||||
@@ -538,6 +596,11 @@ function handleClickItem(item: WorkbenchTodoItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.approvalBizType === 'performance') {
|
||||
openPerformanceDetail(item);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isWorkReportApprovalBizType(item.approvalBizType)) {
|
||||
openWorkReportDetail(item);
|
||||
return;
|
||||
@@ -568,6 +631,14 @@ function findOvertimeApprovalRow(item: WorkbenchTodoItem) {
|
||||
return overtimeApprovalRows.value.find(row => row.id === item.approvalBizId) || null;
|
||||
}
|
||||
|
||||
function findPerformanceApprovalRow(item: WorkbenchTodoItem) {
|
||||
if (!item.approvalBizId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return performanceApprovalRows.value.find(row => row.id === item.approvalBizId) || null;
|
||||
}
|
||||
|
||||
function openOvertimeDetail(item: WorkbenchTodoItem) {
|
||||
const row = findOvertimeApprovalRow(item);
|
||||
if (!row) return;
|
||||
@@ -576,6 +647,21 @@ function openOvertimeDetail(item: WorkbenchTodoItem) {
|
||||
overtimeDetailVisible.value = true;
|
||||
}
|
||||
|
||||
function openPerformanceDetail(item: WorkbenchTodoItem) {
|
||||
const row = findPerformanceApprovalRow(item);
|
||||
if (!row) return;
|
||||
|
||||
currentPerformanceSheet.value = row;
|
||||
performanceDetailVisible.value = true;
|
||||
}
|
||||
|
||||
function openCurrentPerformanceAction(actionType: PerformanceApprovalActionType) {
|
||||
if (!currentPerformanceSheet.value) return;
|
||||
|
||||
currentPerformanceActionType.value = actionType;
|
||||
performanceActionVisible.value = true;
|
||||
}
|
||||
|
||||
function findWorkReportApprovalRow(item: WorkbenchTodoItem) {
|
||||
if (!item.approvalBizId || !isWorkReportApprovalBizType(item.approvalBizType)) {
|
||||
return null;
|
||||
@@ -627,6 +713,12 @@ async function handleWorkReportSubmitted() {
|
||||
await loadWorkReportApprovalItems();
|
||||
}
|
||||
|
||||
async function handlePerformanceActionSubmitted() {
|
||||
performanceActionVisible.value = false;
|
||||
performanceDetailVisible.value = false;
|
||||
await loadPerformanceApprovalItems();
|
||||
}
|
||||
|
||||
// 优先级角标用字典 label 原样回显(rdms_req_priority:P0~P3),不翻译成高/中/低
|
||||
const { getLabel: getPriorityLabel } = useDict(RDMS_REQ_PRIORITY_DICT_CODE);
|
||||
|
||||
@@ -774,6 +866,12 @@ async function handleBatchActionSubmit(payload: { actionType: OvertimeApprovalAc
|
||||
}
|
||||
|
||||
async function loadOvertimeApprovalItems() {
|
||||
if (!hasOvertimeApprovePermission.value) {
|
||||
overtimeApprovalRows.value = [];
|
||||
overtimeApprovalItems.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const { error, data } = await fetchGetOvertimeApplicationApprovalPage({
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
@@ -809,6 +907,42 @@ async function loadOvertimeApprovalItems() {
|
||||
);
|
||||
}
|
||||
|
||||
async function loadPerformanceApprovalItems() {
|
||||
if (!hasPerformanceApprovePermission.value) {
|
||||
performanceApprovalRows.value = [];
|
||||
performanceApprovalItems.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const { error, data } = await fetchPerformanceSheetPage({
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
statusCode: 'sent'
|
||||
});
|
||||
|
||||
if (error || !data) {
|
||||
performanceApprovalRows.value = [];
|
||||
performanceApprovalItems.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
performanceApprovalRows.value = data.list;
|
||||
performanceApprovalItems.value = buildWorkbenchTodoItems(
|
||||
data.list.map(item => ({
|
||||
id: `performance-${item.id}`,
|
||||
category: 'approval',
|
||||
categoryLabel: '我的绩效',
|
||||
title: `${item.periodMonth} 绩效待确认`,
|
||||
createdTime: item.sentTime || item.createTime || item.updateTime || '',
|
||||
deadline: item.sentTime || item.createTime || item.updateTime || null,
|
||||
source: `我的绩效 · ${item.managerName || '--'}`,
|
||||
priority: 'mid',
|
||||
approvalBizType: 'performance',
|
||||
approvalBizId: item.id
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
function buildWorkReportApprovalItems<T extends WorkReportRow>(
|
||||
bizType: WorkReportType,
|
||||
rows: T[]
|
||||
@@ -832,6 +966,14 @@ function buildWorkReportApprovalItems<T extends WorkReportRow>(
|
||||
}
|
||||
|
||||
async function loadWorkReportApprovalItems() {
|
||||
if (!hasWorkReportApprovePermission.value) {
|
||||
weeklyApprovalRows.value = [];
|
||||
monthlyApprovalRows.value = [];
|
||||
projectApprovalRows.value = [];
|
||||
workReportApprovalItems.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
const [weeklyResult, monthlyResult, projectResult] = await Promise.all([
|
||||
fetchGetWeeklyReportApprovalPage({
|
||||
pageNo: 1,
|
||||
@@ -938,7 +1080,7 @@ onActivated(refresh);
|
||||
</div>
|
||||
<div v-else class="workbench-todo__filters-left">
|
||||
<button
|
||||
v-for="tab in approvalBizTabs"
|
||||
v-for="tab in visibleApprovalBizTabs"
|
||||
:key="tab.key"
|
||||
type="button"
|
||||
class="workbench-todo__filter"
|
||||
@@ -1076,6 +1218,13 @@ onActivated(refresh);
|
||||
</ElButton>
|
||||
</ElTooltip>
|
||||
</div>
|
||||
<div v-else-if="item.approvalBizType === 'performance'" class="workbench-todo__actions" @click.stop>
|
||||
<ElTooltip content="查看绩效">
|
||||
<ElButton link type="primary" class="workbench-todo__action-btn" @click="openPerformanceDetail(item)">
|
||||
<IconMdiEyeOutline class="text-15px" />
|
||||
</ElButton>
|
||||
</ElTooltip>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="isWorkReportApprovalBizType(item.approvalBizType)"
|
||||
class="workbench-todo__actions"
|
||||
@@ -1212,6 +1361,22 @@ onActivated(refresh);
|
||||
:row-data="currentWorkReport"
|
||||
@submitted="handleWorkReportSubmitted"
|
||||
/>
|
||||
|
||||
<PerformanceExcelEditorDrawer
|
||||
v-model:visible="performanceDetailVisible"
|
||||
:row-data="currentPerformanceSheet"
|
||||
mode="view"
|
||||
show-approval-footer
|
||||
@start-approval="openCurrentPerformanceAction('confirm')"
|
||||
/>
|
||||
|
||||
<PerformanceActionDialog
|
||||
v-model:visible="performanceActionVisible"
|
||||
:row-data="currentPerformanceSheet"
|
||||
:action-type="currentPerformanceActionType"
|
||||
selectable-action-type
|
||||
@submitted="handlePerformanceActionSubmitted"
|
||||
/>
|
||||
</WorkbenchModuleCard>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user