feat(review-frontend): 项目资料按会前会后分组展示
parent
261173e76e
commit
1ba4d43de4
|
|
@ -37,21 +37,37 @@
|
|||
|
||||
<div class="material-card" v-loading="loading">
|
||||
<div class="material-toolbar">
|
||||
<div class="material-type-wrap">
|
||||
<span class="label">类型:</span>
|
||||
<el-select :model-value="materialSummary.agendaType || projectInfo.agendaCategory" disabled class="type-select">
|
||||
<el-option
|
||||
v-for="option in REVIEW_AGENDA_CATEGORY_OPTIONS"
|
||||
:key="option"
|
||||
:label="option"
|
||||
:value="option"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="toolbar-title">上传资料</div>
|
||||
<el-button link type="primary" @click="handleDownloadTemplate">下载模板</el-button>
|
||||
</div>
|
||||
|
||||
<el-table :data="materialSummary.materials" border class="material-table" empty-text="暂无材料定义">
|
||||
<div class="group-title">会前资料</div>
|
||||
<el-table :data="beforeMeetingMaterials" border class="material-table" empty-text="暂无会前资料">
|
||||
<el-table-column label="资料类型" min-width="220">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
{{ row.materialName }}
|
||||
<span v-if="row.required" class="required-flag">*</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="资料文件" min-width="300">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row.latestFile" class="file-name">{{ row.latestFile.fileName }}</span>
|
||||
<span v-else class="file-empty">未上传</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="260" align="center">
|
||||
<template #default="{ row }">
|
||||
<a class="op-link" @click="triggerUpload(row)">{{ row.latestFile ? '替换' : '上传' }}</a>
|
||||
<a class="op-link" :class="{ disabled: !row.latestFile }" @click="row.latestFile && handleDownload(row.latestFile)">下载</a>
|
||||
<a class="op-link" @click="openHistory(row)">历史版本</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="group-title group-after">会后资料</div>
|
||||
<el-table :data="afterMeetingMaterials" border class="material-table" empty-text="暂无会后资料">
|
||||
<el-table-column label="资料类型" min-width="220">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
|
|
@ -106,12 +122,11 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { getReviewMeeting } from '@/api/review/meeting'
|
||||
import {
|
||||
REVIEW_AGENDA_CATEGORY_OPTIONS,
|
||||
downloadProjectTemplateBundle,
|
||||
getProjectMaterialHistory,
|
||||
getProjectMaterialSummary,
|
||||
|
|
@ -156,6 +171,41 @@ const uploadTarget = ref<ReviewMeetingMaterialItemRespVO>()
|
|||
const historyVisible = ref(false)
|
||||
const historyList = ref<ReviewMeetingMaterialHistoryRespVO[]>([])
|
||||
|
||||
const PHASE_MAPPING: Record<string, Record<string, 'before' | 'after'>> = {
|
||||
项目立项: {
|
||||
PROJECT_ARGUMENT_DOC: 'before',
|
||||
PROJECT_DEFENSE_PPT: 'before',
|
||||
PROJECT_EXPERT_OPINION_SIGNED: 'after'
|
||||
},
|
||||
预验收: {
|
||||
PRE_PROJECT_CONTRACT: 'before',
|
||||
PRE_REQUIREMENT_SPEC: 'before',
|
||||
PRE_ACCEPTANCE_REPORT: 'before',
|
||||
PRE_USER_FUNCTION_TEST: 'before',
|
||||
PRE_SERVICE_CHECKLIST: 'before'
|
||||
},
|
||||
项目终验: {
|
||||
FINAL_ACCEPTANCE_DOC: 'before',
|
||||
FINAL_DEFENSE_PPT: 'before',
|
||||
FINAL_DRAFT_EXPERT_OPINION: 'before',
|
||||
FINAL_SIGNED_EXPERT_OPINION: 'after',
|
||||
FINAL_RECTIFICATION_OPINION: 'after',
|
||||
FINAL_RECTIFICATION_REPLY: 'after'
|
||||
}
|
||||
}
|
||||
|
||||
const beforeMeetingMaterials = computed(() => {
|
||||
const agendaType = materialSummary.value.agendaType
|
||||
const agendaMap = PHASE_MAPPING[agendaType] || {}
|
||||
return materialSummary.value.materials.filter((item) => agendaMap[item.materialCode] !== 'after')
|
||||
})
|
||||
|
||||
const afterMeetingMaterials = computed(() => {
|
||||
const agendaType = materialSummary.value.agendaType
|
||||
const agendaMap = PHASE_MAPPING[agendaType] || {}
|
||||
return materialSummary.value.materials.filter((item) => agendaMap[item.materialCode] === 'after')
|
||||
})
|
||||
|
||||
const loadSummary = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
|
|
@ -360,18 +410,21 @@ onMounted(async () => {
|
|||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.material-type-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
.toolbar-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.label {
|
||||
.group-title {
|
||||
margin: 8px 0 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.type-select {
|
||||
width: 260px;
|
||||
.group-after {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.required-flag {
|
||||
|
|
|
|||
Loading…
Reference in New Issue