2026-09-05-water-facility-pages-ui-unification.md 13 KB

供水设施五页 UI 统一美化规格

  • 日期:2026-09-05
  • 状态:draft(待确认)
  • 任务边界(用户已确认):仅页面美化。只改五个供水设施查询页面的模板结构与样式;不修改任何无关代码,不引入后端依赖,不改任何业务逻辑。
  • 范围仓库:仅 city-life-line 前端仓库;不涉及 pipe-ner-server 后端与 UE Pipelines

Problem Statement

供水设施管理下的五个查询页面——管网信息查询、泵站信息查询、水厂信息查询、水源地信息查询、用水户信息查询——目前是 RuoYi 经典 CRUD 外观:根容器 app-container、裸 el-form 筛选、裸 el-tableright-toolbar,无任何自有 <style> 块,全部依赖全局 src/assets/styles/index.scssfacility-* / detail-drawer 类。

而同系统的管网数据统计分析(WaterFacilityDashboard.vue)、设备台账管理(WaterDevicePage.vue)等页面已采用“供水运行指挥台”蓝白风格:water-page 渐变浅灰蓝底、42px 蓝→青渐变图标页头、filter-card 筛选卡、table-card 表格卡、右侧抽屉。两套视觉并存,供水系统观感不一致。

另有两处小缺陷:五个页面共用的 facility-error 类在全仓无任何样式定义;right-toolbar 的搜索开关交互与新页面语言不一致。

数据、接口、权限、测试契约均已稳定,本任务只对齐视觉外壳。

Solution

将五个页面改造为统一的 water-page 外壳,与参照页同构:

  1. 页头:42px 蓝→青渐变图标 + 页面标题 + 副题 + 右侧刷新按钮(绑定既有 getList);移除 right-toolbar,筛选区常显。
  2. 筛选卡el-card.shadow="never".filter-card,卡头 .card-title(“筛选”)+ 右侧操作按钮(新增/删除/导出/导入)。
  3. 表格卡el-card.shadow="never".table-card,卡头 .card-title(“XX 清单”)+ 表格 + 分页。
  4. 共享样式:新建 waterFacilityPageTheme.scss 承载 chrome 样式,五个页面各以 @use 引用;页级差异仅在 scoped 块内少量补充。
  5. 保持不变:抽屉/弹窗结构与类名、操作列圆形按钮、错误态语义、全部 <script> 逻辑、API 调用、权限指令、字段与列。

User Stories

  1. As a 供水设施管理人员, I want to 五个设施查询页面与管网数据统计分析、设备台账管理使用同一视觉语言, so that 我感知到供水系统是一个整体而不是两套皮肤。
  2. As a 供水设施管理人员, I want to 每页有明确的页头(图标 + 标题 + 职责副题), so that 我能快速确认当前查看的数据范围。
  3. As a 供水设施管理人员, I want to 筛选在卡头、表格在内容卡、按钮就近可及, so that 页面层次清晰、操作密度紧凑。
  4. As a 供水设施管理人员, I want to 既有查询/新增/修改/删除/导出/导入/回收站功能与行为完全不变, so that 美化不改变我的工作方式。
  5. As a 供水设施管理人员, I want to 接口失败时仍在原位置显示错误与重试且保留已有数据, so that 失败可恢复、不丢失上下文。
  6. As a 验收人员, I want to 五个页面在 1440px / 1024px / 390px 宽度下无溢出、重叠或空白渲染, so that 页面在不同终端环境均可用。
  7. As a 维护者, I want to 五页 chrome 样式收敛到一份共享 SCSS, so that 后续统一微调只改一处。

Implementation Decisions

1. 可改动文件(封闭清单,清单外一律不改)

  • 新建:src/views/subSystem/waterSupply/components/waterFacilityPageTheme.scss
  • 修改(仅 <template><style><script> 块零改动):
    • src/views/subSystem/basic/pipeInfo/index.vue(管网信息查询)
    • src/views/subSystem/basic/pumpStation/index.vue(泵站信息查询)
    • src/views/subSystem/basic/waterPlant/index.vue(水厂信息查询)
    • src/views/subSystem/basic/waterSource/index.vue(水源地信息查询)
    • src/views/subSystem/basic/waterUserInfo/index.vue(用水户信息查询)
  • 新建(推荐):tests/waterFacilityPageTheme.test.mjs(源契约测试,见 Testing Decisions)

