eng表单标签页化_f780aeeb.md 8.9 KB


name: eng表单标签页化 overview: 将 gw-ui/src/views/slaj/eng 下 10 个 atteng* 属性编辑弹窗内的超长表单,按现有 el-divider 分组改造为 el-tabs 标签页布局,单屏只显示一个分组,解决表单超出屏幕高度的问题。 design: architecture:

framework: vue

styleKeywords:

- Element Plus
- 企业级简洁
- 标签页分组
- 固定底部操作栏

fontSystem:

fontFamily: PingFang SC
heading:
  size: 16px
  weight: 600
subheading:
  size: 14px
  weight: 500
body:
  size: 14px
  weight: 400

colorSystem:

primary:
  - "#409EFF"
background:
  - "#FFFFFF"
  - "#F5F7FA"
text:
  - "#303133"
  - "#606266"
functional:
  - "#409EFF"
  - "#67C23A"
  - "#F56C6C"
  - "#909399"

todos:

  • id: global-dialog-scroll content: 在 index.scss 增加 eng 弹窗内容区 max-height+overflow 滚动规则 status: completed
  • id: convert-cws-res content: 将 attengcws、attengres 弹窗改为 el-tabs 分组并复位 activeTab(含单点地图) status: completed dependencies:
    • global-dialog-scroll
  • id: convert-dike-wadi content: 将 attengdike、attengwadi 弹窗改为 el-tabs 分组(含起点/终点双地图) status: completed dependencies:
    • global-dialog-scroll
  • id: convert-simple-views content: 将 attengwaga/sd/pust/othe/hyst 五个弹窗改为 el-tabs 分组 status: completed dependencies:
    • global-dialog-scroll
  • id: convert-irr content: 将 attengirr 弹窗改为 5 个 el-tab-pane 分组并复位 activeTab status: completed dependencies:
    • global-dialog-scroll ---

用户需求

工程属性编辑弹窗(10 个 eng 视图)表单字段过多,整体超出屏幕高度,用户希望采用「方案 B:将表单按现有分组拆成标签页(el-tabs)分块显示,单屏只展示一组」来改善。

产品概述

将各工程编辑弹窗内原本纵向排列、以 el-divider 分隔的长表单,重构为顶部标签切换的分组表单。每个分组(如基本信息、供水参数、时间信息等)对应一个 el-tab-pane,用户点击标签切换查看,弹窗高度不再随字段总数增长。

核心功能

  • 将 10 个工程视图弹窗内的 el-divider 分组改造为 el-tabs + el-tab-pane 结构,保持单个 el-form 不变以保证整体校验/提交有效。
  • 打开弹窗时激活标签重置到第一个分组。
  • 地图选点组件(TiandituMapPicker)随其所在分组移入对应 el-tab-pane,坐标回写逻辑不变。
  • 弹窗内容区限制最大高度并支持内部滚动,确保确定/取消按钮始终可见。
  • 弹窗宽度维持 750px,视觉风格与现有 Element Plus 一致。

