From a9298ac6ea235bd207a7e3e14c247d067d056728 Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Wed, 5 Aug 2026 14:28:42 +0800 Subject: [PATCH] docs: add post list name-link and bound users design Co-authored-by: Cursor --- ...-post-list-name-link-bound-users-design.md | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-05-post-list-name-link-bound-users-design.md diff --git a/docs/superpowers/specs/2026-08-05-post-list-name-link-bound-users-design.md b/docs/superpowers/specs/2026-08-05-post-list-name-link-bound-users-design.md new file mode 100644 index 00000000..8463d51b --- /dev/null +++ b/docs/superpowers/specs/2026-08-05-post-list-name-link-bound-users-design.md @@ -0,0 +1,91 @@ +# 职位管理列表:名称快捷链接 + 关联人员展示 + +**日期:** 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` 增加可选或必填: + +```ts +boundUserNames?: string[] +``` + +列表接口保证返回数组时,前端按 `row.boundUserNames || []` 防御即可。 + +## 验收标准 + +- 点击职位名称打开与操作菜单「查看」相同的详情弹窗。 +- 列表显示该职位全部关联人员姓名,多人顿号分隔,列宽不足时换行可见全文。 +- 无人关联时显示 `—`。 +- 在「关联用户」中增删保存后,列表人名无需整页硬刷新即可更新(提交后 `loadData`)。 + +## 风险与约束 + +- 单职位关联用户极多时行高变大:可接受(产品明确要求全部显示并换行)。 +- 列表分页仍按职位分页;enrichment 仅对本页职位批量查询,性能可控。