From f4dc699041f81c9cdd9a187f64adf63581f891b9 Mon Sep 17 00:00:00 2001 From: YANG JIANKUAN Date: Mon, 2 Nov 2026 22:02:34 +0800 Subject: [PATCH] =?UTF-8?q?docs(prototype):=20=E6=96=B0=E5=A2=9E=20MVP=20?= =?UTF-8?q?=E5=8F=AF=E7=82=B9=E5=87=BB=E5=8E=9F=E5=9E=8B=20v0.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 13 个页面覆盖 J1–J5:登录、工作台、新建项目、解析、选包、读标、上传投标文件、查标、报告、项目概览、额度、资质库 - 查标页:出处批注与原文抽屉、三种处理、致命项确认需写说明(U4)、忽略原因校验、撤销、批量、键盘逐条处理 - 读标页:分类、待确认区、补遗更新核对、修改记录、原文高亮、确认清单 - 示意场景沿用 02-user-journeys,条款改写自样本 S02、S10 Co-Authored-By: Claude Opus 5.5 --- docs/prototype/README.md | 49 ++++++ docs/prototype/assets/app.css | 126 +++++++++++++ docs/prototype/assets/app.js | 156 ++++++++++++++++ docs/prototype/assets/data.js | 266 ++++++++++++++++++++++++++++ docs/prototype/bid-check.html | 82 +++++++++ docs/prototype/checklist.html | 184 +++++++++++++++++++ docs/prototype/index.html | 82 +++++++++ docs/prototype/login.html | 66 +++++++ docs/prototype/lots.html | 54 ++++++ docs/prototype/parsing.html | 83 +++++++++ docs/prototype/project-new.html | 76 ++++++++ docs/prototype/project.html | 138 +++++++++++++++ docs/prototype/qualifications.html | 51 ++++++ docs/prototype/quota.html | 64 +++++++ docs/prototype/report.html | 102 +++++++++++ docs/prototype/results.html | 274 +++++++++++++++++++++++++++++ docs/prototype/workbench.html | 75 ++++++++ 17 files changed, 1928 insertions(+) create mode 100644 docs/prototype/README.md create mode 100644 docs/prototype/assets/app.css create mode 100644 docs/prototype/assets/app.js create mode 100644 docs/prototype/assets/data.js create mode 100644 docs/prototype/bid-check.html create mode 100644 docs/prototype/checklist.html create mode 100644 docs/prototype/index.html create mode 100644 docs/prototype/login.html create mode 100644 docs/prototype/lots.html create mode 100644 docs/prototype/parsing.html create mode 100644 docs/prototype/project-new.html create mode 100644 docs/prototype/project.html create mode 100644 docs/prototype/qualifications.html create mode 100644 docs/prototype/quota.html create mode 100644 docs/prototype/report.html create mode 100644 docs/prototype/results.html create mode 100644 docs/prototype/workbench.html diff --git a/docs/prototype/README.md b/docs/prototype/README.md new file mode 100644 index 0000000..30ede49 --- /dev/null +++ b/docs/prototype/README.md @@ -0,0 +1,49 @@ +# MVP 可点击原型 v0.1(2026-11-02) + +按 `docs/analysis/02-user-journeys.md` 的 J1–J5 做的 HTML 原型,覆盖 MVP 全链路:注册 → 新建项目 → 解析 → 选包 → 读标 → 上传投标文件 → 查标 → 导出报告,以及工作台、项目概览、额度、资质库。 + +- **保真度**:中保真。直接使用设计规范的变量和组件(`docs/design/system/`),重点验证流程、信息结构和产品红线落地;视觉细节留到 UI 设计阶段精修。 +- **示意场景**:某市政务服务中心智慧大厅建设项目(政府采购 · 公开招标 · 2 个采购包,投采购包 1)。条款改写自苏采云样本 S02、S10;项目名、金额、页码、投标响应、人名都是示意。 +- **入口**:`index.html`(原型目录,含页面与旅程的对应关系、模拟范围)。 + +## 运行 + +```bash +cd docs && python3 -m http.server 8766 +# 打开 http://127.0.0.1:8766/prototype/ +``` + +必须从 `docs/` 起服务,因为原型引用了 `../design/system/` 和 `../design/logo/`。宋体和数字字体从 `design/logo/.work/fonts` 加载(不进 git),没有时退回系统字体。设计基准 1440 宽,最小 1280。 + +## 文件 + +| 文件 | 内容 | +|---|---| +| `index.html` | 原型目录 | +| `login.html` | 注册 / 登录(含服务协议的围串标禁止条款) | +| `workbench.html` | 工作台 | +| `project-new.html` | 新建项目、上传招标文件;`?addendum=1` 是追加补遗 | +| `parsing.html` | 解析进度、取消、失败演示;`?addendum=1` 是补遗解析 | +| `lots.html` | 选择所投的包 | +| `checklist.html` | 读标:分类、清单、待确认区、补遗更新、修改记录、原文查看器、确认清单 | +| `bid-check.html` | 上传投标文件分册、检查范围、发起检查 | +| `results.html` | 查标:问题处理、出处批注、原文抽屉、键盘操作、批量、需人工核对 | +| `report.html` | 检查报告预览(A4) | +| `project.html` | 项目概览:状态流、AI 摘要、关键日期、文件、检查记录、递交 / 归档 / 删除 | +| `quota.html` | 额度与流水 | +| `qualifications.html` | 资质库 | +| `assets/data.js` | 示意数据(项目、文件页面、清单、检查结果) | +| `assets/app.js` | 页面框架、出处、原文查看器、对话框、轻提示 | +| `assets/app.css` | 页面框架与布局(组件样式在 `design/system/components.css`) | + +## 原型阶段发现的问题(2026-11-02 已按建议确认,见 `docs/decisions.md` P1–P2) + +| 编号 | 问题 | 结论 | +|---|---|---| +| P1 | 「同一项目 24 小时内复查不扣点」的 24 小时从哪次检查算起?如果从「上一次检查」算,用户每天复查一次就能一直不扣点 | 从**上一次扣点的检查**算起,窗口内的复查不扣点、也不延长窗口 | +| P2 | 「需人工核对」的勾选结果按检查批次存,还是按项目存? | 按项目存,复查时沿用;报告里写勾选人和时间 | + +## 和需求、规范的对应 + +- 每个页面对应的 FR 编号见 `index.html` 的「其他页面」表。 +- 产品红线自查:没有出处的结论只出现在「待确认」区;全站无「通过 / 合格 / 保证」字样;红色只用于致命问题;致命问题未处理也能导出和标记已递交;扣点前在按钮旁说明;报告 logo 只在页眉。 diff --git a/docs/prototype/assets/app.css b/docs/prototype/assets/app.css new file mode 100644 index 0000000..9a1c3f7 --- /dev/null +++ b/docs/prototype/assets/app.css @@ -0,0 +1,126 @@ +/* 原型专用:页面框架、布局和各页面的局部样式。组件样式在 design/system/components.css。 */ + +/* ---------- 页面框架 ---------- */ +body.app{display:grid;grid-template-columns:var(--sidebar-w) minmax(0,1fr);min-height:100vh;min-width:1280px} +.sidebar{position:sticky;top:0;height:100vh;display:flex;flex-direction:column;border-right:1px solid var(--border-subtle);background:var(--bg-page);padding:var(--sp-5) var(--sp-3)} +.sidebar .brand{display:block;padding:0 var(--sp-2) var(--sp-6)} +.sidebar .brand img{height:30px;display:block} +.nav{display:flex;flex-direction:column;gap:2px} +.nav a{display:flex;align-items:center;gap:var(--sp-3);height:36px;padding:0 var(--sp-3);border-radius:var(--radius-sm);color:var(--text-primary);text-decoration:none} +.nav a:hover{background:var(--bg-hover)} +.nav a.on{background:var(--bg-surface);box-shadow:inset 2px 0 0 var(--c-ink);font-weight:var(--fw-bold)} +.nav svg,.ic{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round} +.nav .sub{margin:var(--sp-5) var(--sp-3) var(--sp-2);font-size:var(--fs-caption);color:var(--text-secondary)} +.sidebar-foot{margin-top:auto;padding:var(--sp-3);border-top:1px solid var(--border-subtle);font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--text-secondary)} +.sidebar-foot b{display:block;color:var(--text-primary);font-size:var(--fs-body)} + +.main{min-width:0;display:flex;flex-direction:column} +.top{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:var(--sp-4);height:52px;padding:0 var(--sp-8);background:var(--bg-page);border-bottom:1px solid var(--border-subtle)} +.crumbs{display:flex;gap:var(--sp-2);color:var(--text-secondary);min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} +.crumbs a{color:var(--text-secondary);text-decoration:none} +.crumbs a:hover{color:var(--text-primary);text-decoration:underline;text-underline-offset:3px} +.crumbs b{color:var(--text-primary);font-weight:var(--fw-regular);overflow:hidden;text-overflow:ellipsis} +.top-right{margin-left:auto;display:flex;align-items:center;gap:var(--sp-4)} +.quota-chip{display:flex;gap:var(--sp-3);align-items:center;height:28px;padding:0 var(--sp-3);border:1px solid var(--border-subtle);border-radius:var(--radius-sm);color:var(--text-secondary);text-decoration:none;font-size:var(--fs-caption);background:var(--bg-surface)} +.quota-chip .fig{color:var(--text-primary);font-size:14px;margin-left:3px} +.icon-btn{display:inline-grid;place-items:center;width:32px;height:32px;border-radius:var(--radius-sm);color:var(--text-primary);background:none;border:0;cursor:pointer;position:relative} +.icon-btn:hover{background:var(--bg-hover)} +.icon-btn .dot{position:absolute;top:6px;right:6px;width:6px;height:6px;border-radius:50%;background:var(--c-ink)} + +.content{padding:var(--sp-6) var(--sp-8) var(--sp-16);max-width:calc(var(--content-max) + 64px);width:100%} +.content.wide{max-width:none} +.page-title{display:flex;align-items:flex-end;gap:var(--sp-4);margin-bottom:var(--sp-5)} +.page-title h1{font:var(--fw-bold) var(--fs-h1)/var(--lh-h1) var(--font-serif);margin:0} +.page-title p{margin:var(--sp-1) 0 0;color:var(--text-secondary)} +.page-title .actions{margin-left:auto;display:flex;gap:var(--sp-2);align-items:center} + +/* 项目页头 + 页签 */ +.proj-head{padding:var(--sp-5) var(--sp-8) 0;border-bottom:1px solid var(--border-subtle);background:var(--bg-page)} +.proj-head .line1{display:flex;align-items:flex-start;gap:var(--sp-4)} +.proj-head h1{font:var(--fw-bold) var(--fs-h1)/var(--lh-h1) var(--font-serif);margin:0} +.proj-head .meta{margin-top:var(--sp-1);color:var(--text-secondary);display:flex;flex-wrap:wrap;gap:var(--sp-2) var(--sp-4)} +.proj-head .facts{margin-left:auto;display:flex;gap:var(--sp-6);text-align:right;white-space:nowrap} +.proj-head .facts small{display:block;font-size:var(--fs-caption);color:var(--text-secondary)} +.proj-head .facts .fig{font-size:16px} +.tabs{display:flex;gap:var(--sp-6);margin-top:var(--sp-3)} +.tabs a{padding:var(--sp-2) 0 10px;color:var(--text-secondary);text-decoration:none;border-bottom:2px solid transparent;display:flex;gap:6px;align-items:center} +.tabs a:hover{color:var(--text-primary)} +.tabs a.on{color:var(--text-primary);font-weight:var(--fw-bold);border-bottom-color:var(--c-ink)} + +/* ---------- 原文查看器 ---------- */ +.viewer{min-height:0} +.viewer-bar{flex-wrap:wrap} +.viewer-bar .doc-name{display:flex;gap:var(--sp-2);align-items:baseline;min-width:0} +.viewer-bar .doc-file{color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:240px} +.viewer-body{flex:1;overflow:auto;padding:var(--sp-4) 0} +.viewer .sheet{min-height:560px;margin:0 auto;width:calc(100% - 48px);max-width:640px;position:relative} +.sheet .pno{position:absolute;bottom:14px;left:0;right:0;text-align:center;font:12px var(--font-figures);color:#999} +.sheet .h{font-weight:700;margin:4px 0 10px} +.sheet .stub{height:9px;background:#EEE;margin:12px 0;border-radius:1px} +.sheet .stub.s{width:60%} +.viewer-empty{color:var(--text-secondary);font-size:var(--fs-caption);text-align:center;margin-top:var(--sp-4)} +.viewer-note{font-size:var(--fs-caption);color:var(--text-secondary);padding:0 var(--sp-6) var(--sp-3)} + +/* 抽屉(查标页从右侧滑出原文) */ +.drawer{position:fixed;top:0;right:0;bottom:0;width:min(46vw,720px);z-index:40;background:var(--bg-sunken);box-shadow:var(--shadow-overlay);transform:translateX(100%);transition:transform var(--dur-base) var(--ease);display:flex;flex-direction:column} +.drawer.open{transform:none} +.drawer .viewer{flex:1;border:0;border-radius:0} +.drawer-close{margin-left:var(--sp-2)} + +/* ---------- 对话框与轻提示 ---------- */ +.scrim{position:fixed;inset:0;background:rgba(29,39,51,.32);z-index:50;display:grid;place-items:center} +.dialog{width:480px;max-width:calc(100vw - 32px);background:var(--bg-surface);border-radius:var(--radius-md);box-shadow:var(--shadow-overlay);padding:var(--sp-6)} +.dialog.wide{width:640px} +.dialog h2{font:var(--fw-bold) var(--fs-title)/var(--lh-title) var(--font-sans);margin:0 0 var(--sp-3)} +.dialog .body > p{margin:0 0 var(--sp-3)} +.dialog .foot{display:flex;justify-content:flex-end;gap:var(--sp-2);margin-top:var(--sp-6)} +.toast{position:fixed;left:50%;bottom:32px;transform:translateX(-50%);z-index:60;background:var(--c-ink);color:#fff;padding:10px 16px;border-radius:var(--radius-sm);box-shadow:var(--shadow-overlay);display:flex;gap:var(--sp-3);align-items:center} +.toast a{color:#fff} +textarea.input{height:auto;min-height:72px;padding:8px 10px;resize:vertical;line-height:var(--lh-body);width:100%} +.field .input{width:100%} +.field{max-width:none} + +/* ---------- 通用小件 ---------- */ +.muted{color:var(--text-secondary)} +.cap{font-size:var(--fs-caption);line-height:var(--lh-caption)} +.stack > * + *{margin-top:var(--sp-4)} +.section-h{display:flex;align-items:baseline;gap:var(--sp-3);margin:var(--sp-8) 0 var(--sp-3)} +.section-h h2{font:var(--fw-bold) var(--fs-title)/var(--lh-title) var(--font-sans);margin:0} +.section-h .more{margin-left:auto} +.kbd{display:inline-block;min-width:20px;padding:0 5px;border:1px solid var(--border-control);border-bottom-width:2px;border-radius:3px;font:12px/18px var(--font-figures);text-align:center;background:var(--bg-surface)} +.seg{display:inline-flex;border:1px solid var(--border-control);border-radius:var(--radius-sm);overflow:hidden;background:var(--bg-surface)} +.seg button{height:28px;padding:0 10px;border:0;background:none;font:var(--fs-body) var(--font-sans);color:var(--text-primary);cursor:pointer;display:flex;gap:6px;align-items:center} +.seg button + button{border-left:1px solid var(--border-subtle)} +.seg button.on{background:var(--c-ink);color:#fff} +.seg button.on .sev.hint{background:#fff} +.chk{display:flex;gap:var(--sp-3);align-items:flex-start;padding:var(--sp-3) 0;border-top:1px solid var(--border-subtle)} +.chk:first-child{border-top:0} +.chk input{width:16px;height:16px;margin:3px 0 0;accent-color:var(--c-ink)} +.free-badge{font-size:var(--fs-caption);border:1px solid var(--border-control);padding:0 6px;border-radius:2px} +.placeholder{border:1px dashed var(--border-control);color:var(--text-secondary);border-radius:var(--radius-sm);padding:var(--sp-4);text-align:center} + +/* 状态流 */ +.flowline{display:flex;align-items:center;gap:0;margin:var(--sp-2) 0} +.flowline .st{display:flex;align-items:center;gap:var(--sp-2);color:var(--text-secondary);white-space:nowrap} +.flowline .st i{width:10px;height:10px;border-radius:50%;border:1.5px solid var(--border-control);flex:none} +.flowline .st.done{color:var(--text-primary)} +.flowline .st.done i{background:var(--c-ink);border-color:var(--c-ink)} +.flowline .st.now{color:var(--text-primary);font-weight:var(--fw-bold)} +.flowline .st.now i{border:3px solid var(--c-ink)} +.flowline .ln{flex:1;min-width:24px;height:1px;background:var(--border-control);margin:0 var(--sp-3)} + +/* 键值列表 */ +.kv{display:grid;grid-template-columns:112px 1fr;gap:var(--sp-2) var(--sp-4);margin:0} +.kv dt{color:var(--text-secondary)} +.kv dd{margin:0} + +/* 上传区 */ +.drop{border:1.5px dashed var(--border-control);border-radius:var(--radius-sm);background:var(--bg-surface);padding:var(--sp-10) var(--sp-6);text-align:center;cursor:pointer} +.drop:hover{border-color:var(--c-ink)} +.drop b{display:block;font-size:var(--fs-title);margin-bottom:var(--sp-1)} +.file-row{display:grid;grid-template-columns:32px minmax(0,1fr) auto auto;gap:var(--sp-3);align-items:center;padding:var(--sp-3) var(--sp-4);background:var(--bg-surface);border:1px solid var(--border-subtle);border-radius:var(--radius-sm)} +.file-row + .file-row{margin-top:var(--sp-2)} +.file-row .ext{font:600 11px/1 var(--font-figures);border:1px solid var(--border-control);border-radius:2px;padding:4px 0;text-align:center} +.file-row select{height:28px;border:1px solid var(--border-control);border-radius:var(--radius-sm);background:#fff;font:var(--fs-body) var(--font-sans);padding:0 6px} + +@media (prefers-reduced-motion:reduce){.drawer{transition:none}} diff --git a/docs/prototype/assets/app.js b/docs/prototype/assets/app.js new file mode 100644 index 0000000..8c9b4e9 --- /dev/null +++ b/docs/prototype/assets/app.js @@ -0,0 +1,156 @@ +/* 原型公共脚本:页面框架、出处、原文查看器、对话框、轻提示。只模拟交互,不连后端。 */ +(function () { + const D = window.PROTO; + const $ = (s, el = document) => el.querySelector(s); + const $$ = (s, el = document) => [...el.querySelectorAll(s)]; + const esc = (s) => String(s).replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ }[c])); + + /* Lucide 图标(ISC 许可)的简化路径 */ + const ICONS = { + grid: '', + cert: '', + gauge: '', + bell: '', + help: '', + x: '', + plus: '', + upload: '', + file: '', + keyboard: '' + }; + const icon = (n, cls = "ic") => ``; + + /* ---------- 页面框架 ---------- */ + function shell(opt) { + const P = D.project; + const nav = [ + ["workbench.html", "grid", "工作台", "workbench"], + ["qualifications.html", "cert", "资质库", "quals"], + ["quota.html", "gauge", "额度", "quota"] + ].map(([h, i, t, k]) => `${icon(i)}${t}`).join(""); + const side = ``; + const crumbs = (opt.crumbs || []).map((c, i, a) => i < a.length - 1 ? `${c[0]}/` : `${c[0]}`).join(""); + const top = `
+
${crumbs}
+ +
`; + let head = ""; + if (opt.tab) { + const tabs = [["project.html", "概览", "overview"], ["checklist.html", "读标", "checklist"], ["results.html", "查标", "results"], ["report.html", "报告", "report"]] + .map(([h, t, k]) => `${t}${k === "results" ? ' 致命3' : ""}`).join(""); + head = `
+

