13 KiB
13 KiB
盘古用户平台 - 前端UI规范文档 v1.0
适用于本项目所有前端页面开发 作者:pangu 创建时间:2026-01-31
一、设计原则
1.1 统一性原则
- 保持全系统视觉风格一致
- 相同功能使用相同交互模式
- 统一的间距、颜色、字体规范
1.2 简洁性原则
- 页面布局清晰,信息层次分明
- 避免过度设计,突出核心功能
- 表格列宽合理,无大面积空白
1.3 易用性原则
- 操作直观,减少用户学习成本
- 反馈及时,状态清晰可见
- 错误提示友好,引导用户纠正
二、色彩规范
2.1 主题色
| 类型 | 色值 | 用途 |
|---|---|---|
| 主色 | #409EFF |
按钮、链接、选中态 |
| 成功色 | #67C23A |
正常状态、成功提示 |
| 警告色 | #E6A23C |
警告提示 |
| 危险色 | #F56C6C |
停用状态、删除操作、错误提示 |
| 信息色 | #909399 |
辅助信息 |
2.2 中性色
| 类型 | 色值 | 用途 |
|---|---|---|
| 主文本 | #303133 |
标题、正文 |
| 常规文本 | #606266 |
表格、描述 |
| 次要文本 | #909399 |
提示、禁用态 |
| 占位文本 | #C0C4CC |
placeholder |
| 边框色 | #DCDFE6 |
边框、分割线 |
| 背景色 | #F5F7FA |
表头、背景 |
2.3 侧边栏配色
| 类型 | 色值 |
|---|---|
| 背景色 | #304156 |
| 选中背景 | #409EFF |
| 文字颜色 | #FFFFFF |
三、布局规范
3.1 页面结构
<template>
<div class="app-container">
<!-- 搜索区域 -->
<el-card shadow="never" class="search-wrapper">
<el-form>...</el-form>
</el-card>
<!-- 表格区域 -->
<el-card shadow="never" style="margin-top: 12px;">
<!-- 操作按钮 -->
<el-row :gutter="10" style="margin-bottom: 12px;">
<el-col :span="1.5">
<el-button type="primary" :icon="Plus">新增</el-button>
</el-col>
</el-row>
<!-- 表格 -->
<el-table>...</el-table>
<!-- 分页 -->
<el-pagination />
</el-card>
<!-- 弹窗 -->
<el-dialog>...</el-dialog>
</div>
</template>
<style scoped>
.app-container {
padding: 16px;
}
.search-wrapper {
margin-bottom: 0;
}
</style>
3.2 左右分栏布局
适用于:学校管理、学生管理等需要左侧树形筛选的页面
<el-row :gutter="16">
<!-- 左侧树形区域 -->
<el-col :span="6">
<el-card shadow="never">
<template #header>区域筛选</template>
<el-input v-model="filterText" placeholder="输入关键字过滤" />
<el-tree :data="treeData" :filter-node-method="filterNode" />
</el-card>
</el-col>
<!-- 右侧列表区域 -->
<el-col :span="18">
<!-- 搜索表单 + 表格 -->
</el-col>
</el-row>
3.3 间距规范
| 场景 | 间距值 |
|---|---|
| 页面内边距 | 16px |
| 卡片间距 | 12px |
| 表单项间距 | 默认(16px) |
| 按钮组间距 | 10px |
| 表格与分页间距 | 16px |
四、表格规范
4.1 基础表格属性
<el-table
:data="tableData"
border
stripe
v-loading="loading"
:header-cell-style="{ background: '#f5f7fa', color: '#606266' }"
style="width: 100%"
>
必须设置的属性:
border:显示边框stripe:斑马纹v-loading:加载状态header-cell-style:表头样式style="width: 100%":全宽显示
4.2 列宽规范
| 字段类型 | 推荐宽度 | 说明 |
|---|---|---|
| ID/编号 | width="80-140" |
固定宽度 |
| 名称/标题 | min-width="120-200" |
弹性宽度,使用min-width |
| 编码 | width="100-120" |
固定宽度 |
| 状态/类型 | width="80-100" |
固定宽度,居中 |
| 日期时间 | width="160" |
固定宽度 |
| 手机号 | width="120" |
固定宽度 |
| 操作列 | width="120-200" |
根据按钮数量,固定右侧 |
4.3 列定义示例
<!-- 名称列:弹性宽度 + 溢出提示 -->
<el-table-column prop="name" label="名称" min-width="150" show-overflow-tooltip />
<!-- 状态列:固定宽度 + 居中 + Tag -->
<el-table-column prop="status" label="状态" width="80" align="center">
<template #default="{ row }">
<el-tag :type="row.status === '0' ? 'success' : 'danger'">
{{ row.status === '0' ? '正常' : '停用' }}
</el-tag>
</template>
</el-table-column>
<!-- 操作列:固定右侧 -->
<el-table-column label="操作" width="180" fixed="right" align="center">
<template #default="{ row }">
<el-button link type="primary" :icon="Edit" @click="handleEdit(row)">编辑</el-button>
<el-button link type="danger" :icon="Delete" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
4.4 空数据处理
<el-table :data="tableData">
<template #empty>
<el-empty description="暂无数据" />
</template>
</el-table>
4.5 树形表格
<el-table
:data="tableData"
row-key="id"
border
:default-expand-all="isExpand"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
注意事项:
row-key必须指定为唯一标识字段- 确保数据结构中的字段名与
prop一致
五、表单规范
5.1 搜索表单
<el-form :model="queryParams" :inline="true" class="search-form">
<el-form-item label="名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入名称"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="全部" clearable style="width: 100px">
<el-option label="正常" value="0" />
<el-option label="停用" value="1" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
5.2 弹窗表单
<el-dialog
v-model="dialogVisible"
:title="dialogTitle"
width="600px"
:close-on-click-modal="false"
destroy-on-close
>
<el-form
ref="formRef"
:model="form"
:rules="rules"
label-width="100px"
>
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" placeholder="请输入名称" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-switch v-model="form.status" active-value="0" inactive-value="1" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
</template>
</el-dialog>
5.3 输入框宽度规范
| 场景 | 推荐宽度 |
|---|---|
| 搜索表单-短输入 | 100-150px |
| 搜索表单-中输入 | 200px |
| 搜索表单-日期范围 | 240px |
| 弹窗表单 | 100%(默认) |
六、分页规范
<el-pagination
v-model:current-page="queryParams.pageNum"
v-model:page-size="queryParams.pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
style="margin-top: 16px; justify-content: flex-end"
@size-change="handleQuery"
@current-change="handleQuery"
/>
必须设置:
layout="total, sizes, prev, pager, next, jumper":完整布局style="justify-content: flex-end":右对齐:page-sizes="[10, 20, 50, 100]":页码选项
七、状态Tag规范
7.1 状态类型映射
| 状态 | Tag类型 | 示例 |
|---|---|---|
| 正常/启用 | success |
正常 |
| 停用/禁用 | danger |
停用 |
| 家长 | primary(默认) |
家长 |
| 教师 | success |
教师 |
| 男 | primary(默认) |
男 |
| 女 | danger |
女 |
| 未知 | info |
未知 |
7.2 代码示例
<!-- 状态Tag -->
<el-tag :type="row.status === '0' ? 'success' : 'danger'">
{{ row.status === '0' ? '正常' : '停用' }}
</el-tag>
<!-- 身份类型Tag -->
<el-tag :type="row.identityType === '1' ? '' : 'success'">
{{ row.identityType === '1' ? '家长' : '教师' }}
</el-tag>
<!-- 性别Tag -->
<el-tag :type="row.gender === '1' ? '' : row.gender === '2' ? 'danger' : 'info'">
{{ { '0': '未知', '1': '男', '2': '女' }[row.gender] }}
</el-tag>
八、交互规范
8.1 删除确认
const handleDelete = (row) => {
ElMessageBox.confirm(`确定要删除"${row.name}"吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteApi(row.id).then(() => {
ElMessage.success('删除成功')
handleQuery()
})
}).catch(() => {})
}
8.2 消息提示
| 场景 | 类型 | 示例 |
|---|---|---|
| 操作成功 | success |
新增成功、修改成功、删除成功 |
| 操作失败 | error |
操作失败,请重试 |
| 警告提示 | warning |
请先选择数据 |
| 信息提示 | info |
已复制到剪贴板 |
ElMessage.success('操作成功')
ElMessage.error('操作失败')
ElMessage.warning('请先选择数据')
ElMessage.info('已复制到剪贴板')
8.3 Loading状态
- 表格加载:使用
v-loading指令 - 按钮提交:使用
:loading属性 - 页面加载:使用全局Loading
九、Mock数据规范
9.1 响应格式
// 成功响应
{ code: 200, msg: '操作成功', data: { ... } }
// 分页响应
{ code: 200, msg: '查询成功', total: 100, rows: [ ... ] }
// 错误响应
{ code: 500, msg: '操作失败' }
9.2 Mock文件规范
/**
* XXX模块Mock数据
* @author pangu
*/
import Mock from 'mockjs'
// 预置数据定义
const dataList = [...]
// GET请求用RegExp匹配URL(支持query参数)
Mock.mock(/\/api\/xxx\/list/, 'get', (options) => {
return { code: 200, total: 100, rows: [...] }
})
// POST/PUT/DELETE用字符串或正则匹配
Mock.mock('/api/xxx', 'post', { code: 200, msg: '新增成功' })
9.3 字段命名规范
重要:Mock数据中的字段名必须与视图中 prop 属性保持一致!
// ✅ 正确:字段名与视图prop一致
{ regionName: '湖北省', regionCode: 'HB' }
// 对应视图:<el-table-column prop="regionName" />
// ❌ 错误:字段名与视图prop不一致
{ name: '湖北省', code: 'HB' }
// 对应视图:<el-table-column prop="regionName" /> -- 会导致数据不显示
十、文件命名规范
10.1 视图文件
| 类型 | 位置 | 命名 |
|---|---|---|
| 主页面 | views/xxx/index.vue |
index.vue |
| 弹窗组件 | views/xxx/components/XxxDialog.vue |
大驼峰+Dialog |
10.2 API文件
| 位置 | 命名 | 示例 |
|---|---|---|
src/api/ |
小驼峰.js | school.js, member.js |
10.3 Mock文件
| 位置 | 命名 | 示例 |
|---|---|---|
src/mock/ |
小驼峰.js | school.js, member.js |
| 入口文件 | src/mock/index.js |
汇总所有mock |
十一、已知问题清单
11.1 区域管理页面
问题类型: Mock数据字段不匹配
严重程度: 高
问题描述: 区域名称列显示为空
原因分析:
- 视图使用
prop="regionName",但Mock返回name - 视图使用
prop="regionCode",但Mock返回code
修复方案:
// 修改 src/mock/region.js,将字段名改为:
{ regionName: '湖北省', regionCode: 'HB', ... }
// 或修改视图 prop 为:
<el-table-column prop="name" label="区域名称" />
11.2 应用管理页面
问题类型: Mock数据字段不匹配
严重程度: 中
问题描述: 授权接口列为空
原因分析:
- 视图使用
row.apis,但Mock返回row.apiAuth
修复方案:
// 修改 src/views/application/index.vue 第38行
// 将 row.apis 改为 row.apiAuth
<el-tag v-for="api in (row.apiAuth || []).slice(0, 3)" ...>
11.3 年级管理页面
问题类型: Mock接口未正确匹配
严重程度: 高
问题描述: 表格显示"No Data"
原因分析: API调用路径与Mock匹配可能有问题
修复方案: 检查API调用路径是否与Mock正则匹配
11.4 班级管理、学科管理页面
问题类型: 同年级管理
需确认: 同样可能存在Mock匹配问题
11.5 学校管理页面
问题类型: 样式问题
严重程度: 低
问题描述:
- 操作列按钮显示为多行,较拥挤
- 创建时间列可能被截断
修复方案:
- 增加操作列宽度到 220px 或 240px
- 减少操作按钮文字,如"新增年级"改为"加年级"
11.6 Mock数据时间问题
问题类型: 数据质量
严重程度: 低
问题描述: 部分Mock生成的时间数据不合理(如1970年、1971年)
修复方案: 限制时间范围为近5年
十二、修复优先级
| 优先级 | 页面 | 问题 | 影响 |
|---|---|---|---|
| P0 | 区域管理 | 字段不匹配导致数据不显示 | 页面不可用 |
| P0 | 年级/班级/学科管理 | Mock未返回数据 | 页面不可用 |
| P1 | 应用管理 | 授权接口列为空 | 功能缺失 |
| P2 | 学校管理 | 操作列过窄 | 体验不佳 |
| P3 | 全局 | Mock时间数据不合理 | 影响展示 |
文档版本:v1.0
创建时间:2026-01-31
维护团队:pangu