SNAPSHOT W7 已部署稳定态 — 凯迪ERP+OA一体化平台 (MET 73.3%)

恢复点(restore point)。别人改崩后可 git reset --hard 回到此提交。

== 此快照内容 ==
- 后端 oa-backend: 734 控制器 / 711 实体 (Spring Boot 3.2.5 + SQLite, 端口8091)
- 前端 modern-ui/app: Vue3+Vite, 约700页 (构建产物已在 oa-backend/src/main/resources/static)
- 数据库 oa-backend/data/oa.db: 含全部演示数据 (强制入库, 6.6MB)
- 交接文档 go.md + go-code-reference/endpoints/entities/database.md
- 多代理建设脚本 .claude/wf-*.js

== 状态 ==
- 对 凯迪科技ERP_20260507.xlsx 合规 MET ~73.3% (PARTIAL 75: 34可建+6种子/bug+35外部硬天花板)
- 安全: 5轮红队+5轮复检, default-deny分级鉴权, 连续零可利用
- W3~W7 累计补完436缺口; W8末轮(40缺口)为半成品(源码树可编译但未集成)
- 运行: cd oa-backend; java -jar build/libs/oa-backend-0.1.0.jar --server.port=8091; admin/123456

== 排除(gitignore, 可再生) ==
node_modules / oa-backend/build / .jdks / *.log / Backup-ERP-* / 弃用的OFBiz核心(只保留modern-ui)
完整文件夹备份见同目录 Backup-ERP-20260615-191517/ (含上述全部, 仅缺 node_modules)