技术栈

  • 前端框架:Vue 3(<script setup>)+ Element Plus(el-dialog / el-form / el-tabs / el-tab-pane
  • 样式:SCSS(全局 src/assets/styles/index.scss
  • 组件库:Element Plus(项目既有,沿用 el-* 组件与 dict-tagTiandituMapPicker 等自定义组件)

实现方案

总体策略

仅做「视觉分组」改造:把每个弹窗内的 el-form 内容从「el-divider + 连续 el-row」改为「el-tabs 包裹多个 el-tab-pane」,每个 el-tab-pane 容纳原一个分组的所有 el-row不拆分 el-form,仍由 proxy.$refs.formRef.validate() 统一校验全部字段(Element Plus 的 el-tab-pane 默认渲染全部面板,字段始终在 DOM 中,跨标签校验正常)。

关键技术决策

  1. 保持单一 el-form:若拆成多个 form 会破坏现有 validate/提交链路,且需重写校验聚合逻辑,风险高。沿用单 form + tabs 是最小侵入且最稳的方案。
  2. 标签状态复位:每个视图新增 const activeTab = ref('basic')(name 取首分组标识),在 handleAddhandleUpdateactiveTab.value = 'basic',避免上次停留的标签影响新记录。
  3. 地图组件随组迁移attengcws/attengres 的单点 mapCoordsattengdike/attengwadi 的起点 startCoords/终点 endCoords,整体移入对应分组 pane,v-modelcomputed 逻辑完全不变。
  4. 弹窗内容区滚动(全局):因 el-dialog 使用 append-to-body 将内容 teleport 到 body,scoped 深度选择器无法命中,故在全局样式 src/assets/styles/index.scss 增加 .el-dialog__body { max-height: 70vh; overflow-y: auto; } 规则(可限定 eng 弹窗 class 以免误伤其他弹窗),保证单标签仍较长时底部按钮始终可见。
  5. 删除原 el-divider:分组标题由 el-tab-panelabel 承担,原 el-divider 行移除。

实施注意(防回归)

  • 不改动任何字段 proprules、API 调用与提交逻辑,仅调整模板包裹结构。
  • el-tab-pane 不使用 lazy,确保校验时字段已挂载。
  • 地图组件高度(:height="300")保持不变。
  • 弹窗 footer(确定/取消)保持在 el-form 之外、el-dialog#footer 模板内,位于标签区下方固定可见。
  • 全局滚动样式需确认仅作用于 eng 编辑弹窗,避免影响其他短弹窗的默认内边距观感。

架构设计

各视图独立改造,结构一致:

flowchart TD
    A[el-dialog 750px] --> B[el-form ref=formRef :rules=rules]
    B --> C[el-tabs v-model=activeTab]
    C --> D[el-tab-pane label=基本信息]
    C --> E[el-tab-pane label=XX参数 含地图]
    C --> F[el-tab-pane label=时间信息]
    B --> G[footer 确定/取消 固定]

提交链路不变:submit()formRef.validate()add/update API → 关闭弹窗 → 刷新列表。

目录结构

gw-ui/src/assets/styles/
└── index.scss              # [MODIFY] 增加 eng 编辑弹窗内容区 max-height + overflow-y:auto 全局滚动规则
gw-ui/src/views/slaj/eng/
├── attengcws/index.vue     # [MODIFY] 基本信息/供水参数/时间信息 改为 el-tabs;新增 activeTab 并复位;含单点地图
├── attengres/index.vue     # [MODIFY] 基本信息/水库参数/时间信息 改为 el-tabs(字段最多);新增 activeTab 并复位;含单点地图
├── attengdike/index.vue    # [MODIFY] 基本信息/堤防参数/时间信息 改为 el-tabs;含起点+终点双地图
├── attengwadi/index.vue    # [MODIFY] 基本信息/引调水参数/时间信息 改为 el-tabs;含起点+终点双地图
├── attengwaga/index.vue    # [MODIFY] 基本信息/水闸参数/时间信息 改为 el-tabs
├── attengsd/index.vue      # [MODIFY] 基本信息/淤地坝参数/时间信息 改为 el-tabs
├── attengpust/index.vue    # [MODIFY] 基本信息/泵站参数/时间信息 改为 el-tabs
├── attengothe/index.vue    # [MODIFY] 基本信息/工程参数/时间信息 改为 el-tabs
├── attenghyst/index.vue    # [MODIFY] 基本信息/电站参数/时间信息 改为 el-tabs
└── attengirr/index.vue     # [MODIFY] 基本信息/灌区参数/渠道信息/渠系建筑物/时间信息 改为 5 个 el-tab-pane

(不在范围:eng/index.vue 的 base/attr/objEng 弹窗字段较少,无需改造;后端逻辑不变。)

关键代码结构

每个视图脚本新增(以 cws 为例,name 按首分组):

const activeTab = ref('basic')
// handleAdd / handleUpdate 开头增加:
activeTab.value = 'basic'

模板骨架(替换原 divider+rows):

<el-tabs v-model="activeTab">
  <el-tab-pane label="基本信息" name="basic"> ...原基本信息 el-row... </el-tab-pane>
  <el-tab-pane label="供水参数" name="supply"> ...原供水参数 el-row(含地图)... </el-tab-pane>
  <el-tab-pane label="时间信息" name="time"> ...原时间信息 el-row... </el-tab-pane>
</el-tabs>

设计风格

沿用项目既有 Element Plus 企业级简洁风格,不做视觉重构,仅将长表单的「纵向长列表」改为「顶部标签切换的分组表单」。标签栏位于弹窗内容区顶部,分组标题即标签名,单屏只渲染当前分组字段,显著降低纵向高度。

页面区块设计(以弹窗为例)

  • 标签栏区块:弹窗内容区顶部 el-tabs,标签左对齐;激活标签高亮(Element Plus 主色),未激活置灰,悬停有轻微背景变化微交互。
  • 分组内容区块:当前 el-tab-pane 内沿用原 el-row/el-col :span="12" 两列栅格布局,字段间距、label-width(140px) 保持不变;地图组件在对应分组内占满一行。
  • 底部操作区块el-dialog#footer 固定显示「确定 / 取消」按钮,始终可见,不随标签切换或内容滚动而消失。
  • 滚动行为:单分组仍较长时,弹窗内容区内部纵向滚动(max-height:70vh),标签栏与底部按钮固定,符合企业后台操作习惯。

响应式

弹窗宽度维持 750px(桌面端后台场景),标签在窄屏自动换行;字段两列栅格在极小宽度下由 Element Plus 栅格兜底。