定开:验收统计改回「严格按验收时间」口径
按用户确认:验收严格看「验收时间」(accept_date,Q1~Q4),没填验收时间的不计入;本季度 = 验收时间等于当前季度,本年 = 有验收时间。 去掉上一版的「项目状态=已验收」门槛与「验收时间为空算本季度」的兜底;工作看板同口径同步。 (注:因此改「项目状态」不会影响验收统计。)develop-chezhiqi
parent
cd37ea4661
commit
0cf172f49a
|
|
@ -23,4 +23,17 @@
|
||||||
2. **「本周」= 9月第4周、默认展示本周**:`periods` 表原来只到「9月第3周」,`/api/periods` 的 `today_id` 为 `null`,前端只能退回最后一个周期(第3周)。
|
2. **「本周」= 9月第4周、默认展示本周**:`periods` 表原来只到「9月第3周」,`/api/periods` 的 `today_id` 为 `null`,前端只能退回最后一个周期(第3周)。
|
||||||
3. **周次按时间自动创建**:`app/routers/board.py` 的 `list_periods` 里加了一句 —— `_week_period(db, *constants.week_of_date(date.today()))`(复用 `focus._week_period`),每次取周期列表时自动补上「今天所在的这一周」。实测首次请求即生成 **9月第4周(id 53,2026-09-21 ~ 09-27)**,`today_id = 53`,无需手动新建。
|
3. **周次按时间自动创建**:`app/routers/board.py` 的 `list_periods` 里加了一句 —— `_week_period(db, *constants.week_of_date(date.today()))`(复用 `focus._week_period`),每次取周期列表时自动补上「今天所在的这一周」。实测首次请求即生成 **9月第4周(id 53,2026-09-21 ~ 09-27)**,`today_id = 53`,无需手动新建。
|
||||||
|
|
||||||
- 重启 uvicorn(PID 26184);`node --check` / `ast.parse` / `/health` 均通过。本轮改动**未提交**。
|
- 重启 uvicorn(PID 26184);`node --check` / `ast.parse` / `/health` 均通过。
|
||||||
|
|
||||||
|
## 推送 develop-chezhiqi
|
||||||
|
- 提交 **cd37ea4**「定开:统计口径按项目状态同步 + 周次按时间自动创建(合并 main V 0.1.1)」(6 files changed, 53 insertions, 7 deletions)。
|
||||||
|
- 已 push:`07e1b0a..cd37ea4 develop-chezhiqi -> develop-chezhiqi`(此次同时把 fast-forward 的 `bcb3feb V 0.1.1` 一起带上远端);`git status -sb` 复核本地与远端一致。
|
||||||
|
- 仍未提交:`data/board.db.bak-*` 本地备份(8 个,保持 untracked)。
|
||||||
|
|
||||||
|
## 验收口径回退为「严格按验收时间」(用户确认)
|
||||||
|
- 用户在我提出「严格按验收时间 vs 状态联动」后回复「确认」→ 按**严格口径**改回:
|
||||||
|
- `web/app.js` 定开 `renderCustomList`:`accRows = allRows.filter(p => qOf(p.accept_date))`(有验收时间才计入);本季度 = `accept_date == 当前季度`;本年 = 有验收时间。
|
||||||
|
- 工作看板同口径(`customAll`)一起改回。
|
||||||
|
- 去掉了上一版的「项目状态=已验收」门槛与「验收时间为空算本季度」的兜底。
|
||||||
|
- 数字:改成严格口径后 **本年验收 68 / 本季度验收(Q3) 25 / 本季金额 101.54 万** —— 与改之前一致(因为用户已把 3 条缺验收时间的项目补上了验收时间,两种口径现在结果相同)。
|
||||||
|
- 副作用:**改「项目状态」不会影响验收统计**(验收只看验收时间)——已在回复中说明。
|
||||||
|
|
|
||||||
BIN
data/board.db
BIN
data/board.db
Binary file not shown.
17
web/app.js
17
web/app.js
|
|
@ -1178,17 +1178,16 @@
|
||||||
const [data, focusRows, customAll] = await Promise.all([
|
const [data, focusRows, customAll] = await Promise.all([
|
||||||
api("/weekly" + scopeQuery()),
|
api("/weekly" + scopeQuery()),
|
||||||
api("/focus" + focusQuery(["archived=false"])),
|
api("/focus" + focusQuery(["archived=false"])),
|
||||||
// 「本季度验收」与「定制项目 · 项目总览」同一口径:先看「项目状态=已验收」,季度归属再按「验收时间」
|
// 「本季度验收」与「定制项目 · 项目总览」同一口径:严格按「验收时间」(Q1~Q4 季度文本)
|
||||||
api("/custom/projects?archived=false"),
|
api("/custom/projects?archived=false"),
|
||||||
]);
|
]);
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const qYear = now.getFullYear(), qNo = Math.floor(now.getMonth() / 3) + 1;
|
const qYear = now.getFullYear(), qNo = Math.floor(now.getMonth() / 3) + 1;
|
||||||
const qOf = (s) => { const t = String(s || "").trim().toUpperCase(); return /^Q[1-4]$/.test(t) ? t : ""; };
|
const qOf = (s) => { const t = String(s || "").trim().toUpperCase(); return /^Q[1-4]$/.test(t) ? t : ""; };
|
||||||
// 先按「项目状态=已验收」过滤(状态一改统计立即同步);季度归属再按「验收时间」,为空时算本季度
|
// 与「定制项目 · 项目总览」同一口径:严格按「验收时间」(Q1~Q4 季度文本),没填的不计入
|
||||||
const accRows = customAll.filter((p) => String(p.project_status || "").trim() === "已验收");
|
const accQuarter = customAll.filter((p) => qOf(p.accept_date) === "Q" + qNo);
|
||||||
const accQuarter = accRows.filter((p) => { const q = qOf(p.accept_date); return !q || q === "Q" + qNo; });
|
|
||||||
const accQuarterAmount = accQuarter.reduce((a, p) => a + Number(p.amount || 0), 0);
|
const accQuarterAmount = accQuarter.reduce((a, p) => a + Number(p.amount || 0), 0);
|
||||||
const accYearCount = accRows.length;
|
const accYearCount = customAll.filter((p) => qOf(p.accept_date)).length;
|
||||||
state.weekly = data;
|
state.weekly = data;
|
||||||
state.customAll = customAll; // 右栏「高风险项目」用全量台账
|
state.customAll = customAll; // 右栏「高风险项目」用全量台账
|
||||||
state.focusRows = focusRows;
|
state.focusRows = focusRows;
|
||||||
|
|
@ -1939,12 +1938,12 @@
|
||||||
|
|
||||||
const signedQuarter = placed.filter((p) => inQuarter(p.sign_date));
|
const signedQuarter = placed.filter((p) => inQuarter(p.sign_date));
|
||||||
const signedYear = placed.filter((p) => inYear(p.sign_date));
|
const signedYear = placed.filter((p) => inYear(p.sign_date));
|
||||||
// 验收:以「项目状态 = 已验收」为准(状态一改,统计立即同步);
|
// 验收:严格按「验收时间」(accept_date,季度文本 Q1~Q4) —— 没填验收时间的不计入;
|
||||||
// 季度归属看「验收时间」(accept_date,季度文本 Q1~Q4);验收时间为空时按「本季度」计。
|
// 本季度 = 验收时间等于当前季度;本年 = 有验收时间(全部季度)。
|
||||||
const qOf = (s) => { const t = String(s || "").trim().toUpperCase(); return /^Q[1-4]$/.test(t) ? t : ""; };
|
const qOf = (s) => { const t = String(s || "").trim().toUpperCase(); return /^Q[1-4]$/.test(t) ? t : ""; };
|
||||||
const thisQ = "Q" + Q;
|
const thisQ = "Q" + Q;
|
||||||
const accRows = allRows.filter((p) => String(p.project_status || "").trim() === "已验收");
|
const accRows = allRows.filter((p) => qOf(p.accept_date));
|
||||||
const accQuarter = accRows.filter((p) => { const q = qOf(p.accept_date); return !q || q === thisQ; });
|
const accQuarter = accRows.filter((p) => qOf(p.accept_date) === thisQ);
|
||||||
const accYear = accRows;
|
const accYear = accRows;
|
||||||
|
|
||||||
const stat = (label, count, amount, color) =>
|
const stat = (label, count, amount, color) =>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue