refactor(doctor/submissions): 合并到 biz_project_plan + 删除 biz_submission 死代码
- /doctor/submissions 改走 biz_project_plan,与 /manager/plans 字段/组件/状态字典完全对齐 - BizProjectPlan 加 submitter_id (BIGINT) + submitter_name (LEFT JOIN 查询字段) - mapper 改 LEFT JOIN biz_person + sys_user,COALESCE(bp.name, u.user_name) 兜底 - biz_person.user_id 加 UNIQUE 索引 (1:1 LEFT JOIN 无笛卡尔积) - controller 加 doctor 角色自动过滤: list 按 submitter_id, add/edit 强制 submitter_id - 删除 7 个 BizSubmission 死代码 (Controller/Service/Mapper/Domain/XML/Enum) + 1 utils - 路由参数 :subId → :planId (路径名 submission 保留产品文案) - 新增 migration_submission_to_projectPlan_2026_08_18.sql
This commit is contained in:
@@ -10,19 +10,14 @@
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="策划方案名称" prop="title">
|
||||
<el-input v-model="form.title" placeholder="请输入策划方案名称" maxlength="200" show-word-limit />
|
||||
<el-form-item label="策划方案名称" prop="planName">
|
||||
<el-input v-model="form.planName" placeholder="请输入策划方案名称" maxlength="200" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目方向" prop="direction">
|
||||
<el-select v-model="form.direction" placeholder="请选择" style="width:100%">
|
||||
<el-option label="学术项目" value="学术项目" />
|
||||
<el-option label="科研项目" value="科研项目" />
|
||||
<el-option label="共识" value="共识" />
|
||||
<el-option label="指南" value="指南" />
|
||||
<el-option label="会议项目" value="会议项目" />
|
||||
<el-option label="对外交流" value="对外交流" />
|
||||
<el-form-item label="项目方向" prop="planDirectionId">
|
||||
<el-select v-model="form.planDirectionId" placeholder="请选择" style="width:100%">
|
||||
<el-option v-for="opt in planDirectionOptions" :key="opt.id" :label="opt.title" :value="opt.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -40,16 +35,8 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="项目类别" prop="projectCategory">
|
||||
<el-select v-model="form.projectCategory" placeholder="请选择" style="width:100%">
|
||||
<el-option label="学术会议类" value="学术会议类" />
|
||||
<el-option label="专项科研类" value="专项科研类" />
|
||||
<el-option label="调研征集类" value="调研征集类" />
|
||||
<el-option label="慈善帮扶类" value="慈善帮扶类" />
|
||||
<el-option label="标准制定类" value="标准制定类" />
|
||||
<el-option label="患者援助类" value="患者援助类" />
|
||||
<el-option label="专业培训类" value="专业培训类" />
|
||||
</el-select>
|
||||
<el-form-item label="项目类别" prop="planCategory">
|
||||
<dict-select v-model="form.planCategory" dict-type="biz_project_category" value-field="label" style="width:100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -69,7 +56,7 @@
|
||||
:on-remove="onDesignRemove"
|
||||
>
|
||||
<i class="el-icon-upload"></i>
|
||||
<div class="el-upload__text">将设计文件拖到此处,或<em>点击上传</em></div>
|
||||
<div class="el-upload__text">将设计文件拖到此处,或<em>点击上传</em></div>
|
||||
<div class="el-upload__tip" slot="tip">支持 PDF / Word / 图片, 单文件 ≤ 20MB</div>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
@@ -100,7 +87,9 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useUserStore } from '@/store/user'
|
||||
import request from '@/utils/request'
|
||||
import { bizAdd, bizUpdate } from '@/api/public'
|
||||
import { uploadToOss } from '@/utils/oss'
|
||||
import DictSelect from '@/components/DictSelect.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
@@ -111,24 +100,33 @@ const saving = ref(false)
|
||||
const loadingDetail = ref(false)
|
||||
const designFileList = ref([])
|
||||
const designUploading = ref(false)
|
||||
const isEdit = !!route.params.subId
|
||||
const isEdit = !!route.params.planId
|
||||
|
||||
// 项目方向 options (复用 manager 侧接口)
|
||||
const planDirectionOptions = ref([])
|
||||
async function loadPlanDirectionOptions() {
|
||||
try {
|
||||
const { data } = await request.get('/business/specialPlan/options')
|
||||
planDirectionOptions.value = (data && data.data) || data || []
|
||||
} catch { planDirectionOptions.value = [] }
|
||||
}
|
||||
|
||||
const form = reactive({
|
||||
subId: null,
|
||||
title: '',
|
||||
direction: '',
|
||||
planId: null,
|
||||
planName: '',
|
||||
planDirectionId: null,
|
||||
projectForm: '',
|
||||
projectCategory: '',
|
||||
planCategory: '',
|
||||
designFileUrl: '',
|
||||
status: 'DRAFT',
|
||||
status: '0',
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const rules = {
|
||||
title: [{ required: true, message: '请输入策划方案名称', trigger: 'blur' }],
|
||||
direction: [{ required: true, message: '请选择项目方向', trigger: 'change' }],
|
||||
planName: [{ required: true, message: '请输入策划方案名称', trigger: 'blur' }],
|
||||
planDirectionId: [{ required: true, message: '请选择项目方向', trigger: 'change' }],
|
||||
projectForm: [{ required: true, message: '请选择项目形式', trigger: 'change' }],
|
||||
projectCategory: [{ required: true, message: '请选择项目类别', trigger: 'change' }],
|
||||
planCategory: [{ required: true, message: '请选择项目类别', trigger: 'change' }],
|
||||
designFileUrl: [{ required: true, message: '请上传设计文件', trigger: 'change' }]
|
||||
}
|
||||
|
||||
@@ -151,7 +149,6 @@ async function uploadDesign(opts) {
|
||||
ElMessage.success('设计文件上传成功')
|
||||
} catch (e) {
|
||||
ElMessage.error('上传失败: ' + (e?.message || e))
|
||||
// 上传失败时清空 file-list,避免 el-upload 保留失败文件
|
||||
designFileList.value = []
|
||||
} finally {
|
||||
designUploading.value = false
|
||||
@@ -164,24 +161,23 @@ function onDesignRemove() {
|
||||
}
|
||||
|
||||
async function loadDetail() {
|
||||
const subId = route.params.subId
|
||||
if (!subId) return
|
||||
const planId = route.params.planId
|
||||
if (!planId) return
|
||||
loadingDetail.value = true
|
||||
try {
|
||||
const res = await request.get(`/business/submission/${subId}`)
|
||||
const res = await request.get(`/business/projectPlan/${planId}`)
|
||||
if (res?.code === 200 && res.data) {
|
||||
const d = res.data
|
||||
form.subId = d.subId
|
||||
form.title = d.title || ''
|
||||
form.direction = d.direction || ''
|
||||
form.planId = d.planId
|
||||
form.planName = d.planName || ''
|
||||
form.planDirectionId = d.planDirectionId ?? null
|
||||
form.projectForm = d.projectForm || ''
|
||||
form.projectCategory = d.projectCategory || ''
|
||||
form.planCategory = d.planCategory || ''
|
||||
form.designFileUrl = d.designFileUrl || ''
|
||||
form.status = d.status && String(d.status).trim() ? String(d.status).trim().toUpperCase() : 'DRAFT'
|
||||
form.status = d.status && String(d.status).trim() ? String(d.status) : '0'
|
||||
form.remark = d.remark || ''
|
||||
// 已上传的设计文件回显到 file-list
|
||||
if (d.designFileUrl) {
|
||||
const name = d.designFileUrl.split('/').pop() || `${d.title || '设计文件'}.pdf`
|
||||
const name = d.designFileUrl.split('/').pop() || `${d.planName || '设计文件'}.pdf`
|
||||
designFileList.value = [{ name, url: d.designFileUrl }]
|
||||
}
|
||||
} else {
|
||||
@@ -202,8 +198,7 @@ function goBack() {
|
||||
}
|
||||
|
||||
function confirmCancel() {
|
||||
// 检查表单是否有内容
|
||||
const hasContent = form.title || form.direction || form.projectForm || form.projectCategory || form.designFileUrl || form.remark
|
||||
const hasContent = form.planName || form.planDirectionId || form.projectForm || form.planCategory || form.designFileUrl || form.remark
|
||||
if (!hasContent) { goBack(); return }
|
||||
ElMessageBox.confirm('确定取消新建?未保存的内容将丢失', '提示', { type: 'warning' })
|
||||
.then(() => goBack())
|
||||
@@ -221,29 +216,19 @@ async function onSave() {
|
||||
try {
|
||||
let payload = { ...form }
|
||||
if (!isEdit) {
|
||||
// 新建: 强制设为 DRAFT(待提交)
|
||||
payload.status = 'DRAFT'
|
||||
// 写入当前登录用户信息
|
||||
// 新建: 强制 status='0' (未提交), submitter 后端兜底
|
||||
payload.status = '0'
|
||||
payload.submitterId = userStore.user?.userId || null
|
||||
payload.submitterName = userStore.user?.userName || userStore.user?.nickName || ''
|
||||
} else if (!payload.status) {
|
||||
// 修改: 如果状态丢失, 兜底 DRAFT(待提交)
|
||||
payload.status = 'DRAFT'
|
||||
payload.status = '0'
|
||||
}
|
||||
let res
|
||||
if (isEdit) {
|
||||
// 修改: 走 PUT /business/submission
|
||||
res = await request.put('/business/submission', payload)
|
||||
await bizUpdate('projectPlan', payload)
|
||||
} else {
|
||||
// 新建: 走 POST /business/submission
|
||||
res = await request.post('/business/submission', payload)
|
||||
}
|
||||
if (res?.code === 200) {
|
||||
ElMessage.success(isEdit ? '修改成功' : '新建成功')
|
||||
goBack()
|
||||
} else {
|
||||
ElMessage.error(res?.msg || (isEdit ? '修改失败' : '保存失败'))
|
||||
await bizAdd('projectPlan', payload)
|
||||
}
|
||||
ElMessage.success(isEdit ? '修改成功' : '新建成功')
|
||||
goBack()
|
||||
} catch (e) {
|
||||
console.error('[submission-new] save failed', e)
|
||||
ElMessage.error(e?.msg || (isEdit ? '修改失败' : '保存失败'))
|
||||
@@ -253,6 +238,7 @@ async function onSave() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadPlanDirectionOptions()
|
||||
if (isEdit) loadDetail()
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user