188 lines
8.2 KiB
Vue
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>
|