- 招标文件解析后可以追加补遗 / 澄清:单独解析、扣 1 次;新条目标「补遗 N」进正式清单,清单回到草稿(AD1)
- 同一种日期、时间不同的旧条目标「已被补遗 N 更新」,逐条确认更新或保留两条(AD2、AD3)
- 项目字段的新值在概览「采用 / 不采用」:采用时以补遗为准、清掉人工值;采用截止时间时日期条目一起确认;
没确认前查标用旧值,检查预览提示(AD4)
- 补遗不改项目名称、编号、采购人、代理机构、法律体系(更正公告标题会被抽成项目名称);时间比较按北京时间补时区
- 接口:fields/{key}/pending、checklist-items/{id}/supersession;清单项 origin_document、superseded_by;
关键日期 replaces;解析结果 dates_superseded、fields_pending;检查预览 pending_updates
- 前端:补遗模式的上传页、解析页结果、概览确认、读标页来源筛选和日期确认、检查预览提示
- 决策 AD1–AD6;方案和落地记录 docs/architecture/addendum-plan.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
81 lines
4.8 KiB
Python
81 lines
4.8 KiB
Python
"""生成查标测试用的虚构投标文件(对应 tender-mini.pdf 的三条 ★ 条款)。内容全部虚构。
|
||
|
||
cd server && ../.venv/bin/python tests/fixtures/make_bid_fixtures.py # 需要 Gotenberg(:3109)
|
||
|
||
- bid-mini-v1.pdf:响应了资质证书和服务器内存,漏了交换机硬件 BFD → 1 个致命问题「未找到响应」;
|
||
- bid-mini-v2.pdf:补上了交换机硬件 BFD → 复查时这个问题「本次已解决」;
|
||
- bid-mini-forms.pdf:v2 的内容 + 格式文件里的规则问题(大写和小写金额不一致、授权书没填投标人名称、
|
||
报价附加条件、另外给了一个优惠报价),措辞故意和评测集的开发词库不同;
|
||
- bid-mini-quals.pdf:v2 的内容 + 企业资质情况表(证书、编号、有效期,全部虚构),资质匹配的端到端测试用;
|
||
- addendum-mini.pdf:tender-full.pdf 的更正公告(补遗,FR-M2-10):递交截止时间推后一周、新增一条 ★ 参数。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
|
||
import httpx
|
||
|
||
HERE = Path(__file__).parent
|
||
GOTENBERG = "http://127.0.0.1:3109/forms/chromium/convert/html"
|
||
|
||
HEAD = """<!doctype html><html><head><meta charset="utf-8"><style>
|
||
body { font-family: "Noto Serif CJK SC", "Noto Sans CJK SC", serif; font-size: 12pt; line-height: 1.8; margin: 0; }
|
||
h1 { font-size: 16pt; text-align: center; }
|
||
table { border-collapse: collapse; width: 100%; } td, th { border: 1pt solid #333; padding: 4pt; }
|
||
</style></head><body>"""
|
||
|
||
COMMON = [
|
||
"<h1>某市智慧政务系统集成项目投标文件(测试样例,内容虚构)</h1>",
|
||
"<p>投标人:某某信息技术有限公司(虚构单位,仅用于测试)。</p>",
|
||
"<p>一、项目理解。本投标文件是测试用的虚构样例,用于验证投标文件检查流程,内容不对应任何真实的投标人或采购项目。"
|
||
"我方已认真阅读采购文件的全部内容,愿意按采购文件的要求提供货物和服务。</p>",
|
||
"<p>二、资格证明。投标人须具备有效的信息系统集成服务资质证书:我公司具备有效的信息系统集成服务资质证书,"
|
||
"证书复印件见附件1。</p>",
|
||
"<p>三、技术响应。服务器内存不低于32GB的要求:我方服务器内存配置为64GB,并提供产品彩页作为证明材料,见附件2。</p>",
|
||
]
|
||
BFD = "<p>交换机支持硬件BFD,最小报文发送间隔不大于50毫秒的要求:我方交换机支持硬件BFD,最小报文发送间隔为3.3毫秒。</p>"
|
||
TAIL = ["<p>四、售后服务。我公司提供7×24小时售后服务,接到报修后2小时内响应。</p>", "</body></html>"]
|
||
|
||
|
||
def render(name: str, parts: list[str]) -> None:
|
||
html = HEAD + "".join(parts)
|
||
r = httpx.post(GOTENBERG, files={"files": ("index.html", html.encode(), "text/html")}, timeout=60)
|
||
r.raise_for_status()
|
||
(HERE / name).write_bytes(r.content)
|
||
print(name, len(r.content))
|
||
|
||
|
||
FORMS = [
|
||
"<p>五、法定代表人授权委托书。本人王某(姓名)系(投标人名称)的法定代表人,现授权李某为我方代理人。</p>",
|
||
"<p>六、开标一览表</p>",
|
||
"<table><tr><th>项目名称</th><th>投标总报价(元)</th><th>投标总报价(大写)</th></tr>"
|
||
"<tr><td>某市智慧政务系统集成项目</td><td>1,280,000.00</td><td>壹拾贰万捌仟元整</td></tr></table>",
|
||
"<p>让利后总价:1,250,000.00元。</p>",
|
||
"<p>七、本次报价未包含设备运输费用,运输费用由采购人另行承担。</p>",
|
||
]
|
||
|
||
QUALS = [
|
||
"<p>五、企业资质情况表</p>",
|
||
"<table><tr><th>证书名称</th><th>证书编号</th><th>等级</th><th>有效期</th></tr>"
|
||
"<tr><td>安全生产许可证</td><td>(测)JZ安许证字〔2023〕000001</td><td>—</td><td>2023年11月16日至2026年11月15日</td></tr>"
|
||
"<tr><td>ISO9001质量管理体系认证证书</td><td>00000Q00001</td><td>—</td><td>2025年3月10日至2028年3月9日</td></tr>"
|
||
"</table>",
|
||
]
|
||
|
||
ADDENDUM = [
|
||
"<h1>关于某市智慧政务系统集成项目的更正公告(测试样例,内容虚构)</h1>",
|
||
"<p>各潜在供应商:本项目采购文件更正如下,其他内容不变。</p>",
|
||
"<p>一、响应文件递交截止时间更正为:2026年12月8日9时30分(北京时间)。</p>",
|
||
"<p>二、★新增技术要求:存储系统可用容量不低于100TB,并提供产品彩页作为证明材料。</p>",
|
||
"<p>本更正公告是采购文件的组成部分,与采购文件具有同等效力。</p>",
|
||
"</body></html>",
|
||
]
|
||
|
||
if __name__ == "__main__":
|
||
render("bid-mini-v1.pdf", [*COMMON, *TAIL])
|
||
render("bid-mini-v2.pdf", [*COMMON, BFD, *TAIL])
|
||
render("bid-mini-forms.pdf", [*COMMON, BFD, *FORMS, *TAIL])
|
||
render("bid-mini-quals.pdf", [*COMMON, BFD, *QUALS, *TAIL])
|
||
render("addendum-mini.pdf", ADDENDUM)
|