fix(登录页、周报、绩效下签): 修复工作报表日期格式化和类型安全问题

- 移除了未使用的文件夹ZIP图标类型定义
- 添加了formatWeeklyPeriodLabel函数用于周报期间标签格式化
- 改进了日期范围计算逻辑并增加了类型安全检查
- 隐藏了登录页面的版权页脚以优化界面显示
- 修复了绩效签核对话框中的文本描述问题
- 在API响应中增加了对报表开始和结束日期的规范化处理
This commit is contained in:
dk
2026-07-23 14:36:56 +08:00
parent 08fff8bbc5
commit aa683f892b
6 changed files with 32 additions and 9 deletions

View File

@@ -287,6 +287,8 @@ function normalizeWeeklyReport(response: WeeklyReportResponse): Api.WorkReport.W
allowEdit: normalizeBooleanFlag(response.allowEdit),
terminal: normalizeBooleanFlag(response.terminal),
isBusinessTrip: normalizeBooleanFlag(response.isBusinessTrip),
periodStartDate: normalizeDateText(response.periodStartDate) ?? '',
periodEndDate: normalizeDateText(response.periodEndDate) ?? '',
totalWorkHours: normalizeReportTotalWorkHours(response.totalWorkHours, fallbackTotalWorkHours),
submitTime: response.submitTime ?? null,
reviewItems: response.reviewItems?.map(normalizeReviewItem) ?? [],

View File

@@ -130,13 +130,11 @@ declare module 'vue' {
IconMdiFolderOpen: typeof import('~icons/mdi/folder-open')['default']
IconMdiFolderOutline: typeof import('~icons/mdi/folder-outline')['default']
IconMdiFolderPlusOutline: typeof import('~icons/mdi/folder-plus-outline')['default']
IconMdiFolderZipOutline: typeof import('~icons/mdi/folder-zip-outline')['default']
IconMdiInboxMultipleOutline: typeof import('~icons/mdi/inbox-multiple-outline')['default']
IconMdiInformationOutline: typeof import('~icons/mdi/information-outline')['default']
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
IconMdiLinkVariant: typeof import('~icons/mdi/link-variant')['default']
IconMdiPenCheckOutline: typeof import('~icons/mdi/pen-check-outline')['default']
IconMdiPencilOutline: typeof import('~icons/mdi/pencil-outline')['default']
IconMdiPlus: typeof import('~icons/mdi/plus')['default']
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']

View File

@@ -369,9 +369,9 @@ const turbines = [
</main>
</div>
<footer class="scene-footer reveal" style="--d: 0.6s">
© {{ currentYear }} 南京灿能电力自动化股份有限公司 · {{ $t('system.title') }}
</footer>
<!-- <footer class="scene-footer reveal" style="&#45;&#45;d: 0.6s">-->
<!-- © {{ currentYear }} 南京灿能电力自动化股份有限公司 · {{ $t('system.title') }}-->
<!-- </footer>-->
</div>
</template>

View File

@@ -54,7 +54,7 @@ const title = computed(() => (isImportOnly.value ? '导入绩效压缩包' : '
const confirmText = computed(() => (isImportOnly.value ? '开始导入' : '确认执行'));
const teamLabelText = computed(() => {
if (needsZipFile.value) {
return '压缩包中含有的下属';
return '全部下属';
}
return props.teamLabel || '当前范围';

View File

@@ -117,9 +117,21 @@ export function formatWeeklyPeriodLabel(
endDate?: string | null,
periodLabel?: string | null
) {
const startDate = typeof rowOrStart === 'object' && rowOrStart ? rowOrStart.periodStartDate : rowOrStart;
const rangeEndDate = typeof rowOrStart === 'object' && rowOrStart ? rowOrStart.periodEndDate : endDate;
const fallbackLabel = typeof rowOrStart === 'object' && rowOrStart ? rowOrStart.periodLabel : periodLabel;
const isRowPayload =
typeof rowOrStart === 'object' &&
rowOrStart !== null &&
!Array.isArray(rowOrStart) &&
('periodStartDate' in rowOrStart || 'periodEndDate' in rowOrStart || 'periodLabel' in rowOrStart);
let startDate: string | null | undefined;
if (isRowPayload) {
startDate = rowOrStart.periodStartDate;
} else if (typeof rowOrStart === 'string') {
startDate = rowOrStart;
} else {
startDate = undefined;
}
const rangeEndDate: string | null | undefined = isRowPayload ? rowOrStart.periodEndDate : endDate;
const fallbackLabel: string | null | undefined = isRowPayload ? rowOrStart.periodLabel : periodLabel;
const referenceDate = dayjs(startDate || rangeEndDate);
if (referenceDate.isValid()) {

View File

@@ -12,6 +12,7 @@ import {
type WorkReportStructuredTask,
formatPeriodDateRange,
formatPeriodLabel,
formatWeeklyPeriodLabel,
getStructuredSections,
getStructuredTasks
} from '../../shared/types';
@@ -866,7 +867,15 @@ const totalHours = computed(() => {
return (props.model.reviewItems || []).reduce((sum, item) => sum + Number(item.workHours || 0), 0);
});
const periodText = computed(() => {
const weeklyLabel = formatWeeklyPeriodLabel(
props.model.periodStartDate || undefined,
props.model.periodEndDate || undefined,
props.model.periodLabel || props.period
);
if (weeklyLabel && weeklyLabel !== '--') return weeklyLabel;
const rangeText = formatPeriodDateRange(
props.model.periodStartDate || undefined,
props.model.periodEndDate || undefined
@@ -875,10 +884,12 @@ const periodText = computed(() => {
return formatPeriodLabel(props.model.periodLabel || props.period) || '--';
});
const totalTravelDays = computed(() => {
const total = travelSegments.value.reduce((sum, segment) => sum + Number(segment.days || 0), 0);
return Math.round(total * 10) / 10;
});
const hasCompleteTravelSegment = computed(() => travelSegments.value.some(isCompleteTravelSegment));
function calcSegmentDays(segment: TravelSegment) {