unis_manager/.workbuddy/memory/2026-09-14.md

109 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 2026-09-14 负责人 / 团队成员:去掉主次 + 横向排列
## 需求(用户原话)
> 负责人、团队成员 不要分主次,横向排列(显示和管理页面)
采用的解读:① 界面不再出现「主」标记与首行特权,名单里每一位平级、都可删;
② 无论显示处(列表列、详情只读)还是管理处(抽屉修改档的人员编辑器),都改成横向一排,不再纵向堆叠。
## 改动(纯前端,未动后端与库)
`web/app.js`
- `peopleEditorHtml()`:去掉 `opts.primary`(「主」徽标)与「首行不可删」的特殊分支,
每一行都是 `人名下拉 + ×`;「+ 添加负责人 / 添加成员」从名单下方挪进名单容器末尾。
- `bindDrawerPeople()`:新增行 `box.insertBefore(row, add)`(原来 appendChild 会把新行甩到按钮后面)。
- 删掉 `ownersHtml()`(原「第一位用正文、其余用小标签」),只读处统一用 `nameChips()` 对等小标签;
`nameChips(list, empty)` 多一个占位符参数,供卡点/待回款两表保留「未指派」文案。
- 4 处负责人列/行改为全部负责人:项目列表、定制「项目明细」、定制「卡点提醒」、定制「待回款排行」。
后两处原来只显 `x.p.owner`,现在 `nameChips(x.p.owners, "未指派")`。
- 新增 `OWNER_HINT`(两处抽屉共用):界面不标主次,但如实写明「看板、筛选、导出与人力负载取名单第一位做归属统计」。
`web/styles.css`
- `.people-rows`:`flex-direction: column` → `flex-wrap: wrap`(横向一排、放不下自动换行);
`.people-row` 改 `inline-flex`;删掉随本次改动失效的 `.people-tag`。
- 新增 `.people-cell { display:flex; flex-wrap:nowrap; gap:4px }` 给表格里的负责人列。
(先试了 `wrap + max-width:152px`,结果 table 自动布局把列压到 47px、每人一行,等于还是竖排,故改成一排不换行。)
`README.md`:功能表「负责人与团队」行、负责人下拉小节、数据模型 `owner=主负责人` 措辞、API 备注同步。
## 口径没动(重要)
- 存储照旧:`owner` 列 = `owners[0]`(`models.set_people` 负责回写)。UI 不再暗示主次,
但**看板、列表筛选、导出、人力负载、财务「按负责人汇总」仍按那一位归属**——删掉第一位就自动由后一位顶上(已实测)。
- 故意没改:新建弹窗的 `npOwner`/`ncOwner` 仍是单人下拉(建完去抽屉加人);
周看板卡片与右侧详情头仍是单个负责人 chip(该视图的负责人筛选下拉也按主负责人生成);
人力负载表、财务「按负责人汇总」是按人归属的统计表,不是展示位。
- 列表仍未加「团队成员」列(保持列表精简,成员在抽屉里看)。
## 验证(临时实例 8791 + `data/board.db` 副本,未写真实库)
- `node --check web/app.js` 通过;`dev.logs()` 全程为空。
- 项目列表:AI Agent 4 位负责人一排(`.people-cell` 内 chip 的 top 全等);无负责人显示「—」。
- 详情只读:负责人/团队成员首元素即 `.tag-mini`(不再有正文态的第一位),单行。
- 修改档:`#dwOwners`/`#cdOwners` 子项 `flex-wrap: wrap`、无 `.people-tag`、4 行都带 `[data-pdel]`、
添加按钮在末尾;点添加后空行插在按钮之前。
- 删掉第一位(付艾)保存 → `GET /api/projects/83` 得 `owner=潘朝钊`、`owners=[潘朝钊,汤全昆,钟文俊]`。
- 定制「项目明细 / 卡点提醒 / 待回款排行」三表负责人列一排显示,空值文案仍分别是「—」和「未指派」。
- 收尾:8791 已停(`lsof -iTCP:8791 -sTCP:LISTEN` 空),临时库已删;用户实例 8770(PID 44988/99343)未动,
本轮无 .py 改动,浏览器刷新即可看到新界面。
## 待办(历史遗留,未动)
`scripts/import_excel.py` 里旧台账 `LedgerItem` 的导入解析是否退役。
---
# 2026-09-14 多负责人只对重点项目生效(定制交付改回单负责人)
## 需求(用户原话)
> 多负责人仅对于重点项目适用,请把相关的页面都做调整。
采用的解读:① 多负责人(`owners` 名单)这套能力**只保留在重点项目**;
② 定制交付回到**单个「交付负责人」下拉**,但**上一轮新增的「团队成员」保留**(用户没说要撤);
③ 定制侧所有展示位(列表列、只读档、项目明细、卡点提醒、待回款排行)与筛选口径都按单负责人走。
## 前端 `web/app.js`
- 定制抽屉修改档 2044:`#cdOwners` 人员编辑器 → `ownerSelectHtml(p.owner, 'id="cdOwner" style="width:150px"')`
单人下拉;2045 的 `peopleEditorHtml("cdMembers", …)` 团队成员编辑器原样保留。
- 定制保存 body 2147-2148:`owner: $("#cdOwner").value || null` + `members: peopleValues("cdMembers")`,不再送 `owners`。
- 定制只读档 2058-2059:`ro("交付负责人", esc(p.owner||"—"))`(回到纯文本)、`ro("团队成员", nameChips(p.members))`。
- 定制三表负责人列改回单人名:项目明细 1831、卡点提醒 1674、待回款 1780。
- 顺手清掉本轮造的孤儿:`OWNER_HINT` 常量删除并内联到唯一使用点(重点项目 2775,文案改口径);
`nameChips(list)` 去掉 `empty` 参数(上一轮为定制两表加的,现在没人传了)。
- 新建弹窗 `ncOwner`(1895)/`npOwner` 本就是单人下拉,未动。
- 重点项目侧**一行未改**:列表 1350 `.people-cell`+`nameChips(p.owners)`、抽屉 2775/2780/2789/2790、保存 2943-2944。
(`.people-cell` CSS 还有这一处使用,故保留。)
## 后端(收口理由:界面已不可达的写路径必须一起关掉,否则库里会有两份真相)
- `app/routers/custom.py`:`CustomProjectIn.owners` 字段删除;孤儿 import `or_`、`people_like` 清掉;
列表筛选 → `q.filter(CustomProject.owner == owner)`;
POST `model_dump(exclude={"members"})` + `set_people(cp, None, payload.members)`;
PATCH → `set_people(cp, None, payload.get("members"))`。传了 `owners` 也直接被忽略(已实测)。
- `app/routers/weekly.py`:124(定制段)→ `if owner and cp.owner != owner`;81(重点项目段)保留 `all_owners(...)`。
- `app/models.py`:`CustomProject.to_dict` 删 `"owners"` 键;`other_owners` 列注释 → `# 已停用:定制交付不做多负责人`。
**列不删、不加迁移**:`set_people(cp, None, …)` 不写该列,旧值原样躺在库里静默隐藏(已实测改写 owner 后旧值仍在)。
- `staff.py` 人名改名同步逻辑未动(对 custom 成为 no-op,但代码仍正确,不顺手重构)。
## `README.md`
功能表「负责人与团队」行改成「多负责人仅重点项目;定制 = 交付负责人(单人)+团队成员」;
筛选口径写明「重点项目命中任一负责人、定制按交付负责人命中」;
`peopleEditorHtml` 小节注明现在只剩重点项目抽屉在用;数据模型 / API 定制行同步(custom 不再接受 `owners`)。
## 迁移决策
真实库 `data/board.db` 的 `custom_projects` 119 行里 `owner`/`other_owners`/`members` **三列全空** → 无数据可迁,
故不做任何迁移脚本,只让界面与 API 停止读写 `other_owners`。
## 验证(临时实例 8792 + `/tmp/umtest/single.db` = 真实库副本 + 造数据,真实库只读)
- `node --check web/app.js`、`py_compile app/models.py app/routers/custom.py app/routers/weekly.py` 通过;`dev.logs()` 全程 `[]`。
- API:定制 `#5` 响应**无 `owners` 键**,`owner=陈玉婷`、`members=[潘远银,向上]`;重点 `#83` `owners=[付艾,潘朝钊]` 不变。
POST/PATCH 带 `owners` 被忽略;定制筛选「陈玉婷」→`[5]`,重点筛选「潘朝钊」→`[83,80]`;
`/weekly`、`/stats`、`/custom/board`、`/custom/stats`、`/staff`、`/focus`、`/export/*` 全 200。
注:`GET /api/custom/projects/{id}` 返回 `{project, updates, timeline}` 包壳,`owner` 在 `project` 下。
- UI(iab tab 30):定制只读档 labels = …交付负责人|团队成员…,无 `#cdOwners`;修改档 `#cdOwner` value=陈玉婷、
`#cdMembers` 2 行+添加按钮;端到端改「陈玉婷→汤全昆」保存 → toast「已保存」→
库 `(5,'汤全昆',',况春华,陈航,',',潘远银,向上,')`(other_owners 未被改写)→ 只读档显示正确;
筛选「汤全昆」命中、筛选遗留名「况春华」不再命中(符合预期)。
- 重点项目回归:列表一排多负责人(AI Agent = 付艾|潘朝钊);只读档 ownerChips/memberChips 各 2 个;
修改档 `#dwOwners`=[付艾,潘朝钊]、`#dwMembers`=[梁帅超,罗帮旺]、`.people-rows` 横向。
- 收尾:8792 已停、临时库已删;用户实例 8770(PID 520/44988)未动,`.py` 由 run.sh 热重载,前端刷新浏览器即可。
## 待办(未动,等用户定)
1. 周看板卡片与重点项目列表的负责人 chip 仍只显主负责人 `owner`,要不要改成显示全部负责人。
2. `scripts/import_excel.py` 旧台账 `LedgerItem` 导入是否退役(历史遗留)。