fix(加班申请、工作报告、我的绩效): 重构页面样式、修复一系列bug、对不合理的地方进行调整。

This commit is contained in:
dk
2026-06-22 23:07:21 +08:00
parent b1d52b852f
commit 632c123112
30 changed files with 1574 additions and 451 deletions

View File

@@ -2,6 +2,7 @@
/* eslint-disable no-void */
import { computed, markRaw, reactive, ref } from 'vue';
import { ElMessageBox, ElTag } from 'element-plus';
import dayjs from 'dayjs';
import {
fetchDeleteProjectReport,
fetchExportProjectReportContent,
@@ -27,8 +28,7 @@ import {
resolveWorkReportStatusTagType,
transformWorkReportPage
} from '../shared/types';
import { resolveWorkReportSummaryPeriod } from '../shared/utils';
import TeamReportSummary from '../shared/components/team-report-summary.vue';
import { buildProjectPeriodFromMonth, resolveWorkReportSummaryPeriod } from '../shared/utils';
import ProjectReportSearch from './modules/search-panel.vue';
import IconMdiDeleteOutline from '~icons/mdi/delete-outline';
import IconMdiEyeOutline from '~icons/mdi/eye-outline';
@@ -72,6 +72,22 @@ const isTeamMode = computed(() => props.teamContext?.mode === 'team');
const isTeamRootSelected = computed(() => Boolean(isTeamMode.value && props.teamContext?.isRootSelected));
const currentProjectOwnerIds = computed(() => resolveTeamQueryUserIds(props.teamContext));
const reportTitle = computed(() => getWorkReportTypeDisplayLabel('project', isTeamMode.value));
const normalizedPeriodRange = computed(() => {
const periodRange = searchParams.periodStartDate;
if (!periodRange?.length) {
return periodRange;
}
const [startDate, endDate] = periodRange;
const start = dayjs(startDate);
const end = dayjs(endDate || startDate);
if (!start.isValid() || !end.isValid()) {
return periodRange;
}
return [start.startOf('month').format('YYYY-MM-DD'), end.endOf('month').format('YYYY-MM-DD')];
});
const table = useUIPaginatedTable<
Awaited<ReturnType<typeof fetchGetProjectReportPage>>,
@@ -81,6 +97,7 @@ const table = useUIPaginatedTable<
api: () =>
fetchGetProjectReportPage({
...searchParams,
periodStartDate: normalizedPeriodRange.value,
projectOwnerIds: currentProjectOwnerIds.value
}),
transform: response => transformWorkReportPage(response, searchParams.pageNo ?? 1, searchParams.pageSize ?? 10),
@@ -129,7 +146,42 @@ const table = useUIPaginatedTable<
});
// 团队统计始终使用当前周期(当前半月),不跟随列表第一条数据的周期
const summaryPeriod = computed(() => resolveWorkReportSummaryPeriod('project'));
const summaryPeriod = computed(() =>
resolveWorkReportSummaryPeriod('project', {
periodRange: normalizedPeriodRange.value
})
);
const summaryPeriodKeys = computed(() => {
const dateRange = normalizedPeriodRange.value;
const fallbackKey = summaryPeriod.value.periodKey;
if (!dateRange?.length) {
return fallbackKey ? [fallbackKey] : [];
}
const [startDate, endDate] = dateRange;
const start = dayjs(startDate);
const end = dayjs(endDate || startDate);
if (!start.isValid() || !end.isValid()) {
return fallbackKey ? [fallbackKey] : [];
}
const keys: string[] = [];
const endBoundary = end.endOf('month');
for (
let cursor = start.startOf('month');
cursor.isBefore(endBoundary, 'month') || cursor.isSame(endBoundary, 'month');
cursor = cursor.add(1, 'month')
) {
keys.push(buildProjectPeriodFromMonth(cursor, 1).periodKey);
keys.push(buildProjectPeriodFromMonth(cursor, 2).periodKey);
}
return keys;
});
const hasSearchedDateRange = computed(() => searchParams.periodStartDate?.length === 2);
function getRowActions(row: Api.WorkReport.Project.ProjectReport): BusinessTableAction[] {
const actions: BusinessTableAction[] = [
@@ -271,6 +323,7 @@ function createExportSearchParams() {
const { pageNo: _pageNo, pageSize: _pageSize, ...params } = searchParams;
return {
...params,
periodStartDate: normalizedPeriodRange.value,
projectOwnerIds: currentProjectOwnerIds.value
};
}
@@ -337,17 +390,32 @@ async function loadTeamSummary() {
return;
}
const dateRange = normalizedPeriodRange.value;
const summaryParams: Api.WorkReport.Common.TeamReportSummaryParams = { reportType: 'project' };
if (dateRange?.length === 2) {
summaryParams.periodStartDate = dateRange[0];
summaryParams.periodEndDate = dateRange[1];
} else {
summaryParams.periodKey = summaryPeriod.value.periodKey;
}
teamSummaryLoading.value = true;
const { error, data } = await fetchGetTeamReportSummary({
reportType: 'project',
periodKey: summaryPeriod.value.periodKey
});
const { error, data } = await fetchGetTeamReportSummary(summaryParams);
teamSummaryLoading.value = false;
teamSummary.value = error || !data ? null : data;
}
defineExpose({ reload });
defineExpose({
reload,
teamSummary,
teamSummaryLoading,
summaryPeriod,
summaryPeriodKeys,
hasSearchedDateRange,
loadTeamSummary
});
</script>
<template>
@@ -364,16 +432,6 @@ defineExpose({ reload });
@search="handleSearch"
/>
<TeamReportSummary
v-if="isTeamRootSelected"
report-type="project"
:period-key="summaryPeriod.periodKey"
:period-label="formatPeriod(summaryPeriod)"
:loading="teamSummaryLoading"
:summary="teamSummary"
@reminded="loadTeamSummary"
/>
<ElCard class="flex-1-hidden card-wrapper" body-class="business-table-card-body">
<template #header>
<div class="flex flex-wrap items-center justify-between gap-12px">