SFT/docs/superpowers/specs/2026-07-09-list-batch-delet...

10 KiB

通用列表批量删除交互改造 + 阶段2设计:基础配置(核心企业/客户经理)

  • 状态: 已与用户确认
  • 上级文档: 2026-07-08-fryl-frontend-overall-design.md(总体架构与阶段划分,阶段2=基础配置)
  • 支撑材料: 2026-07-08-module-requirements-mapping.md 第 8 节(核心企业/客户经理字段、业务规则、原型参考路径)
  • 本文档产出物: ①ProTable.vue 勾选+批量删除能力改造;②回归修改用户管理/角色管理/机构管理三页面的删除交互;③新增基础配置模块两个页面(核心企业管理、客户经理管理);④缺失的后端接口.md 对应条目更新/新增

0. 变更背景

阶段1完成后,用户对已交付的列表页交互提出统一调整要求:删除操作从"行内操作列单行删除"改为"表格勾选(支持多选)+ 顶部工具栏批量删除",且要求追溯应用到已完成的用户管理/角色管理/机构管理,并作为阶段2及后续所有列表页的标准交互模式。本文档一并覆盖该改造与阶段2的业务内容,后续阶段的列表页默认遵循本文档确定的交互模式,不再重复设计。

1. 范围

Part A(交互改造,影响已有代码):

  • src/components/ProTable.vue 增加勾选列与选中状态管理
  • src/views/system/user/UserList.vuerole/RoleList.vueorg/OrgList.vue 三页面的删除交互回归修改
  • mock-server 新增批量删除路由(替换原单个 DELETE /xxx/{id})
  • 缺失的后端接口.md 第 15 条(用户删除)、第 20 条(角色删除部分)、第 23 条(机构删除)更新为批量删除契约

Part B(阶段2新内容):

  • 核心企业管理(/base-config/channel):完整 CRUD
  • 客户经理管理(/base-config/manager):完整 CRUD
  • 菜单树新增顶层模块"基础配置",两个子节点及按钮权限码,role_admin 内置角色权限同步更新
  • 缺失的后端接口.md 新增"基础配置接口"一节

不包含:其余业务模块(客户管理/钱包管理等)。

2. Part A:ProTable 勾选 + 批量删除能力

2.1 ProTable.vue 改造点

  • 新增 rowSelection prop(Boolean,默认 true),控制是否渲染勾选列(极少数将来可能出现的只读列表页可关闭)
  • 内部新增 selectedRowKeys = ref([]),通过 <a-table :row-selection="rowSelection ? { selectedRowKeys, onChange } : undefined"> 接入 AntD 勾选列
  • 以下时机自动清空 selectedRowKeys(不做跨页选中保留,保持实现简单):handleSearchhandleResethandleTableChange(翻页/改分页大小)、reload() 执行完成后
  • defineExpose 新增导出 selectedRowKeys(供父组件 :disabled="selectedRowKeys.length === 0" 判断)及 clearSelection() 方法
  • 沿用现有 #actions 具名 slot(已渲染在搜索表单下方、表格上方的 .toolbar 区域),不新增 slot 名称;业务页面在该 slot 内并排放置"新增""删除"两个按钮

2.2 批量删除交互统一模式(供 Part A 回归页面与 Part B 新页面共同遵循)

<template #actions>
  <a-space>
    <a-button v-permission="'xxx:add'" type="primary" @click="openCreateModal">新增</a-button>
    <a-popconfirm
      title="确定删除选中的 N 项吗?"
      :disabled="proTableRef.selectedRowKeys.length === 0"
      @confirm="handleBatchDelete"
    >
      <a-button v-permission="'xxx:delete'" danger :disabled="proTableRef.selectedRowKeys.length === 0">
        删除
      </a-button>
    </a-popconfirm>
  </a-space>
</template>
  • 未勾选任何行时"删除"按钮 disabled(而非隐藏),鼠标悬浮可感知按钮存在但当前不可用
  • 确认后调用对应批量删除接口,传入 selectedRowKeys
  • 接口返回后按下述规则展示结果,然后 proTableRef.reload():
    • 全部成功:message.success('已删除 N 条')
    • 部分成功:Modal.warning,标题"部分删除成功",内容汇总"成功 X 条;以下 Y 条未删除:① 名称 - 原因 ② 名称 - 原因 …"
    • 全部失败:Modal.error 展示同样的失败清单

2.3 行内操作列保留范围

只有"删除"移出行内操作列。以下操作因业务上天然只能针对单条记录,继续保留在行内操作列:

  • 用户管理:修改、锁定/解锁、密码修改、密码重置并发短信
  • 角色管理:修改(、查看,若有)
  • 机构管理:修改

2.4 mock-server 批量删除接口设计

统一契约(user/role/org 三个资源同构):

DELETE /system/{resource}/batch

请求参数(Body):{ ids: string[] }(至少 1 个)

响应 data:

字段 类型 说明
successIds string[] 删除成功的 id 列表
failed array 删除失败项,元素结构 { id, name, reason }

code 始终为 200(接口调用本身成功);部分/全部业务失败通过 data.failed 体现,不使用错误 code。校验规则复用各资源已有的删除保护规则(内置角色/机构不可删、关联用户不可删等),逐条判断,不因一条失败而中断整个批次。

原有单个 DELETE /system/{resource}/{id} 接口移除,批量接口以 ids: [singleId] 覆盖单删场景,避免维护两套契约。

3. Part B:核心企业管理

