From 32f1a386b44bf993be559d544ba3c4eb1b316e8b Mon Sep 17 00:00:00 2001 From: yumoqing Date: Fri, 4 Sep 2026 11:10:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=8D=E5=AE=A1=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=B8=A6=E5=9B=9E=E5=BD=92+=E5=A2=9E=E9=87=8F=E7=BB=93?= =?UTF-8?q?=E6=9E=84(=E4=B8=8A=E4=B8=80=E8=BD=AE=E6=84=8F=E8=A7=81+?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=AE=B0=E5=BD=95)=EF=BC=8C=E6=A0=B9?= =?UTF-8?q?=E6=B2=BB=E5=AE=A1=E6=A0=B8=E6=97=A0=E5=9B=9E=E5=BD=92=E6=84=8F?= =?UTF-8?q?=E8=AF=86=E6=89=93=E5=9C=B0=E9=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pipeline_bidding/bid_flow.py | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/pipeline_bidding/bid_flow.py b/pipeline_bidding/bid_flow.py index 07d4ca2..fcf2f66 100644 --- a/pipeline_bidding/bid_flow.py +++ b/pipeline_bidding/bid_flow.py @@ -613,7 +613,7 @@ async def reconcile_project(sor, project_id, project_name=""): needs_qc = [(t, s, imp, rnd) for t, s, imp, rnd, _on in qc_pending if s == "unaudited" or (s == "rework" and t not in over_types)] created_qc = [] - for t, _, _, _ in needs_qc: + for t, _, _, rnd in needs_qc: if await _open_qc_type_tasks(sor, project_id, t) > 0: continue # 竞态守卫(2026-09-02):该维度分析/重做任务在办 → 不派审核。 @@ -623,10 +623,41 @@ async def reconcile_project(sor, project_id, project_name=""): if dim and await _open_dim_tasks(sor, project_id, dim) > 0: acts.append("waiting: 维度「%s」分析任务在办,暂不派 %s 审核" % (dim, t)) continue + # 回归+增量结构(2026-09-03):复审任务带上「上一轮意见+本轮修正记录」, + # 审核输出必须分两段——上轮意见逐条回归验证、本轮新发现问题。 + # 根治:审核方每轮全量重读无回归意识,旧问题修了没人验收、 + # 新问题源源不断,产出在 8.0 分横住冲不过 8.5(实测 chapter_outline r4-r7)。 + prev_imp, fixes = "", "" + if rnd and int(rnd) >= 2: + prev = await sor.sqlExe( + "SELECT improvement FROM bid_qc_reviews WHERE project_id=${p}$ " + "AND qc_type=${t}$ AND round=${r}$", + {"p": project_id, "t": t, "r": int(rnd) - 1}) + await sor.sqlExe("COMMIT", {}) + if prev: + prev_imp = rec_to_dict(prev[0]).get("improvement") or "" + fx = await sor.sqlExe( + "SELECT action, entity, detail, updated_at FROM audit_log " + "WHERE tenant_id=${p}$ AND entity IN ('bid_chapters','bid_doc_requirements'," + "'bid_scoring_items','bid_qualifications','bid_cost_benefit') " + "ORDER BY updated_at DESC LIMIT 30", + {"p": project_id}) + await sor.sqlExe("COMMIT", {}) + fixes = "\n".join( + "- [%s] %s/%s: %s" % (rec_to_dict(f).get("updated_at", "")[:16], + rec_to_dict(f).get("entity", ""), + rec_to_dict(f).get("action", ""), + (rec_to_dict(f).get("detail") or "")[:80]) + for f in fx[:20]) + qparams = {"stage": "qc_analysis", "task_kind": "bid_qc", "qc_types": [t]} + if prev_imp: + qparams["prev_round"] = int(rnd) - 1 + qparams["prev_improvement"] = prev_imp + qparams["recent_fixes"] = fixes tid = await create_role_task( sor, project_id, R_QC, "%s 解析产出契合度审核(%s)" % (pname, t), - {"stage": "qc_analysis", "task_kind": "bid_qc", "qc_types": [t]}) + qparams) acts.append("created: QC 审核任务 %s(%s)" % (tid, t)) created_qc.append(t) if created_qc: