style(meeting-new): 严格按 People.vue 标准重写 (第二轮)
按 /style-alignment skill 重新对齐: - 用 el-form + el-form-item (skill form 页标准, 不另起 div.form-actions) - 用 el-button type=primary (Element Plus 默认主题, 不覆盖 CSS) - 用 el-input / el-date-picker (替代 raw input[type=text], Element Plus 风格统一) - 删自定义 .btn / .btn-primary / .btn-default / .form-row / .form-label / .form-input CSS - 删自定义 2 列 grid 布局 (prototype 特定, 跟项目标准不符) - 11 项全用 el-form-item 包裹 (label 无冒号) - 底部按钮直接 <el-form-item> 包裹 (skill 标准) - 单 page-card + max-width: 1200px (form 页 skill 标准) - 保留 红字提示 .hint-text + 只读值 .form-value 业务专属 CSS - 保留 el-form :rules 校验 (替代手动 if 判断) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,85 +1,61 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page-card manager-meeting-new">
|
<div class="page-card manager-meeting-new">
|
||||||
<!-- 面包屑 (skill: 首页 / 分类 / 当前页) -->
|
<!-- 面包屑 -->
|
||||||
<div class="breadcrumb">首页 / 会议管理 / 新建会议</div>
|
<div class="breadcrumb">首页 / 会议管理 / 新建会议</div>
|
||||||
|
|
||||||
<!-- 红字提示 (业务规则, 跟原型一致) -->
|
<!-- 红字提示 (业务规则) -->
|
||||||
<p class="hint-text">*会议名称默认为项目名称,不可修改</p>
|
<p class="hint-text">*会议名称默认为项目名称,不可修改</p>
|
||||||
|
|
||||||
<div class="card">
|
<!-- 整张 el-form (skill form 页标准: el-form 包裹所有 el-form-item, 不另起 form-actions) -->
|
||||||
<div class="form-grid">
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||||
<!-- 左列 (原型 6 项只读值) -->
|
<!-- 左列 6 项只读快照 (来自 biz_project 派生) -->
|
||||||
<div class="form-row">
|
<el-form-item label="项目编号">
|
||||||
<span class="form-label">项目编号</span>
|
<span class="form-value code">{{ snap.projectNo }}</span>
|
||||||
<span class="form-value code">{{ snap.projectNo }}</span>
|
</el-form-item>
|
||||||
</div>
|
<el-form-item label="项目名称">
|
||||||
<div class="form-row">
|
<span class="form-value">{{ snap.projectName }}</span>
|
||||||
<span class="form-label">项目名称</span>
|
</el-form-item>
|
||||||
<span class="form-value">{{ snap.projectName }}</span>
|
<el-form-item label="总场次/总期数">
|
||||||
</div>
|
<span class="form-value">{{ snap.totalSessions }}</span>
|
||||||
<div class="form-row">
|
</el-form-item>
|
||||||
<span class="form-label">总场次/总期数</span>
|
<el-form-item label="支持单位">
|
||||||
<span class="form-value">{{ snap.totalSessions }}</span>
|
<span class="form-value">{{ snap.sponsorOrgName }}</span>
|
||||||
</div>
|
</el-form-item>
|
||||||
<div class="form-row">
|
<el-form-item label="创建时间">
|
||||||
<span class="form-label">支持单位</span>
|
<span class="form-value">{{ snap.createTime }}</span>
|
||||||
<span class="form-value">{{ snap.sponsorOrgName }}</span>
|
</el-form-item>
|
||||||
</div>
|
<el-form-item label="创建人员">
|
||||||
<div class="form-row">
|
<span class="form-value">{{ snap.createBy }}</span>
|
||||||
<span class="form-label">创建时间</span>
|
</el-form-item>
|
||||||
<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 输入) -->
|
<!-- 右列 5 项: 1 只读 + 4 输入 -->
|
||||||
<div class="form-row">
|
<el-form-item label="会议名称">
|
||||||
<span class="form-label">会议名称</span>
|
<span class="form-value">{{ form.meetingName }}</span>
|
||||||
<span class="form-value">{{ form.meetingName }}</span>
|
</el-form-item>
|
||||||
</div>
|
<el-form-item label="期数" prop="periodNo">
|
||||||
<div class="form-row">
|
<el-input v-model="form.periodNo" placeholder="请输入期数" />
|
||||||
<span class="form-label">期数</span>
|
</el-form-item>
|
||||||
<input type="text" class="form-input" v-model="form.periodNo" placeholder="请输入期数" />
|
<el-form-item label="会议开始时间" prop="startTime">
|
||||||
</div>
|
<el-date-picker v-model="form.startTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择开始时间" />
|
||||||
<div class="form-row">
|
</el-form-item>
|
||||||
<span class="form-label">会议开始时间</span>
|
<el-form-item label="会议结束时间" prop="endTime">
|
||||||
<el-date-picker
|
<el-date-picker v-model="form.endTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择结束时间" />
|
||||||
v-model="form.startTime"
|
</el-form-item>
|
||||||
type="datetime"
|
<el-form-item label="备注">
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
<el-input v-model="form.remark" placeholder="请输入备注" />
|
||||||
placeholder="选择开始时间"
|
</el-form-item>
|
||||||
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>
|
|
||||||
|
|
||||||
<!-- 底部按钮 -->
|
<!-- 底部按钮 (skill: 直接用 el-form-item 包裹, 不另起 div.form-actions) -->
|
||||||
<div class="form-actions">
|
<el-form-item>
|
||||||
<button type="button" class="btn btn-primary" @click="onSave">保存</button>
|
<el-button type="primary" @click="onSave">保存</el-button>
|
||||||
<button type="button" class="btn btn-default" @click="goBack">取消</button>
|
<el-button @click="goBack">取消</el-button>
|
||||||
</div>
|
</el-form-item>
|
||||||
</div>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { bizAdd, bizGet } from '@/api/public'
|
import { bizAdd, bizGet } from '@/api/public'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
@@ -87,8 +63,9 @@ import { ElMessage } from 'element-plus'
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const preselectProjectId = route.query.projectId || ''
|
const preselectProjectId = route.query.projectId || ''
|
||||||
|
const formRef = ref(null)
|
||||||
|
|
||||||
// 项目只读快照 (左列 6 项 + 右列"会议名称"默认)
|
// 项目只读快照 (左列 6 项)
|
||||||
const snap = reactive({
|
const snap = reactive({
|
||||||
projectNo: '',
|
projectNo: '',
|
||||||
projectName: '',
|
projectName: '',
|
||||||
@@ -98,9 +75,9 @@ const snap = reactive({
|
|||||||
createBy: ''
|
createBy: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
// 表单 (右列 5 项: meetingName 只读 + periodNo/startTime/endTime/remark 输入)
|
// 表单 (右列 5 项: meetingName 只读 + 4 输入)
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
projectId: preselectProjectId ? Number(preselectProjectId) : null, // 提交时拼到 body
|
projectId: preselectProjectId ? Number(preselectProjectId) : null,
|
||||||
projectNo: '',
|
projectNo: '',
|
||||||
projectName: '',
|
projectName: '',
|
||||||
meetingName: '',
|
meetingName: '',
|
||||||
@@ -110,10 +87,14 @@ const form = reactive({
|
|||||||
remark: ''
|
remark: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
periodNo: [{ required: true, message: '请输入期数', trigger: 'blur' }],
|
||||||
|
startTime: [{ required: true, message: '请选择会议开始时间', trigger: 'change' }],
|
||||||
|
endTime: [{ required: true, message: '请选择会议结束时间', trigger: 'change' }]
|
||||||
|
}
|
||||||
|
|
||||||
async function onSave() {
|
async function onSave() {
|
||||||
if (!form.periodNo) { ElMessage.warning('请输入期数'); return }
|
try { await formRef.value.validate() } catch (e) { return }
|
||||||
if (!form.startTime) { ElMessage.warning('请选择会议开始时间'); return }
|
|
||||||
if (!form.endTime) { ElMessage.warning('请选择会议结束时间'); return }
|
|
||||||
try {
|
try {
|
||||||
await bizAdd('meeting', {
|
await bizAdd('meeting', {
|
||||||
projectId: form.projectId,
|
projectId: form.projectId,
|
||||||
@@ -139,14 +120,13 @@ onMounted(async () => {
|
|||||||
try {
|
try {
|
||||||
const r = await bizGet('project', preselectProjectId)
|
const r = await bizGet('project', preselectProjectId)
|
||||||
const d = (r && r.data) || {}
|
const d = (r && r.data) || {}
|
||||||
// 6 项只读快照 (左列)
|
|
||||||
snap.projectNo = d.projectNo || ''
|
snap.projectNo = d.projectNo || ''
|
||||||
snap.projectName = d.projectName || ''
|
snap.projectName = d.projectName || ''
|
||||||
snap.totalSessions = d.totalSessions ?? ''
|
snap.totalSessions = d.totalSessions ?? ''
|
||||||
snap.sponsorOrgName = d.sponsorOrgName || ''
|
snap.sponsorOrgName = d.sponsorOrgName || ''
|
||||||
snap.createTime = d.createTime || ''
|
snap.createTime = d.createTime || ''
|
||||||
snap.createBy = d.createBy || ''
|
snap.createBy = d.createBy || ''
|
||||||
// 会议名称默认 = 项目名称 (跟原型 §#3 红字一致)
|
// 会议名称默认 = 项目名称 (跟红字提示一致)
|
||||||
form.projectNo = d.projectNo || ''
|
form.projectNo = d.projectNo || ''
|
||||||
form.projectName = d.projectName || ''
|
form.projectName = d.projectName || ''
|
||||||
form.meetingName = d.projectName || ''
|
form.meetingName = d.projectName || ''
|
||||||
@@ -155,20 +135,21 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/* === 整页面板 (skill 标准: 单 page-card, form 页 max-width 1200px) === */
|
/* === 整页面板 (skill: form 页 page-card 设 max-width: 1200px) === */
|
||||||
.manager-meeting-new {
|
.manager-meeting-new {
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 面包屑 (跟 executor/People.vue 一致) */
|
||||||
.breadcrumb {
|
.breadcrumb {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #8c8c8c;
|
color: #8c8c8c;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 红字提示 (skill: 业务规则, 用 .hint-text) */
|
/* 红字提示 (skill .hint-list 风格: 白底 + 灰边 + 8px 圆角 + 红字) */
|
||||||
.hint-text {
|
.hint-text {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 1px solid #f0f0f0;
|
border: 1px solid #f0f0f0;
|
||||||
@@ -180,117 +161,14 @@ onMounted(async () => {
|
|||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 表单容器 (跟原型 .card 一致, 不是嵌套 page-card) */
|
/* 只读值样式 (跟 el-form-item 的 input 同高, 让布局对齐) */
|
||||||
.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 {
|
.form-value {
|
||||||
flex: 1;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #1a1a1a;
|
color: #333;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
}
|
}
|
||||||
.form-value.code {
|
.form-value.code {
|
||||||
font-family: ui-monospace, "Courier New", monospace;
|
font-family: ui-monospace, "Courier New", monospace;
|
||||||
color: var(--brand-primary);
|
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>
|
</style>
|
||||||
Reference in New Issue
Block a user