已确认影响面:五个 basic/*/index.vue 仅被 waterSupply/facility/{pipe,pumpStation,plant,source,user}.vue 单行壳引用,改造不外溢到其他模块。壳组件本身不改。

2. 每页模板结构(五页同构,以水厂页为例)

  1. 根:<div class="app-container"><div class="water-page facility-page">
  2. 新增页头:

    <div class="page-heading">
     <div class="page-title">
       <span class="page-title-icon"><el-icon><House /></el-icon></span>
       <div><h2>水厂信息查询</h2><span class="muted">水厂档案、能力与运行状态维护</span></div>
     </div>
     <el-button class="heading-refresh" :icon="Refresh" :loading="loading" @click="getList">刷新</el-button>
    </div>
    
    • 图标为 Element Plus 线性图标,已在 src/components/SvgIcon/svgicon.js + main.js 全局注册,模板直接写组件名,无需任何 script 改动
    • 图标映射(初值;执行者可在“语义匹配的 EP 线性图标”约束内微调,图标名不存在会触发 Vue 运行时警告,需人工验证渲染):管网 Share、泵站 Odometer、水厂 House、水源地 Water、用水户 User
    • 副题文案:管网“管线档案、属性与状态查询”、泵站“泵站档案、能力与运行状态维护”、水厂“水厂档案、能力与运行状态维护”、水源地“水源档案、类型与运行状态维护”、用水户“用水户档案、类型与状态维护”(可按执行者判断微调,须与业务术语一致)。
  3. 移除 right-toolbar(全局组件,直接删除标签即可);showSearch 变量保留在 script 不动,筛选表单 v-show 改为常显(去掉 v-show 或保持 true 语义)。

  4. 筛选区套 el-card.shadow="never".filter-card,卡头 <div class="card-title"><el-icon><Search/></el-icon><span>筛选</span></div>;新增/删除/导出/导入按钮移入卡头右侧(沿用原 v-hasPermi 指令与事件绑定,逐字保留)。

  5. 表格 + 分页套 el-card.shadow="never".table-card,卡头 <div class="card-title"><el-icon><List/></el-icon><span>水厂清单</span></div>(“XX 清单”按各页业务名);表格列、fixed="right" 操作列、分页组件属性全部不变。

  6. 新增/修改抽屉:保留 class="facility-form-drawer":title="dialogTitle"direction="rtl" 及尺寸(720/760px)原样。

  7. 详情抽屉:保留 class="detail-drawer"direction="rtl" 及尺寸(600/650px)原样。

  8. 操作列:保留 facility-row-actionsfacility-row-action is-detail/is-edit/is-delete 原样。

  9. 回收站 el-dialog、导入弹窗 WaterFacilityImportDialog:结构、类名、视觉(EP 默认)均不变。

  10. 错误横幅:模板不变;.facility-error 在页级 scoped 补样式(如 margin-bottom: 16px),el-alert + 重试逻辑不动。

3. 样式基准(唯一取值来源,不另行发明)

从以下已验证实现中提取,逐值对齐,不新增设计变量:

  • src/views/subSystem/waterSupply/components/WaterDevicePage.vue scoped(约 896–1130 行)
  • src/views/subSystem/waterSupply/components/WaterFacilityDashboard.vue scoped(约 388–658 行)
  • src/views/subSystem/waterSupply/components/waterSupplyPageTheme.scss(既有 28 行)

关键 token(已与参照页核对):

元素
页面背景 linear-gradient(135deg, #eff6ff 0%, #f8fafc 45%, #eef2f7 100%)
页面容器 min-height: calc(100vh - 84px); padding: 20px
页头图标块 42×42,linear-gradient(135deg, #2563eb 0%, #06b6d4 100%),白图标,圆角 8,box-shadow: 0 8px 16px rgba(37, 99, 235, .2)
标题 / 副题 h2 20px #1e293b.muted 13px #64748b
刷新按钮 白底、border: 1px solid #bfdbfecolor: #2563eb
卡片(filter/table) border: 1px solid #e2e8f0、圆角 8、box-shadow: 0 6px 14px rgba(15, 23, 42, .04)、白底
筛选卡头 padding: 14px 18pxbackground: #fbfdffborder-bottom: 1px solid #e2e8f0
筛选表单项 margin: 8px 16px 8px 0;label #475569
卡标题图标 #2563eb
过渡 120–180ms

设计文档红线(docs/design/2026-08-22-water-supply-work-order-ui.md 视觉规范):圆角 6–8px、细边框 + 轻阴影;不用大圆角胶囊、装饰性渐变、嵌套卡片;状态文字 + 颜色双表达;768px 以下抽屉占满可用宽度、页头纵向堆叠。

4. 样式块结构(每页)

<style scoped lang="scss">
@use '../../waterSupply/components/waterFacilityPageTheme.scss';
/* 仅页级差异(背景类名微调、个别间距) */
</style>
  • 共享 SCSS 内容:.water-page.facility-page.page-heading.page-title.page-title-icon.muted.heading-refresh.filter-card(含 :deep 卡头/表单项)、.table-card(含 :deep 表头)、.card-title.facility-error、768px 响应式。
  • 抽屉/弹窗内容经 append-to-body 传送,scoped 不生效:.facility-form-drawer / .detail-drawer 视觉继续由全局 src/assets/styles/index.scss 现有规则承担,不移植、不修改、不删除;如确需抽屉微调,放页级非 scoped <style lang="scss"> 块(参照 WaterDevicePage 1323 行起的模式)。
  • 五页各自 @use 同一文件会产生 5 份相同 CSS,与现有主题文件的 5 处 @use 模式一致,接受。

