fix(check): 修留出集暴露的 5 处(规则集 2026.11-r3)
- 响应方式:「逐条响应」要说的是要求 / 参数 / 偏离,声明函填写说明不算;「否则视为无效响应」不算默认接受 - 偏离栏按「是不是明确满足」判断:偏离栏、响应情况栏一起看,其他短写法请人核对(最高重要);表体序号认「技-86」等 - 另报价、附加条件按结构判断(另一个不同的总价金额、保留 / 另行 / 调整报价等) - 空白栏:「精确到年月日」不算没填 - 比对时折叠异体字(戶→户等),原文照存 - 记录决策 E2:先修再跑国动真实投标文件 开发集召回 75%、规矩投标文件问题数不变;留出集参考数字见 check-eval §12(已看过,仅参考)。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -257,3 +257,102 @@ def test_validity_in_letter_table_and_chinese_dates() -> None:
|
||||
("FORM.VALIDITY_SHORT", "fatal"),
|
||||
("FORM.DATE_AFTER_DEADLINE", "hint"),
|
||||
}
|
||||
|
||||
|
||||
def test_generalized_quotes_conditions_and_blanks() -> None:
|
||||
"""留出集暴露的写法(check-eval §11)改成按结构判断;例句既不取自开发集,也不取自留出集。"""
|
||||
d = doc(
|
||||
[
|
||||
*opening_table("2,000,000.00", "贰佰万元整"),
|
||||
para(10, "若贵方接受分批付款,我方总价可下调为1,900,000.00元。", page=2),
|
||||
para(11, "另附选配清单,选配部分合计报价800,000.00元。", page=2),
|
||||
para(12, "本单位类似项目业绩合同金额2,500,000.00元。", page=2), # 业绩金额:不是另一个报价
|
||||
para(13, "我方投标总价为2,000,000.00元,已含全部税费。", page=2), # 等于总价
|
||||
para(14, "如遇原材料价格大幅上涨,供货价格由双方另行商定。", page=3),
|
||||
para(15, "我方保留根据厂家排产情况调整交付周期的权利。", page=3),
|
||||
para(16, "设备数量以届时实际供货清单为准,合同金额相应结算。", page=3),
|
||||
para(17, "合同最终以双方签订的合同文本为准。", page=3), # 常见套话:不算
|
||||
para(18, "日期选择控件精确到年月日。", page=4), # 说明:不算没填
|
||||
para(19, "签署时间:年月日", page=4),
|
||||
]
|
||||
)
|
||||
hits, _ = rules.run(rules.Facts(), [d], [])
|
||||
got = sorted((h.code, h.evidence[0][1].seq) for h in hits)
|
||||
assert got == [
|
||||
("FORM.BLANK_FIELD", 19),
|
||||
("FORM.CONDITION_ADDED", 14),
|
||||
("FORM.CONDITION_ADDED", 15),
|
||||
("FORM.CONDITION_ADDED", 16),
|
||||
("PRICE.MULTIPLE_QUOTES", 10),
|
||||
("PRICE.MULTIPLE_QUOTES", 11),
|
||||
]
|
||||
assert {h.severity for h in hits if h.code == "PRICE.MULTIPLE_QUOTES"} == {"important"}
|
||||
|
||||
|
||||
def test_deviation_column_values_other_than_clear_ok_need_review() -> None:
|
||||
"""偏离栏按「是不是明确满足」判断:「基本一致」这类说法请人核对(重要),「无偏离」不报。"""
|
||||
rows = [
|
||||
cell(1, "技术偏离表", 74, 76, w=200),
|
||||
cell(2, "序号", 80, 100, w=20),
|
||||
cell(3, "招标要求", 110, 100, w=150),
|
||||
cell(4, "偏离", 300, 100),
|
||||
cell(5, "技-1", 82, 124, w=8),
|
||||
cell(6, "支持双电源冗余", 110, 124, w=150),
|
||||
cell(7, "无偏离", 300, 124),
|
||||
cell(8, "技-2", 82, 146, w=8),
|
||||
cell(9, "支持热插拔风扇模块", 110, 146, w=150),
|
||||
cell(10, "基本一致", 300, 146),
|
||||
]
|
||||
hits, _ = rules.run(rules.Facts(), [doc(rows)], [])
|
||||
assert [(h.title, h.severity) for h in hits] == [("响应表里写了「基本一致」", "important")]
|
||||
|
||||
|
||||
def test_variant_glyphs_compare_equal() -> None:
|
||||
from bid_doctor.document.pipeline.text_layer import norm
|
||||
|
||||
assert norm("用戶 可以查看") == norm("用户可以查看")
|
||||
|
||||
|
||||
def test_response_content_column_and_wrapped_cells_are_not_flagged() -> None:
|
||||
"""有「偏离」栏时只看偏离栏:「投标响应」栏写「支持」「3年」是响应内容,不报;窄栏把「无偏离」折成两段,拼起来判断。"""
|
||||
rows = [
|
||||
cell(1, "序号", 80, 100, w=20),
|
||||
cell(2, "招标要求", 110, 100, w=120),
|
||||
cell(3, "投标响应", 240, 100),
|
||||
cell(4, "偏离", 310, 100, w=30),
|
||||
cell(5, "1", 82, 124, w=8),
|
||||
cell(6, "质保期不少于3年", 110, 124, w=120),
|
||||
cell(7, "3年", 240, 124),
|
||||
cell(8, "无偏", 310, 124, w=30),
|
||||
cell(9, "离", 310, 136, w=30),
|
||||
cell(10, "2", 82, 160, w=8),
|
||||
cell(11, "支持远程运维", 110, 160, w=120),
|
||||
cell(12, "支持", 240, 160),
|
||||
cell(13, "无偏离", 310, 160, w=30),
|
||||
]
|
||||
for c in rows:
|
||||
x0, y0, x1, _ = c.quads[0]
|
||||
c.cell = [
|
||||
x0,
|
||||
100 if y0 == 100 else 124 if y0 in (124, 136) else 160,
|
||||
x1,
|
||||
(124 if y0 == 100 else 160 if y0 in (124, 136) else 190),
|
||||
]
|
||||
hits, _ = rules.run(rules.Facts(), [doc(rows)], [])
|
||||
assert hits == []
|
||||
|
||||
|
||||
def test_long_response_mentioning_noncompliance_is_not_negative() -> None:
|
||||
"""响应栏里一大段正常响应提到「不符合……时预警」,不是不满足;只有开头就写不满足才算。"""
|
||||
from bid_doctor.check import deviation
|
||||
|
||||
def s(text: str) -> Sentence:
|
||||
x = cell(1, text, 0, 0)
|
||||
x.cell = [0, 0, 100, 20]
|
||||
return x
|
||||
|
||||
long_ok = s("满足,对规划条件不符合村庄规划的用地范围进行高亮标记并预警")
|
||||
assert deviation.judge([long_ok], "投标响应情况") == "ok"
|
||||
assert deviation.judge([s("部分响应")], "投标响应情况") == "negative"
|
||||
assert deviation.judge([s("不满足,现有版本仅支持单机部署")], "投标响应情况") == "negative"
|
||||
assert deviation.judge([s("无偏"), s("离")], "偏离") == "ok"
|
||||
|
||||
Reference in New Issue
Block a user