${P.name}

+
${P.buyer}${P.regime} · ${P.method}投 采购包 1(共 2 个包)${P.no}
+
+
+
投标截止${P.deadlineText} · 剩 ${P.daysLeft} 天
+
状态${P.status}
+
就绪未就绪
+
+
`; + } + document.head.insertAdjacentHTML("beforeend", ''); + document.body.classList.add("app"); + const main = $("main"); + main.classList.add("main"); + document.body.insertAdjacentHTML("afterbegin", side); + main.insertAdjacentHTML("afterbegin", top + head); + $("[data-notice]").addEventListener("click", () => toast("解析完成:补遗 1 已并入清单(新增 2 条,更新 1 条)。")); + } + + /* ---------- 出处 ---------- */ + function citeLabel(c) { + const d = D.docs[c[0]]; + return `${d.name} · 第 ${c[1]} 页`; + } + function quote(c) { + const p = (D.pages[c[0]] || {})[c[1]] || []; + const hit = p.find((x) => x.id === c[2]); + return hit ? hit.t : ""; + } + /* 段落里只标出关键原句;没有关键原句时整段标出 */ + function marked(text, key, tag = "mark") { + const i = key ? text.indexOf(key) : -1; + if (i < 0) return `<${tag}>${esc(text)}`; + return esc(text.slice(0, i)) + `<${tag}>${esc(key)}` + esc(text.slice(i + key.length)); + } + function cite(c, opt = {}) { + return `
${citeLabel(c)}${opt.noQuote ? "" : `${marked(quote(c), c[3])}`}
`; + } + + /* ---------- 原文查看器 ---------- */ + function viewer(el, opt = {}) { + let cur = null, list = []; + el.classList.add("viewer"); + el.innerHTML = `
+ 原文 +
${opt.closable ? `` : ""}
+
+