3.1 字段(表单 + 列表)

字段 类型 必填 说明
渠道名称 string 文本输入
渠道编号 string 文本输入,不做唯一性校验(可与其他渠道共用同一编号)
应用编号 string 文本输入
母户开户行 string 文本输入
所属机构 机构 id 复用 OrgTreeSelect 组件,全量机构树单选(需给该组件增加可配置 placeholder prop,默认值改为"请选择所属机构"以适配非"上级机构"场景)
创建时间 string - 自动生成,列表展示,不出现在表单

列表列:序号、渠道名称、渠道编号、应用编号、母户开户行、所属机构、创建时间、操作(仅"修改"按钮,行内)。

3.2 查询条件

所属机构(OrgTreeSelect)、渠道编号、渠道名称(严格对应 docx 2.8.1.3)。

3.3 操作与业务规则

  • 新增/修改/批量删除/查询,完整 CRUD(已与用户确认,不受 docx 详细章节仅提"新增"字面限制)
  • 不做删除引用检查(当前阶段无其他模块真实引用渠道数据)
  • 无查看态,新增/修改复用同一弹窗表单

3.4 API

  • GET /base-config/channel/list?orgId&channelCode&channelName&page&pageSize{ list, total }
  • POST /base-config/channel
  • PUT /base-config/channel/{id}
  • DELETE /base-config/channel/batch(body { ids })

4. Part B:客户经理管理

4.1 字段(表单 + 列表)

字段 类型 必填 说明
机构号 string 自由文本,不关联本系统机构树,不做唯一性校验
机构名称 string 自由文本,与机构号手动配对录入,不做关联校验
工号 string 文本输入,全局唯一
姓名 string 文本输入

列表列:序号、机构号、机构名称、工号、姓名、操作(仅"修改"按钮,行内)。无创建时间列(docx 列表要素未列出,不额外添加)。

4.2 查询条件

机构名称、机构号、姓名、工号(按原型截图 4 个查询字段,覆盖 docx 文字描述的工号/姓名两项)。

特殊提示:仅当用户点击"查询"按钮主动触发搜索(非页面初次进入的默认加载)且返回结果为空列表时,除展示空表格外,额外 message.warning('客户经理不存在'),落地 docx"查询时必须校验客户经理是否存在"的规则。

4.3 操作与业务规则

  • 新增/修改/批量删除/查询,完整 CRUD
  • 工号重复时新增/修改返回业务错误码,前端提示"工号已存在"
  • 不做删除引用检查

4.4 API

  • GET /base-config/manager/list?orgCode&orgName&name&jobNumber&page&pageSize{ list, total }
  • POST /base-config/manager
  • PUT /base-config/manager/{id}
  • DELETE /base-config/manager/batch(body { ids })

5. 菜单权限树变更

mock-server/data/menu.jsmenuTree 根数组追加一个新的顶层节点(与 system 同级):

{
  "id": "base_config",
  "name": "基础配置",
  "path": "/base-config",
  "icon": "AppstoreOutlined",
  "type": "menu",
  "children": [
    {
      "id": "base_channel",
      "name": "核心企业管理",
      "path": "/base-config/channel",
      "component": "base-config/channel/ChannelList",
      "type": "menu",
      "buttons": [
        { "code": "channel:add", "name": "新增" },
        { "code": "channel:edit", "name": "修改" },
        { "code": "channel:delete", "name": "删除" }
      ]
    },
    {
      "id": "base_manager",
      "name": "客户经理管理",
      "path": "/base-config/manager",
      "component": "base-config/manager/ManagerList",
      "type": "menu",
      "buttons": [
        { "code": "manager:add", "name": "新增" },
        { "code": "manager:edit", "name": "修改" },
        { "code": "manager:delete", "name": "删除" }
      ]
    }
  ]
}

mock-server/data/roles.js 中内置角色 role_adminmenuIds 需追加 'base_config', 'base_channel', 'base_manager'(buttonCodes 通过 flattenButtons(menuTree) 动态计算,无需手动改)。

对应视图文件:src/views/base-config/channel/ChannelList.vuesrc/views/base-config/manager/ManagerList.vue

6.《缺失的后端接口.md》变更清单

  • 更新第 15 条(用户删除)→ 改为 DELETE /system/user/batch,补充 successIds/failed 响应字段表
  • 更新第 20 条角色删除部分 → 改为 DELETE /system/role/batch,同上
  • 更新第 23 条机构删除部分 → 改为 DELETE /system/org/batch,同上
  • 新增"8.3 系统管理接口"末尾或独立新增"8.4 基础配置接口"一节,包含:核心企业列表查询/新增/修改/批量删除(4条)、客户经理列表查询/新增/修改/批量删除(4条),共 8 条

7. 验收标准

  • 用户管理/角色管理/机构管理三页面:表格出现勾选列,行内操作列不再有"删除";顶部工具栏"新增/删除"并列,未勾选时删除按钮禁用;勾选后可批量删除,混合可删/不可删对象时能看到汇总失败原因提示
  • 核心企业管理、客户经理管理两页面均可完整走通:查询(含"客户经理不存在"提示)、新增、修改、批量删除
  • 顶部主菜单出现"基础配置"模块,其下"核心企业管理""客户经理管理"两个二级菜单可正常访问、按钮权限受角色勾选控制
  • npm run build 通过;Edge headless 端到端验证覆盖上述交互闭环
  • 缺失的后端接口.md 完成本文档第 6 节列出的更新与新增