时间戳: 20260615-191517

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Qiufeng
2026-06-15 19:19:15 +08:00
co-authored by Claude Opus 4.8
commit 5e51dc3f56
10584 changed files with 2501339 additions and 0 deletions
@@ -0,0 +1,204 @@
package com.kaidi.oa.seed;
import com.kaidi.oa.common.Money;
import com.kaidi.oa.domain.BidDocVersion;
import com.kaidi.oa.domain.BidTenderDoc;
import com.kaidi.oa.repository.BidDocVersionRepository;
import com.kaidi.oa.repository.BidRepository;
import com.kaidi.oa.repository.BidTenderDocRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.time.LocalDate;
/**
* 招标文件台账 + 投标文件协同编制版本演示数据。
*
* @Order(215) 在所有主数据 Seeder 之后运行;幂等(count > 0 则跳过)。
*/
@Component
@Order(215)
public class BidTenderDocSeeder implements CommandLineRunner {
private final BidTenderDocRepository tenderDocRepo;
private final BidDocVersionRepository docVersionRepo;
private final BidRepository bidRepo;
public BidTenderDocSeeder(BidTenderDocRepository tenderDocRepo,
BidDocVersionRepository docVersionRepo,
BidRepository bidRepo) {
this.tenderDocRepo = tenderDocRepo;
this.docVersionRepo = docVersionRepo;
this.bidRepo = bidRepo;
}
@Override
public void run(String... args) {
if (tenderDocRepo.count() > 0) return; // 幂等
// 取前两个投标 id(若存在)
var bids = bidRepo.findAll();
long bid1 = bids.isEmpty() ? 1L : bids.get(0).getId();
long bid2 = bids.size() > 1 ? bids.get(1).getId() : bid1;
Instant now = Instant.now();
LocalDate today = LocalDate.now();
// ====== 招标文件台账演示数据 ======
// bid1 — 招标文件(已下载,已付标书费)
BidTenderDoc d1 = new BidTenderDoc();
d1.setBidId(bid1);
d1.setDocType("招标文件");
d1.setDocTitle("长沙市污水处理厂扩容工程招标文件(第一册)");
d1.setFileRef("files/bid-tender/招标文件_污水厂扩容_v1.pdf");
d1.setDownloadDate(today.minusDays(20).toString());
d1.setPurchaseFee(Money.of(500.00));
d1.setFeePaidStatus("已付");
d1.setDeadlineDate(today.plusDays(5).toString());
d1.setStatus("已下载");
d1.setBondAmount(Money.of(50000.00));
d1.setBondPayMethod("银行转账");
d1.setBondStatus("已缴");
d1.setOwner("陈志远");
d1.setCreatedAt(now);
tenderDocRepo.save(d1);
// bid1 — 澄清文件
BidTenderDoc d2 = new BidTenderDoc();
d2.setBidId(bid1);
d2.setDocType("澄清文件");
d2.setDocTitle("长沙市污水处理厂扩容工程招标澄清函(第1号)");
d2.setFileRef("files/bid-tender/澄清函_污水厂扩容_01.pdf");
d2.setDownloadDate(today.minusDays(10).toString());
d2.setPurchaseFee(Money.ZERO);
d2.setFeePaidStatus("已付");
d2.setDeadlineDate(today.plusDays(5).toString());
d2.setStatus("已下载");
d2.setBondAmount(Money.ZERO);
d2.setBondStatus("未缴");
d2.setOwner("陈志远");
d2.setCreatedAt(now);
tenderDocRepo.save(d2);
// bid1 — 答疑文件
BidTenderDoc d3 = new BidTenderDoc();
d3.setBidId(bid1);
d3.setDocType("答疑文件");
d3.setDocTitle("长沙市污水处理厂扩容工程投标答疑(汇总版)");
d3.setFileRef("files/bid-tender/答疑_污水厂扩容_汇总.pdf");
d3.setDownloadDate(today.minusDays(7).toString());
d3.setPurchaseFee(Money.ZERO);
d3.setFeePaidStatus("已付");
d3.setDeadlineDate(today.plusDays(5).toString());
d3.setStatus("已下载");
d3.setBondAmount(Money.ZERO);
d3.setBondStatus("未缴");
d3.setRemark("答疑共 12 条,涉及工艺方案和报价清单调整");
d3.setOwner("陈志远");
d3.setCreatedAt(now);
tenderDocRepo.save(d3);
// bid2 — 招标文件(未付标书费,保证金逾期未退)
BidTenderDoc d4 = new BidTenderDoc();
d4.setBidId(bid2);
d4.setDocType("招标文件");
d4.setDocTitle("株洲市道路改造工程招标文件");
d4.setFileRef("files/bid-tender/招标文件_株洲道路_v1.pdf");
d4.setDownloadDate(today.minusDays(65).toString());
d4.setPurchaseFee(Money.of(300.00));
d4.setFeePaidStatus("未付");
d4.setDeadlineDate(today.minusDays(30).toString()); // 已过期
d4.setStatus("已下载");
d4.setBondAmount(Money.of(30000.00));
d4.setBondPayMethod("保险保函");
d4.setBondStatus("已缴"); // 逾期未退,催办
d4.setRemark("未中标,保证金应已退回但未确认,请催办");
d4.setOwner("刘伟");
d4.setCreatedAt(now.minusSeconds(3600 * 24 * 65));
tenderDocRepo.save(d4);
// bid2 — 补充文件(截止日临近预警演示)
BidTenderDoc d5 = new BidTenderDoc();
d5.setBidId(bid2);
d5.setDocType("补充文件");
d5.setDocTitle("株洲市道路改造工程补充技术要求");
d5.setFileRef("files/bid-tender/补充要求_株洲道路.pdf");
d5.setDownloadDate(today.minusDays(3).toString());
d5.setPurchaseFee(Money.ZERO);
d5.setFeePaidStatus("已付");
d5.setDeadlineDate(today.plusDays(2).toString()); // 紧急 — 2天内到期
d5.setStatus("待处理");
d5.setBondAmount(Money.ZERO);
d5.setBondStatus("未缴");
d5.setOwner("刘伟");
d5.setCreatedAt(now);
tenderDocRepo.save(d5);
// ====== 投标文件版本协同演示数据 ======
if (docVersionRepo.count() > 0) return;
// bid1 商务标 — v1 草稿 → v2 审核中
BidDocVersion v1 = new BidDocVersion();
v1.setBidId(bid1);
v1.setDocPart("商务标");
v1.setVersion("v1");
v1.setDocTitle("污水厂扩容工程商务标(初稿)");
v1.setFileRef("files/bid-doc/商务标_污水厂_v1.docx");
v1.setCollaborators("陈志远,李明");
v1.setSubmitter("陈志远");
v1.setStatus("已驳回");
v1.setReviewComment("报价清单有误,需根据答疑调整综合单价");
v1.setAnnotations("[李明 @ " + today.minusDays(12) + "] 第3章综合单价表需重算\n[陈志远 @ " + today.minusDays(11) + "] 已核,修订后提交v2");
v1.setSubmittedAt(now.minusSeconds(3600 * 24 * 12));
v1.setCreatedAt(now.minusSeconds(3600 * 24 * 14));
docVersionRepo.save(v1);
BidDocVersion v2 = new BidDocVersion();
v2.setBidId(bid1);
v2.setDocPart("商务标");
v2.setVersion("v2");
v2.setDocTitle("污水厂扩容工程商务标(修订版)");
v2.setFileRef("files/bid-doc/商务标_污水厂_v2.docx");
v2.setCollaborators("陈志远,李明,张华");
v2.setSubmitter("陈志远");
v2.setStatus("审核中");
v2.setAnnotations("[张华 @ " + today.minusDays(5) + "] 综合单价已按答疑调整,请财务复核");
v2.setSubmittedAt(now.minusSeconds(3600 * 24 * 5));
v2.setCreatedAt(now.minusSeconds(3600 * 24 * 7));
docVersionRepo.save(v2);
// bid1 技术标 — v1 已定稿
BidDocVersion v3 = new BidDocVersion();
v3.setBidId(bid1);
v3.setDocPart("技术标");
v3.setVersion("v1");
v3.setDocTitle("污水厂扩容工程技术标(定稿)");
v3.setFileRef("files/bid-doc/技术标_污水厂_v1_final.docx");
v3.setCollaborators("王涛,赵雪");
v3.setSubmitter("王涛");
v3.setStatus("已定稿");
v3.setReviewComment("技术方案完整,已通过合规审核");
v3.setAnnotations("[赵雪 @ " + today.minusDays(8) + "] 施工方案第4节水处理工艺描述更新\n[王涛 @ " + today.minusDays(7) + "] 全文定稿确认");
v3.setSubmittedAt(now.minusSeconds(3600 * 24 * 8));
v3.setFinalizedAt(now.minusSeconds(3600 * 24 * 7));
v3.setCreatedAt(now.minusSeconds(3600 * 24 * 10));
docVersionRepo.save(v3);
// bid1 报价单 — v1 草稿
BidDocVersion v4 = new BidDocVersion();
v4.setBidId(bid1);
v4.setDocPart("报价单");
v4.setVersion("v1");
v4.setDocTitle("污水厂扩容工程报价单(草稿)");
v4.setFileRef("files/bid-doc/报价单_污水厂_v1.xlsx");
v4.setCollaborators("李明,周斌");
v4.setSubmitter("李明");
v4.setStatus("草稿");
v4.setAnnotations("[周斌 @ " + today.minusDays(3) + "] 材料单价已更新至2026年5月指导价");
v4.setSubmittedAt(now.minusSeconds(3600 * 24 * 3));
v4.setCreatedAt(now.minusSeconds(3600 * 24 * 4));
docVersionRepo.save(v4);
}
}