fix(登录页、周报、绩效下签): 修复工作报表日期格式化和类型安全问题
- 移除了未使用的文件夹ZIP图标类型定义 - 添加了formatWeeklyPeriodLabel函数用于周报期间标签格式化 - 改进了日期范围计算逻辑并增加了类型安全检查 - 隐藏了登录页面的版权页脚以优化界面显示 - 修复了绩效签核对话框中的文本描述问题 - 在API响应中增加了对报表开始和结束日期的规范化处理
This commit is contained in:
@@ -287,6 +287,8 @@ function normalizeWeeklyReport(response: WeeklyReportResponse): Api.WorkReport.W
|
|||||||
allowEdit: normalizeBooleanFlag(response.allowEdit),
|
allowEdit: normalizeBooleanFlag(response.allowEdit),
|
||||||
terminal: normalizeBooleanFlag(response.terminal),
|
terminal: normalizeBooleanFlag(response.terminal),
|
||||||
isBusinessTrip: normalizeBooleanFlag(response.isBusinessTrip),
|
isBusinessTrip: normalizeBooleanFlag(response.isBusinessTrip),
|
||||||
|
periodStartDate: normalizeDateText(response.periodStartDate) ?? '',
|
||||||
|
periodEndDate: normalizeDateText(response.periodEndDate) ?? '',
|
||||||
totalWorkHours: normalizeReportTotalWorkHours(response.totalWorkHours, fallbackTotalWorkHours),
|
totalWorkHours: normalizeReportTotalWorkHours(response.totalWorkHours, fallbackTotalWorkHours),
|
||||||
submitTime: response.submitTime ?? null,
|
submitTime: response.submitTime ?? null,
|
||||||
reviewItems: response.reviewItems?.map(normalizeReviewItem) ?? [],
|
reviewItems: response.reviewItems?.map(normalizeReviewItem) ?? [],
|
||||||
|
|||||||
2
src/typings/components.d.ts
vendored
2
src/typings/components.d.ts
vendored
@@ -130,13 +130,11 @@ declare module 'vue' {
|
|||||||
IconMdiFolderOpen: typeof import('~icons/mdi/folder-open')['default']
|
IconMdiFolderOpen: typeof import('~icons/mdi/folder-open')['default']
|
||||||
IconMdiFolderOutline: typeof import('~icons/mdi/folder-outline')['default']
|
IconMdiFolderOutline: typeof import('~icons/mdi/folder-outline')['default']
|
||||||
IconMdiFolderPlusOutline: typeof import('~icons/mdi/folder-plus-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']
|
IconMdiInboxMultipleOutline: typeof import('~icons/mdi/inbox-multiple-outline')['default']
|
||||||
IconMdiInformationOutline: typeof import('~icons/mdi/information-outline')['default']
|
IconMdiInformationOutline: typeof import('~icons/mdi/information-outline')['default']
|
||||||
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
|
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
|
||||||
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
|
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
|
||||||
IconMdiLinkVariant: typeof import('~icons/mdi/link-variant')['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']
|
IconMdiPencilOutline: typeof import('~icons/mdi/pencil-outline')['default']
|
||||||
IconMdiPlus: typeof import('~icons/mdi/plus')['default']
|
IconMdiPlus: typeof import('~icons/mdi/plus')['default']
|
||||||
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
|
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
|
||||||
|
|||||||
@@ -369,9 +369,9 @@ const turbines = [
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="scene-footer reveal" style="--d: 0.6s">
|
<!-- <footer class="scene-footer reveal" style="--d: 0.6s">-->
|
||||||
© {{ currentYear }} 南京灿能电力自动化股份有限公司 · {{ $t('system.title') }}
|
<!-- © {{ currentYear }} 南京灿能电力自动化股份有限公司 · {{ $t('system.title') }}-->
|
||||||
</footer>
|
<!-- </footer>-->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const title = computed(() => (isImportOnly.value ? '导入绩效压缩包' : '
|
|||||||
const confirmText = computed(() => (isImportOnly.value ? '开始导入' : '确认执行'));
|
const confirmText = computed(() => (isImportOnly.value ? '开始导入' : '确认执行'));
|
||||||
const teamLabelText = computed(() => {
|
const teamLabelText = computed(() => {
|
||||||
if (needsZipFile.value) {
|
if (needsZipFile.value) {
|
||||||
return '压缩包中含有的下属';
|
return '全部下属';
|
||||||
}
|
}
|
||||||
|
|
||||||
return props.teamLabel || '当前范围';
|
return props.teamLabel || '当前范围';
|
||||||
|
|||||||
@@ -117,9 +117,21 @@ export function formatWeeklyPeriodLabel(
|
|||||||
endDate?: string | null,
|
endDate?: string | null,
|
||||||
periodLabel?: string | null
|
periodLabel?: string | null
|
||||||
) {
|
) {
|
||||||
const startDate = typeof rowOrStart === 'object' && rowOrStart ? rowOrStart.periodStartDate : rowOrStart;
|
const isRowPayload =
|
||||||
const rangeEndDate = typeof rowOrStart === 'object' && rowOrStart ? rowOrStart.periodEndDate : endDate;
|
typeof rowOrStart === 'object' &&
|
||||||
const fallbackLabel = typeof rowOrStart === 'object' && rowOrStart ? rowOrStart.periodLabel : periodLabel;
|
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);
|
const referenceDate = dayjs(startDate || rangeEndDate);
|
||||||
|
|
||||||
if (referenceDate.isValid()) {
|
if (referenceDate.isValid()) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
type WorkReportStructuredTask,
|
type WorkReportStructuredTask,
|
||||||
formatPeriodDateRange,
|
formatPeriodDateRange,
|
||||||
formatPeriodLabel,
|
formatPeriodLabel,
|
||||||
|
formatWeeklyPeriodLabel,
|
||||||
getStructuredSections,
|
getStructuredSections,
|
||||||
getStructuredTasks
|
getStructuredTasks
|
||||||
} from '../../shared/types';
|
} from '../../shared/types';
|
||||||
@@ -866,7 +867,15 @@ const totalHours = computed(() => {
|
|||||||
|
|
||||||
return (props.model.reviewItems || []).reduce((sum, item) => sum + Number(item.workHours || 0), 0);
|
return (props.model.reviewItems || []).reduce((sum, item) => sum + Number(item.workHours || 0), 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
const periodText = computed(() => {
|
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(
|
const rangeText = formatPeriodDateRange(
|
||||||
props.model.periodStartDate || undefined,
|
props.model.periodStartDate || undefined,
|
||||||
props.model.periodEndDate || undefined
|
props.model.periodEndDate || undefined
|
||||||
@@ -875,10 +884,12 @@ const periodText = computed(() => {
|
|||||||
|
|
||||||
return formatPeriodLabel(props.model.periodLabel || props.period) || '--';
|
return formatPeriodLabel(props.model.periodLabel || props.period) || '--';
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalTravelDays = computed(() => {
|
const totalTravelDays = computed(() => {
|
||||||
const total = travelSegments.value.reduce((sum, segment) => sum + Number(segment.days || 0), 0);
|
const total = travelSegments.value.reduce((sum, segment) => sum + Number(segment.days || 0), 0);
|
||||||
return Math.round(total * 10) / 10;
|
return Math.round(total * 10) / 10;
|
||||||
});
|
});
|
||||||
|
|
||||||
const hasCompleteTravelSegment = computed(() => travelSegments.value.some(isCompleteTravelSegment));
|
const hasCompleteTravelSegment = computed(() => travelSegments.value.some(isCompleteTravelSegment));
|
||||||
|
|
||||||
function calcSegmentDays(segment: TravelSegment) {
|
function calcSegmentDays(segment: TravelSegment) {
|
||||||
|
|||||||
Reference in New Issue
Block a user