refactor(submissions): 方案A — mapper submitter_name + 页面样式对齐 + 紧急迁移

- mapper: selectFields 加 COALESCE(bp.name, u.user_name), LEFT JOIN biz_person (uk_person_user_id 防笛卡尔积)
- mapper: insert 补 7 字段 (plan_name/plan_direction/plan_category/project_form/design_file_url/is_settled/project_no), plan_name NOT NULL 缺默认
- SQL: 紧急迁移脚本 add submitter_id + idx + biz_person UNIQUE (ALTER, 不 DROP)
- SubmissionNew: page-card + breadcrumb + max-width 1200px, accept=.pdf/.png/.jpg/.jpeg, __silentError 防双 toast
- SubmissionNew: el-upload drag 模式 A (对齐 Meetings.vue, 删 design-uploader 自定义 CSS)
- SubmissionDetail: 删状态/投稿人/投稿时间/审计, 改 Preview 组件展示设计文件
This commit is contained in:
郭庆泰
2026-08-18 00:51:53 +08:00
parent b52a334184
commit 67be5345ad
4 changed files with 137 additions and 132 deletions
+19 -37
View File
@@ -39,8 +39,7 @@
<el-form-item label="设计文件">
<div class="readonly-cell">
<template v-if="detail.designFileUrl">
<el-link type="primary" :href="detail.designFileUrl" target="_blank">查看</el-link>
<el-link type="primary" style="margin-left: 12px" :href="detail.designFileUrl" :download="downloadName">下载</el-link>
<el-button link type="primary" @click="openPreview(detail.designFileUrl, detail.planName || '设计文件')">查看</el-button>
</template>
<span v-else>-</span>
</div>
@@ -55,25 +54,6 @@
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="8">
<el-form-item label="状态">
<audit-status-tag v-if="detail.status" :status="detail.status" />
<span v-else>-</span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="投稿人">
<el-input :model-value="display.submitterName" readonly />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="投稿时间">
<el-input :model-value="display.createTime" readonly />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
@@ -81,6 +61,9 @@
<div class="detail-actions">
<el-button @click="goBack">返回</el-button>
</div>
<!-- 附件预览 (图片/PDF 直接预览, 其他类型给下载链接) -->
<Preview v-model="previewOpen" :url="previewUrl" :title="previewTitle" />
</div>
</template>
@@ -89,7 +72,7 @@ import { ref, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import request from '@/utils/request'
import AuditStatusTag from '@/components/AuditStatusTag.vue'
import Preview from '@/components/Preview.vue'
const route = useRoute()
const router = useRouter()
@@ -97,42 +80,41 @@ const router = useRouter()
const loading = ref(false)
const detail = ref({})
// 显示用: 空值显示 "-", 时间格式化
const previewOpen = ref(false)
const previewUrl = ref('')
const previewTitle = ref('设计文件')
function openPreview(url, title) {
if (!url) { ElMessage.warning('暂无附件'); return }
previewUrl.value = url
previewTitle.value = title || '设计文件'
previewOpen.value = true
}
// 显示用: 空值显示 "-"
function fmt(v) {
if (v === null || v === undefined || v === '') return '-'
return v
}
function fmtTime(t) {
if (!t) return '-'
try { return new Date(t).toLocaleString('zh-CN', { hour12: false }) } catch { return t }
}
const display = computed(() => ({
planName: fmt(detail.value.planName),
planDirectionTitle: fmt(detail.value.planDirectionTitle || detail.value.planDirection),
projectForm: fmt(detail.value.projectForm),
planCategory: fmt(detail.value.planCategory),
remark: fmt(detail.value.remark),
submitterName: fmt(detail.value.submitterName),
createTime: fmtTime(detail.value.createTime)
remark: fmt(detail.value.remark)
}))
function goBack() {
router.push({ path: '/doctor/submissions', query: { _t: Date.now() } })
}
function downloadName() {
const url = detail.value.designFileUrl || ''
const last = url.split('/').pop()
return last || `submission-${detail.value.planId}`
}
async function load() {
const planId = route.params.planId
if (!planId) { ElMessage.warning('参数缺失'); goBack(); return }
loading.value = true
try {
const res = await request.get(`/business/projectPlan/${planId}`)
const res = await request.get(`/business/projectPlan/${planId}`, { __silentError: true })
if (res?.code === 200) {
detail.value = res.data || {}
} else {