点击清单项或出处,在这里查看原文并高亮原句。

`; + const body = $("[data-v-body]", el); + function render() { + const [doc, page, hl] = cur; + const d = D.docs[doc]; + $("[data-v-name]", el).textContent = d.name; + $("[data-v-file]", el).textContent = d.file; + $("[data-v-page]", el).textContent = `第 ${page} / ${d.pages} 页`; + const paras = (D.pages[doc] || {})[page]; + const inner = paras + ? paras.map((p) => p.h ? `

${esc(p.t)}

` : `

${p.id === hl ? marked(p.t, cur[3], 'span class="hl on"') : esc(p.t)}

`).join("") + : '
'; + body.innerHTML = `
${inner}
— ${page} —
+

${doc === "B1" && page === 3 ? "扫描页 · 文字由 OCR 识别,请以原图为准。" : "页码以规范化 PDF 为准(原型只做了被引用的页面)。"}

`; + const on = $(".hl.on", body); + if (on) on.scrollIntoView({ block: "center", behavior: "smooth" }); + const i = list.findIndex((x) => x.join("|") === cur.join("|")); + $("[data-v-prev]", el).disabled = i <= 0; + $("[data-v-next]", el).disabled = i < 0 || i >= list.length - 1; + } + function open(c, all) { + cur = c; list = all || [c]; + render(); + if (opt.onOpen) opt.onOpen(); + } + $("[data-v-prev]", el).onclick = () => { const i = list.findIndex((x) => x.join("|") === cur.join("|")); if (i > 0) open(list[i - 1], list); }; + $("[data-v-next]", el).onclick = () => { const i = list.findIndex((x) => x.join("|") === cur.join("|")); if (i < list.length - 1) open(list[i + 1], list); }; + if (opt.closable) $("[data-v-close]", el).onclick = opt.onClose; + return { open }; + } + + /* ---------- 对话框与轻提示 ---------- */ + function dialog({ title, body, ok = "确定", cancel = "取消", wide = false, onOk, onOpen }) { + const s = document.createElement("div"); + s.className = "scrim"; + s.innerHTML = ``; + document.body.appendChild(s); + const close = () => { s.remove(); document.removeEventListener("keydown", onKey); }; + const onKey = (e) => { if (e.key === "Escape") close(); }; + document.addEventListener("keydown", onKey); + s.addEventListener("click", (e) => { if (e.target === s) close(); }); + if (cancel) $("[data-cancel]", s).onclick = close; + $("[data-ok]", s).onclick = () => { if (!onOk || onOk(s) !== false) close(); }; + if (onOpen) onOpen(s); + const f = $("textarea, input, [data-ok]", s); + if (f) f.focus(); + return s; + } + let toastTimer; + function toast(msg) { + let t = $(".toast"); + if (!t) { t = document.createElement("div"); t.className = "toast"; t.setAttribute("role", "status"); document.body.appendChild(t); } + t.innerHTML = msg; + clearTimeout(toastTimer); + toastTimer = setTimeout(() => t.remove(), 4000); + } + + window.App = { D, $, $$, esc, icon, shell, cite, citeLabel, quote, viewer, dialog, toast }; +})(); diff --git a/docs/prototype/assets/data.js b/docs/prototype/assets/data.js new file mode 100644 index 0000000..e267e74 --- /dev/null +++ b/docs/prototype/assets/data.js @@ -0,0 +1,266 @@ +/* 原型示意数据。场景见 docs/analysis/02-user-journeys.md: + * 某市政务服务中心智慧大厅建设项目(政府采购 · 公开招标 · 2 个采购包,投采购包 1)。 + * 条款文字改写自苏采云样本 S02、S10;项目名、金额、页码、投标响应、人名均为示意。 */ +window.PROTO = { + today: "2026-11-02", + user: { name: "王敏", company: "南京某信息技术有限公司", plan: "专业版" }, + quota: { parse: { left: 37, total: 50 }, check: { left: 12, total: 20 } }, + + project: { + id: "p1", + name: "某市政务服务中心智慧大厅建设项目", + no: "ZC-2026-0418", + buyer: "某市政务服务管理办公室", + agent: "某市公共资源交易中心", + regime: "政府采购", + method: "公开招标", + deadline: "2026-11-20 09:30", + deadlineText: "11月20日 09:30", + daysLeft: 17, + status: "已检查", + lots: [ + { no: 1, name: "智慧大厅软硬件集成", budget: "286.00", cap: "286.00", bid: true }, + { no: 2, name: "机房网络设备更新", budget: "132.00", cap: "132.00", bid: false } + ] + }, + + /* 文件:role = tender 招标文件 / addendum 补遗 / bid 投标分册 */ + docs: { + T: { name: "招标文件", file: "ZC-2026-0418 采购文件.pdf", role: "tender", pages: 186 }, + A1: { name: "补遗 1", file: "关于 ZC-2026-0418 的更正公告.pdf", role: "addendum", pages: 2 }, + B1: { name: "商务册", file: "商务册-v3.docx", role: "bid", pages: 64 }, + B2: { name: "技术册", file: "技术册-v3.docx", role: "bid", pages: 212 }, + B3: { name: "报价册", file: "报价册-v2.docx", role: "bid", pages: 8 } + }, + + /* 原文页面(只做了被引用到的页)。出处格式:[文件, 页码, 段落 id, 关键原句(可选,只高亮这一句)] */ + pages: { + T: { + 2: [ + { t: "一、项目基本情况", h: 1 }, + { t: "项目编号:ZC-2026-0418" }, + { t: "项目名称:某市政务服务中心智慧大厅建设项目" }, + { t: "采购方式:公开招标" }, + { id: "t2-cap", t: "预算金额:418.00万元。最高限价:418.00万元(采购包1:286.00万元,采购包2:132.00万元)。" }, + { t: "采购需求:详见第六章《采购需求》。" }, + { id: "t2-sme", t: "本项目(是/否)专门面向中小企业采购:否。对小微企业给予价格扣除优惠。" }, + { t: "合同履行期限:合同签订后 90 日历天内完成交付并通过验收。" }, + { id: "t2-joint", t: "本项目(是/否)接受联合体投标:否。" } + ], + 6: [ + { t: "四、提交投标文件截止时间、开标时间和地点", h: 1 }, + { id: "t6-deadline", t: "1.提交投标文件截止时间、开标时间:2026年11月20日09时30分(北京时间)。" }, + { id: "t6-place", t: "2.投标文件递交方式:通过政府采购电子交易平台在线递交加密的电子投标文件,不接受纸质投标文件。" }, + { t: "3.开标地点:某市公共资源交易中心开标室(远程不见面开标)。" }, + { id: "t6-ask", t: "4.对采购文件的询问或质疑,应在采购文件公告期限届满之日起七个工作日内以书面形式提出。" } + ], + 18: [ + { t: "34. 投标人存在下列情况之一的,投标无效:", h: 1 }, + { id: "t18-seal", t: "(一)投标文件未按招标文件要求签署、盖章的;" }, + { id: "t18-qual", t: "(二)不具备招标文件中规定的资格要求的;" }, + { id: "t18-cap", t: "(三)报价超过招标文件中规定的预算金额或者最高限价的;" }, + { t: "(四)投标文件含有采购人不能接受的附加条件的;" }, + { id: "t18-valid", t: "(五)投标文件中承诺的投标有效期少于招标文件中载明的投标有效期;" }, + { t: "(六)法律、法规和招标文件规定的其他无效情形。" } + ], + 21: [ + { t: "投标资料表", h: 1 }, + { id: "t21-valid", t: "投标有效期:90天。" }, + { id: "t21-deposit", t: "投标保证金:本项目不收取投标保证金。" }, + { id: "t21-copies", t: "投标文件份数:电子投标文件1份,须使用CA数字证书加密后上传。" }, + { id: "t21-quote", t: "20.5 投标人只能提交一个投标报价,提交2个以上投标报价的投标文件按照投标无效处理。" } + ], + 23: [ + { t: "二、资格条件(“1”~“7”项必须提供,否则投标无效)", h: 1 }, + { id: "t23-license", t: "1.投标人合法有效的法人或者其他组织的营业执照等证明文件。以上证明文件提供扫描件。" }, + { id: "t23-fin", t: "2.财务状况报告,至少提供:(1)本项目开标时间前6个月内任一时间截点的资产负债表的扫描件1份;(2)本项目开标时间前6个月内任何1月(不含开标当月)利润表月报表的扫描件1份。" }, + { id: "t23-tax", t: "3.本项目开标时间前6个月内任何1月的依法缴纳税收和社会保障资金的相关材料的扫描件。" }, + { id: "t23-ability", t: "4.《具备履行合同所必需的设备和专业技术能力的书面声明》(加盖电子签章)。" }, + { id: "t23-record", t: "5.参加政府采购活动前3年内在经营活动中没有重大违法记录的书面声明(加盖电子签章)。" }, + { id: "t23-credit", t: "8.投标人无被列入失信被执行人、重大税收违法案件当事人名单、政府采购严重失信行为记录名单的信用记录。" } + ], + 24: [ + { t: "三、符合条件(必须提供,否则投标无效)", h: 1 }, + { id: "t24-quote", t: "1.报价符合性审查:投标报价不得超过采购包最高限价;投标报价低于采购包最高限价45%的,提供与报价合理性相关的书面说明及必要的证明材料。" }, + { id: "t24-letter", t: "3.《投标函》(加盖电子签章,格式见招标文件第七章)。" }, + { id: "t24-auth", t: "4.《法定代表人授权委托书》(法定代表人签字或盖章并加盖单位电子签章)。" }, + { id: "t24-dev", t: "5.《偏离表》(加盖电子签章,格式见招标文件第七章)。" }, + { id: "t24-mark", t: "本文件中打“★”内容为实质性要求,投标人须全部满足,否则投标无效。" } + ], + 31: [ + { t: "第四章 评标标准(综合评分法)", h: 1 }, + { id: "t31-price", t: "价格分(10分):满足招标文件要求且投标价格最低的投标报价为评标基准价,其价格分为满分。" }, + { id: "t31-tech", t: "技术规格(40分):完全满足★和▲参数得基础分,▲参数每负偏离一项扣2分,一般参数每负偏离一项扣0.5分。" }, + { id: "t31-plan", t: "项目实施方案(20分):方案内容齐全、符合实际切实可行且无缺陷得20分,每存在一处缺陷扣2分。" }, + { id: "t31-service", t: "售后服务方案(10分):对第六章“四、售后服务要求”进行完善并详细描述,每缺少一项内容扣1分。" }, + { id: "t31-iso", t: "体系认证(6分):投标人具有有效的ISO9001、ISO27001、ISO20000认证证书,每提供一项得2分(以投标截止日在有效期内为准,提供证书扫描件)。" }, + { id: "t31-case", t: "类似业绩(8分):近三年(2023年1月1日以来)承担过政务服务大厅智能化项目的,每提供一个得2分,最多8分(提供合同关键页扫描件)。" } + ], + 41: [ + { t: "采购包1 · 货物需求一览表", h: 1 }, + { t: "序号 3 应用服务器 2 台", faint: true }, + { id: "t41-server", t: "★ 2U机架式服务器,CPU:配置≥2颗海光架构32C 2.7GHz,内存: ≥512G DDR4,系统盘: 2块≥480G SSD,存储盘: ≥2块8T SATA、≥4块3.84T SSD……" }, + { id: "t41-nic", t: "网络:配置≥4个1GbE 接口,≥4个10GbE 光接口(含光模块),电源:配置2块800W冗余电源。" }, + { id: "t41-cpu", t: "★ 设备采用国产自主可控CPU芯片,投标文件中提供国产化适配承诺函,格式自制。" }, + { t: "备注:加★为核心技术参数;加▲为重要技术参数;其他为通用技术参数。" } + ], + 44: [ + { t: "序号 5 核心交换机 1 台", faint: true }, + { id: "t44-bfd", t: "★ 支持硬件BFD,最小报文发送间隔≤50ms,提供相关证明材料(包含但不限于产品官网公开参数截图证明等)。" }, + { id: "t44-port", t: "▲ 交换容量≥19.2Tbps,包转发率≥2880Mpps,业务槽位≥4个。" } + ], + 47: [ + { t: "序号 9 排队叫号一体机 6 台", faint: true }, + { id: "t47-screen", t: "显示屏尺寸≥21.5英寸,分辨率≥1920×1080,支持身份证、社保卡读取。" }, + { id: "t47-ups", t: "▲ 自助服务终端须提供不少于3年原厂质保,提供原厂质保承诺函。" } + ] + }, + A1: { + 1: [ + { t: "关于 ZC-2026-0418 的更正公告(补遗 1)", h: 1 }, + { id: "a1-deadline", t: "一、提交投标文件截止时间、开标时间更正为:2026年11月20日09时30分(北京时间)。原为2026年11月18日09时30分。" }, + { id: "a1-param", t: "二、采购包1 序号3 应用服务器“系统盘”参数更正为:2块≥960G SSD。" } + ] + }, + B1: { + 3: [ + { t: "一、投标函", h: 1 }, + { t: "致:某市公共资源交易中心" }, + { t: "我方已仔细研究了某市政务服务中心智慧大厅建设项目(项目编号:ZC-2026-0418)招标文件的全部内容……" }, + { id: "b1-date", t: "投标人(电子签章):南京某信息技术有限公司  日期:2026年11月25日" } + ], + 5: [ + { t: "二、法定代表人授权委托书", h: 1 }, + { t: "本授权委托书声明:我李某某系南京某信息技术有限公司的法定代表人,现授权委托王敏为我公司代理人……" }, + { id: "b1-auth-seal", t: "法定代表人(签字或盖章):李某某  投标人(电子签章):(签章位置为空)" } + ], + 27: [ + { t: "九、类似项目业绩", h: 1 }, + { id: "b1-oldname", t: "我公司承担的某区智慧校园一期项目(项目编号 QJ-2025-0112)已顺利通过验收,本项目将沿用该项目的实施团队……" } + ], + 38: [ + { t: "十二、体系认证证书", h: 1 }, + { id: "b1-iso", t: "ISO/IEC 27001 信息安全管理体系认证证书 证书编号:01226IS0458 有效期至:2026年11月15日" } + ] + }, + B2: { + 12: [ + { t: "技术偏离表(采购包1)", h: 1 }, + { t: "第 11 行 CPU:2颗海光 7380 32C 2.7GHz 无偏离", faint: true }, + { id: "b2-mem", t: "第 12 行 内存:256G DDR4 无偏离" }, + { t: "第 13 行 系统盘:2块960G SSD 无偏离", faint: true } + ], + 58: [ + { t: "核心交换机技术响应", h: 1 }, + { id: "b2-bfd", t: "支持硬件BFD,最小报文发送间隔3.3ms,满足要求。" } + ], + 77: [ + { t: "排队叫号一体机技术响应", h: 1 }, + { id: "b2-screen", t: "显示屏:21英寸 LED 背光液晶屏,分辨率1920×1080。" } + ] + }, + B3: { + 1: [ + { t: "开标一览表", h: 1 }, + { t: "项目名称:某市政务服务中心智慧大厅建设项目 采购包:1" }, + { id: "b3-total", t: "投标总价(小写):2876000.00 元 (大写):贰佰捌拾柒万陆仟元整" } + ], + 3: [ + { t: "分项价格表(采购包1)", h: 1 }, + { id: "b3-sum", t: "合计:2868000.00 元" } + ] + } + }, + + /* 清单:cat = qual 资格 / invalid 无效条款 / score 评分 / date 日期与递交 / param 技术参数 */ + categories: [ + { id: "qual", name: "资格条件" }, + { id: "invalid", name: "无效条款" }, + { id: "score", name: "评分办法" }, + { id: "date", name: "日期与递交" }, + { id: "param", name: "技术参数" } + ], + checklist: [ + { id: "c1", cats: ["qual", "invalid"], title: "营业执照等主体资格证明文件(扫描件)", lot: 0, src: "ai", cite: ["T", 23, "t23-license"] }, + { id: "c2", cats: ["qual", "invalid"], title: "财务状况报告:资产负债表 + 利润表月报表(开标前 6 个月内)", lot: 0, src: "ai", cite: ["T", 23, "t23-fin"] }, + { id: "c3", cats: ["qual", "invalid"], title: "依法缴纳税收和社会保障资金的材料(开标前 6 个月内任 1 月)", lot: 0, src: "ai", cite: ["T", 23, "t23-tax"] }, + { id: "c4", cats: ["qual", "invalid"], title: "具备履行合同所必需的设备和专业技术能力的书面声明(加盖电子签章)", lot: 0, src: "ai", cite: ["T", 23, "t23-ability"] }, + { id: "c5", cats: ["qual", "invalid"], title: "前 3 年内无重大违法记录的书面声明(加盖电子签章)", lot: 0, src: "ai", cite: ["T", 23, "t23-record"] }, + { id: "c6", cats: ["qual"], title: "信用记录:未被列入失信被执行人等名单", lot: 0, src: "ai", cite: ["T", 23, "t23-credit"] }, + { id: "c7", cats: ["invalid"], title: "投标文件按要求签署、盖章", lot: 0, src: "ai", cite: ["T", 18, "t18-seal"] }, + { id: "c8", cats: ["invalid"], title: "报价不超过采购包 1 最高限价 286.00 万元", lot: 1, src: "ai", cite: ["T", 2, "t2-cap", "采购包1:286.00万元"] }, + { id: "c9", cats: ["invalid"], title: "只能提交一个投标报价", lot: 0, src: "ai", cite: ["T", 21, "t21-quote"] }, + { id: "c10", cats: ["invalid", "date"], title: "投标有效期不少于 90 天", lot: 0, src: "ai", cite: ["T", 21, "t21-valid"] }, + { id: "c11", cats: ["invalid"], title: "《法定代表人授权委托书》签字或盖章并加盖单位电子签章", lot: 0, src: "ai", cite: ["T", 24, "t24-auth"] }, + { id: "c12", cats: ["score"], title: "技术规格 40 分:▲ 参数每负偏离一项扣 2 分", lot: 0, src: "ai", cite: ["T", 31, "t31-tech"] }, + { id: "c13", cats: ["score"], title: "项目实施方案 20 分", lot: 0, src: "ai", cite: ["T", 31, "t31-plan"] }, + { id: "c14", cats: ["score"], title: "体系认证 6 分:ISO9001 / ISO27001 / ISO20000,投标截止日在有效期内", lot: 0, src: "ai", cite: ["T", 31, "t31-iso"] }, + { id: "c15", cats: ["score"], title: "类似业绩 8 分:2023 年以来政务服务大厅智能化项目", lot: 0, src: "ai", cite: ["T", 31, "t31-case"] }, + { id: "c16", cats: ["date"], title: "提交投标文件截止时间:2026年11月20日 09:30", old: "2026年11月18日 09:30", lot: 0, src: "addendum", srcName: "补遗 1", cite: ["A1", 1, "a1-deadline"], updated: true }, + { id: "c17", cats: ["date"], title: "递交方式:电子交易平台在线递交,CA 加密", lot: 0, src: "ai", cite: ["T", 6, "t6-place"] }, + { id: "c18", cats: ["date"], title: "投标保证金:不收取", lot: 0, src: "ai", cite: ["T", 21, "t21-deposit"] }, + { id: "c19", cats: ["param", "invalid"], imp: "★", title: "应用服务器:内存 ≥ 512G DDR4", lot: 1, src: "ai", cite: ["T", 41, "t41-server", "内存: ≥512G DDR4"] }, + { id: "c20", cats: ["param", "invalid"], imp: "★", title: "应用服务器:国产自主可控 CPU,提供国产化适配承诺函", lot: 1, src: "ai", cite: ["T", 41, "t41-cpu"] }, + { id: "c21", cats: ["param"], imp: "★", title: "应用服务器:系统盘 2 块 ≥ 960G SSD", old: "2 块 ≥ 480G SSD", lot: 1, src: "addendum", srcName: "补遗 1", cite: ["A1", 1, "a1-param"], updated: true }, + { id: "c22", cats: ["param", "invalid"], imp: "★", title: "核心交换机:支持硬件 BFD,最小发送间隔 ≤ 50ms,提供证明材料", lot: 1, src: "ai", cite: ["T", 44, "t44-bfd", "最小报文发送间隔≤50ms,提供相关证明材料"] }, + { id: "c23", cats: ["param"], imp: "▲", title: "核心交换机:交换容量 ≥ 19.2Tbps,包转发率 ≥ 2880Mpps", lot: 1, src: "ai", cite: ["T", 44, "t44-port"] }, + { id: "c24", cats: ["param"], imp: "", title: "排队叫号一体机:显示屏 ≥ 21.5 英寸", lot: 1, src: "ai", cite: ["T", 47, "t47-screen", "显示屏尺寸≥21.5英寸"] }, + { id: "c25", cats: ["param"], imp: "▲", title: "自助服务终端:不少于 3 年原厂质保,提供承诺函", lot: 1, src: "ai", cite: ["T", 47, "t47-ups"] }, + { id: "c26", cats: ["qual"], title: "不接受联合体投标", lot: 0, src: "manual", edited: true, cite: ["T", 2, "t2-joint"] } + ], + hiddenLotItems: 9, /* 采购包 2 的条目数(未投,折叠) */ + pending: [ + { id: "q1", title: "投标文件须胶装成册并逐页加盖骑缝章", reason: "未找到出处", src: "ai" }, + { id: "q2", imp: "★", title: "核心产品须提供原厂授权书", reason: "把握不大", src: "ai", cite: ["T", 44, "t44-port"] } + ], + + /* 检查结果(第 2 次检查)。sev = fatal / major / hint;status = todo / ok / fixed / ignored */ + check: { + no: 2, time: "11月2日 14:20", rules: "IT 集成 2026.11", + files: "商务册 v3、技术册 v3、报价册 v2", + resolved: 2, + findings: [ + { id: "f1", sev: "fatal", item: "c8", title: "报价超过采购包 1 的最高限价", flag: "新增", + text: ["开标一览表报价 287.60 万元,采购包 1 最高限价 286.00 万元,超出 1.60 万元。", "这一项会导致投标无效。请核对开标一览表的报价。"], + cites: [["T", 2, "t2-cap", "采购包1:286.00万元"], ["B3", 1, "b3-total", "2876000.00 元"]] }, + { id: "f2", sev: "fatal", item: "c19", title: "★ 条款疑似不满足:应用服务器内存", flag: "沿用 · 上次标记为已修改,问题仍在", + text: ["技术偏离表第 12 行响应「内存 256G DDR4」,要求「≥512G DDR4」。", "这一项会导致投标无效。请在技术偏离表第 12 行和对应产品参数中更正内存配置。"], + cites: [["T", 41, "t41-server", "内存: ≥512G DDR4"], ["B2", 12, "b2-mem", "内存:256G DDR4"]] }, + { id: "f3", sev: "fatal", item: "c11", title: "授权委托书的单位签章位置未发现盖章", flag: "新增", + text: ["商务册第 5 页《法定代表人授权委托书》的「投标人(电子签章)」位置是空的。本检查只看有无,不鉴定真伪。", "这一项会导致投标无效。请在递交前补盖单位电子签章。"], + cites: [["T", 24, "t24-auth", "加盖单位电子签章"], ["B1", 5, "b1-auth-seal", "投标人(电子签章):(签章位置为空)"]] }, + { id: "f4", sev: "major", item: "c22", title: "缺少 ★ 参数的证明材料:核心交换机硬件 BFD", + text: ["已响应「支持硬件 BFD」,但没有找到官网参数截图等证明材料。请在技术册补充证明材料。"], + cites: [["T", 44, "t44-bfd", "提供相关证明材料(包含但不限于产品官网公开参数截图证明等)"], ["B2", 58, "b2-bfd", "支持硬件BFD"]], missing: "证明材料未找到 · 已查找:技术册(全部章节)、商务册(附件)" }, + { id: "f5", sev: "major", item: "c8", title: "开标一览表与分项价格表合计不一致", + text: ["开标一览表 287.60 万元,分项价格表合计 286.80 万元,相差 0.80 万元。", "按招标文件规定,两者不一致时以开标一览表为准,不作无效处理;但会影响价格评审。请核对两表。"], + cites: [["B3", 1, "b3-total", "2876000.00 元"], ["B3", 3, "b3-sum", "2868000.00 元"]] }, + { id: "f6", sev: "major", item: "c14", title: "资质过期预警:ISO27001 证书在投标截止日前到期", flag: "新增", + text: ["证书有效期至 2026年11月15日,早于投标截止日 11月20日。按评分办法,这一项可能不得分。", "请上传换发后的证书,或在资质库更新有效期。"], + cites: [["T", 31, "t31-iso", "以投标截止日在有效期内为准"], ["B1", 38, "b1-iso", "有效期至:2026年11月15日"]] }, + { id: "f7", sev: "hint", item: "c10", title: "投标函落款日期晚于投标截止日", flag: "沿用", status: "ok", by: "王敏", at: "11月1日 16:05", + text: ["投标函落款「2026年11月25日」,投标截止时间是 2026年11月20日 09:30。"], + cites: [["B1", 3, "b1-date", "日期:2026年11月25日"]] }, + { id: "f8", sev: "hint", item: "c15", title: "投标文件里出现了其他项目的名称", flag: "新增", + text: ["商务册第 27 页出现「某区智慧校园一期项目」及其项目编号。如果是业绩介绍可以忽略;如果是照搬旧标书留下的,请修改。"], + cites: [["B1", 27, "b1-oldname", "某区智慧校园一期项目(项目编号 QJ-2025-0112)"]] }, + { id: "f9", sev: "hint", item: "c24", title: "一般参数疑似不满足:叫号一体机显示屏尺寸", + text: ["技术册第 77 页响应「21英寸」,要求「≥21.5英寸」。一般参数负偏离每项扣 0.5 分。"], + cites: [["T", 47, "t47-screen", "显示屏尺寸≥21.5英寸"], ["B2", 77, "b2-screen", "21英寸"]] } + ], + manual: [ + { id: "m1", title: "电子投标文件已使用 CA 数字证书加密", cite: ["T", 21, "t21-copies"] }, + { id: "m2", title: "在截止时间前通过电子交易平台上传,并取得回执", cite: ["T", 6, "t6-place"] }, + { id: "m3", title: "加密使用的 CA 证书在有效期内,开标时可正常解密", cite: ["T", 21, "t21-copies"] } + ] + }, + + projects: [ + { id: "p1", hoursLeft: 408, name: "某市政务服务中心智慧大厅建设项目", buyer: "某市政务服务管理办公室", lot: "采购包 1", due: "11月20日 09:30 · 剩 17 天", dueCls: "", status: "已检查", ready: "未就绪", fatal: 3, href: "results.html" }, + { id: "p2", hoursLeft: 53, name: "某区智慧社区平台运维服务", buyer: "某区民政局", lot: "全部", due: "剩 2 天 5 小时", dueCls: "due-soon", status: "已检查", ready: "就绪", fatal: 0, href: "project.html" }, + { id: "p3", hoursLeft: 7, name: "某县数据中心机房改造项目", buyer: "某县大数据管理局", lot: "标段 1", due: "今天 17:00 截止", dueCls: "due-today", status: "编制中", ready: "", fatal: 0, href: "checklist.html" }, + { id: "p4", hoursLeft: 600, name: "某市医保信息系统等保测评服务", buyer: "某市医疗保障局", lot: "全部", due: "11月28日 10:00 · 剩 25 天", dueCls: "", status: "跟进中", ready: "", fatal: 0, href: "project-new.html" }, + { id: "p5", hoursLeft: 9999, name: "某区智慧校园一期", buyer: "某区教育局", lot: "全部", due: "已截止", dueCls: "due-past", status: "已递交", ready: "", fatal: 0, href: "project.html" }, + { id: "p6", hoursLeft: 9999, name: "某市不动产登记信息平台升级", buyer: "某市自然资源和规划局", lot: "采购包 2", due: "已截止", dueCls: "due-past", status: "已归档", ready: "", fatal: 0, href: "project.html" } + ] +}; diff --git a/docs/prototype/bid-check.html b/docs/prototype/bid-check.html new file mode 100644 index 0000000..ee1bf18 --- /dev/null +++ b/docs/prototype/bid-check.html @@ -0,0 +1,82 @@ + + + + + +上传投标文件并检查 · 标博士原型 + + + + + + + +
+
+

上传投标文件并检查

只处理加密前的 Word / PDF 稿。每次重新上传都是一个新版本,检查结果关联到具体版本。

+
i

清单 v3 还是草稿(补遗 1 并入后没有重新确认),检查结果以当前清单为准。去确认清单

+ +

投标文件分册

+
+ +

这次会检查什么

+
+
会查
  • 清单 26 条的响应完整性(未响应 / 负偏离未说明 / 疑似不满足)
  • 形式要件:格式文件是否齐全、签章位置有没有盖章、落款日期、其他项目名称
  • 资质匹配:按投标截止日判断证书是否过期(用你的资质库)
  • 报价形式:限价三层、开标一览表与分项合计、大小写
+
不查
  • 份数、密封、CA 加密、递交回执(列为「需人工核对」)
  • 签章真伪
  • 报价是否合理、报多少
  • 评分高低
+
+ +
+ 24 小时内复查不扣额度:从上次扣点的检查(11-01 16:00)算起,至今天 16:00 + 取消 + +
+
+
+
+ + + + + diff --git a/docs/prototype/checklist.html b/docs/prototype/checklist.html new file mode 100644 index 0000000..f4d291f --- /dev/null +++ b/docs/prototype/checklist.html @@ -0,0 +1,184 @@ + + + + + +读标 · 标博士原型 + + + + + + + +
+
+

项目检查清单

+
+
+ 反馈:有遗漏的要求 + + +
+
+
+ +
+
+
+
+ + + + + + diff --git a/docs/prototype/index.html b/docs/prototype/index.html new file mode 100644 index 0000000..9d58537 --- /dev/null +++ b/docs/prototype/index.html @@ -0,0 +1,82 @@ + + + + + +标博士 原型目录 + + + + + + + + +
+
标博士
+

MVP 可点击原型 v0.1

+

按 docs/analysis/02-user-journeys.md 的 J1–J5 走一遍 MVP 链路。示意场景:某市政务服务中心智慧大厅建设项目(政府采购 · 公开招标 · 2 个采购包,投采购包 1)。条款改写自苏采云样本 S02、S10,项目名、金额、页码、投标响应和人名都是示意。直接使用设计规范的变量和组件(design/system/),所以是中保真:重点验证流程、信息结构和红线落地,视觉细节留到 UI 设计阶段精修。

+ +

J1 · 首次体验:从上传到导出报告

+ + +

其他页面

+ + + + + + + + + + +
页面对应要点
工作台FR-M6-01按截止排序;倒计时临近用赭色;就绪只在「已检查」显示;致命计数
项目概览FR-M6-02、M2-09、J2状态流;AI 摘要带出处;关键日期(补遗更新);文件与版本;标记已递交(可撤销)、归档、删除(输入项目名确认)
追加补遗 → 解析补遗FR-M2-10、J2-1补遗单独扣 1 次;并入清单后回到草稿,由用户核对
额度FR-M6-03、J3扣点规则可见;流水对应到任务;预扣 / 退回成对出现;复查免扣也有记录
资质库FR-M6-08、J2-3到期按项目截止日判断;缺附件显示「待补录」
组件预览设计规范原型用到的全部组件
+ +

模拟了什么、没模拟什么

+
+
可以点、会变化
    +
  • 查标:处理 / 撤销 / 忽略原因校验 / 致命项确认说明 / 批量 / 快捷键 J K O 1 2 3 U ? / 原文抽屉 / 就绪状态与页签计数联动
  • +
  • 读标:分类筛选、点清单项看原文高亮、待确认区采纳与丢弃、补遗更新核对、修改记录、确认清单
  • +
  • 解析与检查的进度动画、取消、失败演示
  • +
  • 项目状态:标记已递交、撤销、归档、删除确认
  • +
  • 报告:勾选附录、出处后实时重排
+
没有做
    +
  • 真实文件上传与解析(点上传区就出示例文件)
  • +
  • 数据不保存,刷新后恢复初始状态
  • +
  • 原文查看器只做了被引用到的页面
  • +
  • 免费版的差异(报告角标、额度用完后的升级引导)只在文字里说明
  • +
  • 运营后台(FR-M6-09)、通知中心、账号设置
+
+ +

运行

+

在 docs/ 目录运行 python3 -m http.server 8766,打开 http://127.0.0.1:8766/prototype/。宋体和数字字体从 design/logo/.work/fonts 加载,没有该目录时退回系统字体。设计基准 1440 宽,最小 1280。

+
+ + diff --git a/docs/prototype/login.html b/docs/prototype/login.html new file mode 100644 index 0000000..703d62e --- /dev/null +++ b/docs/prototype/login.html @@ -0,0 +1,66 @@ + + + + + +登录 · 标博士原型 + + + + + + + + +
+ 标博士 BIAOBOSHI +

标博士,你的AI投标专家

+
    +
  • 读标:每一条要求都有出处上传招标文件,逐条提取资格、无效条款、评分、日期和 ★ 参数,点一下就跳到原文那一页。
  • +
  • 查标:递交前逐条对一遍把投标文件和清单逐条核对,找出没响应、疑似不满足、漏盖章的地方,由你逐条确认。
  • +
  • 报告:谁在什么时候确认了什么导出带处理记录的检查报告,写明查了什么、没查什么。
  • +
+ +
+
+ +
+
+
+ +
+ + + +
+ + + + + diff --git a/docs/prototype/lots.html b/docs/prototype/lots.html new file mode 100644 index 0000000..4e94d42 --- /dev/null +++ b/docs/prototype/lots.html @@ -0,0 +1,54 @@ + + + + + +选择所投的包 · 标博士原型 + + + + + + + +
+
+

选择要投的包

识别到 2 个采购包。清单只保留通用条目和所选包的条目,没选的包折叠隐藏,以后可以改。

+ + +
通用条目 18 条(资格条件、无效情形、递交要求等),所有包都适用,始终保留。
+ +
+
+ + + + + diff --git a/docs/prototype/parsing.html b/docs/prototype/parsing.html new file mode 100644 index 0000000..16f3e87 --- /dev/null +++ b/docs/prototype/parsing.html @@ -0,0 +1,83 @@ + + + + + +解析中 · 标博士原型 + + + + + + + +
+
+

正在解析招标文件

ZC-2026-0418 采购文件.doc · 186 页

+
+
+
    +
    +

    300 页以内一般 10 分钟内完成(原型里加速演示)。可以离开本页,完成或失败都会发站内通知。

    +
    + 已预扣 1 次解析,成功后结算;失败、超时或取消会自动退回 + + 回工作台,完成后通知我 + +
    +
    +
    +
    +

    演示:解析失败的样子

    +
    +
    + + + + + diff --git a/docs/prototype/project-new.html b/docs/prototype/project-new.html new file mode 100644 index 0000000..321c11a --- /dev/null +++ b/docs/prototype/project-new.html @@ -0,0 +1,76 @@ + + + + + +新建项目 · 标博士原型 + + + + + + + +
    +
    +

    新建项目

    上传招标文件,标博士会逐条提取要求,每一条都带原文出处。

    +
    +
    +
    +
    + 把招标文件拖到这里,或点击选择 + 支持 PDF(含扫描件)、Word(DOC / DOCX)、WPS。正文和附件分开的,可以一起上传。
    + 专业版单个文件不超过 500 页、100 MB(示意,以套餐页为准) +
    +
    +
    +
    +
    + 选好文件后显示扣点 + 取消 + +
    +
    +
    + + + + + diff --git a/docs/prototype/project.html b/docs/prototype/project.html new file mode 100644 index 0000000..7408964 --- /dev/null +++ b/docs/prototype/project.html @@ -0,0 +1,138 @@ + + + + + +项目概览 · 标博士原型 + + + + + + + +
    +
    +
    +
    +
    + +
    +

    AI 摘要项目要点每一条都可以点出处核对

    +
    +
    法律体系
    政府采购 · 公开招标(按「投标无效」口径检查)
    +
    预算 / 限价
    采购包 1:286.00 万元(最高限价同预算)第 2 页
    +
    评标方法
    综合评分法:价格 10、技术 40、实施方案 20、售后 10、认证 6、业绩 8 第 31 页
    +
    联合体
    不接受 已修改第 2 页
    +
    中小企业
    不专门面向中小企业;小微企业有价格扣除 第 2 页
    +
    保证金
    不收取 第 21 页
    +
    递交
    电子交易平台在线递交,CA 加密,不接受纸质 第 6 页
    +
    ★ 条款
    采购包 1 和通用部分共 4 条 · 在清单里查看
    +
    +
    +
    +

    检查记录上传新版本并检查

    + + + + + + +
    批次时间投标文件结果报告
    第 2 次11-02 14:20商务册 v3、技术册 v3、报价册 v2致命3 重要3 提示3查看
    第 1 次11-01 16:00商务册 v2、技术册 v2、报价册 v1致命2 重要4 提示211-01 报告.pdf
    +
    +
    +
    +
    +

    关键日期

    +
      +
    • 10-28采购文件公告发布
    • +
    • 11-09询问、质疑截止(公告期满后 7 个工作日)第 6 页
    • +
    • 11-20 09:30投标截止 / 开标 · 剩 17 天
      已被补遗 1 更新,原为 11-18 09:30
      补遗 1
    • +
    • 2027-02-18投标有效期至(截止日起 90 天)第 21 页
    • +
    +

    MVP 只在站内显示倒计时,不发截止提醒。

    +
    +
    +

    文件

    +

    招标方

    +
    PDF
    招标文件
    ZC-2026-0418 采购文件.pdf · 186 页 · 解析成功
    读标
    +
    PDF
    补遗 1
    更正公告 · 2 页 · 新增 0 条、更新 2 条
    读标
    +

    投标文件(加密前的 Word / PDF 稿)

    +
    DOCX
    商务册 v3
    64 页 · 11-02 14:12 上传
    +
    DOCX
    技术册 v3
    212 页 · 11-02 14:12 上传
    +
    DOCX
    报价册 v2
    8 页 · 11-01 15:40 上传
    +
    +
    +

    项目操作

    +
    +

    标记已递交后项目变为只读,仍可导出报告;可以撤销,撤销会留下记录。

    +
    +
    +
    +
    +
    + + + + + + diff --git a/docs/prototype/qualifications.html b/docs/prototype/qualifications.html new file mode 100644 index 0000000..b9764b0 --- /dev/null +++ b/docs/prototype/qualifications.html @@ -0,0 +1,51 @@ + + + + + +资质库 · 标博士原型 + + + + + + +
    +
    +

    资质库

    查标时用来核对证书有没有过期、等级够不够。数据只来自你自己录入的内容,系统不从外部补数据。

    +
    +
    !

    1 张证书会在进行中项目的投标截止日前到期。到期判断以每个项目的投标截止日为准,不以今天为准。

    + + + +
    名称类型等级证书编号发证机构有效期至附件
    +

    MVP 只有最小资质库;业绩、人员、历史标书等完整资产库在 V1 提供。

    +
    +
    + + + + + diff --git a/docs/prototype/quota.html b/docs/prototype/quota.html new file mode 100644 index 0000000..27cf1d8 --- /dev/null +++ b/docs/prototype/quota.html @@ -0,0 +1,64 @@ + + + + + +额度 · 标博士原型 + + + + + + + +
    +
    +

    额度

    专业版 · 本期 2026-11-01 至 2027-10-31。额度绑定企业主体,不可转让;期末未用完的额度不结转。

    +
    +
    i

    额度用到 80% 和 100% 时会站内提醒(每个周期每个档位只提醒一次),提醒用赭色,不用红色。

    +
    +
    解析剩余37/ 50 次

    已用 13 次 · 招标文件和补遗各算 1 次

    +
    检查剩余12/ 20 次

    已用 8 次 · 同一项目 24 小时内复查不扣

    +
    按功能分布(本期)

    读标 11 次 · 补遗 2 次
    查标 8 次 · 复查免扣 5 次

    +
    + +

    扣点规则

    所有扣点都能在下方流水里对应到具体项目和任务
    + + + + + + +
    动作扣点不扣点
    解读一份招标文件或补遗1 次解析(发起时预扣,成功后结算)解析失败、超时、取消:自动退回
    对一个项目做一次全量检查1 次检查(投标文件解析含在内)检查中断、系统异常;同一项目 24 小时内复查
    + +

    流水

    + + + + + + + + + + + +
    时间类型额度数量关联项目 / 任务说明
    11-02 14:31退回解析+1智慧大厅建设项目 · 解析任务 PJ-0417解析失败:OCR 未识别出文字
    11-02 14:28预扣解析−1智慧大厅建设项目 · 解析任务 PJ-0417
    11-02 14:20—检查0智慧大厅建设项目 · 第 2 次检查24 小时内复查,不扣
    11-02 10:05结算解析−1智慧大厅建设项目 · 补遗 1
    11-01 16:00结算检查−1智慧大厅建设项目 · 第 1 次检查
    11-01 10:40结算解析−1智慧大厅建设项目 · 招标文件
    11-01 09:00发放解析 / 检查+50 / +20专业版开通(对公转账)运营:开通单 KT-1101
    +
    +
    + + + + + diff --git a/docs/prototype/report.html b/docs/prototype/report.html new file mode 100644 index 0000000..3b69618 --- /dev/null +++ b/docs/prototype/report.html @@ -0,0 +1,102 @@ + + + + + +检查报告 · 标博士原型 + + + + + + + +
    +
    +
    +
    +
    +

    导出报告

    + + + +
    !

    还有 3 项致命问题待处理,报告会如实列出。

    +
    +
    +
    +

    已导出的报告

    +
    11-01 16:12 · 第 1 次检查.pdf
    王敏 导出 · 12 页
    +

    报告生成后不再改动,随项目归档;重新导出会生成一份新的。

    +
    +
    +
    +
    +
    +
    + + + + + diff --git a/docs/prototype/results.html b/docs/prototype/results.html new file mode 100644 index 0000000..76f928f --- /dev/null +++ b/docs/prototype/results.html @@ -0,0 +1,274 @@ + + + + + +查标 · 标博士原型 + + + + + + + +
    +
    +
    +
    +

    采购包 1 的检查结果

    +

    第 2 次检查 · 11月2日 14:20 · 商务册 v3、技术册 v3、报价册 v2 · 规则版本 IT 集成 2026.11 · 清单版本 v2(已确认)

    +
    +
    + 24 小时内复查不扣额度(至今天 16:00) + 重新检查 + 导出报告 +
    +
    +

    + +
    +
    + + + + +
    + 只显示待处理的问题;已处理的在列表底部。 +
    + + +
    +
    + +
    + +

    需人工核对

    这些要求从文件里看不出来,请递交前自己核对并勾选。勾选结果会写进报告附录。
    +
    +
    +
    + + + + + + + diff --git a/docs/prototype/workbench.html b/docs/prototype/workbench.html new file mode 100644 index 0000000..3e834b3 --- /dev/null +++ b/docs/prototype/workbench.html @@ -0,0 +1,75 @@ + + + + + +工作台 · 标博士原型 + + + + + + + +
    +
    +
    +

    工作台

    按投标截止时间排序。截止临近的项目排在前面。

    + +
    +
    +
    进行中的项目4

    已递交 1 · 已归档 1

    +
    7 天内截止2

    最近:今天 17:00

    +
    待处理的致命问题3

    在 1 个项目里

    +
    本期额度剩余37次解析

    检查 12 次 · 查看明细

    +
    +
    +
    + +
    +
    +
    + + + +
    项目所投包截止状态就绪致命
    +

    「就绪」只在「已检查」的项目上显示,只表示致命问题都已处理,不代表投标文件没有问题。截止临近用赭色提示,不用红色。

    +
    +
    + + + + +