5. 明确不做(一期)

  • 页面指标卡(metric-grid):需后端统计接口,无后端契约前不做。
  • 参照页自身的样式去重重构:不动参照页。

6. 实施顺序

  1. T-A 打样:新建共享 SCSS + 改造水厂页 → 全量测试 + 构建 + 人工确认视觉基准。
  2. T-B 铺开:按同构模板改造其余四页(仅标题/副题/图标/按钮权限串不同)。
  3. T-C 收尾:五页 × 参照页一致性走查、三档宽度截图、全量测试 + 构建 + 会话记忆落盘。

Testing Decisions

既有测试零修改通过(类名保留决策的直接原因):

  • tests/detailDrawerRule.test.mjs
    • 第 40–57 行锁定五页的 :title="dialogTitle" + class="facility-form-drawer" + direction="rtl"facility-row-actionsfacility-row-action is-detail/is-edit/is-delete —— 模板改造必须逐字保留这些类名与属性顺序;
    • 第 15–30 行全仓规则:标题含“详情/查看”等关键词的 el-dialog 禁止、所有 el-drawer 必须 rtl、非 facility-form-drawer 抽屉类名须含 detail-drawer —— 保持现状即通过;
    • 第 32–38 行:派单弹窗保持 dialog(与本任务无关,回归确认)。
  • tests/waterFacilityQuery.test.mjs 第 48–57 行:五页 handleDetail.catch + this.errorMessage = getRequestErrorMessage( 错误保留语义必须原样保留。
  • 全量 node --test tests:无新增失败(当前既有失败仅限 monitor/job 只读详情规则等已知非本任务问题,不得恶化)。

新增源契约测试(推荐)tests/waterFacilityPageTheme.test.mjs,沿用项目“读源文件断言”风格:

  • 五个页面根节点含 water-page 类;
  • 五个页面 @use 共享主题文件;
  • 五个页面不再出现 right-toolbar
  • 五个页面存在 page-headingfilter-cardtable-card

验证门禁:

  • node --test tests 全量通过;
  • npm run build:prod 成功;
  • git diff --check 干净;
  • 1440px / 1024px / 390px 三档宽度关键页面截图(设计文档验收标准),确认菜单、表格、抽屉、弹窗无溢出、重叠或空白渲染。

Out of Scope(硬边界)

  • 五个页面 <script> 块的任何改动(查询构造、CRUD、导入导出、回收站、权限指令、API 调用、错误处理逻辑);
  • 任何字段、列、字典、权限字符串、接口路径的变更;
  • 后端仓库(pipe-ner-server)与 UE 仓库(Pipelines)的任何改动;
  • 全局样式文件(src/assets/styles/*)与其他模块页面的改动;
  • 其他供水页面(报警、监测、设备、工单、GIS、首页)的改动;
  • 新增后端统计接口与页面指标卡;
  • WaterFacilityImportDialog、回收站弹窗的视觉改动(保持 Element Plus 默认);
  • 测试断言基线的修改——类名刻意保留以实现测试零改动;若执行者认为必须改测试,即已越界,须先取得确认;
  • 提交/合并/推送——沿用既有约定不合并、不推送,提交策略由用户另行决定。

Further Notes

  • 五个页面位于 basic 模块,但已确认仅供水菜单壳引用,影响面封闭在五个供水菜单。
  • EP 图标全局注册(svgicon.js 遍历 @element-plus/icons-vue 注册组件名),模板零 script 改动即可用图标;图标名拼写错误会在运行时产生 Vue 警告,T-A 打样时必须人工验证五个图标正常渲染。
  • 全局 index.scss.facility-* 规则是五页唯一致用方;改造后页内 scoped 类(water-page/filter-card/table-card 等)与全局类无命名冲突,全局规则原样保留,清理另行任务处理。
  • 参照页(WaterDevicePage/WaterAlarmPage 等)自带全套重复 scoped 样式是既有模式;本任务只抽取供水设施五页的共享 SCSS,不反向重构参照页。
  • 会话记忆按 AGENTS.md 约定记录于 memory/sessions/2026-09-05.md