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,201 @@
package com.kaidi.oa.seed;
import com.kaidi.oa.common.Money;
import com.kaidi.oa.domain.ArApItem;
import com.kaidi.oa.domain.TaxFiling;
import com.kaidi.oa.repository.ArApItemRepository;
import com.kaidi.oa.repository.TaxFilingRepository;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
/**
* 财务部缺口种子补充(W8批次)。
*
* 补全:
* ① TaxFiling:补充 8 条多税种/多状态(报表附注 §12 "应交税费明细" 需多条数据演示)。
* ② ArApItem:补充 12 条带 [CERT:*] 发票认证状态标记的应付款(§3 进项税抵扣台账演示)。
*
* 幂等:各表通过 code 前缀判断跳过。
*
* @Order(215) 在既有 FinDeptSeeder(@Order 12)、BranchFinDemoSeeder(@Order 15) 之后。
*/
@Component
@Order(215)
public class FinDeptGapSeeder implements ApplicationRunner {
private final TaxFilingRepository taxRepo;
private final ArApItemRepository arApRepo;
public FinDeptGapSeeder(TaxFilingRepository taxRepo,
ArApItemRepository arApRepo) {
this.taxRepo = taxRepo;
this.arApRepo = arApRepo;
}
@Override
@Transactional
public void run(ApplicationArguments args) {
seedTaxFilings();
seedApWithInvoiceCert();
}
// ===================== TaxFiling 多税种演示 =====================
private void seedTaxFilings() {
// 幂等:若已有超过2条则跳过
if (taxRepo.count() > 2) return;
Object[][] data = {
// code, taxType, period, taxBase, taxRate, taxAmount, status, filingDate, payDate, remark
{ "TAX-VAT-2026-04", "增值税", "2026-04",
new BigDecimal("1820000.00"), 13.0, new BigDecimal("236600.00"),
TaxFiling.S_PAID, "2026-04-15", "2026-04-20",
"2026年4月增值税主申报 | 销项税额265460-进项税额28860=应纳236600" },
{ "TAX-VAT-2026-05", "增值税", "2026-05",
new BigDecimal("2105000.00"), 13.0, new BigDecimal("273650.00"),
TaxFiling.S_FILED, "2026-05-15", null,
"2026年5月增值税申报(已申报待缴款)" },
{ "TAX-VAT-2026-06", "增值税", "2026-06",
new BigDecimal("1680000.00"), 13.0, new BigDecimal("218400.00"),
TaxFiling.S_PENDING, null, null,
"2026年6月增值税(待申报)" },
{ "TAX-CIT-2026-Q1", "企业所得税", "2026-Q1",
new BigDecimal("4200000.00"), 15.0, new BigDecimal("630000.00"),
TaxFiling.S_PAID, "2026-04-25", "2026-04-28",
"2026Q1企业所得税季报(高新技术企业15%税率)" },
{ "TAX-CIT-2026-Q2", "企业所得税", "2026-Q2",
new BigDecimal("3650000.00"), 15.0, new BigDecimal("547500.00"),
TaxFiling.S_PENDING, null, null,
"2026Q2企业所得税季报(待申报)" },
{ "TAX-STAMP-2026-H1", "印花税", "2026-H1",
new BigDecimal("120000000.00"), 0.03, new BigDecimal("36000.00"),
TaxFiling.S_PAID, "2026-06-30", "2026-06-30",
"2026上半年购销合同印花税(税率0.03‰×合同额)" },
{ "TAX-URB-2026-04", "城市维护建设税", "2026-04",
new BigDecimal("236600.00"), 7.0, new BigDecimal("16562.00"),
TaxFiling.S_PAID, "2026-04-15", "2026-04-20",
"2026年4月城建税(增值税236600×7%)" },
{ "TAX-EDUC-2026-04", "教育费附加", "2026-04",
new BigDecimal("236600.00"), 3.0, new BigDecimal("7098.00"),
TaxFiling.S_PAID, "2026-04-15", "2026-04-20",
"2026年4月教育费附加(增值税236600×3%)" },
};
for (Object[] row : data) {
String code = (String) row[0];
boolean exists = taxRepo.findAll().stream().anyMatch(t -> code.equals(t.getCode()));
if (exists) continue;
TaxFiling t = new TaxFiling();
t.setCode(code);
t.setTaxType((String) row[1]);
t.setPeriod((String) row[2]);
t.setTaxBase((BigDecimal) row[3]);
t.setTaxRate((Double) row[4]);
t.setTaxAmount((BigDecimal) row[5]);
t.setStatus((String) row[6]);
t.setFilingDate((String) row[7]);
t.setPayDate((String) row[8]);
t.setRemark((String) row[9]);
t.setCompanySubject("凯迪科技股份有限公司");
t.setOwner("税务会计");
taxRepo.save(t);
}
}
// ===================== 带发票认证状态的应付单 =====================
private void seedApWithInvoiceCert() {
// 幂等:若已有 AP-CERT 前缀的记录则跳过
boolean certExists = arApRepo.findAll().stream()
.anyMatch(i -> i.getCode() != null && i.getCode().startsWith("AP-CERT-"));
if (certExists) return;
Object[][] data = {
// code, party, ref, amount, dueDate, certStatus, remark
{ "AP-CERT-001", "武汉凯博机械有限公司", "INV-2026-0401", new BigDecimal("182000.00"),
"2026-05-31", "已认证",
"[CERT:已认证] 增值税专用发票 INV-2026-0401 已通过税局认证,进项税额23660元可抵扣" },
{ "AP-CERT-002", "湖南振华电气设备公司", "INV-2026-0402", new BigDecimal("95600.00"),
"2026-06-15", "已抵扣",
"[CERT:已抵扣] INV-2026-0402 进项税额12428元已在4月增值税申报中抵扣" },
{ "AP-CERT-003", "长沙天宇科技有限公司", "INV-2026-0415", new BigDecimal("268000.00"),
"2026-06-30", "已认证",
"[CERT:已认证] INV-2026-0415 增值税专票,进项税额34840元已认证待抵扣" },
{ "AP-CERT-004", "岳阳联盛原材料公司", "INV-2026-0420", new BigDecimal("135000.00"),
"2026-05-20", "未认证",
"[CERT:未认证] INV-2026-0420 普通发票(非专票),不可抵扣进项税" },
{ "AP-CERT-005", "广州正泰电气集团", "INV-2026-0428", new BigDecimal("412000.00"),
"2026-07-15", "未认证",
"[CERT:未认证] INV-2026-0428 专票已收到,尚未提交税局认证(请务必在当月认证截止前提交)" },
{ "AP-CERT-006", "深圳鑫泰电子元器件", "INV-2026-0501", new BigDecimal("88500.00"),
"2026-06-30", "已认证",
"[CERT:已认证] INV-2026-0501 电子增值税专用发票,进项税额11505元已认证" },
{ "AP-CERT-007", "成都博远机电制造", "INV-2026-0505", new BigDecimal("326000.00"),
"2026-07-31", "未认证",
"[CERT:未认证] INV-2026-0505 金额较大,专票正在邮寄途中,待收票后认证" },
{ "AP-CERT-008", "北京华控仪器仪表", "INV-2026-0512", new BigDecimal("67800.00"),
"2026-06-20", "已抵扣",
"[CERT:已抵扣] INV-2026-0512 进项税额8814元已在5月增值税申报中抵扣" },
{ "AP-CERT-009", "济南钢铁集团贸易", "INV-2026-0515", new BigDecimal("520000.00"),
"2026-08-15", "已认证",
"[CERT:已认证] INV-2026-0515 大额原材料采购专票,进项税额67600元,已认证待下月抵扣" },
{ "AP-CERT-010", "上海绿洲环保科技", "INV-2026-0520", new BigDecimal("42000.00"),
"2026-07-01", "未认证",
"[CERT:未认证] INV-2026-0520 服务费增值税专票(6%税率),待认证" },
{ "AP-CERT-011", "天津港航物流集团", "INV-2026-0522", new BigDecimal("185000.00"),
"2026-07-31", "已认证",
"[CERT:已认证] INV-2026-0522 运输服务9%增值税,进项税额16606元已认证" },
{ "AP-CERT-012", "武汉宏达建设集团", "INV-2026-0525", new BigDecimal("1250000.00"),
"2026-09-30", "未认证",
"[CERT:未认证] INV-2026-0525 工程服务9%增值税,金额较大,需财务总监签批后认证" },
};
for (Object[] row : data) {
ArApItem item = new ArApItem();
item.setCode((String) row[0]);
item.setArApType(ArApItem.T_AP);
item.setPartyName((String) row[1]);
item.setRelatedRef((String) row[2]);
BigDecimal amt = (BigDecimal) row[3];
// 已抵扣的标记为已结清(已核销),其余未核销
String certStatus = (String) row[5];
boolean settled = "已抵扣".equals(certStatus);
item.setAmount(amt);
item.setWrittenOff(settled ? amt : BigDecimal.ZERO);
item.setUnwrittenOff(settled ? BigDecimal.ZERO : amt);
item.setStatus(settled ? ArApItem.S_SETTLED : ArApItem.S_OPEN);
item.setDueDate((String) row[4]);
item.setRemark((String) row[6]);
item.setCompanySubject("凯迪科技股份有限公司");
item.setOwner("应付会计");
item.setCreatedAt(Instant.now().minus(15 + (long)(Math.random() * 30), ChronoUnit.DAYS));
arApRepo.save(item);
}
}
}