Files
cn-rdms-web/src/views/personal-center/work-report/shared/components/detail-dialog.vue
dk 80f028bcb9 fix(工作报告): 修复工作报告存在的若干问题。
feat(加班申请): 支持批量审批。
2026-06-13 13:06:39 +08:00

188 lines
8.2 KiB
Vue

<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { fetchGetMonthlyReportDetail, fetchGetProjectReportDetail, fetchGetWeeklyReportDetail } from '@/service/api';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import BusinessFormSection from '@/components/custom/business-form-section.vue';
import {
WORK_REPORT_TYPE_LABEL,
type WorkReportRow,
type WorkReportType,
formatDate,
formatEmptyText,
formatPeriod,
formatPeriodDateRange,
formatWeeklyPeriodLabel,
getProjectReportFlagLabel,
getWorkReportStatusLabel
} from '../types';
defineOptions({ name: 'WorkReportDetailDialog' });
const visible = defineModel<boolean>('visible', { default: false });
const props = defineProps<{
reportType: WorkReportType;
rowData?: WorkReportRow | null;
}>();
const loading = ref(false);
const detail = ref<WorkReportRow | null>(null);
const title = computed(() => `${WORK_REPORT_TYPE_LABEL[props.reportType]}详情`);
const weeklyDetail = computed(() =>
props.reportType === 'weekly' ? (detail.value as Api.WorkReport.Weekly.WeeklyReport | null) : null
);
const periodText = computed(() => {
if (!detail.value) return '--';
return props.reportType === 'weekly' ? formatWeeklyPeriodLabel(detail.value) : formatPeriod(detail.value);
});
const periodTooltip = computed(() => {
if (!detail.value || props.reportType !== 'weekly') return '';
return formatPeriodDateRange(detail.value);
});
watch(visible, isVisible => {
if (isVisible) loadDetail();
});
async function loadDetail() {
if (!props.rowData?.id) return;
loading.value = true;
let result;
if (props.reportType === 'weekly') {
result = await fetchGetWeeklyReportDetail(props.rowData.id);
} else if (props.reportType === 'monthly') {
result = await fetchGetMonthlyReportDetail(props.rowData.id);
} else {
result = await fetchGetProjectReportDetail(props.rowData.id);
}
loading.value = false;
if (!result.error && result.data) {
detail.value = result.data;
}
}
function getProjectDetail() {
return detail.value as Api.WorkReport.Project.ProjectReport | null;
}
function getPersonalDetail() {
return detail.value as Api.WorkReport.Weekly.WeeklyReport | Api.WorkReport.Monthly.MonthlyReport | null;
}
</script>
<template>
<BusinessFormDialog v-model="visible" :title="title" preset="lg" :loading="loading" :show-footer="false">
<div v-if="detail" class="work-report-detail">
<BusinessFormSection title="基础信息">
<ElDescriptions :column="3" border size="small">
<ElDescriptionsItem label="报告周期">
<ElTooltip :disabled="!periodTooltip || periodTooltip === '--'" :content="periodTooltip" placement="top">
<span>{{ periodText }}</span>
</ElTooltip>
</ElDescriptionsItem>
<ElDescriptionsItem label="状态">
{{ getWorkReportStatusLabel(detail.statusCode, detail.statusName) }}
</ElDescriptionsItem>
<ElDescriptionsItem label="直属上级">{{ detail.supervisorName }}</ElDescriptionsItem>
<ElDescriptionsItem label="开始日期">{{ formatDate(detail.periodStartDate) }}</ElDescriptionsItem>
<ElDescriptionsItem label="结束日期">{{ formatDate(detail.periodEndDate) }}</ElDescriptionsItem>
<ElDescriptionsItem label="总工时">{{ formatEmptyText(detail.totalWorkHours) }}</ElDescriptionsItem>
<ElDescriptionsItem label="提交时间">{{ formatEmptyText(detail.submitTime) }}</ElDescriptionsItem>
<ElDescriptionsItem label="审批时间">{{ formatEmptyText(detail.approvalTime) }}</ElDescriptionsItem>
<ElDescriptionsItem label="审批意见">{{ formatEmptyText(detail.approvalComment) }}</ElDescriptionsItem>
</ElDescriptions>
</BusinessFormSection>
<template v-if="reportType === 'project'">
<BusinessFormSection title="项目信息">
<ElDescriptions :column="2" border size="small">
<ElDescriptionsItem label="项目名称">{{ getProjectDetail()?.projectName }}</ElDescriptionsItem>
<ElDescriptionsItem label="半月周期">
{{ getProjectReportFlagLabel(getProjectDetail()?.flag) }}
</ElDescriptionsItem>
<ElDescriptionsItem label="项目负责人">{{ getProjectDetail()?.projectOwnerName }}</ElDescriptionsItem>
<ElDescriptionsItem label="技术负责人">
{{ formatEmptyText(getProjectDetail()?.technicalOwnerName) }}
</ElDescriptionsItem>
<ElDescriptionsItem label="项目状态" :span="2">
{{ formatEmptyText(getProjectDetail()?.projectStatusDesc) }}
</ElDescriptionsItem>
<ElDescriptionsItem label="整体计划进度" :span="2">
{{ formatEmptyText(getProjectDetail()?.projectProgressPlan) }}
</ElDescriptionsItem>
<ElDescriptionsItem label="要点描述" :span="2">
{{ formatEmptyText(getProjectDetail()?.projectKeyPoints) }}
</ElDescriptionsItem>
<ElDescriptionsItem label="项目问题" :span="2">
{{ formatEmptyText(getProjectDetail()?.projectProblems) }}
</ElDescriptionsItem>
</ElDescriptions>
</BusinessFormSection>
<BusinessFormSection title="本期工作内容">
<ElTable border :data="getProjectDetail()?.currentItems || []">
<ElTableColumn prop="itemTitle" label="工作内容" min-width="180" />
<ElTableColumn prop="workHours" label="工时" width="100" />
<ElTableColumn prop="priorityCode" label="优先级" width="120" />
<ElTableColumn prop="progressRate" label="进度" width="100" />
</ElTable>
</BusinessFormSection>
<BusinessFormSection title="下期计划工作内容">
<ElTable border :data="getProjectDetail()?.nextItems || []">
<ElTableColumn prop="itemTitle" label="工作内容" min-width="180" />
<ElTableColumn prop="workHours" label="工时" width="100" />
<ElTableColumn prop="priorityCode" label="优先级" width="120" />
<ElTableColumn prop="progressRate" label="进度" width="100" />
</ElTable>
</BusinessFormSection>
</template>
<template v-else>
<BusinessFormSection title="当期重点工作回顾">
<ElTable border :data="getPersonalDetail()?.reviewItems || []">
<ElTableColumn prop="itemTitle" label="事项" min-width="160" />
<ElTableColumn prop="workHours" label="工时" width="100" />
<ElTableColumn prop="contentText" label="工作内容" min-width="220" show-overflow-tooltip />
<ElTableColumn prop="reflectionText" label="复盘反思" min-width="220" show-overflow-tooltip />
</ElTable>
</BusinessFormSection>
<BusinessFormSection title="下周期重点工作计划">
<ElTable border :data="getPersonalDetail()?.planItems || []">
<ElTableColumn prop="itemTitle" label="事项" min-width="160" />
<ElTableColumn prop="targetText" label="目标" min-width="220" show-overflow-tooltip />
<ElTableColumn prop="supportNeed" label="支持需求" min-width="220" show-overflow-tooltip />
</ElTable>
</BusinessFormSection>
<BusinessFormSection v-if="reportType === 'weekly'" title="出差信息">
<ElDescriptions :column="3" border size="small">
<ElDescriptionsItem label="是否出差">
{{ weeklyDetail?.isBusinessTrip ? '是' : '否' }}
</ElDescriptionsItem>
<ElDescriptionsItem label="出差天数">
{{ formatEmptyText(weeklyDetail?.totalTravelDays) }}
</ElDescriptionsItem>
</ElDescriptions>
<ElTable class="mt-12px" border :data="weeklyDetail?.travelSegments || []">
<ElTableColumn prop="startDate" label="开始日期" width="120" />
<ElTableColumn prop="endDate" label="结束日期" width="120" />
<ElTableColumn prop="travelDays" label="天数" width="100" />
<ElTableColumn prop="location" label="地点" min-width="160" />
</ElTable>
</BusinessFormSection>
</template>
</div>
</BusinessFormDialog>
</template>
<style scoped>
.work-report-detail {
min-width: 0;
}
</style>