fix(meetings): 还原 MeetingNew.vue 到 a081da8 模板结构 (左6+右5, 无项目形式/总期数), 保留 3 模式逻辑

This commit is contained in:
郭庆泰
2026-08-18 23:45:08 +08:00
parent ba34f04432
commit 8fd7eaeb5a
+36 -53
View File
@@ -5,9 +5,9 @@
<!-- el-form 包裹 + label-width 110px (跟原型一致) --> <!-- el-form 包裹 + label-width 110px (跟原型一致) -->
<el-form ref="formRef" :model="form" :rules="rules" label-width="110px"> <el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
<!-- 2 列布局 (跟原型 .form-grid 一致: grid-auto-flow: column 让左 6 7 对齐) --> <!-- 2 列布局 (跟原型 .form-grid 一致: grid-auto-flow: column 让左 6 5 对齐) -->
<div class="form-grid"> <div class="form-grid">
<!-- 左列 6 项只读快照 (来自 biz_project 派生, 来自 meeting.projectId) --> <!-- 左列 6 项只读快照 (来自 biz_project 派生) -->
<el-form-item label="项目编号"> <el-form-item label="项目编号">
<span class="form-value code">{{ snap.projectNo }}</span> <span class="form-value code">{{ snap.projectNo }}</span>
</el-form-item> </el-form-item>
@@ -27,23 +27,12 @@
<span class="form-value">{{ snap.createUserName }}</span> <span class="form-value">{{ snap.createUserName }}</span>
</el-form-item> </el-form-item>
<!-- 右列 6 可编辑 + 备注 (跨双列): 会议名称/项目形式/期数/总期数/开始/结束/备注 --> <!-- 右列 5 : 1 只读 (会议名称 = 项目名) + 4 输入 -->
<el-form-item label="会议名称" prop="meetingName"> <el-form-item label="会议名称">
<el-input v-model="form.meetingName" placeholder="请输入会议名称" /> <span class="form-value">{{ form.meetingName }}</span>
</el-form-item>
<el-form-item label="项目形式" prop="projectForm">
<el-select v-model="form.projectForm" placeholder="请选择项目形式" style="width:100%">
<el-option label="线上" value="线上" />
<el-option label="线下" value="线下" />
<el-option label="线上+线下" value="线上+线下" />
<el-option label="其他" value="其他" />
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="期数" prop="periodNo"> <el-form-item label="期数" prop="periodNo">
<el-input-number v-model="form.periodNo" :min="1" :precision="0" placeholder="请填写第几期" /> <el-input v-model="form.periodNo" placeholder="请填写第几期" />
</el-form-item>
<el-form-item label="总期数" prop="totalPeriods">
<el-input-number v-model="form.totalPeriods" :min="1" :precision="0" />
</el-form-item> </el-form-item>
<el-form-item label="会议开始时间" prop="startTime"> <el-form-item label="会议开始时间" prop="startTime">
<el-date-picker v-model="form.startTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择开始时间" /> <el-date-picker v-model="form.startTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择开始时间" />
@@ -51,8 +40,8 @@
<el-form-item label="会议结束时间" prop="endTime"> <el-form-item label="会议结束时间" prop="endTime">
<el-date-picker v-model="form.endTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择结束时间" /> <el-date-picker v-model="form.endTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择结束时间" />
</el-form-item> </el-form-item>
<el-form-item label="备注" class="full-row" prop="remark"> <el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" /> <el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item> </el-form-item>
</div> </div>
@@ -81,7 +70,7 @@ const router = useRouter()
// copy: ?meetingId=xxx&mode=copy → POST /business/meeting (复制) // copy: ?meetingId=xxx&mode=copy → POST /business/meeting (复制)
// 修改/复制 URL 同时带 projectId 让左列快照能立即加载 (不必先等 bizGet meeting) // 修改/复制 URL 同时带 projectId 让左列快照能立即加载 (不必先等 bizGet meeting)
const meetingId = route.query.meetingId || '' const meetingId = route.query.meetingId || ''
const urlProjectId = route.query.projectId || '' // URL 直接带的 projectId const urlProjectId = route.query.projectId || ''
const mode = computed(() => { const mode = computed(() => {
if (meetingId && route.query.mode === 'copy') return 'copy' if (meetingId && route.query.mode === 'copy') return 'copy'
if (meetingId) return 'edit' if (meetingId) return 'edit'
@@ -102,27 +91,22 @@ const snap = reactive({
createUserName: '' createUserName: ''
}) })
// ========== 表单 (右列 6 项可编辑 + 备注 1 项, 顺序跟 template 对齐) ========== // ========== 表单 (右列 5 项: meetingName 只读 + 4 输入) ==========
const form = reactive({ const form = reactive({
projectId: null, projectId: urlProjectId ? Number(urlProjectId) : null,
projectNo: '', projectNo: '',
projectName: '', projectName: '',
meetingName: '', // 1. 会议名称 meetingName: '',
projectForm: '', // 2. 项目形式 periodNo: '',
periodNo: 1, // 3. 期数 startTime: '',
totalPeriods: 1, // 4. 总期数 endTime: '',
startTime: '', // 5. 会议开始时间 remark: ''
endTime: '', // 6. 会议结束时间
remark: '' // 7. 备注 (跨双列)
}) })
const rules = { const rules = {
meetingName: [{ required: true, message: '请输入会议名称', trigger: 'blur' }],
periodNo: [{ required: true, message: '请填写第几期', trigger: 'blur' }], periodNo: [{ required: true, message: '请填写第几期', trigger: 'blur' }],
projectForm: [{ required: true, message: '请选择项目形式', trigger: 'change' }],
startTime: [{ required: true, message: '请选择会议开始时间', trigger: 'change' }], startTime: [{ required: true, message: '请选择会议开始时间', trigger: 'change' }],
endTime: [{ required: true, message: '请选择会议结束时间', trigger: 'change' }], endTime: [{ required: true, message: '请选择会议结束时间', trigger: 'change' }]
totalPeriods: [{ required: true, message: '请填写总期数', trigger: 'blur' }]
} }
// ========== 加载项目快照 ========== // ========== 加载项目快照 ==========
@@ -150,17 +134,14 @@ async function loadMeeting(mid) {
form.projectNo = d.projectNo || '' form.projectNo = d.projectNo || ''
form.projectName = d.projectName || '' form.projectName = d.projectName || ''
form.meetingName = d.meetingName || '' form.meetingName = d.meetingName || ''
form.periodNo = d.periodNo || 1 form.periodNo = d.periodNo || ''
form.projectForm = d.projectForm || ''
form.startTime = d.startTime || '' form.startTime = d.startTime || ''
form.endTime = d.endTime || '' form.endTime = d.endTime || ''
form.totalPeriods = d.totalPeriods || 1
form.remark = d.remark || '' form.remark = d.remark || ''
// 左列快照 projectNo/projectName 用 meeting 冗余字段 (即使 project_id 为 NULL 也能显示) // 左列快照 projectNo/projectName 用 meeting 冗余字段 (即使 project_id 为 NULL 也能显示)
snap.projectNo = d.projectNo || '' snap.projectNo = d.projectNo || ''
snap.projectName = d.projectName || '' snap.projectName = d.projectName || ''
// 总场次/支持单位/创建时间/创建人员 优先用 URL projectId, 其次 meeting.projectId // 总场次/支持单位/创建时间/创建人员 优先用 URL projectId, 其次 meeting.projectId
// (URL 带的 projectId 优先, 避免 copy 模式下 user 没传导致再读 meeting)
const pid = urlProjectId || d.projectId const pid = urlProjectId || d.projectId
if (pid) { if (pid) {
await loadProjectSnapshot(pid) await loadProjectSnapshot(pid)
@@ -172,17 +153,26 @@ async function onSave() {
try { await formRef.value.validate() } catch (e) { return } try { await formRef.value.validate() } catch (e) { return }
submitting.value = true submitting.value = true
try { try {
const payload = { ...form } const payload = {
projectId: form.projectId,
projectNo: form.projectNo,
projectName: form.projectName,
meetingName: form.meetingName,
periodNo: form.periodNo,
startTime: form.startTime,
endTime: form.endTime,
remark: form.remark
}
if (mode.value === 'edit') { if (mode.value === 'edit') {
// 修改: 走 bizUpdate, 带 meetingId (后端 WHERE 用, 不能 delete) // 修改: 走 bizUpdate, 带 meetingId (后端 WHERE 用, 不能 delete)
payload.meetingId = form.meetingId
// __silentError: 拦截器不自动 toast, 错误统一由下方 catch 处理 (避免双 toast) // __silentError: 拦截器不自动 toast, 错误统一由下方 catch 处理 (避免双 toast)
await bizUpdate('meeting', payload, { __silentError: true }) await bizUpdate('meeting', payload, { __silentError: true })
ElMessage.success('修改成功') ElMessage.success('修改成功')
} else { } else {
// 新建 / 复制: 走 bizAdd, 不传 meetingId (AUTO_INCREMENT) // 新建 / 复制: 走 bizAdd
delete payload.meetingId
await bizAdd('meeting', payload, { __silentError: true }) await bizAdd('meeting', payload, { __silentError: true })
ElMessage.success(mode.value === 'copy' ? '复制成功' : '创建成功') ElMessage.success(mode.value === 'copy' ? '复制成功' : '会议创建成功')
} }
goBack() goBack()
} catch (e) { } catch (e) {
@@ -193,27 +183,24 @@ async function onSave() {
} }
function goBack() { function goBack() {
// 跳回列表 (用 name 而非 path, hash 模式 + 路由可复用) // 跳回列表
router.push({ name: 'manager-meetings' }) router.push({ name: 'manager-meetings' })
} }
onMounted(async () => { onMounted(async () => {
if (mode.value === 'edit') { if (mode.value === 'edit') {
// 修改: 加载会议详情 (左列项目快照由 meeting.projectId 派生)
await loadMeeting(meetingId) await loadMeeting(meetingId)
} else if (mode.value === 'copy') { } else if (mode.value === 'copy') {
// 复制: 加载会议详情, name 加 " 副本", periodNo reset 为 1 (用户填) // 复制: 加载会议详情, name 加 " 副本"
await loadMeeting(meetingId) await loadMeeting(meetingId)
form.meetingName = (form.meetingName || '') + ' 副本' form.meetingName = (form.meetingName || '') + ' 副本'
form.periodNo = 1 // 复制后让用户重新填期数
} else { } else {
// 新建: 加载项目快照, meetingName 默认 = 项目名 // 新建: 加载项目快照, meetingName 默认 = 项目名
if (urlProjectId) { if (urlProjectId) {
form.projectId = Number(urlProjectId) || null
await loadProjectSnapshot(urlProjectId) await loadProjectSnapshot(urlProjectId)
form.projectNo = snap.projectNo form.projectNo = snap.projectNo
form.projectName = snap.projectName form.projectName = snap.projectName
form.meetingName = snap.projectName // 默认会议名 = 项目名 form.meetingName = snap.projectName
} }
} }
}) })
@@ -233,12 +220,12 @@ onMounted(async () => {
margin-bottom: 24px; margin-bottom: 24px;
} }
/* === 2 列布局 (跟原型 .form-grid 一致, grid-auto-flow: column 让左 6 右 6 + 备注 1 项, 共 7 行) === */ /* === 2 列布局 (跟原型 .form-grid 一致, grid-auto-flow: column 让左 6 右 5 对齐) === */
.form-grid { .form-grid {
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
grid-auto-flow: column; grid-auto-flow: column;
grid-template-rows: repeat(7, auto); grid-template-rows: repeat(6, auto);
gap: 20px 32px; gap: 20px 32px;
max-width: 900px; max-width: 900px;
} }
@@ -246,10 +233,6 @@ onMounted(async () => {
.form-grid :deep(.el-form-item) { .form-grid :deep(.el-form-item) {
margin-bottom: 0; margin-bottom: 0;
} }
/* 备注占满整行 (跨双列), 放在 form 末尾, 视觉上独占一行 */
.form-grid :deep(.full-row) {
grid-column: 1 / -1;
}
/* 只读值样式 */ /* 只读值样式 */
.form-value { .form-value {