排水管网调查 · 项目管理平台 —— 前端设计规范 v1.0
版本 1.0 · 2026-09-14 · 作者 Lei / Hermes 依据:
xmgl/index.html(项目台账)、xmgl/project.html(项目工作台)两份原型实测源码审计 目标技术底座:Vue 3 + Vite + TypeScript + Element Plus 2.14.5 对标:Element Plus 设计原则、Ant Design 设计价值观与全局规则、ArcoDesign 栅格规范
0. 文档定位与适用范围
| 项 | 说明 |
|---|---|
| 覆盖范围 | 桌面 Web 端(≥1280px)项目管理平台:项目台账、项目工作台、图层与字段定义、作业区、人员、工作评论、成果评价 |
| 不覆盖 | 移动端 map-app(app.ygcxy.top,已有独立设计系统)、后端接口契约、数据库设计 |
| 强制级别 | 必须(MUST) = 验收卡点;应该(SHOULD) = 默认遵守,偏离需在 PR 说明理由;可(MAY) = 可选 |
| 落地形态 | 本规范为唯一设计事实来源;所有页面/组件开发前先对齐本规范章节,代码评审按第 8 章验收清单逐条过 |
一句话目标:把原型里「业务想得很清楚、但工程化程度很低」的状态,收敛成一套 token 驱动、Element Plus 为骨、地图为中枢的可维护前端规范。
1. 原型识别报告(实测,非目测)
审计方法:解压源码 → 解析 <style> / <script> / <body> → 统计色值/字号/圆角/阴影/层级/事件/无障碍属性和函数清单。以下数字均为脚本统计真实值。
1.1 两份原型的定位
index.html |
project.html |
|
|---|---|---|
| 定位 | 项目管理 台账列表页 | 项目 地图工作台 |
| 行数 / CSS / JS | 1662 行 / 14.9KB / 27.9KB | 2594 行 / 27.2KB / 43.4KB |
| 函数数 | 30 | 59 |
| 布局骨架 | 顶栏 58px + 单列内容(max-width 1500,居中) | 顶栏 54px + 左菜单 280px + 功能面板 372px + 地图自适应 |
| 地图 | Leaflet 1.9.4(弹窗内画项目范围) | Leaflet 1.9.4(天地图 WMTS vec/cva/img/cia 四源) |
| 浮层 | 1 个(三 Tab 新建/编辑项目弹窗,980px) | 4 个模态 + 3 个互斥侧栏 + 1 个 popover + 2 个地图编辑提示条 |
| 数据持久化 | 无(localStorage 0 处) |
部分(localStorage 4 处:作业区、评论) |
| 接口调用 | 无(fetch 0 处,纯 mock 常量) |
无(fetch 0 处,纯 mock 常量) |
1.2 信息架构(原型已定义,建议保留)
① 项目台账(index.html) - 顶栏:品牌「项目管理」+ 用户 - 筛选区:项目名称、创建时间、项目类别、项目状态 + 查询/重置 - 台账表 7 列:项目名称 / 所属区域 / 项目内角色 / 项目状态 / 创建人 / 开工时间 / 操作(编辑 · 删除 · 进入) - 新建/编辑弹窗三 Tab:1 项目基本信息 → 2 关联图层 → 3 关联人员(含「项目范围地图框选」)
② 项目工作台(project.html) 左菜单 6 组:
| 分组 | 二级项 |
|---|---|
| 项目管理 | 作业区管理、项目交底、人员管理、工作评论 |
| 外业调查 | 管线调查、污染源调查、排口调查、排水户调查 |
| 测绘编辑 | 测绘坐标导入、数据质量检查、数据修改编辑 |
| 质量评价 | 成果评价、成果导出 |
| 管网检测 | (空壳,未展开) |
| 质量抽检 | (空壳,未展开) |
地图工具栏 6 个:全图 / 图层控制 / 清除 / 管网分析 / 人员定位 / 工作评论;右下角「矢量|卫星」分段切换。
1.3 真实业务数据模型(这是原型最有价值的部分)
Project
├─ id, name, creator, createTime, status(未开始|进行中|已关闭)
├─ category: self(自建项目) | related(关联项目)
├─ region: { province, city, county } ← 省市区三级联动
├─ layers: [图层标识…] ← 关联图层清单
├─ fields: { 图层标识: [字段定义…] } ← 每图层的字段定义
├─ roles: { 管理:[人], 调查:[人], 测绘:[人], 检测:[人], 内业:[], 质检:[], 安全:[] }
└─ extent: null | 矩形/多边形范围 ← 项目范围(地图框选)
- 图层结构 LAYER_STRUCTURE(16 类,两级):管线 / 管点{雨水, 污水, 合流} / 排口 / 截流 / 闸阀 / 泵站 / 排水户 / 水系 / 闸门 / 污染源 / 淤堵问题 / 管网病害 / 片区 / 污水处理厂
- 字段定义 LAYER_FIELDS:每图层一套
{ name, label, type, required, def },字段类型 6 种:文本 / 数值 / 日期 / 下拉 / 布尔 / 坐标 - 例(管线):
PIPE_NO管线编号(文本,必填)、PIPE_TYPE管线类型(下拉,默认雨水)、DIAMETER管径(数值)、MATERIAL材质(文本)、DEPTH埋深(数值)、OWNER权属单位(文本)、BUILD_YEAR建设年代(日期) - 例(管点-雨水):
NODE_NO管点编号(必填)、WELL_DEPTH井深、COVER_MAT井盖材质、X/Y(坐标) - 人员组织:7 角色(管理/调查/测绘/检测/内业/质检/安全)× 部门 7 个(综合管理部、外业调查一队/二队、测绘队、检测中心、数据内业组、质检部)
- 作业区 Area:多段面 + 顶点可拖拽编辑 + 片区颜色 + 编号(如
GLO-01)+ localStorage 持久化 - 工作评论 Comment:
{ author, lat/lng, at[被@人], min(距今分钟), status(open|closed), content, replies[] }—— 评论必须绑地图坐标,这是核心设计
规范结论:图层结构与字段定义是可配置的业务资产,不是硬编码常量。规范要求落地为「图层注册表 + 字段定义 DSL」,与 map-app 的
LayerDef架构方向保持一致。
1.4 交互资产盘点(原型做得好、必须继承的)
| # | 交互 | 原型实现 | 规范动作 |
|---|---|---|---|
| 1 | 地图模式状态机 | 画范围 / 拖顶点编辑 / 拾取评论点 三种模式,各配一条 edit-bar 提示条承载「当前模式 + 完成 + 取消」 |
抽象为正式规范(见 5.6) |
| 2 | 工具栏=面板开关(互斥) | tPeople / tComment / tLayers 打开对应侧栏,切换自动关闭前一个 |
固化为「单激活」规则 |
| 3 | 地图↔列表双向联动 | 点作业区卡片 → 地图定位;点地图要素 → 面板高亮 | 固化为强制 M 级要求 |
| 4 | 顶点级几何编辑 + 保存/取消 | 拖拽顶点 → 保存范围 / 取消(可回退) | 加入「可撤销」规范 |
| 5 | 面板可拖拽 | makeDraggable |
保留;补齐吸附与键盘等效 |
| 6 | 人员轨迹与日历 | 人员详情弹窗内含轨迹 + 日历选日 | 归入业务组件库 |
| 7 | @人员提醒 | 评论内 @ 选择器 + 通知 |
映射 EP el-mention |
| 8 | 片区颜色选择 | 颜色 + 编号 + 名称 | 映射 EP el-color-picker |
| 9 | 身份化权限(按角色禁用操作) | canEdit / canDelete |
固化为「禁用而非隐藏」规则 |
| 10 | 消息铃铛 + 消息 popover | badge + 消息列表 | 映射 el-badge + el-popover |
1.5 源码一致性审计(问题清单的硬证据)
| 维度 | index.html | project.html | 问题判定 |
|---|---|---|---|
| 硬编码色值 | 40 种 hex(主色 #1A73E8 19 次,另含 #4A90E2 #1259B8 #9CC2F0 #B9D5F7 #A9CDF7 等 6 个蓝变体) |
40 种 hex,但主色 #1A73E8 仅 2 次,灰蓝系 #22303F #3C4D5E #5A6B7B #4A5C6E #8A94A6 #2C3E50 各 7-9 次 |
❌ 主色未确立、灰阶失控 |
| 字号取值 | 7 种(11/12/13/14/16/19/20px) | 10 种(9/10/11/12/13/14/15/16/18/20px,9px 用 2 处) | ❌ 无字号阶梯,出现 9px 不可读字号 |
| 圆角取值 | 10 种(4/5/6/8/10/11/12/14/18/50%) | 10 种(3/5/6/7/8/9/10/12/15/50%) | ❌ 无圆角阶梯 |
| 阴影 | 6 条不同 box-shadow,rgba(30,60,90,.05) 重复 2 次 |
12 条不同阴影、15 种 rgba | ❌ 阴影无层级体系 |
| z-index | 1000 / 3000(2 档) | 500/600/700/1500/2000/3000(6 档,500 用 4 次) | ❌ 层级随意,浮层叠压风险 |
| 动效 | 8 处 transition: all .15s,无缓动曲线 |
.15s/.12s/.2s,无缓动曲线 |
❌ 无动效 token、无不透明度/位移规范 |
| 间距 | gap 出现 6/7/8/9/10/12/16;padding 出现 7/10/11/12/14/15/18/22/28 |
gap 出现 4/5/6/7/8/9/10/12/14;padding 出现 8/9/10/11/12/14/16/18/20 |
❌ 非 8pt 栅格,值域失控 |
| 无障碍 | aria-* 0 处、tabindex 0 处 |
aria-* 9 处(工具栏按钮有 aria-label)、tabindex 0 处 |
❌ 键盘不可达、屏幕阅读器不可用 |
| 原生弹窗 | alert ×2、confirm ×1 |
alert ×5、confirm ×2 |
❌ 必须全量替换为 EP 组件 |
| 图标 | <svg> 0、<img> 0(用文字符号) |
<svg> 6(工具栏)、emoji 🔔 混用 |
❌ 图标体系不统一 |
| 工程化 | 单文件 1662 行;字符串拼 innerHTML 8 处 |
单文件 2594 行;innerHTML 15 处;59 个全局函数 |
❌ 零组件化、零类型 |
1.6 原型体检评分
评分口径:每维 10 分,共 10 维 / 100 分。评分依据全部来自 1.5 的实测统计与 1.4 的交互盘点。
| # | 维度 | index | project | 依据摘要 |
|---|---|---|---|---|
| 1 | 信息架构与导航 | 6.5 | 7.5 | 台账单表清晰但无分页/排序/面包屑;工作台 6 组菜单结构合理,但 2 组为空壳 |
| 2 | 布局与栅格 | 6.0 | 7.0 | 工作台「菜单+面板+画布」是成熟主从结构;但全 px 固定、无栅格、无折叠、<1280px 不可用 |
| 3 | 视觉一致性与 token 化 | 5.0 | 4.0 | 色值/字号/圆角/阴影/层级五项全部失控(见 1.5) |
| 4 | 交互完备度 | 6.0 | 8.0 | 工作台有模式状态机+提示条+互斥面板+拖拽,为全场最强项;台账缺 loading/批量/排序 |
| 5 | 弹窗与反馈体系 | 6.0 | 6.5 | 浮层分工合理(4 模态+3 侧栏+popover);但 alert×7 / confirm×3 原生、toast 自研、无反馈分级 |
| 6 | 表单与数据录入 | 6.0 | 6.5 | 有省市区联动、地图框选、颜色选择、@人员;但仅标红星、无实时校验与错误定位 |
| 7 | 地图与业务联动 | 6.0 | 8.0 | 作业区/轨迹/人员/评论标记全在地图上,业务与地图耦合深度是核心资产;但用 Leaflet 与项目 MapLibre 栈不一致 |
| 8 | 状态完整度(空/载/错/权限) | 3.0 | 4.0 | 仅有空态和在线状态,无 loading / 错误 / 无权限态 |
| 9 | 无障碍 | 2.0 | 3.5 | aria 几乎为零、tabindex 为零、9px 字号、emoji 图标 |
| 10 | 工程可维护性 | 3.0 | 3.0 | 单文件 1.6-2.6k 行、innerHTML 23 处、零类型零组件化 |
| 合计 | 49.5 / 100 | 58.5 / 100 |
结论(读法): - 业务能力(4/6/7 维)已经 8 分水平——原型作者清楚「管网调查在工地上怎么干活」,这是最难得的资产,规范要保护它而不是推倒它。 - 规范能力(3/9/10 维)只有 3-5 分——所有扣分集中在「没 token、没无障碍、没组件化、无三态」,这些恰好是 Element Plus 能补的。 - 因此本文档的策略是:不动信息架构与地图交互,把视觉与工程规范整体换血。
2. 设计原则(5 条,全部可判定)
对标:Element Plus 四原则(一致 / 反馈 / 效率 / 可控)+ Ant Design 四价值观(自然 / 确定性 / 意义感 / 生长性)。本项目落成以下 5 条,每条附可判定标准。
P1 · 地图优先(Canvas First,MUST)
地图是本平台的主画布,不是背景图。 - 判定:任何常驻浮层(侧栏、抽屉、面板)遮挡地图面积 ≤ 30%;弹窗遮挡 ≤ 60% 且可关闭;禁止出现遮罩压暗地图后不可点击地图的交互。 - 依据:附件原型的 edit-bar / pickBar / 图层面板均浮于地图且不遮全图,方向正确,须固化为硬规则。
P2 · 单源一致性(Single Source,MUST)
全站色值、字号、圆角、阴影、间距、层级、动效只有一个来源:src/styles/tokens.scss + Element Plus 变量覆盖。
- 判定:grep -rE "#[0-9a-fA-F]{3,6}" src/ --include=*.vue 只允许命中 tokens 文件;业务组件 0 命中。
- 对应原型问题:两份原型合计 80 处色值、17 种字号、20 种圆角(见 1.5)。
P3 · 反馈分级(Feedback Tiers,MUST)
反馈强度必须匹配事件重要度,四档对应四组件,禁止 alert / confirm。
- 判定:grep -rn "alert(\|confirm(" src/ 结果必须为 0;所有破坏性操作 100% 走 ElMessageBox。
- 依据:Ant Design 明确「重要的失败信息不建议使用轻量级提示」;原型有 alert ×7、confirm ×3。
P4 · 可控与可回退(Controllability,MUST)
用户必须能撤销、回退、终止。地面作业(画范围、拖顶点、批量改字段)尤其重要。
- 判定:几何编辑必有「保存 / 取消」双出口;批量操作先给影响面数字;可撤销操作用 ElMessage + 撤销按钮或编辑栈。
- 依据:原型 保存范围 / 取消、重新绘制 已具备雏形,须补齐键盘等效与离开拦截。
P5 · 信息密度优先(Density First,SHOULD)
这是工作台不是官网。数据密度优先于留白。 - 判定:表格默认行高 48px(紧凑档 40px),控件默认高 32px;页头总高 ≤ 56px;禁止「大留白 + 大标题」营销式排版;禁止字号 < 12px。 - 依据:原型出现 9px、10px 字号,以及单文件内 10 档字号混用,须一刀切断。
3. Design Tokens 与 Element Plus 变量映射
实现方式(二选一,推荐 A):
- 方案 A(推荐)· CSS 变量覆盖:html { --el-color-primary: … },零构建成本、可运行时换肤。
- 方案 B · SCSS 编译期覆盖:@use "element-plus/theme-chalk/src/index.scss" with ($colors: …),体积更小但需全量编译。
3.1 品牌与功能色
主色取 #1E74FF,理由:与同业务线移动端 map-app 主色一致(品牌连续性),且比原型 #1A73E8 更亮、更适配深色顶栏与地图叠加。原型 #1A73E8 作为备选取值。
| Token | CSS 变量 | 值 | 用途 |
|---|---|---|---|
| primary | --el-color-primary |
#1E74FF |
主按钮、选中、链接、地图要素强调 |
| primary-hover | --el-color-primary-light-3 |
#629EFF |
悬停(EP 自动派生) |
| primary-active | --el-color-primary-dark-2 |
#185DCC |
按下 |
| primary-soft | --el-color-primary-light-9 |
#E8F1FF |
选中底、浅色标签底(替代原型 #EAF2FE) |
| success | --el-color-success |
#17A673 |
正常、完成、已验收(沿用原型绿) |
| warning | --el-color-warning |
#E8901F |
待处理、超期(沿用原型橙) |
| danger | --el-color-danger |
#E04B4B |
错误、删除、质检不合格(沿用原型红) |
| info | --el-color-info |
#8A94A6 |
中性标签、禁用说明(沿用原型灰) |
功能色浅底统一取各自 light-9:success #E8F6F1、warning #FDF4E9、danger #FCEDED、info #F3F4F6。
3.2 中性色(文字 / 边框 / 填充 / 背景)
收敛规则:原型出现 6 种相近灰蓝(#22303F #3C4D5E #4A5C6E #5A6B7B #7B8A99 #8A94A6),统一压到 5 阶(与 EP $text-color 同名,只改值)。
| 语义 | CSS 变量 | 值 | 原型的哪几个灰被它吸收 |
|---|---|---|---|
| 标题/主文字 | --el-text-color-primary |
#22303F |
#22303F、#2C3E50 |
| 正文/常规 | --el-text-color-regular |
#4A5C6E |
#3C4D5E、#4A5C6E、#5A6B7B |
| 次要/说明 | --el-text-color-secondary |
#8A94A6 |
#7B8A99、#8A94A6、#9AA8B6 |
| 占位符 | --el-text-color-placeholder |
#A8ABB2 |
— |
| 禁用 | --el-text-color-disabled |
#C3CDD6 |
#C3CDD6 |
| 边框 | CSS 变量 | 值 |
|---|---|---|
| 默认边框 | --el-border-color |
#E3E9F0 |
| 轻边框 | --el-border-color-light |
#EDF1F6 |
| 分隔线 | --el-border-color-lighter |
#F2F5F9 |
| 强调边框 | --el-border-color-dark |
#D5DEE8 |
| 背景/填充 | CSS 变量 | 值 | 用途 |
|---|---|---|---|
| 页面底 | --el-bg-color-page |
#EEF2F7 |
全局背景(沿用原型) |
| 卡片底 | --el-bg-color |
#FFFFFF |
卡片、表格、面板 |
| 浅填充 | --el-fill-color-light |
#F5F8FB |
表头、hover 行 |
| 地图浮层底 | 自定义 --c-float-bg |
rgba(255,255,255,.96) |
地图工具条/提示条(不用毛玻璃,见 6.3) |
3.3 字号阶梯(收敛到 5 档,硬门禁)
原型 17 种取值(含 9px / 10px / 11px / 15px / 19px)全部作废。
| 档位 | 值 | EP 变量 | 用途 |
|---|---|---|---|
| XS | 12px | --el-font-size-extra-small |
角标、单位、表格辅助列、时间 |
| S | 13px | --el-font-size-small |
次要说明、表头、卡片元信息 |
| B | 14px | --el-font-size-base |
正文默认、按钮、表单、表格单元格 |
| M | 16px | --el-font-size-medium |
弹窗标题、卡片标题、面板标题 |
| XL | 20px | --el-font-size-extra-large |
页面标题、关键统计数字 |
配套:行高正文 1.5、标题 1.4、数字列 1.2;字重仅允许 400 / 500 / 600(禁止 700 以上,标题统一 600;数字用 font-variant-numeric: tabular-nums)。EP 的 18px(large)留空不用。
3.4 间距(8pt 栅格)
只允许 4 / 8 / 12 / 16 / 24 / 32 / 40 / 48(4 为半步,仅用于图标与文字之间)。
- 原型的 5/6/7/9/10/11/14/15/18/22 全部作废。
- 语义化:--sp-1:4 --sp-2:8 --sp-3:12 --sp-4:16 --sp-5:24 --sp-6:32 --sp-7:40 --sp-8:48
- 组合规则(对标 Ant Design「亲密性」):同组内元素 8px,组间 16px,区块间 24px,页面级 32px。
- 卡片内边距 20px(页面级卡片)/ 16px(嵌套卡片);页边距 24px。
3.5 圆角阶梯(收敛到 4 档)
| 档 | 值 | EP 变量 | 用途 |
|---|---|---|---|
| xs | 2px | --el-border-radius-small |
标签、角标 |
| s | 4px | --el-border-radius-base |
按钮、输入框、选择器 —— EP 默认,保持不动 |
| m | 6px | 自定义 --radius-card |
卡片、面板、表格容器 |
| l | 8px | 自定义 --radius-dialog |
弹窗、抽屉、地图浮层大块 |
| full | 50% | --el-border-radius-circle |
头像、色点 |
作废:3/5/7/9/10/11/12/14/15/18px。
3.6 阴影(3 档)
| 档 | 值 | 用途 |
|---|---|---|
| card | 0 1px 3px rgba(30,60,90,.06) |
卡片、表格容器(静态) |
| raised | 0 4px 16px rgba(20,40,60,.10) |
悬停卡片、地图浮层、下拉 |
| overlay | 0 12px 32px rgba(20,40,60,.16) |
弹窗、抽屉、popover |
EP 的 --el-box-shadow / -light / -lighter / -dark 四组统一映射为上述 3 档(dark 与 overlay 合并)。
3.7 层级(z-index,分层表,禁止随意取数)
| 层 | 值 | 内容 |
|---|---|---|
| 1 | 0 | 页面内容、表格 |
| 2 | 10 | 卡片内粘性表头、面板头部 |
| 3 | 100 | 应用顶栏、侧栏(常驻) |
| 4 | 1000 | 地图浮层:工具条、底图切换、图层面板、编辑提示条 |
| 5 | 2000 | 下拉、Popover、Tooltip(EP popper) |
| 6 | 3000 | 模态弹窗、Drawer、遮罩 |
| 7 | 4000 | ElMessage / ElMessageBox / ElNotification(EP 默认,不改) |
依据:原型 z-index 出现 500/600/700/1500/2000/3000 六档且 500 复用 4 次,存在浮层被压风险;EP 官方只定义 normal 1 / top 1000 / popper 2000,扩展层须显式声明。
3.8 动效
| Token | 值 | 用途 |
|---|---|---|
--dur-fast |
100ms | 按下反馈、hover 变色 |
--dur-base |
200ms | 下拉展开、Tab 切换、面板 |
--dur-slow |
300ms | 弹窗、抽屉(对齐 EP --el-transition-duration 0.3s) |
--ease-out |
cubic-bezier(.23,1,.32,1) |
入场(快起步) |
--ease-in-out |
cubic-bezier(.4,0,.2,1) |
尺寸/位移 |
--ease-drawer |
cubic-bezier(.32,.72,0,1) |
抽屉/面板(iOS 手感) |
硬规则:UI 动效 ≤ 300ms;状态类变化(hover/选中)≤ 100ms;必须提供 @media (prefers-reduced-motion: reduce) 降级(去位移、保留淡入)。作废原型的 transition: all .15s(all 会误伤布局属性,改显式属性名)。
3.9 业务图层配色(16 类图层的分类色板)
按管网感知惯例分配,地图与列表色块共用同一 token(原型已用色块↔多边形呼应的手法,必须延续):
| 类别 | 色值 | 归类 |
|---|---|---|
| 管线 / 管点-雨水 | #1E74FF |
雨水(蓝) |
| 管点-污水 | #8B5CF6 |
污水(紫) |
| 管点-合流 | #0EA5E9 |
合流(青) |
| 排口 | #E8901F |
排口(橙) |
| 泵站 / 闸阀 / 闸门 / 截流 | #17A673 |
构筑物(绿) |
| 排水户 | #14B8A6 |
排水户 |
| 水系 | #38BDF8 |
水系 |
| 污水处理厂 | #6366F1 |
厂站 |
| 污染源 / 淤堵问题 | #E04B4B |
问题(红) |
| 管网病害 | #DC2626 |
病害(深红) |
| 片区 | #94A3B8 |
面域(中性) |
规则:同上图 ≤ 8 种颜色;同类同色;问题类一律红系以便外业一眼识别。
3.10 Token 落地代码(可直接复制)
/* src/styles/element-override.scss —— Element Plus 主题覆盖(唯一改色入口) */
:root {
/* 品牌色 */
--el-color-primary: #1E74FF;
--el-color-primary-light-3: #629EFF;
--el-color-primary-light-5: #8EBAFF;
--el-color-primary-light-7: #BCD5FF;
--el-color-primary-light-8: #D2E3FF;
--el-color-primary-light-9: #E8F1FF;
--el-color-primary-dark-2: #185DCC;
--el-color-success: #17A673;
--el-color-warning: #E8901F;
--el-color-danger: #E04B4B;
--el-color-error: #E04B4B;
--el-color-info: #8A94A6;
/* 中性色 */
--el-text-color-primary: #22303F;
--el-text-color-regular: #4A5C6E;
--el-text-color-secondary: #8A94A6;
--el-text-color-placeholder: #A8ABB2;
--el-text-color-disabled: #C3CDD6;
--el-border-color: #E3E9F0;
--el-border-color-light: #EDF1F6;
--el-border-color-lighter: #F2F5F9;
--el-border-color-dark: #D5DEE8;
--el-bg-color: #FFFFFF;
--el-bg-color-page: #EEF2F7;
--el-fill-color-light: #F5F8FB;
/* 字号 / 圆角 / 动效 */
--el-font-size-extra-small: 12px;
--el-font-size-small: 13px;
--el-font-size-base: 14px;
--el-font-size-medium: 16px;
--el-font-size-extra-large: 20px;
--el-border-radius-small: 2px;
--el-border-radius-base: 4px;
--el-transition-duration: 300ms;
--el-transition-duration-fast: 100ms;
/* 项目扩展 token */
--radius-card: 6px;
--radius-dialog: 8px;
--sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
--sp-5: 24px; --sp-6: 32px; --sp-7: 40px; --sp-8: 48px;
--shadow-card: 0 1px 3px rgba(30, 60, 90, .06);
--shadow-raised: 0 4px 16px rgba(20, 40, 60, .10);
--shadow-overlay: 0 12px 32px rgba(20, 40, 60, .16);
--dur-fast: 100ms; --dur-base: 200ms; --dur-slow: 300ms;
--ease-out: cubic-bezier(.23, 1, .32, 1);
--ease-in-out: cubic-bezier(.4, 0, .2, 1);
--ease-drawer: cubic-bezier(.32, .72, 0, 1);
--c-float-bg: rgba(255, 255, 255, .96);
--z-map-float: 1000; --z-popper: 2000; --z-modal: 3000;
}
/* 统一密度与卡片外观 */
.el-card { border-radius: var(--radius-card); box-shadow: var(--shadow-card); }
.el-table { font-variant-numeric: tabular-nums; }
.el-button { font-weight: 500; }
4. 布局规范
4.1 断点与最小支持宽度
| 断点 | 宽度 | 说明 |
|---|---|---|
| XL | ≥ 1920 | 工作台可开「双面板」(表单面板 + 图层面板并排) |
| L | 1600–1919 | 设计基准(原型 1600×1000 实测) |
| M | 1280–1599 | 左菜单自动折叠为 64px 图标栏,面板宽度 360px |
| S | < 1280 | 降级提示:本平台为桌面作业系统,给出「请使用 1280px 以上宽屏」提示页(M 级要求,不做移动适配) |
依据:工作台三栏最小需求 = 64 + 320 + 800(地图可用下限)≈ 1184px;原型固定 280+372+余量,在 1280 以下必挤。
4.2 五种页面骨架(全平台只允许这 5 种)
S1 · 台账页(对齐 index.html)
AppHeader 56px
└ FilterCard 24px 页边距,卡片内 20px,字段 gap 16px,行数 ≤ 2
└ TableCard 工具条 48px(左:批量操作/列设置;右:密度/刷新/导出)+ 表格 + Pagination 56px
规则:内容区 max-width: 1760px(原型 1500 偏窄,宽屏浪费);表格必须有分页(默认 20/页,可选 20/50/100)、排序、列设置。
S2 · 表单/详情页(新建/编辑项目 → 路由页)
AppHeader 56px
└ Breadcrumb 40px(≥3 层时显示,最多 5 级)
└ PageHeader 56px(标题 20/600 + 右侧主操作)
└ 内容卡(表单宽 880px 单列 / 1120px 双列;steps 步骤条在顶部)
└ 底部粘性操作条 64px(取消 / 保存,主操作靠右)
规则:超过 6 个字段的录入不再用弹窗,改本骨架(原型的三 Tab 980px 弹窗属于超标,见 5.4)。
S3 · 工作台(本项目主力骨架)(对齐 project.html)
AppHeader 56px
└ AppBody flex:1,overflow:hidden
├ Sidebar 240px(展开)/ 64px(折叠) ── el-menu,深白底,分组可折叠,折叠态记忆到 localStorage
├ Panel 360px(可选) ── 业务面板容器(作业区 / 人员 / 评论),同一时刻最多 1 个
└ Workspace flex:1 min-width:0 ── 地图画布 + 浮层
规则:
- 面板宽度 360px(原 372 收敛);面板头 56px(标题 16/600 + 右侧主按钮);面板体独立滚动。
- 顶栏高度统一 56px(原型 58/54 不一致)。
- 面板显隐用宽度过渡 --dur-slow --ease-drawer,地图 resize() 必须跟随(地图容器尺寸变化后调用 map.resize(),否则瓦片错位)。
- 地图区 min-width: 800px。
S4 · 地图全屏页(图层浏览、成果查看) AppHeader 56px + 地图 100%,仅浮层:右竖工具条(40×40,gap 6)+ 右下底图切换 + 左下比例尺/坐标。
S5 · 结果/异常页(提交成功、无权限、404)
居中卡 480px,图标 64px + 标题 20/600 + 说明 14/次要 + 主次按钮;对齐 EP el-result。
4.3 栅格与对齐
- 组件库栅格:
el-row :gutter="24"+el-col :span,24 等分(对齐 ArcoDesign 建议:24 等分适合信息量大、分组多的中后台)。 - 基础单位 8px(ArcoDesign:8 为栅格原子单位,主流分辨率水平/垂直均可被 8 整除)。
- 内容必须对齐列,不得落在水槽(gutter)中(ArcoDesign 明确规则)。
- 表单栅格:单列表单 label 右对齐宽 96px;双列表单 label 顶对齐;只读态转
el-descriptions(2/3 列)。 - 表格数字列右对齐、无
tabular-nums以外的数字格式化;状态列固定宽 96px 居中。
4.4 密度
| 档 | 表格行高 | 控件高 | 用于 |
|---|---|---|---|
| default | 48px | 32px | 默认 |
| compact | 40px | 28px | 工作台内嵌表格、图层字段定义表(字段多) |
规则:密度开关放表格工具条,记忆到 localStorage;同页面内不得混用两档。
4.5 页头与导航
- 顶栏组成:左 品牌 + 面包屑(或当前项目名,超长省略
max-width: 320px);右 消息铃铛(el-badge)+ 帮助 + 用户(头像 30px + 名称)。 - 侧栏菜单:一级分组可折叠(
el-menu的el-sub-menu),选中态用--el-color-primary-light-9底 + 主色文字 + 左侧 2px 主色条;折记忆到 localStorage。 - 面包屑:层级 > 3 时隐藏中间项;当前页面导航已能说明位置时不使用面包屑(对齐 Ant Design)。
5. 交互规范
5.1 反馈分级决策表(MUST,全站唯一口径)
| 级别 | 组件 | 何时用 | 何时禁止 |
|---|---|---|---|
| L1 轻提示 | ElMessage(默认 3s) |
成功结果、非破坏性的即时确认(保存成功、复制成功、已切换底图) | 重要失败(会被漏看);需要用户决策的事 |
| L2 通知 | ElNotification |
后台进程结果(成果导出完成、批量检查跑完)、需要留痕的告警 | 用户主动操作且立即看到结果的事 |
| L3 对话框 | ElMessageBox |
破坏性操作二次确认(删除、关闭评论、清空范围);不可逆动作 | 仅作提示、无决策的事(标题党的「提示」弹窗一律禁止) |
| L3+ 业务弹窗 | ElDialog / ElDrawer |
需要录入或展示丰富内容的任务 | 超过 6 个字段(改用页 / Drawer) |
| L4 行内 | el-form-item error / el-alert |
表单校验、页面级持续错误、需立即注意的系统异常 | 一次性操作反馈 |
依据:Ant Design 明确「重要的失败信息不建议使用轻量级提示方式」,「弹窗是很强的反馈机制,只有在传递非常重要、且可操作的信息时才需要使用它」。原型 alert ×7、confirm ×3 必须全部替换。
文案模板(统一句式,MUST):
- 成功:已保存 / 已删除「鼓楼区 01 号作业区」(带对象名)
- 失败:保存失败:网络超时,请重试(原因 + 下一步动作)
- 危险确认:标题 = 动作(删除作业区);正文 = 影响面(删除后该作业区的 24 条调查数据将一并移除,且不可恢复。);按钮 = 取消 / 删除(危险色),禁止「确定/取消」这种无信息量按钮。
5.2 加载态(MUST)
| 场景 | 方案 | 规则 |
|---|---|---|
| 首屏/整页 | el-skeleton 骨架屏 |
表格用行骨架(默认 5 行)、卡片用块骨架 |
| 局部刷新(表格翻页、筛选) | v-loading 于表格容器 |
遮罩 300ms 内不出(防闪烁),E 级延迟显示 |
| 按钮提交 | el-button :loading |
提交期锁定按钮并禁用重复点击;文案保持原样不变形 |
| 地图数据加载 | 地图角落小 Spin + 状态文案(正在加载 1,204 个管点…) |
禁止整屏遮罩压地图(违反 P1) |
| 长任务 | el-progress + ElNotification 完成通知 |
超过 3s 的任务必须可后台化 |
5.3 状态完整性(MUST,覆盖原型缺口)
每个数据容器(表格、列表、面板、地图图层)必须实现 4 态,且文案 + 主操作明确:
| 态 | 组件 | 文案示例 | 主操作 |
|---|---|---|---|
| 无数据(首次) | el-empty |
还没有项目,先创建一个 |
新建项目 |
| 无结果(筛选后) | el-empty |
没有符合条件的项目 |
清空筛选条件 |
| 无权限 | 自定义插画 | 你在该项目中的角色为「调查」,无权限查看成果评价 |
申请权限(或返回) |
| 出错 | el-result status="error" |
数据加载失败 |
重试 |
错误归因三档(与 map-app 架构一致):Unsupported(能力不支持 → 静默降级)/ Denied(用户侧:权限、定位被拒 → 友好提示 + 给替代路径)/ Failed(系统侧 → 提示 + 重试 + 上报 console/埋点,不向用户暴露堆栈)。
5.4 数据表格交互(MUST)
原型台账表缺少的必须补齐:
| 能力 | 实现 |
|---|---|
| 分页 | el-pagination,默认 20,可 20/50/100;总数常显 |
| 排序 | 服务端排序;createTime 默认倒序;排序箭头与列宽不抖动 |
| 列设置 | el-popover + el-checkbox-group,状态存 localStorage;至少锁定「项目名称」与「操作」列 |
| 密度 | default / compact 切换(见 4.4) |
| 行内操作 | ≤ 3 个直接展示;> 3 个收进「更多」el-dropdown;操作列固定宽(3 个操作 = 140px),右固定 |
| 行选择 | el-table type=selection + 表头全选;选中后出现批量操作条(带影响面数字:已选 12 项) |
| 空列处理 | 空值统一显示 —,禁止空白 |
| 列宽 | 文本列 min-width 自适应,状态/时间/操作列定宽 |
5.5 地图 ↔ 列表双向联动(MUST,本平台核心)
| 交互 | 行为 |
|---|---|
| 列表 hover 行 | 地图对应要素加粗描边 + 提升图层(不改颜色,避免语义混淆) |
| 列表点击行 | 地图 fitBounds 定位该要素(padding 80px),并高亮;同一时刻仅 1 个选中 |
| 点击地图要素 | 对应列表项滚动到可见区(scroll-into-view)+ 选中态 + 左侧面板切换到对应分组 |
| 面板切换 | 关闭上一个面板并清空其地图高亮 |
| 要素密集 | 同级要素靠聚集/抽稀;点击后给出 popup 而非直接改选中(防误触) |
5.6 地图操作模式状态机(MUST —— 原型最强项,正式固化)
原型已用 edit-bar / pickBar 承载「当前模式 + 完成 + 取消」,抽象为正式规范:
idle ──点「框选范围/新增作业区」──▶ drawing ──双击/点击首点──▶ editing ──保存──▶ idle
│ │ │
│ └── Esc/取消 ──────────┘
├──点「评论位置」──▶ picking ──点击地图──▶ 回填表单 → idle(Esc 取消)
├──点「测距」─────▶ measuring ──Esc/再次点击──▶ idle
└──点要素 ────────▶ selected ──点空白──▶ idle
规则(MUST):
1. 同一时刻只有 1 个非 idle 模式;进入新模式的隐式规则 = 先退出旧模式(原型已验证可行)。
2. 每种模式在地图顶部居中显示提示条:当前动作 + 操作指引 + 步数(可选)+ [完成] [取消];提示条高 40px,宽自适应 ≤ 480px,底 --c-float-bg,z-index --z-map-float,永不遮挡鼠标正在操作的区域(跟随鼠标对侧,或固定顶部并留出地图拖动区)。
3. Esc 逐层退出:弹窗 → 模式 → 选中(逆序,一次退一层)。
4. 模式中光标变化:crosshair(绘制)/ move(编辑)/ pointer(拾取)/ crosshair(测距)。
5. 关键:进入绘制/编辑模式时必须锁定地图的拖动与缩放(dragPan.disable() / scrollZoom.disable()),否则会误拖地图——原型未处理,属必修项。
6. 顶点拖拽时吸附到已有管点/顶点(阈值 8px 屏幕距离)。
5.7 面板互斥与显隐
- 左侧菜单的一级分组可折叠;二级项切换 = 切换中列面板(作业区管理 / 人员管理 / 工作评论)。
- 地图右侧工具条按钮 = 同一面板/模式的快捷开关;按钮激活态与面板显隐必须双向同步(原型已做,须保持)。
- 切换面板时:
Panel宽度动画 300ms;地图resize()在同一帧后调用。 - 关闭的方式必须齐全:面板头
×、切换其他菜单项、Esc。取消遮罩压暗(地图须始终可见可点,符合 P1)。
5.8 键盘与无障碍交互(MUST,原型为 0)
| 键 | 行为 |
|---|---|
Esc |
逐层退出浮层/模式/选中;有未保存改动时先弹「放弃编辑?」 |
Enter |
表单提交(非 textarea 内);列表行进入详情 |
Tab / Shift+Tab |
全站可达,焦点环 0 0 0 3px var(--el-color-primary-light-7) |
↑ / ↓ |
表格行间移动选中(tabindex="0" 于表格容器) |
Ctrl/Cmd + S |
保存当前表单(防浏览器默认保存) |
Ctrl/Cmd + Enter |
提交评论 / 发布反馈 |
空格 + 拖拽 |
地图平移(默认支持) |
Shift + 点击 |
列表多选 |
要求:所有纯图标按钮必须有 aria-label(原型工具栏已有 6 处,须扩展到全部);图片/图形要素有等价文本;焦点环不得移除。
5.9 破坏性操作与撤销(MUST)
| 操作 | 处理 |
|---|---|
| 删除项目 / 作业区 / 评论 | ElMessageBox 二次确认,标题=动作、正文含对象名与影响面、按钮用动作词 |
| 关闭评论 | 二次确认(原型已有,保留);关闭后不可再回复 → 文案说明 |
| 批量删除 / 批量改字段 | 确认框必须显示 将影响 12 条数据,其中 3 条已被质检锁定 |
| 全部勾选(跨页) | 必须显式提示「已选中全部 128 项」,禁止静默全选 |
| 几何编辑(画范围/拖顶点) | 保存前可「取消」回退;已保存的提供「编辑范围」重入 |
| 可撤销的轻操作 | ElMessage 带「撤销」按钮,6s 内可撤 |
防误触:危险按钮与安全按钮之间间距 ≥ 24px;危险按钮默认非聚焦态;行内删除用 el-popconfirm(轻量)而非弹窗,除非有级联数据。
5.10 表单与校验(MUST)
- 校验时机:失焦校验 + 提交时全量校验;输入中不报错(除格式可即时判定的如坐标)。
- 错误展示:行内红字 + 输入框红边,同时在表单顶部给
el-alert汇总并锚点跳转到第一个错误项(超长表单必备)。 - 必填标记:统一
*前置红色 + 表单右上角图例说明(不能只靠红点,原型缺陷)。 - 字段类型 → EP 组件映射:文本
el-input/ 数值el-input-number(管径、井深需带单位与精度)/ 日期el-date-picker(禁止只用于创建时间的只读字段用datetime-local)/ 下拉el-select/ 布尔el-switch/ 坐标el-input×2 + 「地图取点」按钮。 - 长文本:> 200 字用
el-input type=textarea :rows=4并显示字数与上限。 - 离开拦截:表单
isDirty时路由离开 / 关弹窗 →ElMessageBox三选:保存并离开/放弃修改/继续编辑。
5.11 防重复与并发
- 提交类按钮:请求期间
loading+disabled(MUST)。 - 同一资源并发编辑:保存时带
updatedAt/version,409 冲突弹「数据已被 张伟 修改」并提供「查看差异 / 覆盖 / 放弃」。 - 列表刷新:手动刷新按钮 + 切换筛选自动刷新;不做轮询(除人员在线上报,30s 且页面可见时才轮询,
visibilitychange暂停)。
6. 弹窗与浮层规范(本次重点)
6.1 五种浮层选型决策树(MUST)
需要用户处理的信息/任务
├─ 只是告知,无需决策?
│ ├─ 操作后即时、3s 内可读完 ──────────▶ ElMessage (L1)
│ └─ 后台进程 / 需留痕 / 多条汇总 ─────▶ ElNotification (L2)
├─ 需要确认(破坏性/不可逆)?──────────▶ ElMessageBox (L3)
├─ 需要录入或查看较丰富内容?
│ ├─ 字段 ≤ 6,单任务,无附件 ────────▶ ElDialog (width ≤ 720)
│ ├─ 字段 7–20,需保留背景上下文 ─────▶ ElDrawer (rtl, size ≤ 720)
│ └─ 字段 > 20 / 多步 / 含表格附件 ───▶ 独立路由页(骨架 S2)
└─ 徽标、悬浮说明、快捷设置 ───────────▶ ElTooltip / ElPopover (≤ 360px)
判定辅助(三条硬线):
1. 宽度硬线:Dialog 最宽 900px;超过说明内容超载 → 改 Drawer 或页面。
2. 高度硬线:不超过视口 80vh;超过必须内部滚动,且头/脚固定。
3. 上下文硬线:用户需要边看背景数据边填(如「按台账核对后录入」)→ 必须 Drawer,不用 Dialog。
6.2 Dialog 规范
| 项 | 规格 |
|---|---|
| 宽度阶梯 | xs 400 / sm 480 / md 560 / lg 720 / xl 900,只允许这 5 档;max-width: 90vw |
| 高度 | 内容自适应,max-height: 80vh;超出则 body 滚动,header/footer 固定 |
| 圆角 | --radius-dialog 8px |
| 阴影 | --shadow-overlay;遮罩 rgba(20,40,60,.45) |
| 头部 | 高 56px,padding 0 24px;标题 16px/600,单行省略;标题 ≤ 14 字,超长改用 Drawer 或加副标题行 |
| 内容区 | padding 20px 24px;表单单列(宽度 ≥ 720 时才允许双列 24px 间距) |
| 底部 | 高 64px,padding 0 24px,按钮右对齐,间距 12px;主操作在最右,危险操作在主操作左侧且用危险色 |
| 关闭 | 右上 × 40×40 点击区;Esc 关闭;遮罩点击 —— 非表单弹窗可关,表单弹窗不关(防误丢数据) |
| 动画 | 淡入 + scale(.96→1),--dur-slow --ease-out,位置从遮罩中心缩放(非从屏幕外飞入) |
| 内容销毁 | 统一 destroy-on-close(避免残留表单状态);需保留状态的用 v-model 显式管理 |
| 滚动 | 长内容只滚 body;头部标题与底部按钮常驻;滚动条宽度预留 scrollbar-gutter: stable |
| 层级 | --z-modal: 3000,append-to-body 必须开(避免被父容器 overflow:hidden 裁切) |
| 嵌套 | 最多 2 层;第 2 层必须是 sm 以内且无二级嵌套;禁止「弹窗里再开弹窗改数据」 |
EP 配置约定:
<el-dialog v-model="visible" width="560px" :close-on-click-modal="false"
destroy-on-close append-to-body align-center
:before-close="handleBeforeClose">
6.3 Drawer 规范
| 项 | 规格 |
|---|---|
| 方向 | 默认 rtl(从右进);仅「左侧筛选」类用 ltr |
| 尺寸 | sm 400 / md 560 / lg 720,最大 720px;max-width: 90vw |
| 头部 | 高 56px,同 Dialog;必须有 ×,底部必须有操作条(避免只能靠 × 退出) |
| 内容区 | padding 20px 24px,独立滚动;表单可分节(节标题 14/600 + 24px 上间距) |
| 底部 | 粘性操作条 64px:取消 / 保存;有未保存改动时在关闭前拦截 |
| 与地图共存 | Drawer 打开时不遮地图遮罩(无 modal 遮罩或遮罩点击穿透),地图保持可见可点(P1)。若业务流程要求聚焦,则遮罩透明度降到 rgba(20,40,60,.25) 并允许点击关闭 |
| 动画 | --dur-slow --ease-drawer;内容错位 < 50ms 淡入(可选) |
6.4 ElMessageBox(确认类)规范
| 类型 | 场景 | 规格 |
|---|---|---|
warning |
非破坏但需确认(关闭评论、解绑人员) | 主按钮默认色 |
danger |
破坏性(删除项目/作业区/批量删除) | 主按钮 type="danger";默认聚焦「取消」,防止回车误删 |
prompt |
需要输入理由(质检驳回、成果退回) | 必填校验,空值禁用确认按钮 |
必带内容:标题=动作短语 + 正文=对象名 + 影响面 + 是否可恢复 + 按钮=动作词。
禁止:无正文的「确定要删除吗?」、无对象名的删除、「确定/取消」按钮。
6.5 Message / Notification 规范
| ElMessage | ElNotification | |
|---|---|---|
| 位置 | 顶部居中,距顶 20px | 右上角,距顶 20px,距右 24px |
| 时长 | 3s(成功/信息)/ 5s(错误) | 6s(成功)/ 不自动关(错误,需手动) |
| 宽度 | 内容自适应,max-width: 400px |
固定 360px |
| 内容 | 单行,≤ 30 字 | 标题(进程名)+ 描述(结果 + 跳转链接) |
| 并发 | 同类合并(grouping: true),最多堆叠 3 条 |
最多 3 条,超出排队 |
| 必须带 | 成功/失败动词;失败带原因与下一步 | 结果 + 可操作入口(查看成果) |
6.6 Tooltip / Popover 规范
ElTooltip:纯文本说明,≤ 30 字;地图工具条按钮、图标按钮必须有(原型缺);延迟 300ms 出,--dur-fast。ElPopover:可含交互内容(列设置、消息列表、快捷筛选);宽 ≤ 360px;trigger="click";内部有表单时禁止自动关闭(需显式关闭按钮)。- 消息列表(原型的
msgPop):改用el-popover+el-badge,未读数 > 99 显示99+;列表项高 56px,点击进入对应业务对象。
6.7 地图工作台专属浮层(本项目特有,MUST)
| 浮层 | 规格 |
|---|---|
| 右侧竖工具条 | 贴地图右边缘 16px、垂直居中;按钮 40×40,圆角 6px,gap: 6px;底 --c-float-bg + --shadow-raised;激活态:主色底 + 白图标;每键带 Tooltip 与 aria-label |
| 右下底图切换 | el-segmented(EP 2.7+)或自研分段;两段固定宽 48px,高 32px;图标/文字 13px;选中态主色(原型已如此) |
| 地图左上信息条 | 当前项目名 + 图层计数 + 比例尺;高 32px,只在需要时出现 |
| 编辑/拾取提示条 | 见 5.6:顶部居中、高 40px、≤ 480px、含 [完成] [取消]、z=1000 |
| 图层面板 | .lp 面板 240×auto,右上角(工具条左侧 12px);行高 32px,树形缩进 16px/级;每行:复选框 + 色块 + 名称(+ 数量角标);面板最大高 60vh 可滚动 |
| 要素 Popup | 宽 280–360px,圆角 8px,含标题(要素名)+ 关键字段(≤ 5 项,label: value 两列)+ 单个主操作按钮 |
| 上传/导出进度条 | 地图左下角,宽 320px |
| 浮层通用 | 一律 position: absolute 于地图容器内(非 Teleport 到 body,避免与页面滚动耦合);容器 pointer-events: none,子元素 pointer-events: auto(保证浮层间隙可拖动地图);仅当浮层需盖住应用顶栏时才用 fixed + z-index(原型工作台不需要) |
地图浮层禁忌(MUST NOT): - 不得用毛玻璃/backdrop-filter(原型未用,且会与地图瓦片叠加出现性能与可读性问题); - 不得在浮层上再叠浮层超过 1 层(图层面板 → 行内设置用 Popover 例外); - 不得用纯色遮罩压暗地图。
6.8 原型浮层 → 新方案映射(改造清单)
| 原型 | 现状 | 新方案 | 理由 |
|---|---|---|---|
index.html 新建/编辑项目弹窗(980px,三 Tab,内含地图) |
超宽、内含交互地图、步进与提交耦合 | 改为路由页(骨架 S2) + el-steps 3 步:基本信息 → 关联图层 → 关联人员;步骤可回退,最后一步才提交 |
900px 是 Dialog 硬线;含地图的弹窗会与「地图模式状态机」冲突;分步表单需可中断、可回退(P4) |
index.html 项目范围「框选范围」嵌入表单 |
小地图里画矩形 | 独立 MapPickerDialog(xl 900,或全屏 S4):地图大图框选 → 确认后回填 extent 摘要(已选范围 1.24 km²) |
符合 P1;框选需足够画布 |
index.html 省市区三级 select |
三个并排 select | el-cascader(filterable,可搜索) |
减少点击、支持搜索;数据结构本来就是三级 |
project.html 作业区新增/编辑 areaModal |
440px 弹窗 + 地图重新绘制按钮 | 保留 Dialog(字段 ≤ 5)→ md 560,含 el-color-picker + 「在地图上绘制」按钮(触发 5.6 的 drawing 模式) |
字段少,Dialog 合适;绘制分离到地图模式 |
project.html personModal 人员详情(轨迹+日历) |
自研弹窗,宽 440 | 保留 Drawer (md 560) 或 xl 900 Dialog:左信息 + 右轨迹地图 |
人员详情含地图与日历,信息量大,Drawer 更合适 |
project.html composeModal 添加评论 |
480px 弹窗 + 地图选点 + @人员 | 保留 Dialog(sm 480),el-mention 替代自研 @ 选择器;评论位置用「在地图上重新选择位置」触发 picking 模式 |
字段少且与当前地图上下文强相关,Dialog 不打断作业 |
project.html commentModal 评论详情(回复流) |
520px 弹窗 | 改 Drawer (md 560):帖子流 + 回复框 + 底部操作条(发送反馈 / 关闭评论) | 需保留地图上下文看坐标位置;内容可增长 |
project.html msgPop 消息 popover |
自研 popover | el-popover + el-badge |
组件化 |
project.html cm-toast |
自研 toast | ElMessage |
统一反馈 |
全部 alert() ×7 / confirm() ×3 |
原生 | ElMessage / ElMessageBox |
P3 硬规则 |
edit-bar / pickBar 两条提示条 |
自研、两套相似样式 | 抽象为统一组件 <MapActionBar> |
同一语义不应两套实现 |
三个 area-panel 侧栏 |
各自独立 DOM | 统一 <WorkPanel> 容器(一致的头/体/滚动/动画),内容分三种 |
保证面板规格一致 |
7. 组件映射表(原型控件 → Element Plus)
原则:能用 EP 原生就不自研;自研仅限「地图与管网业务」特有组件(第 8 章)。EP 2.14.5 组件全集为 12 基础 + 1 配置 + 25 表单 + 23 数据 + 9 导航 + 10 反馈 + 2 其他,下表只列本项目用到/替换到的。
7.1 基础与布局
| 原型控件 | EP 组件 | 备注 |
|---|---|---|
.app-header 顶栏 |
el-container/el-header + 自研 <AppHeader> |
高 56px 固定 |
.app-main 内容区 |
el-container/el-main |
padding 24px |
.sidebar 左菜单 |
el-menu + el-sub-menu + el-menu-item |
折叠/记忆;图标用 @element-plus/icons-vue |
.card 卡片 |
el-card |
圆角 --radius-card,无 hover 阴影变化 |
.area-panel 业务面板 |
自研 <WorkPanel>(内部 el-scrollbar) |
统一规格(头 56 / 体滚动 / 底操作) |
.filter-card 筛选卡 |
el-form :inline="true" + el-space |
字段 gap 16px,行 ≤ 2 |
| 通用分栏(表单+预览) | el-splitter(EP 2.10+)/ el-row+el-col |
支持拖拽调宽 |
7.2 数据展示
| 原型控件 | EP 组件 | 备注 |
|---|---|---|
.proj-table 台账表 |
el-table + el-table-column |
见 5.4 必备能力 |
| 表格工具栏 | el-button-group + el-dropdown + el-popover(列设置) |
— |
| 分页 | el-pagination |
见 5.4 |
| 状态标签(进行中/已关闭/未开始) | el-tag(type: primary/info/success/danger) |
状态→色的映射固定:进行中=primary、未开始=info、已关闭=info(空心)、质检不合格=danger、已完成=success |
| 作业区卡片行 | el-card 或自研 <ListRow> |
色块 14px 圆点 + 名称 + 编号 |
| 统计数字(调查2/测绘1/检测1) | el-statistic 或纯文本 + tabular-nums |
小尺寸场景用文本 |
| 图层树(16 类两级) | el-tree(show-checkbox、default-expand-all)/ el-tree-select |
节点带色块;父子联动与「只选子不选父」规则需显式定义 |
| 字段定义表(可编辑行) | el-table + 单元格内 el-input/el-select/el-switch |
行内编辑;必填列 el-switch |
| 人员列表 | el-table 或 <ListRow> |
在线点 8px 圆点(success/info) |
| 评论列表(帖子流) | 自研 <CommentItem>(el-avatar + el-tag + el-timeline) |
回复用嵌套缩进 24px |
| 消息列表 | el-popover + <ListRow> |
未读 el-badge |
| 无数据 | el-empty |
四态之一 |
| 骨架 | el-skeleton |
表格行骨架 |
| 结果页 | el-result |
成功/失败/无权限 |
| 描述列表(只读详情) | el-descriptions |
2-3 列 |
| 时间线(轨迹/流程) | el-timeline |
— |
| 日历(人员上报日) | el-calendar |
单元格内显示上报数 |
| 进度 | el-progress |
导出/质检进度 |
| 水印(涉密图纸) | el-watermark |
成果导出页启用 |
7.3 数据录入
| 原型控件 | EP 组件 | 备注 |
|---|---|---|
| 文本输入 | el-input(含 show-word-limit) |
高 32px |
| 数值(管径/井深/埋深) | el-input-number(precision、单位后缀) |
管径整数、埋深 0.01 |
| 下拉(项目状态/类别、部门、角色) | el-select(filterable 当选项 > 8) |
角色多选用 multiple + collapse-tags |
| 省市区三级 | el-cascader |
替换 3 个 select |
| 日期时间(创建时间/开工时间) | el-date-picker type="datetime" / date |
统一 value-format="YYYY-MM-DD HH:mm" |
| 布尔 | el-switch |
— |
| 坐标 X/Y | el-input ×2 + 「地图取点」按钮 |
触发 picking 模式 |
| 颜色(片区色) | el-color-picker |
预置 8 色 + 自定义 |
| @人员提醒 | el-mention |
替换自研 at-picker |
| 人员多选(项目角色) | el-select multiple 或 el-transfer |
角色人数多时用 transfer |
| 文件(成果/图纸导入) | el-upload(drag、限制大小与类型) |
显示校验失败原因 |
| 表单 | el-form + el-form-item + rules |
见 5.10 |
| 步骤条(三步新建) | el-steps |
横向,步骤 ≤ 5 |
| 筛选标签组(全部/我创建的/我参与的) | el-radio-group + el-radio-button 或 el-segmented |
原型自研 cm-tabs 替换 |
| 底图矢量/卫星 | el-segmented |
— |
7.4 反馈与浮层
ElMessage / ElNotification / ElMessageBox / ElDialog / ElDrawer / ElPopover / ElTooltip / ElAlert / ElLoading —— 用法见第 5、6 章。
7.5 导航
el-breadcrumb(≤ 3 级可见,最多 5 级)/ el-tabs(页面级切换)/ el-tabs type="card"(局部)/ el-dropdown(行操作、用户菜单)/ el-backtop(长列表)。
8. 地图与管网业务组件(自研,EP 不覆盖)
自研范围严格限定为「地图画布 + 管网语义」,共 12 个组件。架构遵循 map-app 已定方向:地图能力收口到 mapApi 单一入口 + 组件薄壳,本平台复用同一套设计语言,不另起一套。
| # | 组件 | 职责 | 关键接口 |
|---|---|---|---|
| 1 | <MapCanvas> |
地图容器与实例生命周期(唯一持有 map 实例的地方) | v-model:view, @ready, @click |
| 2 | mapApi(非组件) |
唯一地图能力出口:init/resize/flyTo/fitBounds/setBasemap/layers.*/draw.*/measure.* |
页面只调 mapApi,禁止直接 import maplibregl |
| 3 | <MapToolbar> |
右竖工具条(全图/图层/清除/管网分析/人员定位/工作评论) | :active, @action |
| 4 | <BasemapSwitch> |
矢量/卫星分段切换 | v-model |
| 5 | <LayerPanel> |
图层控制面板(树 + 可选 + 计数) | :layers, v-model:visible |
| 6 | <MapActionBar> |
统一编辑/拾取提示条(替代原型 edit-bar + pickBar 两套) | :mode, :steps, @done, @cancel |
| 7 | <FeatureEditor> |
顶点级几何编辑(拖拽/吸附/撤销栈 30 步) | :geometry, @change, @save |
| 8 | <AreaList> |
作业区列表(色块 + 编号 + 统计 + 行操作) | :areas, @focus, @edit |
| 9 | <PeopleLayer> |
人员点位/在线状态/轨迹渲染 | :people, :track |
| 10 | <CommentMarker> |
评论地图标记(带序号 + 状态色) | :comments, @focus |
| 11 | <FeaturePopup> |
要素信息气泡(标题 + ≤5 字段 + 1 主操作) | :feature |
| 12 | <TrackCalendar> |
人员轨迹 + 日历联动 | :person, v-model:date |
约定:
- 图层定义走「图层注册表 + LayerDef(纯数据)」:{ id, name, group, category, color, zIndex, geometryType, fields[], visible } —— 与原型的 LAYER_STRUCTURE + LAYER_FIELDS 一一对应,可后端下发。
- 层级(z 序)显式声明,禁止依赖「谁先加载谁在下」的隐式顺序。
- 要素样式全部来自 3.9 的图层色板 token。
- 地图模式状态机收敛在 mapApi.mode,UI 只订阅状态(见 5.6)。
9. 技术栈与工程约定
9.1 版本(npm registry 实测,2026-09-14)
| 包 | 版本 |
|---|---|
| vue | 3.5.42 |
| vite | 8.3.0 |
| typescript | 7.0.2 |
| vue-router | 5.3.1 |
| pinia | 4.0.3 |
| element-plus | 2.14.5 |
| @element-plus/icons-vue | 2.3.2 |
| @vitejs/plugin-vue | 6.0.9 |
| sass | 1.104.1 |
| axios | 1.20.0 |
| dayjs | 1.11.23 |
| unplugin-auto-import | 21.1.0 |
| unplugin-vue-components | 32.1.0 |
注:
element-plus与@element-plus/icons-vue为强绑定版本,升级须同步;sass走sass-embedded更快但需 Node ≥ 18。
9.2 目录结构(按职责分层,避免文件堆一层)
src/
├─ api/ # 接口层(按业务域分文件)
├─ assets/
├─ components/
│ ├─ base/ # 通用基础组件(AppHeader/WorkPanel/ListRow/StatusTag)
│ ├─ map/ # 第 8 章的 12 个地图业务组件
│ └─ business/ # 业务组件(LayerTree/FieldEditor/AreaList…)
├─ composables/ # useXxx(useTable/useDialog/useMapMode/useUnsavedGuard)
├─ layouts/ # 5 种页面骨架(LedgerLayout/WorkbenchLayout/…)
├─ router/ # 路由 + 守卫(权限、离开拦截)
├─ stores/ # pinia
├─ styles/
│ ├─ element-override.scss # EP 主题覆盖(唯一改色入口)
│ ├─ tokens.scss # 扩展 token
│ └─ index.scss
├─ types/ # 业务类型(LayerDef/Project/Area/Comment…)
├─ utils/
└─ views/ # 页面(与路由 1:1)
9.3 硬约定(评审即卡点)
| # | 约定 | 检查方式 |
|---|---|---|
| 1 | 业务代码 0 硬编码色值 | grep -rE "#[0-9a-fA-F]{3,6}" src/ --include=*.vue 无命中 |
| 2 | 禁止 alert / confirm |
grep -rn "alert(\|confirm(" src/ 无命中 |
| 3 | 字号只用 5 档 token | grep -rn "font-size" src/**/*.vue 只出现 var(--el-font-size-*) |
| 4 | 间距为 4 的倍数 | 抽查;stylelint 规则可自动化 |
| 5 | 图标统一 @element-plus/icons-vue(地图工具栏许可自研线性 SVG,须同规格 1.75 描边/24 网格) |
无 emoji 图标 |
| 6 | 页面只通过 mapApi 触达地图 |
grep -rn "maplibregl" src/views/ 无命中 |
| 7 | 组件 <script setup lang="ts">,禁 any(unknown + 收窄) |
vue-tsc --noEmit |
| 8 | 表格/列表必须有 loading / empty / error 三态 | 评审清单 |
| 9 | 破坏性操作 100% 二次确认 | 评审清单 |
| 10 | 主题可换肤:所有业务色走 token,禁止在组件内 !important 覆盖 EP |
grep -rn "!important" src/ 无命中 |
| 11 | EP 按需引入(unplugin-vue-components 的 ElementPlusResolver),不整包 app.use(ElementPlus) |
构建产物检查 |
| 12 | 中文文案:中英文间加空格、标点用全角、按钮 ≤ 6 字、无「的」冗余 | 文案评审 |
10. 验收清单(可测门禁)
A 视觉一致性
- [ ] 色值扫描 0 硬编码;主色 #1E74FF 全站唯一蓝
- [ ] 字号取值 = 5 档;无 < 12px
- [ ] 圆角取值 ≤ 4 档 + 50%;间距全部落在 4 的倍数
- [ ] z-index 只出现 10 / 100 / 1000 / 2000 / 3000 / 4000
B 交互完整性
- [ ] 每个列表/表格具备 loading / empty / no-result / error 四态
- [ ] 破坏性操作 100% 二次确认,且文案含对象名 + 影响面
- [ ] 提交类按钮有 loading 且防重复点击
- [ ] 未保存表单在离开/关闭时被拦截
- [ ] Esc 可逐层退出:弹窗 → 地图模式 → 选中
- [ ] 地图模式互斥;进入绘制/编辑时锁地图拖拽缩放
C 弹窗规范
- [ ] 无宽度超出 5 档阶梯的 Dialog
- [ ] 无 Dialog 高于 80vh 或宽于 90vw
- [ ] 表单字段 > 6 的一律 Drawer 或路由页
- [ ] 所有弹窗头 56px / 脚 64px / 内边距 20-24px
- [ ] 表单弹窗 close-on-click-modal=false
- [ ] 嵌套深度 ≤ 2
D 无障碍与键盘
- [ ] 所有纯图标按钮有 aria-label
- [ ] 焦点环可见;Tab 可达全部可操作元素
- [ ] 文字对比度 ≥ 4.5:1(正文)、≥ 3:1(大字)
- [ ] prefers-reduced-motion 降级生效
E 地图与业务
- [ ] 列表 hover/点击 ↔ 地图要素双向联动,选中唯一
- [ ] 地图浮层遮挡面积 ≤ 30%
- [ ] 地图容器尺寸变化后调用 mapApi.resize()(无瓦片错位)
- [ ] 图层色与列表色块同源(3.9 色板)
F 工程与性能
- [ ] vue-tsc --noEmit 0 报错;0 any
- [ ] 生产构建 0 警告;EP 按需引入
- [ ] 首屏 LCP < 2.0s(内网);页面切换 < 300ms
- [ ] 浏览器控制台 0 报错/0 警告(每页实测截图留档)
11. 实施路线(每阶段独立可回滚)
| 阶段 | 内容 | 产出 | 前置 |
|---|---|---|---|
| P0 骨架 | 工程初始化(版本按 9.1)、tokens + EP 覆盖、5 种骨架与路由、AppHeader/Sidebar | 可跑的空壳 + 主题可验证 | — |
| P1 底座组件 | WorkPanel / ListRow / StatusTag / useTable / useDialog / useUnsavedGuard / 四态容器 |
组件库 8-10 个 + 演示页 | P0 |
| P2 台账闭环 | S1 台账页(筛选/分页/排序/列设置/批量)+ 三步新建项目(S2 路由页)+ 级联/树/字段编辑 | 项目 CRUD 全流程 | P1 |
| P3 工作台闭环 | S3 骨架 + mapApi + <MapCanvas> + 工具条 + 图层注册表 + MapActionBar + FeatureEditor |
作业区在地图上增删改查 | P1 |
| P4 业务深化 | 人员(点位/轨迹/日历)、工作评论(地图坐标 + @ + 回复流)、消息通知 | 三个面板全功能 | P3 |
| P5 收口 | 无障碍(Tab/aria/对比度)、四态补齐、性能、验收清单全过 | 可交付版本 | P2-P4 |
关键风险与对策:
- 风险 1 · EP 视觉同质化 → 对策:皮肤层 + 地图业务组件差异化(见 13 章方向 B)。
- 风险 2 · 地图模式与弹窗交互打架 → 对策:P3 阶段先把状态机跑通再做业务弹窗(6.7/6.8 已定规则)。
- 风险 3 · 图层字段定义可配置化导致表单动态渲染复杂 → 对策:字段类型只有 6 种,用「字段类型 → 组件」注册表 + el-form 动态渲染,避免 if-else 堆叠。
12. 设计原则速查卡(打印用)
地图优先 浮层遮地图 ≤30%,地图永远可见可点
单源一致 色/字/距/角/影/层/动 —— 只有 tokens 一个来源,组件 0 硬编码
反馈分级 Message(轻) → Notification(后台) → MessageBox(确认) → Dialog/Drawer(任务)
可控回退 破坏必确认、编辑必可撤、长流程必可中断
密度优先 表格 48/40,控件 32/28,无大留白、无 <12px 字
13. 头脑风暴:三个可选设计方向
三个方向的差别不在「好不好看」,而在 Element Plus 承担多少、我们自研多少、地图在信息架构里的位置。
方向 A · EP 原生稳态(规范先行,视觉跟随 EP)
- 做法:完全用 EP 原生组件,只覆盖 CSS 变量(本文档第 3 章);不自研视觉层,不自研业务组件(除地图必需)。
- 优点:交付最快、最稳;无障碍与交互细节由 EP 兜底;与任何 EP 生态工具(ProComponents、表单设计器)无缝;团队/外包上手零成本;EP 升级无痛。
- 缺点:EP 的视觉语言(4px 圆角、密集中性灰、
#409EFF惯性)会主导产品观感,同质化明显;地图工作台的三栏 + 浮层形态与 EP 默认布局语言不匹配,仍要魔改。 - 适合:交付时间被压得很紧、甲方不关心视觉识别度。
| 交付速度 | 一致性 | 独特性 | 风险 |
|---|---|---|---|
| 9 | 9 | 3 | 低 |
方向 B · EP 为骨 + 自有皮肤层(推荐)
- 做法:EP 提供交互、无障碍与表单/表格/反馈底座;在其上叠一层 ① token 皮肤层(第 3 章,主色
#1E74FF而非 EP 蓝)② 12 个地图与管网业务组件(第 8 章)③ 5 种页面骨架(4.2)。组件一律薄壳包裹 EP,业务页面不直接写 EP 细节。 - 优点:一致性与无障碍由 EP 保证,识别度由皮肤层与地图组件提供;地图工作台(本项目真正的核心)有专属设计与语义;后续换视觉主题只改 tokens。与 map-app 的「能力收口 + 薄壳」架构方向一致,两套端可共享图层/字段/配色定义。
- 缺点:需要维护 token 层与 EP 版本的兼容(每次 EP 升级需跑一遍视觉回归);自研 12 个组件有工作量(约占总工时 35%)。
- 适合:本项目——业务复杂度高、地图是核心、要长期维护。
| 交付速度 | 一致性 | 独特性 | 风险 |
|---|---|---|---|
| 7 | 8 | 8 | 中 |
方向 C · 地图中枢重设计(打破三栏)
- 做法:不再「左菜单 + 列表中继 + 地图」三栏,改为 地图全屏为唯一主场:左右两侧可收起的浮动 Dock(作业区/人员/评论/图层),底部时间轴(作业进度 + 上报时间线),列表退化为 Dock 内的紧凑列表,所有业务对象都成为地图上的图层 + 时间维度。
- 优点:最贴合外业/内业真实工作方式(都在地图上作业,不在地图边上);识别度与产品气质最强;天生适配大屏指挥场景。
- 缺点:原型的 6 组菜单信息架构要重建;学习成本高(用户需要重新建立「去哪找东西」的心智);工期最长(+40%);若甲方后续要求「像常规后台」,返工风险大。
- 适合:作为 v2 目标——等 P0-P5 的底座(图层注册表、mapApi、业务组件)落地后,换骨架成本才低。
| 交付速度 | 一致性 | 独特性 | 风险 |
|---|---|---|---|
| 4 | 7 | 10 | 高 |
结论与推荐
推荐方向 B,理由: 1. 本项目的扣分项(3 视觉一致性 4 分 / 9 无障碍 2-3.5 分 / 10 工程化 3 分)恰好是 EP 最强的部分,而加分项(4 交互 / 7 地图)恰好是 EP 不能给的——B 是唯一同时保住两端的选择。 2. 方向 A 会把 4/7 维的地图资产降格成普通表单页,丢掉了原型最值钱的东西。 3. 方向 C 的正确时机是「底座已就位」,现在做会把架构风险和视觉风险叠在同一个阶段。
14. 待你拍板的关键决策点
| # | 决策 | 选项 | 建议 |
|---|---|---|---|
| 1 | 设计方向 | A 稳态 / B 皮肤层 / C 地图中枢 | B |
| 2 | 主色 | #1E74FF(复用 map-app)/ #1A73E8(原型原色)/ #409EFF(EP 默认) |
#1E74FF |
| 3 | 弹窗策略(新建项目) | 保留 980px 三 Tab 弹窗 / 改三步路由页 | 改路由页(6.8 已论证) |
| 4 | 与 map-app 的关系 | 完全独立项目 / 共享图层·字段·配色定义层 | 共享定义层(避免两套管网数据模型) |
| 5 | 图表库(成果评价/看板) | 暂不引入 / ECharts / 其他 | 需要时再定,本期不引入 |
| 6 | 是否先出视觉稿 | 直接按本规范开发 / 先出 2-3 个视觉方向稿再开发 | 先出稿(沿用你惯常流程) |
附录 A · 原型缺陷速查(改前 → 改后)
| # | 改前(原型实测) | 改后(本规范) |
|---|---|---|
| 1 | 40 种硬编码色值,6 个蓝变体 | 1 个主色 + 4 功能色 + 9 中性色(3.1-3.2) |
| 2 | 17 种字号,最小 9px | 5 档,最小 12px(3.3) |
| 3 | 20 种圆角 | 4 档 + 50%(3.5) |
| 4 | 18 条阴影、15 种 rgba | 3 档(3.6) |
| 5 | z-index 6 档随意取值 | 6 层语义表(3.7) |
| 6 | transition: all .15s ×多处 |
3 时长 + 3 曲线 + 显式属性(3.8) |
| 7 | 间距 5/6/7/9/10/11/14/15/18/22 混杂 | 4 的倍数,7 档语义(3.4) |
| 8 | alert ×7 / confirm ×3 |
ElMessage / ElMessageBox(5.1) |
| 9 | aria-* 近 0、tabindex 0 |
全量 aria-label + 焦点管理 + 快捷键(5.8) |
| 10 | 顶栏高度 58 / 54 不一致 | 统一 56px(4.2) |
| 11 | 980px 三 Tab 弹窗内含地图 | 三步路由页 + 独立 MapPickerDialog(6.8) |
| 12 | 两条相似提示条 edit-bar / pickBar | 统一 <MapActionBar>(8 章) |
| 13 | 三个侧栏各自实现 | 统一 <WorkPanel>(6.7/8 章) |
| 14 | 表格无分页/排序/列设置/批量 | 全量补齐(5.4) |
| 15 | 无 loading / 错误态 | 四态规范(5.3) |
| 16 | 地图模式未锁地图拖拽 | 进入绘制必须 dragPan.disable()(5.6 规则 5) |
| 17 | 图标体系不统一,emoji 🔔 混用 | EP 图标 + 地图工具栏自研同规格线性图标(9.3 约定 5) |
| 18 | 单文件 2.6k 行、innerHTML 23 处 |
组件化目录结构 + 类型化(9.2/9.3) |
附录 B · 变更记录
| 版本 | 日期 | 变更 |
|---|---|---|
| 1.0 | 2026-09-14 | 首版:原型识别与评分、5 条设计原则、完整 token 体系(含 EP 变量映射与可复制代码)、5 种页面骨架、11 类交互规范、7 类浮层规范(含原型浮层改造映射)、组件映射表、12 个地图业务组件、工程约定与验收清单、三方向头脑风暴 |