2026-08-05-post-list-name-link-bound-users-design.md 3.5 KB

职位管理列表:名称快捷链接 + 关联人员展示

日期: 2026-08-05
范围: web-admin 职位管理页 + GET /web/admin/posts 列表 enrichment
状态: 设计已确认,待实现

背景

职位管理(/#/system-manage/system/post)已有查看弹窗(SystemViewDialog)与「关联用户」能力,但列表中:

  • 「职位名称」为纯文本,需经操作菜单才能查看;
  • 无法一眼看到该职位已关联的人员。

目标

  1. 列表「职位名称」改为快捷链接,点击打开已有【查看】弹窗。
  2. 列表新增「关联人员」列,展示该职位全部关联用户姓名;超宽时换行,不省略。

非目标

  • 不改查看弹窗结构与加载逻辑(仍可按需拉绑定用户/角色)。
  • 不改关联用户 / 角色配置弹窗交互(仅保存后刷新列表以同步人名)。
  • Create/Update 请求体不写入关联人员字段。

方案选择

采用 列表接口批量 enrichment:

  • list_posts 对本页职位一次性查询 sys_user_post + sys_user,在每行附加只读字段 boundUserNames: string[]。
  • 避免前端对每行 N+1 请求 /posts/{id}/users。

姓名取值:优先 nick_name,为空则回退 user_no;过滤已删除用户(del_flag=0)。排序:与绑定表查询顺序一致即可(稳定、可预期)。

后端设计

响应字段

在职位列表项(及 _row_to_dict 用于列表场景)增加:

字段 类型 说明
boundUserNames string[] 关联用户显示名;无人则为 []

单条 create/update 成功返回可不强制带该字段;前端以列表刷新为准。

实现要点

  • 文件:backend/app/crud/post.py(或与 user.py 协作的批量查询函数)。
  • 在 list_posts 取得本页 SysPost 行后,按 post_id IN (...) + tenant_no 批量查绑定与用户昵称,再写入各行 dict。
  • 不信任客户端传入的 boundUserNames;写接口忽略该字段。

前端设计

页面

web-admin/src/views/system/post/index.vue

  1. 职位名称列

    • 模板:el-button link type="primary",文案为 row.postName。
    • @click → 已有 handleView(row)。
    • 行双击查看保持不变。
  2. 关联人员列

    • 位置:职位编码与状态之间。
    • 展示:boundUserNames 用顿号 、 拼接;空数组显示 —(formatDisplayOrDash 或等价)。
    • 样式:单元格内文案 white-space: normal、word-break: break-word,全部显示、超宽换行;不使用 show-overflow-tooltip 省略。
  3. 刷新

    • handlePostBindSubmit 成功后调用 loadData(),保证人名与绑定一致。

类型

web-admin/src/types/api.d.ts → Api.Post.PostItem 增加可选或必填:

boundUserNames?: string[]

列表接口保证返回数组时,前端按 row.boundUserNames || [] 防御即可。

验收标准

  • 点击职位名称打开与操作菜单「查看」相同的详情弹窗。
  • 列表显示该职位全部关联人员姓名,多人顿号分隔,列宽不足时换行可见全文。
  • 无人关联时显示 —。
  • 在「关联用户」中增删保存后,列表人名无需整页硬刷新即可更新(提交后 loadData)。

风险与约束

  • 单职位关联用户极多时行高变大:可接受(产品明确要求全部显示并换行)。
  • 列表分页仍按职位分页;enrichment 仅对本页职位批量查询,性能可控。