refactor: 合并 biz_support_unit/biz_execution_unit/biz_service_org 为 biz_org, 删除 2 张孤儿表, 改 biz_person.work_unit → org_id FK
主要改动: - SQL: biz_support_unit → biz_org, 加 org_type, 加 business_nature; 删 biz_execution_unit, biz_service_org - SQL: biz_project.support_unit_id/name + service_org_id/name → org_id/name/type - SQL: biz_meeting.support_unit_name → org_name - SQL: biz_person.work_unit → org_id (FK) - 后端: 新 BizOrg entity/mapper/service/controller - 后端: BizProject/BizMeeting 字段重命名 - 后端: 删 12 个 BizSupportUnit/BizExecutionUnit/BizServiceOrg Java 文件 - 后端: BizPersonImportVO.workUnit → orgName (导入时查 biz_org 取 org_id) - 后端: BizAuthController.registerExecutor 完整实现 (原 registerSupplier stub) - 前端: 新 admin/Orgs.vue + manager/Orgs.vue (原 SupportUnits) - 前端: RegisterExecutor.vue (原 RegisterSupplier, 单页 2 步) - 前端: sponsor/executor/manager 多个文件 workUnit → orgId/orgName 重命名 - 前端: 统一 supplier → executor, 业务命名 sponsor(赞助方) / executor(执行方=供应商) - 前端: 全工程 execution → executor (company type / role / person unit_type)
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div class="submission-detail">
|
||||
<!-- 面包屑 (与 SubmissionNew 一致) -->
|
||||
<div class="breadcrumb">
|
||||
<a @click="goBack">我的项目设计投稿</a> > 投稿详情
|
||||
</div>
|
||||
|
||||
<!-- 表单卡片 (与 SubmissionNew 同款) -->
|
||||
<el-card v-loading="loading" shadow="never" class="detail-card">
|
||||
<el-form label-width="120px" class="readonly-form">
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="策划方案名称">
|
||||
<el-input :model-value="display.title" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目方向">
|
||||
<el-input :model-value="display.direction" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目形式">
|
||||
<el-input :model-value="display.projectForm" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目类别">
|
||||
<el-input :model-value="display.projectCategory" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="24">
|
||||
<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>
|
||||
</template>
|
||||
<span v-else>-</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<el-input :model-value="display.remark" type="textarea" :rows="4" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态">
|
||||
<el-tag v-if="detail.status !== null && detail.status !== undefined && detail.status !== ''" :type="statusType(detail.status)" disable-transitions>
|
||||
{{ statusLabel(detail.status) }}
|
||||
</el-tag>
|
||||
<span v-else>-</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="投稿时间">
|
||||
<el-input :model-value="display.createTime" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 操作按钮 (与 SubmissionNew 同位置同样式) -->
|
||||
<div class="detail-actions">
|
||||
<el-button @click="goBack">返回</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import request from '@/utils/request'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const loading = ref(false)
|
||||
const detail = ref({})
|
||||
|
||||
// 显示用: 空值显示 "-", 时间格式化
|
||||
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 }
|
||||
}
|
||||
|
||||
// 状态 → el-tag 类型映射
|
||||
const STATUS_TYPE_MAP = {
|
||||
'待审核': 'warning',
|
||||
'审核通过': 'success',
|
||||
'已退回': 'danger',
|
||||
'未结题': 'info',
|
||||
'已结题': 'success'
|
||||
}
|
||||
function statusType(s) {
|
||||
return STATUS_TYPE_MAP[s] || 'info'
|
||||
}
|
||||
const display = computed(() => ({
|
||||
title: fmt(detail.value.title),
|
||||
direction: fmt(detail.value.direction),
|
||||
projectForm: fmt(detail.value.projectForm),
|
||||
projectCategory: fmt(detail.value.projectCategory),
|
||||
remark: fmt(detail.value.remark),
|
||||
status: fmt(detail.value.status),
|
||||
createTime: fmtTime(detail.value.createTime)
|
||||
}))
|
||||
|
||||
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.subId}`
|
||||
}
|
||||
|
||||
async function load() {
|
||||
const subId = route.params.subId
|
||||
if (!subId) { ElMessage.warning('参数缺失'); goBack(); return }
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await request.get(`/business/submission/${subId}`)
|
||||
if (res?.code === 200) {
|
||||
detail.value = res.data || {}
|
||||
} else {
|
||||
ElMessage.error(res?.msg || '加载失败')
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[submission-detail] load failed', e)
|
||||
ElMessage.error(e?.msg || '加载失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.submission-detail { max-width: 1000px; }
|
||||
.breadcrumb { font-size: 13px; color: #8c8c8c; margin-bottom: 16px; }
|
||||
.breadcrumb a { color: var(--brand-primary); cursor: pointer; text-decoration: none; }
|
||||
.breadcrumb a:hover { color: var(--brand-primary-deep, var(--brand-primary)); }
|
||||
|
||||
.detail-card { border-radius: 6px; }
|
||||
.detail-card :deep(.el-card__body) { padding: 24px 28px; }
|
||||
|
||||
/* 只读表单样式 - 模拟 el-input 视觉, 但只显示文字 */
|
||||
.readonly-form :deep(.el-form-item) { margin-bottom: 22px; }
|
||||
.readonly-form :deep(.el-form-item__label) { color: #606266; font-weight: normal; }
|
||||
|
||||
.readonly-cell {
|
||||
min-height: 40px;
|
||||
line-height: 38px;
|
||||
padding: 0 14px;
|
||||
background: #fafafa;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 4px;
|
||||
color: #262626;
|
||||
font-size: 14px;
|
||||
word-break: break-all;
|
||||
}
|
||||
.remark-cell {
|
||||
min-height: 110px;
|
||||
line-height: 1.6;
|
||||
padding: 12px 14px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.readonly-form :deep(.el-link) { font-weight: 500; }
|
||||
|
||||
.detail-actions { margin-top: 16px; }
|
||||
:deep(.el-button) { border-radius: 4px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user