diff --git a/AGENTS.md b/AGENTS.md index a52a34f..d720fa6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -221,4 +221,5 @@ samples/ - 2026-11-04:按用户决定(E2)先修留出集暴露的 5 处(响应方式识别、偏离栏按「是不是明确满足」判断、另报价 / 附加条件按结构判断、空白栏、异体字),规则集 2026.11-r3。开发集不退化(召回 75%、规矩投标文件问题数不变);留出集参考数字召回 54% → 69%、规矩投标文件问题 1134 → 82(已看过,正式成绩仍以冻结代码那次为准)。见 `docs/architecture/check-eval.md` §12。 - 2026-11-04:查标第 5 步检查报告:导出 → 后台用 Gotenberg 生成 A4 PDF(首页覆盖范围和免责声明、问题明细、需人工核对附录,页眉 logo、页脚免责一句和页码)→ 加密归档,可重复下载;前端加「报告」标签页(选项、导出、内嵌预览、历次下载)。补了项目状态流转(递交 / 撤销递交 / 归档 / 撤销归档,致命未处理也能递交,递交后只读,都留痕)。产品可以从上传招标文件一路走到导出报告、标记递交。见 `docs/architecture/m3-plan.md` 进度。 - 2026-11-04:查标第 4 步资质库和资质匹配(`docs/architecture/qualification-plan.md`,QL1–QL7 全部按建议确认)。资质库页可增删改、挂证书扫描件(企业级密钥加密),到期按进行中项目的投标截止日提醒;查标按证书类别词表(16 类,产品证书、人员证书不进匹配)核对有效期、等级、有没有覆盖,投标文字层按清单项定级,只有资质库记录的降一级、出处显示「依据:资质库记录」,规则集 2026.11-r4。开发集不退化;派生的资质情况表上 D12 3 / 3、D18 2 / 2、规矩的资质表 0 误报,但表和词表是对着同一批样本写的,泛化要等国动真实文件(`check-eval.md` §13)。 -- 下一步:国动真实投标文件(用户晚些提供,到时先读标、请用户看清单,再查标一次;请用户按公司真实证书录资质库);其余可做:第 6 步前端补齐(键盘操作、批量处理、判断有误反馈、日期选择器的日历弹层)、M6 剩下的 P0(额度流水、套餐开通、数据删除、运营后台)。 +- 2026-11-04:项目基本信息修改和分包选择(FR-M2-03、04,`docs/architecture/project-info-plan.md`,PI1–PI7 全部按建议确认)。新增「概览」标签页(项目要点可改、带出处、可恢复 AI 值;采购包;关键日期)和选包页(手工调整、一键「不分包」);清单默认只列通用 + 所投的包;检查记下当时用的截止时间、限价、所投的包、法律体系,报告按它写,之后改了信息查标页提示重新检查。样本里分包识别对的只有 S10(S06 把分项认成 5 个包,S01、S08 单包写了包号),改进分包抽取记进读标专项。 +- 下一步:国动真实投标文件(用户晚些提供,到时先读标、请用户看清单,再查标一次;请用户按公司真实证书录资质库);其余可做:补遗追加(FR-M2-10,含补遗带来的新值确认)、第 6 步前端补齐(键盘操作、批量处理、判断有误反馈、日期选择器的日历弹层、概览页的检查记录和文件卡)、M6 剩下的 P0(额度流水、套餐开通、数据删除、运营后台)。 diff --git a/apps/web/src/components/FieldDialog.vue b/apps/web/src/components/FieldDialog.vue new file mode 100644 index 0000000..32ed190 --- /dev/null +++ b/apps/web/src/components/FieldDialog.vue @@ -0,0 +1,166 @@ + + + + + diff --git a/apps/web/src/components/ItemDialog.vue b/apps/web/src/components/ItemDialog.vue index 226bc48..fdd0860 100644 --- a/apps/web/src/components/ItemDialog.vue +++ b/apps/web/src/components/ItemDialog.vue @@ -12,13 +12,14 @@ import { computed, ref, watch } from "vue"; import { errorTitle, isApiError } from "@/lib/api"; import type { ItemFields } from "@/lib/checklistOps"; import { category, CATEGORY_ORDER, IMPORTANCE_MARK, IMPORTANCE_NAME } from "@/lib/labels"; -import type { ChecklistItem } from "@/lib/queries"; +import type { ChecklistItem, Lot } from "@/lib/queries"; type Mode = "edit" | "accept" | "create"; type Cat = ChecklistItem["categories"][number]; type Imp = ChecklistItem["importance"]; -const props = defineProps<{ mode: Mode; item?: ChecklistItem | null; defaultCategory?: Cat }>(); +/** lots:项目的分包(不含默认包);有 2 个及以上时可以改条目归属哪个包(FR-M2-04) */ +const props = defineProps<{ mode: Mode; item?: ChecklistItem | null; defaultCategory?: Cat; lots?: Lot[] }>(); const open = defineModel("open", { required: true }); const emit = defineEmits<{ /** 提交:changes 只含改过的字段;ack = 人工确认、无出处 */ @@ -32,6 +33,7 @@ const cats = ref([]); const imp = ref("normal"); const evidence = ref(""); const reqText = ref(""); +const lotId = ref(null); const ack = ref(false); const busy = ref(false); const err = ref(""); @@ -46,6 +48,7 @@ watch(open, (v) => { imp.value = i?.importance ?? "normal"; evidence.value = i?.evidence_required ?? ""; reqText.value = i?.requirement_text ?? ""; + lotId.value = i?.lot_id ?? null; ack.value = false; err.value = titleErr.value = catErr.value = ""; }); @@ -75,6 +78,7 @@ function changes(): ItemFields { if (!i || imp.value !== i.importance) out.importance = imp.value; const ev = evidence.value.trim() || null; if (ev !== (i?.evidence_required ?? null)) out.evidence_required = ev; + if ((props.lots?.length ?? 0) > 1 && lotId.value !== (i?.lot_id ?? null)) out.lot_id = lotId.value; const rt = reqText.value.trim() || null; if (reqEditable.value && rt !== (i?.requirement_text ?? null)) out.requirement_text = rt; return out; @@ -129,6 +133,13 @@ function submit() { ★ 条款不满足就会被判无效,已同时归在「无效条款」 +
+ + +
diff --git a/apps/web/src/components/ProjectHead.vue b/apps/web/src/components/ProjectHead.vue index 38ddf10..51b6407 100644 --- a/apps/web/src/components/ProjectHead.vue +++ b/apps/web/src/components/ProjectHead.vue @@ -1,6 +1,6 @@ + + + + diff --git a/apps/web/src/pages/OverviewPage.vue b/apps/web/src/pages/OverviewPage.vue new file mode 100644 index 0000000..9e489a9 --- /dev/null +++ b/apps/web/src/pages/OverviewPage.vue @@ -0,0 +1,267 @@ + + + + + diff --git a/apps/web/src/pages/ParsePage.vue b/apps/web/src/pages/ParsePage.vue index 0798845..f43768c 100644 --- a/apps/web/src/pages/ParsePage.vue +++ b/apps/web/src/pages/ParsePage.vue @@ -190,7 +190,9 @@ const result = computed(() => j.value?.result ?? null); 回工作台,完成后通知我