Files
guoju0808/ry-vue3/src/views/manager/MeetingNew.vue
T
郭庆泰andClaude 5b4008d24a style(meeting-new): 对齐 manager/MeetingNew.vue 到项目统一风格
- 替换 #1890ff / #169bd5 硬编码蓝 → var(--brand-primary) / var(--brand-primary-deep)
- 单 page-card 包裹 + max-width: 1200px (form 页 skill 标准)
- 面包屑 改 首页 / 会议管理 / 新建会议 (skill 标准, 原型 项目列表 / 新建会议)
- 删 h1 新建会议 大标题 (skill 禁忌)
- 红字提示包到 .hint-text (skill .hint-list 风格, 12px #ff4d4f + #fff bg + #f0f0f0 border)
- form-label 110px → 120px (skill label-width 标准)
- 保留 6+5 form-row 布局 (跟原型 1:1)
- 保留 768px 响应式

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-18 22:41:04 +08:00

296 lines
8.0 KiB
Vue

<template>
<div class="page-card manager-meeting-new">
<!-- 面包屑 (skill: 首页 / 分类 / 当前页) -->
<div class="breadcrumb">首页 / 会议管理 / 新建会议</div>
<!-- 红字提示 (业务规则, 跟原型一致) -->
<p class="hint-text">*会议名称默认为项目名称,不可修改</p>
<div class="card">
<div class="form-grid">
<!-- 左列 (原型 6 项只读值) -->
<div class="form-row">
<span class="form-label">项目编号</span>
<span class="form-value code">{{ snap.projectNo }}</span>
</div>
<div class="form-row">
<span class="form-label">项目名称</span>
<span class="form-value">{{ snap.projectName }}</span>
</div>
<div class="form-row">
<span class="form-label">总场次/总期数</span>
<span class="form-value">{{ snap.totalSessions }}</span>
</div>
<div class="form-row">
<span class="form-label">支持单位</span>
<span class="form-value">{{ snap.sponsorOrgName }}</span>
</div>
<div class="form-row">
<span class="form-label">创建时间</span>
<span class="form-value">{{ snap.createTime }}</span>
</div>
<div class="form-row">
<span class="form-label">创建人员</span>
<span class="form-value">{{ snap.createBy }}</span>
</div>
<!-- 右列 (原型 5 : 1 只读 + 4 输入) -->
<div class="form-row">
<span class="form-label">会议名称</span>
<span class="form-value">{{ form.meetingName }}</span>
</div>
<div class="form-row">
<span class="form-label">期数</span>
<input type="text" class="form-input" v-model="form.periodNo" placeholder="请输入期数" />
</div>
<div class="form-row">
<span class="form-label">会议开始时间</span>
<el-date-picker
v-model="form.startTime"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择开始时间"
class="form-input-picker"
/>
</div>
<div class="form-row">
<span class="form-label">会议结束时间</span>
<el-date-picker
v-model="form.endTime"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择结束时间"
class="form-input-picker"
/>
</div>
<div class="form-row">
<span class="form-label">备注</span>
<input type="text" class="form-input" v-model="form.remark" placeholder="请输入备注" />
</div>
</div>
<!-- 底部按钮 -->
<div class="form-actions">
<button type="button" class="btn btn-primary" @click="onSave">保存</button>
<button type="button" class="btn btn-default" @click="goBack">取消</button>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { bizAdd, bizGet } from '@/api/public'
import { ElMessage } from 'element-plus'
const route = useRoute()
const router = useRouter()
const preselectProjectId = route.query.projectId || ''
// 项目只读快照 (左列 6 项 + 右列"会议名称"默认)
const snap = reactive({
projectNo: '',
projectName: '',
totalSessions: '',
sponsorOrgName: '',
createTime: '',
createBy: ''
})
// 表单 (右列 5 项: meetingName 只读 + periodNo/startTime/endTime/remark 输入)
const form = reactive({
projectId: preselectProjectId ? Number(preselectProjectId) : null, // 提交时拼到 body
projectNo: '',
projectName: '',
meetingName: '',
periodNo: '',
startTime: '',
endTime: '',
remark: ''
})
async function onSave() {
if (!form.periodNo) { ElMessage.warning('请输入期数'); return }
if (!form.startTime) { ElMessage.warning('请选择会议开始时间'); return }
if (!form.endTime) { ElMessage.warning('请选择会议结束时间'); return }
try {
await bizAdd('meeting', {
projectId: form.projectId,
projectNo: form.projectNo,
projectName: form.projectName,
meetingName: form.meetingName,
periodNo: form.periodNo,
startTime: form.startTime,
endTime: form.endTime,
remark: form.remark
})
ElMessage.success('会议创建成功')
goBack()
} catch (e) {
ElMessage.error(e?.msg || '保存失败')
}
}
function goBack() { router.push('/manager/projects') }
onMounted(async () => {
if (!preselectProjectId) return
try {
const r = await bizGet('project', preselectProjectId)
const d = (r && r.data) || {}
// 6 项只读快照 (左列)
snap.projectNo = d.projectNo || ''
snap.projectName = d.projectName || ''
snap.totalSessions = d.totalSessions ?? ''
snap.sponsorOrgName = d.sponsorOrgName || ''
snap.createTime = d.createTime || ''
snap.createBy = d.createBy || ''
// 会议名称默认 = 项目名称 (跟原型 §#3 红字一致)
form.projectNo = d.projectNo || ''
form.projectName = d.projectName || ''
form.meetingName = d.projectName || ''
} catch (e) {}
})
</script>
<style scoped>
/* === 整页面板 (skill 标准: 单 page-card, form 页 max-width 1200px) === */
.manager-meeting-new {
max-width: 1200px;
margin: 0 auto;
padding: 16px;
}
.breadcrumb {
font-size: 13px;
color: #8c8c8c;
margin-bottom: 12px;
}
/* 红字提示 (skill: 业务规则, 用 .hint-text) */
.hint-text {
background: #fff;
border: 1px solid #f0f0f0;
border-radius: 8px;
padding: 12px 20px;
margin-bottom: 16px;
font-size: 12px;
color: #ff4d4f;
line-height: 1.8;
}
/* 表单容器 (跟原型 .card 一致, 不是嵌套 page-card) */
.card {
background: #fff;
border-radius: 8px;
padding: 32px 40px;
border: 1px solid #f0f0f0;
}
/* 2 列布局 (跟原型 .form-grid 一致, grid-auto-flow: column 让左 6 右 5 对齐) */
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-flow: column;
grid-template-rows: repeat(6, auto);
gap: 20px 32px;
max-width: 900px;
}
.form-row {
display: flex;
align-items: center;
}
/* skill 标准: label-width 120px */
.form-label {
flex: 0 0 120px;
font-size: 14px;
color: #595959;
text-align: right;
padding-right: 16px;
white-space: nowrap;
}
.form-input {
flex: 1;
min-width: 0;
height: 32px;
padding: 0 12px;
border: 1px solid #d9d9d9;
border-radius: 4px;
font-size: 13px;
color: #333;
background: #fff;
outline: none;
transition: all 0.2s;
}
.form-input:focus {
border-color: var(--brand-primary);
box-shadow: 0 0 0 3px rgba(30, 58, 138, 0.1);
}
/* el-date-picker 撑满 flex:1 (跟 .form-input 同宽) */
.form-input-picker { flex: 1; min-width: 0; }
.form-input-picker :deep(.el-input__inner) {
height: 32px;
border-radius: 4px;
}
.form-value {
flex: 1;
font-size: 14px;
color: #1a1a1a;
line-height: 32px;
}
.form-value.code {
font-family: ui-monospace, "Courier New", monospace;
color: var(--brand-primary);
}
/* 按钮区 (跟原型一致, 用 .btn 自定义风格, 主色改用 var(--brand-primary)) */
.form-actions {
display: flex;
gap: 12px;
justify-content: flex-start;
margin-top: 32px;
padding-top: 24px;
border-top: 1px solid #f0f0f0;
}
.btn {
height: 40px;
padding: 0 32px;
border-radius: 5px;
font-size: 14px;
cursor: pointer;
min-width: 140px;
transition: all 0.2s;
border: 1px solid transparent;
}
.btn-primary {
background: var(--brand-primary);
color: #fff;
border-color: var(--brand-primary);
}
.btn-primary:hover {
background: var(--brand-primary-deep);
border-color: var(--brand-primary-deep);
}
.btn-default {
background: #fff;
color: #333;
border-color: #797979;
}
.btn-default:hover {
border-color: var(--brand-primary);
color: var(--brand-primary);
}
@media (max-width: 768px) {
.manager-meeting-new { padding: 16px; }
.card { padding: 16px; }
.form-grid { grid-template-columns: 1fr; grid-auto-flow: row; }
.form-actions { flex-direction: column; }
.btn { width: 100%; }
}
</style>