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:
@@ -0,0 +1,236 @@
|
||||
package com.kaidi.oa.seed;
|
||||
|
||||
import com.kaidi.oa.domain.SewageCostSavingProject;
|
||||
import com.kaidi.oa.domain.SewagePlantBenchmark;
|
||||
import com.kaidi.oa.repository.SewageCostSavingProjectRepository;
|
||||
import com.kaidi.oa.repository.SewagePlantBenchmarkRepository;
|
||||
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.math.RoundingMode;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* 城镇污水运营中心·横向对标 + 降本增效项目台账 演示种子数据。
|
||||
*
|
||||
* 补深审计 low 缺口(8.绩效与成本分析):
|
||||
* 1. SewagePlantBenchmark:同区域同类水厂外部横向对标数据(6家水厂,含本厂,湖南区域一级A口径);
|
||||
* 2. SewageCostSavingProject:节能技改项目独立台账(5个项目,多状态多类型,含基期+实际节约额自动计算)。
|
||||
*
|
||||
* 幂等:各表 count == 0 才插入。
|
||||
*/
|
||||
@Component
|
||||
@Order(206)
|
||||
public class SewageBenchmarkSeeder implements ApplicationRunner {
|
||||
|
||||
private final SewagePlantBenchmarkRepository benchmarkRepo;
|
||||
private final SewageCostSavingProjectRepository savingRepo;
|
||||
|
||||
public SewageBenchmarkSeeder(SewagePlantBenchmarkRepository benchmarkRepo,
|
||||
SewageCostSavingProjectRepository savingRepo) {
|
||||
this.benchmarkRepo = benchmarkRepo;
|
||||
this.savingRepo = savingRepo;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void run(ApplicationArguments args) {
|
||||
seedBenchmarks();
|
||||
seedCostSavingProjects();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ 同类水厂横向对标
|
||||
|
||||
private void seedBenchmarks() {
|
||||
if (benchmarkRepo.count() > 0) return;
|
||||
|
||||
// 本厂(凯迪科技·城镇污水一厂,标注 isSelf=true)
|
||||
benchmark("凯迪科技城镇污水一厂", "湖南省·岳阳市", 5.0, "一级A", "2025",
|
||||
0.312, 18.5, "0.058", "1.85",
|
||||
97.2, 96.8, "自填", true, "王芳");
|
||||
|
||||
// 区域同类水厂 A(处理规模相近)
|
||||
benchmark("岳阳滨水污水处理有限公司", "湖南省·岳阳市", 4.0, "一级A", "2025",
|
||||
0.298, 16.2, "0.052", "1.72",
|
||||
98.1, 97.5, "政府公开", false, "刘洋");
|
||||
|
||||
// 区域同类水厂 B(区域最优,吨水电耗最低)
|
||||
benchmark("岳阳君山水务股份有限公司", "湖南省·岳阳市", 6.0, "一级A", "2025",
|
||||
0.275, 15.8, "0.048", "1.63",
|
||||
98.5, 98.2, "行业报告·住建部2025年城镇排水年报", false, "刘洋");
|
||||
|
||||
// 区域同类水厂 C(规模稍大)
|
||||
benchmark("湘阴城乡水务集团第二污水厂", "湖南省·岳阳市", 8.0, "一级A", "2025",
|
||||
0.305, 17.3, "0.055", "1.78",
|
||||
96.8, 95.5, "集团汇总", false, "陈静");
|
||||
|
||||
// 区域同类水厂 D(较差样本,拉开分布)
|
||||
benchmark("临湘市污水处理厂", "湖南省·岳阳市", 3.0, "一级A", "2025",
|
||||
0.338, 20.6, "0.068", "2.05",
|
||||
94.2, 93.1, "政府公开", false, "陈静");
|
||||
|
||||
// 省级对标样本(规模最大,指标优异)
|
||||
benchmark("长沙第二污水处理厂", "湖南省·长沙市", 20.0, "地方特别限值", "2025",
|
||||
0.258, 14.1, "0.042", "1.52",
|
||||
99.0, 98.8, "行业报告·2025湖南省城镇污水处理年报", false, "王芳");
|
||||
}
|
||||
|
||||
private void benchmark(String plantName, String region, double capacity, String dischargeStd,
|
||||
String statPeriod, double unitPower, double unitReagent,
|
||||
String unitRepairCost, String unitTotalCost,
|
||||
double complianceRate, double equipIntactRate,
|
||||
String dataSrc, boolean isSelf, String maintainer) {
|
||||
SewagePlantBenchmark b = new SewagePlantBenchmark();
|
||||
b.setPlantName(plantName);
|
||||
b.setRegion(region);
|
||||
b.setCapacity(capacity);
|
||||
b.setDischargeStd(dischargeStd);
|
||||
b.setStatPeriod(statPeriod);
|
||||
b.setUnitPower(unitPower);
|
||||
b.setUnitReagent(unitReagent);
|
||||
b.setUnitRepairCost(new java.math.BigDecimal(unitRepairCost));
|
||||
b.setUnitTotalCost(new java.math.BigDecimal(unitTotalCost));
|
||||
b.setComplianceRate(complianceRate);
|
||||
b.setEquipIntactRate(equipIntactRate);
|
||||
b.setDataSrc(dataSrc);
|
||||
b.setIsSelf(isSelf);
|
||||
b.setMaintainer(maintainer);
|
||||
b.setCreatedAt(Instant.now());
|
||||
b.setUpdatedAt(Instant.now());
|
||||
benchmarkRepo.save(b);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ 降本增效项目台账
|
||||
|
||||
private void seedCostSavingProjects() {
|
||||
if (savingRepo.count() > 0) return;
|
||||
|
||||
// 项目1:曝气变频改造——已完结,节约可观
|
||||
// 基期:吨水电耗 0.32 kWh/m³,月均水量 150000 m³
|
||||
// 改造后:吨水电耗 0.275 kWh/m³,验证 6 个月
|
||||
// 节约电量/月 = (0.32-0.275) × 150000 = 6750 kWh/月
|
||||
// 节约电费 = 6750 × 6 × 0.58 = 23490 元
|
||||
costSavingProject("JNJ-0001", "曝气系统变频节能改造", "节能改造", "水厂1号",
|
||||
"2024-03-01", "2024-08-31", "2024-09-15",
|
||||
"98000", 3,
|
||||
0.32, 22.5, 150000.0,
|
||||
6, 0.275, 22.0, 155000.0,
|
||||
"0.58", "8.50",
|
||||
"已完结", "王芳",
|
||||
"对3台提升泵+曝气风机加装变频器,实现精确曝气控制。已通过3个月基期+6个月效果验证,累计节约电量40500 kWh,节约电费23490元,静态回收期约25个月。");
|
||||
|
||||
// 项目2:精确加药系统升级——已完结,药耗降低
|
||||
// 基期:吨水药耗 20 g/m³,月均水量 150000 m³,药剂单价 8.5 元/kg
|
||||
// 改造后:吨水药耗 17.5 g/m³,验证 3 个月
|
||||
// 节约药量/月 = (20-17.5)/1000 × 150000 = 375 kg/月
|
||||
// 节约药费 = 375 × 3 × 8.5 = 9562.5 元
|
||||
costSavingProject("JNJ-0002", "在线水质联动精确加药系统", "精确加药", "水厂1号",
|
||||
"2024-06-01", "2024-10-31", "2024-11-10",
|
||||
"65000", 3,
|
||||
0.31, 20.0, 150000.0,
|
||||
3, 0.31, 17.5, 152000.0,
|
||||
"0.58", "8.50",
|
||||
"已完结", "刘洋",
|
||||
"引入在线氨氮/TP传感器与加药泵PLC联动,实现PAC/PAM按需投加。药耗下降12.5%,月节约药剂375 kg,节约费用约3187元/月。");
|
||||
|
||||
// 项目3:PAM替换为改性淀粉基助凝剂(药剂替代)——效果验证中
|
||||
// 基期:吨水药耗 5.2 g/m³(PAM),药剂单价 12 元/kg
|
||||
// 替换后:预期吨水药耗 4.5 g/m³,药剂单价 7.8 元/kg(改性淀粉)
|
||||
costSavingProject("JNJ-0003", "PAM替代:改性淀粉基助凝剂中试", "药剂替代", "水厂1号",
|
||||
"2025-03-01", "2025-08-31", null,
|
||||
"28000", 3,
|
||||
0.31, 5.2, 148000.0,
|
||||
3, 0.31, 4.5, 148000.0,
|
||||
"0.58", "7.80",
|
||||
"效果验证", "陈静",
|
||||
"试用改性淀粉基绿色助凝剂替代PAM,环保指标更优且成本更低。目前已完成3个月中试,吨水药耗从5.2降至4.5 g/m³,进入效果验证阶段。");
|
||||
|
||||
// 项目4:污泥脱水系统能效提升——改造中
|
||||
costSavingProject("JNJ-0004", "污泥脱水机变频节能改造", "节能改造", "水厂2号",
|
||||
"2025-08-01", "2025-12-31", null,
|
||||
"45000", 3,
|
||||
0.29, 18.0, 120000.0,
|
||||
3, 0.265, 18.0, 120000.0,
|
||||
"0.58", "8.50",
|
||||
"改造中", "王芳",
|
||||
"对2台带式压滤机驱动电机实施变频改造,预计吨水电耗降低0.025 kWh/m³,月节约电量3000 kWh。目前设备已进场,安装调试中。");
|
||||
|
||||
// 项目5:峰谷用电策略优化——立项中
|
||||
costSavingProject("JNJ-0005", "峰谷电价优化运行策略", "工艺优化", "全站",
|
||||
"2025-11-01", "2026-03-31", null,
|
||||
"5000", 3,
|
||||
0.32, 19.5, 270000.0,
|
||||
6, 0.305, 19.5, 270000.0,
|
||||
"0.58", "8.50",
|
||||
"立项中", "刘洋",
|
||||
"分析峰谷用电时段,将非核心用电负荷(污泥脱水、曝气辅机)移至谷段运行。通过调整运行策略降低电费(综合电价从0.58降至平均0.55元/kWh),无设备改造,主要是运行制度优化。");
|
||||
}
|
||||
|
||||
private void costSavingProject(String code, String projectName, String projectType, String plant,
|
||||
String kickoffDate, String planFinishDate, String actualFinishDate,
|
||||
String investCost, int baseMonths,
|
||||
double baseUnitPower, double baseUnitReagent, double baseMonthlyWater,
|
||||
int verifyMonths, double actualUnitPower, double actualUnitReagent, double actualMonthlyWater,
|
||||
String powerPrice, String reagentPrice,
|
||||
String projStatus, String owner, String remark) {
|
||||
SewageCostSavingProject p = new SewageCostSavingProject();
|
||||
p.setCode(code);
|
||||
p.setProjectName(projectName);
|
||||
p.setProjectType(projectType);
|
||||
p.setPlant(plant);
|
||||
p.setKickoffDate(kickoffDate);
|
||||
p.setPlanFinishDate(planFinishDate);
|
||||
p.setActualFinishDate(actualFinishDate);
|
||||
p.setInvestCost(new BigDecimal(investCost));
|
||||
p.setBaseMonths(baseMonths);
|
||||
p.setBaseUnitPower(baseUnitPower);
|
||||
p.setBaseUnitReagent(baseUnitReagent);
|
||||
p.setBaseMonthlyWater(baseMonthlyWater);
|
||||
p.setVerifyMonths(verifyMonths);
|
||||
p.setActualUnitPower(actualUnitPower);
|
||||
p.setActualUnitReagent(actualUnitReagent);
|
||||
p.setActualMonthlyWater(actualMonthlyWater);
|
||||
p.setPowerPrice(new BigDecimal(powerPrice));
|
||||
p.setReagentPrice(new BigDecimal(reagentPrice));
|
||||
p.setProjStatus(projStatus);
|
||||
p.setOwner(owner);
|
||||
p.setRemark(remark);
|
||||
p.setCreatedAt(Instant.now());
|
||||
p.setUpdatedAt(Instant.now());
|
||||
|
||||
// 自动计算节约量
|
||||
double deltaUnitPower = baseUnitPower - actualUnitPower;
|
||||
double savedKwhPerM = Math.max(0, deltaUnitPower * actualMonthlyWater);
|
||||
double savedKwhTotal = savedKwhPerM * verifyMonths;
|
||||
double deltaUnitReagent = baseUnitReagent - actualUnitReagent;
|
||||
double savedReagentKgPerM = Math.max(0, deltaUnitReagent / 1000.0 * actualMonthlyWater);
|
||||
BigDecimal pp = new BigDecimal(powerPrice);
|
||||
BigDecimal rp = new BigDecimal(reagentPrice);
|
||||
BigDecimal savedPowerCost = BigDecimal.valueOf(savedKwhTotal).multiply(pp)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
BigDecimal savedReagentCost = BigDecimal.valueOf(savedReagentKgPerM * verifyMonths).multiply(rp)
|
||||
.setScale(2, RoundingMode.HALF_UP);
|
||||
BigDecimal savedTotal = savedPowerCost.add(savedReagentCost);
|
||||
p.setSavedKwhPerMonth(Math.round(savedKwhPerM * 100.0) / 100.0);
|
||||
p.setSavedKwhTotal(Math.round(savedKwhTotal * 100.0) / 100.0);
|
||||
p.setSavedReagentKgPerMonth(Math.round(savedReagentKgPerM * 100.0) / 100.0);
|
||||
p.setSavedPowerCost(savedPowerCost);
|
||||
p.setSavedReagentCost(savedReagentCost);
|
||||
p.setSavedTotalCost(savedTotal);
|
||||
|
||||
BigDecimal invest = new BigDecimal(investCost);
|
||||
if (savedTotal.compareTo(BigDecimal.ZERO) > 0 && verifyMonths > 0) {
|
||||
BigDecimal monthlyRate = savedTotal.divide(BigDecimal.valueOf(verifyMonths), 4, RoundingMode.HALF_UP);
|
||||
if (monthlyRate.compareTo(BigDecimal.ZERO) > 0) {
|
||||
double pb = invest.divide(monthlyRate, 2, RoundingMode.HALF_UP).doubleValue();
|
||||
p.setPaybackMonths(pb);
|
||||
}
|
||||
}
|
||||
|
||||
savingRepo.save(p);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user