236 lines
12 KiB
Java
236 lines
12 KiB
Java
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.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 才插入。
|
||
*/
|
||
@DemoSeed
|
||
@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);
|
||
}
|
||
}
|