# 2026-09-17 ## 清空「定开项目」模块数据 按用户要求清空 `data/board.db` 里定开项目模块的全部数据(保留表结构与其余模块)。 - 备份:`data/board.db.bak-before-clear-custom-20260917_105824` - 删除顺序:先子表 `custom_updates`(28 行)→ 再父表 `custom_projects`(119 行),避免外键孤儿。 - 清空前摘要:119 个定开项目(归档 0),合同额合计约 395.2 万,累计计收 0。 - 清空后校验:两表均 0 行,`custom_updates` 孤儿记录 0。 - 接口验证:`/api/custom/projects` 返回 `[]`;`/api/weekly` 的 `custom` 段 0 条,KPI 中 `custom_total / custom_amount / custom_new / custom_updated / revenue_delta` 全部归零。项目管理模块(`projects`/`tasks`/`updates`)未受影响。 - `ledger_items`(定开台账)本来就是 0 行,未动。 ## 导入《定开项目.xlsx》市场台账 + 扩展 custom_projects 字段 用户提供 `C:/Users/Administrator/Desktop/定开项目.xlsx`(Sheet1,120 行含表头 → **119 条数据**,14 列),要求导入定开项目库、按表格调整字段、并加「更新时间」字段便于按周查看变化。经确认采用:**新增字段(不重构)** + **每行一个更新时间** + **项目状态新增独立字段**。 ### 表结构(10 个新字段,靠 `schema_patch.ensure_columns` 自动 ALTER TABLE) `origin`(项目归属) / `project_code`(项目ID, index) / `office`(办事处) / `industry`(行业) / `man_days`(市场下单人天) / `market_owner`(市场责任人) / `project_status`(项目状态) / `accept_plan`(推动验收计划) / `risk_level`(风险值) / `update_date`(更新时间 YYYY-MM-DD, index) ### 字段映射(表格列 → DB 列) - 项目归属→origin、项目名称→name、项目ID→project_code、行业→industry、市场下单人天→man_days、市场责任人→market_owner、项目状态→project_status、推动验收计划→accept_plan、风险值→risk_level、备注→remark - **下单时间→`sign_date`**(原字段注释就是「签单/下单时间」);**办事处→`region`(归一化)+ `office`(原样)**;**验收时间→`accept_date`** - `entry_date`(入库时间)兜底取下单时间,保证明细列表「按入库时间倒序」有排序键 ### 数据质量(表格里就有的问题,未擅自改) - 重名 2 行:「甘肃省水利厅图像站建设项目二期」×2,**项目ID 不同**(HGSE25122401N / HGS025010202N)→ 导入脚本**有 ID 时只按 ID 匹配**,否则会互相覆盖 - 1 行无项目ID(高新区感知源-钰田(定制开发))、1 行无办事处 - 「验收时间/推动验收计划」是**季度文本**(Q1..Q4/27年),互补:60+59=119 - 「下单时间」混格式:91 个真日期 + 28 个文本(`2024年3月前`、`2024/`)→ 日期转 YYYY-MM-DD,文本原样存 - 「市场责任人」51 人**全部不在花名册**(销售侧人员,与 `owner` 交付负责人是两个概念) - 只有「深圳」不在区域词表 → 已在 `constants.REGION_ALIAS` 加 `深圳/深圳市 → 广东` ### 改动文件 - `app/models.py`:CustomProject 加 10 字段 + `to_dict` 输出 - `app/routers/custom.py`:PATCH 白名单加新字段;**台账字段有变化时刷新 `update_date`**(无变化不刷新,已实测);创建时写 `update_date`;`CustomProjectIn` 补字段 - `app/routers/export.py`:导出追加 10 列(末尾追加,保持原 money_cols 索引不变) - `web/app.js`:明细列表 16→25 列(加 项目ID/行业/项目归属/市场责任人/项目状态/风险值/人天/推动验收/更新时间);新增 `statusPill`/`riskPill` 小色块;详情抽屉加「市场台账」区块(只读 + 编辑);KPI 提示加 人天/高风险 - `scripts/import_custom_ledger.py`:**新建**,openpyxl 读取 + 按 ID/名称 upsert + 变更比对,支持 `--dry-run` / `--date` ### 验证 - 导入:新增 119 / 更新 0 / 无变化 0;**重复导入幂等**(0/0/119) - 分布与源表一致:项目状态 已验收60/待开发31/交付完成17/交付中9/退单2;行业 安平51/政府25/企业22/教育11/交通6/医疗2/行业1/高速1 - `/api/custom/projects` 返回 119 条含全部新字段;导出 34 列、合计行人天 5066 - PATCH 改 industry → update_date 由 2026-01-01 刷新为今天;提交相同值 → 保持旧日期(变更检测正确),测试后已还原 - 备份:`data/board.db.bak-before-ledger-import-20260917_141759` ### 遗留 / 待确认 - 119 行 `stage` 全是默认 `signed`、`progress` 0、计收/开票/回款为空 —— 新台账不带这些业务字段,模块里依赖它们的旧列(进度%、可确认、已计收、开票、回款)目前是空的 - 页面未做浏览器截图验证(agent-browser 未安装,装 Chromium 要 ~500MB 且规则禁止全局 npm),只做了 JS 语法校验 + 接口/导出功能验证 ## 定开项目明细表改为按 Excel 表头顺序展示 用户要求明细表字段参考导入的 Excel 表头。实际 Excel 表头顺序(14 列)为:项目归属 / 项目名称 / 项目ID / 下单时间 / 办事处 / 行业 / 市场下单人天 / 订单金额 / 市场责任人 / 项目状态 / 验收时间 / 推动验收计划 / 风险值 / 备注。 - 重排 `renderCustomList` 表头+数据行,完全按此顺序;追加「更新时间」(用户此前要求,非 Excel 字段)与「操作」列 → 共 16 列。 - 从主表移除 Excel 没有的旧列:区域、负责人(owner)、入库、交付、阶段、进度%、可确认/已计收/开票/回款 —— 这些仍保留在详情抽屉里。 - 顶部统计行改为:合同额/万、人天、高风险数、已验收数(去掉空的计收/开票/回款)。 - 纯前端改动(`web/app.js`),后端无需重启;接口此前已验证返回全部新字段。node `--check` 语法通过。 ## 明细表交互改造:去按钮 / 状态筛选 / 新建表单对齐 Excel / 统计条 用户四项要求:① 明细表去掉「详情」「归档」按钮 ② 新增「项目状态」筛选 ③「新建定开项目」字段参考 Excel 调整 ④ 表格上方加统计(项目数量+金额、本月/本年新增下单、本月/本年验收)。 ### 新增字段 `accept_date_real`(验收日期,真实日期) Excel 里「验收时间」是季度文本(Q1..Q4),无法算「本月/本年」,故新增 **`accept_date_real`**(String(16), YYYY-MM-DD, index)专门用于验收统计,与 `accept_date`(季度文本,展示用)并存互补。 - 改动:`models.py`(字段 + to_dict)、`custom.py`(CustomProjectIn / PATCH 白名单 / create 时 `region` 可由 `office` 归一化推导)、`scripts/import_custom_ledger.py`(导入时对「已验收」+季度文本的行补当年季度末占位;**仅在库中为空时补,不覆盖用户手改的真日期**)。 - 一次性回填:已导入的 119 行中 60 条「已验收」补上 2026 季度末(Q1→03-31/Q2→06-30/Q3→09-30/Q4→12-31),不动 `update_date`。结果:本年验收 60、本月(9月)验收 17。 ### 前端(web/app.js + styles.css) - **去按钮**:`renderCustomList` 行操作列只留「修改」(`data-cedit`);名称仍可点开详情(`data-copen`)。`bindCustomList` 移除 `data-carch` 绑定。 - **状态筛选**:工具栏加 `