8.9 KiB
项目长期记忆 · unis_manager
软件部关键任务追踪看板。FastAPI 后端 + 原生 JS 前端 + SQLite。
运行环境(Windows)
run.sh 是 macOS 专用(open、/Users/jiliu/... 绝对路径),Windows 上按以下方式手动跑:
- Python 解释器(已装好依赖):
C:/Users/Administrator/.workbuddy/binaries/python/envs/default/Scripts/python.exe - 装依赖:
<PY> -m pip install -r requirements.txt - 启动:
<PY> -m uvicorn app.main:app --host 127.0.0.1 --port 8770 - 端口/配置来自
.env(PORT=8770)。DB 用 SQLite,落在data/board.db,仓库里已带数据。 - 健康检查:
GET /health;API 文档:/api/docs;首页:/。
关键结构
app/后端:main.py(入口,挂载/api子应用 +/static)、models.py、schemas.py、constants.py、routers/{board,projects,custom,focus,weekly,staff,ai,export}.py、ai_parser.py、export.py、schema_patch.py、config.py。web/前端:index.html/app.js/styles.css/icons.js(零构建,no-cache + ETag)。scripts/运维脚本:init_db.py、import_excel.py、import_staff.py、migrate_custom.py、shift_year.py、fix_period_split.py、merge_project.py、add_entry_date.py、import_custom_ledger.py(把《定开项目.xlsx》市场台账导入custom_projects,支持--dry-run/--date,按 项目ID→名称 匹配做 upsert + 变更比对)。.workbuddy/memory/存每日工作日志(随仓库提交,2026-09-12 起)。schema_patch.ensure_columns会在启动时自动给已有表补上模型里新增的可空列(ALTER TABLE ... ADD COLUMN),所以加字段只需改models.py,不用写迁移脚本。
业务模型
四模块:① 工作看板(只读汇总 /api/weekly+/api/focus)② 项目管理(projects/tasks/updates)③ 定开项目(原「定制交付」,表 custom_projects/custom_updates)④ 每周重点工作(weekly_focus)。
三支撑页:人力资源(staff,全系统负责人唯一来源)、更新录入、设置。
②③ 两套独立项目体系,共用一个花名册。
定开项目的两套字段(2026-09-17 起)
custom_projects 同时承载两套口径,互不覆盖:
- 交付跟踪口径(原有):
stage(商务阶段)/progress/revenue_amount/invoice_amount/received_amount/owner(交付负责人,来自花名册) - 市场台账口径(2026-09-17 从《定开项目.xlsx》导入):
origin(项目归属)/project_code(项目ID)/office(办事处)/industry(行业)/man_days(市场下单人天)/market_owner(市场责任人,销售侧,不在花名册)/project_status(已验收/待开发/交付完成/交付中/退单)/accept_plan(推动验收计划)/risk_level(1.高风险/2.低风险)/update_date(更新时间)。origin(项目归属) 取值:新签订单 / 存量项目 / 汇智直签 / 提前交付(2026-09-20 增) / 其他;progress(Float, NOT NULL, 默认 0) 复用为「交付中」项目的进度(%)
映射要点:下单时间→sign_date、办事处→region(归一化)+office(原样)、验收时间→accept_date(存的是季度文本 Q1..Q4,不是日期)、备注→remark。accept_date 与 accept_plan 互补(60+59=119)。
accept_date vs accept_date_real(2026-09-17 增):accept_date 存季度文本(Q1..Q4),只作展示;新增 accept_date_real(真实日期 YYYY-MM-DD)专门给「本月/本年验收」统计用。导入脚本会给「已验收 + 季度文本」的行补当年季度末占位(Q1→03-31…Q4→12-31),且只在库中为空时补,不覆盖界面手改的真日期。统计口径(2026-09-20 定稿):下单看 sign_date(本季度/本年按日期归属);验收看「验收时间」accept_date(季度文本 Q1~Q4)——本季度验收 = accept_date 等于当前季度,本年验收 = 有验收时间(全部季度)。不再用 accept_date_real(它只作参考/展示,历史上有 4 条 Q3 行缺值,曾导致本季度验收少算)。
明细表(renderCustomList)列顺序对齐 Excel 14 列 + 更新时间 + 操作;行内只有「修改」(详情靠点名称;归档按钮已按要求去掉)。定开视图有 3 个 tab:项目明细 / 本周进展 / 年度任务(state.customTab;原交付流水线 / 阶段看板 / 财务跟踪已下线)。列表在客户端按 关键字 + 项目归属 + 区域 + 状态 过滤。统计条 .stat-row 基于全部已下单项目(不随搜索/筛选变化):已下单项目 / 合同额 + 本季度下单 + 本年新增下单 + 本季度验收 + 本年验收——已下单 = 项目归属 ∈ {新签订单, 存量项目, 汇智直签}(isPlaced() / CUSTOM_PLACED),提前交付不计入下单。「本周进展」tab(renderCustomWeekly)列出「更新时间」在本周(周一~周日)的项目,上方 3 张卡:验收情况(本周更新 ∩ 已验收)/ 本周新增项目(按「下单时间」sign_date 在本周 ∩ 已下单或提前交付)/ 交付项目(本周更新 ∩ 交付中+交付完成)。「年度任务」tab(renderCustomAnnual)按《年度任务.xlsx》出表:季度 + 计收目标(万元,前端常量 CUSTOM_ANNUAL_TARGETS = Q1 35/Q2 225/Q3 160/Q4 260)+ 回填列——计收项目(accept_date == Qn)/ 新增签单(isPlaced 且 sign_date 在本年该季度),金额元→万元,完成率 = 计收金额 ÷ 目标。表格 customTableHtml(rows) 两个 tab 共用,在「项目状态」后新增进度列(progress,仅 状态=交付中 或 >0 时显示 N%)。项目名称搜索框回车才查询(bindKeyword(id,{enter:true});cKeyword 定开 / pKeyword 项目已启用)。导出 Excel 列与明细表一致(15 列),跟随 归档/区域/状态/关键字 筛选。openNewCustomDialog(新建,更新录入页共用)字段同样对齐 Excel,提交时 region 由后端按 office 归一化(深圳→广东)。
update_date(更新时间)的语义:只在台账字段确有变化时才刷新(无变化不刷新)。
- 取值:导入/初始 = 该行「下单时间」
sign_date(2026-09-17 全量刷过);界面「修改 / 新建」提交后 = 提交时间YYYY-MM-DD HH:MM(2026-09-18 起)。字段是String(16),正好放「YYYY-MM-DD HH:MM」。 - 用于明细表按更新时间倒序 + 按周筛选/删除。
- 与
updated_at(TimestampMixin 自动时间戳,任何改动都变)不是一回事。
导入「市场责任人」等销售侧人名不走花名册校验,不要往 staff 里塞。
登录与权限(2026-09-23 合并 main V 0.1.1 起)
- 全站需登录:未登录访问
/api/*返回 401。默认管理员 admin / admin123(app/config.py的ADMIN_PASSWORD默认值,可用.env覆盖);另有user(部门成员)。 - 权限模型:
roles.menus是 JSON(board/custom/focus/intake/projects/rbac/settings/staff,值rw/ro);内置角色 管理员 / 部门成员 / 只读访客。代码:app/security.py(hashlib+hmac 手写,无新依赖)、app/routers/auth.py、app/routers/rbac.py;表users/roles/user_sessions。
术语(2026-09-16 起)
模块③ 的正式称呼是 「定开项目」(旧称「定制交付」),界面统一用「定开」:定开项目 / 定开项目明细 / 定开合同额 / 定开记录 / 定开动态 / 定开待计收。categories 表里也有一行分类叫「定开项目」。
但这些字面量必须保留「定制」,改了会坏数据或逻辑:
"定制开发"—— 历史 Excel 的项目容器名,是import_excel.py/migrate_custom.py/fix_period_split.py/add_entry_date.py里的匹配条件。import_excel.py中(("定制","交付","项目支撑"), "定开项目")的元组键 —— 匹配 Excel 原始分组名,只有映射目标值是「定开项目」。"定制产品组"——staff.group的团队名,constants.py:STAFF_GROUPS里有它,7 人属于该组。
代码标识符(custom / custom_projects / API 路由 / CSS 类名)保持英文原名,未随中文改名。
约定
- 当前开发分支:
develop-chezhiqi(跟踪origin/develop-chezhiqi;main 为发布线)。 - 改代码后重启服务即可(未开 DEV 热加载)。
- 动数据库前先备份:
cp data/board.db data/board.db.bak。 - 周期标签格式
9月第1周,可写2027年1月第1周显式指定年份。
Windows 运维小抄
- 查端口占用:
netstat -ano | grep "127.0.0.1:8770.*LISTENING" - 停服务:git bash 下
taskkill //PID会被路径转换破坏参数,改用 PowerShellStop-Process -Id <PID> -Force更稳。 - 服务重启后
/health的BOOT_ID会变,可据此确认是新进程。