diff --git a/sql/energy/energy_alter_frontend.sql b/sql/energy/energy_alter_frontend.sql new file mode 100644 index 0000000..84f8bce --- /dev/null +++ b/sql/energy/energy_alter_frontend.sql @@ -0,0 +1,3 @@ +-- energy_alter_frontend.sql +ALTER TABLE energy_bill ADD COLUMN cooperation_type TINYINT DEFAULT NULL COMMENT '合作模式(1=预充值 2=月结算)' AFTER station_name; +ALTER TABLE energy_station_config ADD COLUMN auto_match TINYINT DEFAULT 1 COMMENT '自动匹配开关(0=关闭 1=开启)' AFTER cooperation_type; diff --git a/yudao-module-energy/pom.xml b/yudao-module-energy/pom.xml new file mode 100644 index 0000000..0954d4f --- /dev/null +++ b/yudao-module-energy/pom.xml @@ -0,0 +1,23 @@ + + + + cn.iocoder.cloud + yudao + ${revision} + + 4.0.0 + yudao-module-energy + pom + + ${project.artifactId} + 能源账单模块,包含加氢记录、费用明细、账单管理、账户管理等功能 + https://github.com/YunaiV/yudao-cloud + + + yudao-module-energy-api + yudao-module-energy-server + + + diff --git a/yudao-module-energy/yudao-module-energy-api/pom.xml b/yudao-module-energy/yudao-module-energy-api/pom.xml new file mode 100644 index 0000000..c0cb88b --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/pom.xml @@ -0,0 +1,39 @@ + + + + yudao-module-energy + cn.iocoder.cloud + ${revision} + + 4.0.0 + yudao-module-energy-api + jar + + ${project.artifactId} + 能源账单 API,定义枚举、错误码等 + https://github.com/YunaiV/yudao-cloud + + + + cn.iocoder.cloud + yudao-common + + + + + cn.iocoder.cloud + yudao-spring-boot-starter-web + provided + + + + + org.springframework.boot + spring-boot-starter-validation + true + + + + diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/AccountStatusEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/AccountStatusEnum.java new file mode 100644 index 0000000..c118053 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/AccountStatusEnum.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum AccountStatusEnum { + NORMAL(0, "正常"), + WARNING(1, "预警"), + OVERDUE(2, "欠费"); + + private final Integer status; + private final String name; + + public static AccountStatusEnum valueOf(Integer status) { + return Arrays.stream(values()) + .filter(item -> item.getStatus().equals(status)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/AdjustmentTypeEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/AdjustmentTypeEnum.java new file mode 100644 index 0000000..207f4e8 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/AdjustmentTypeEnum.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum AdjustmentTypeEnum { + INCREASE(0, "调增"), + DECREASE(1, "调减"); + + private final Integer type; + private final String name; + + public static AdjustmentTypeEnum valueOf(Integer type) { + return Arrays.stream(values()) + .filter(item -> item.getType().equals(type)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/AuditStatusEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/AuditStatusEnum.java new file mode 100644 index 0000000..9501e24 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/AuditStatusEnum.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum AuditStatusEnum { + PENDING(0, "待审核"), + APPROVED(1, "已通过"), + REJECTED(2, "已驳回"); + + private final Integer status; + private final String name; + + public static AuditStatusEnum valueOf(Integer status) { + return Arrays.stream(values()) + .filter(item -> item.getStatus().equals(status)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BillAuditStatusEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BillAuditStatusEnum.java new file mode 100644 index 0000000..0cd4360 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BillAuditStatusEnum.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum BillAuditStatusEnum { + PENDING(0, "待审核"), + APPROVED(1, "已通过"), + REJECTED(2, "已驳回"); + + private final Integer status; + private final String name; + + public static BillAuditStatusEnum valueOf(Integer status) { + return Arrays.stream(values()) + .filter(item -> item.getStatus().equals(status)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BillStatusEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BillStatusEnum.java new file mode 100644 index 0000000..e22cf71 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BillStatusEnum.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum BillStatusEnum { + DRAFT(0, "草稿"), + GENERATED(1, "已生成"), + VOID(2, "已作废"); + + private final Integer status; + private final String name; + + public static BillStatusEnum valueOf(Integer status) { + return Arrays.stream(values()) + .filter(item -> item.getStatus().equals(status)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BillSubmitStatusEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BillSubmitStatusEnum.java new file mode 100644 index 0000000..8c42eb0 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BillSubmitStatusEnum.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum BillSubmitStatusEnum { + NOT_SUBMITTED(0, "未提交"), + SUBMITTED(1, "已提交"), + REJECTED(2, "已驳回"); + + private final Integer status; + private final String name; + + public static BillSubmitStatusEnum valueOf(Integer status) { + return Arrays.stream(values()) + .filter(item -> item.getStatus().equals(status)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BizTypeEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BizTypeEnum.java new file mode 100644 index 0000000..e4c5d6b --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/BizTypeEnum.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum BizTypeEnum { + HYDROGEN_DEDUCTION(0, "加氢扣款"), + BILL_SETTLEMENT(1, "账单结算"), + MANUAL_ADJUST(2, "手动调整"), + RECHARGE(3, "充值"), + REMIT(4, "汇款"); + + private final Integer type; + private final String name; + + public static BizTypeEnum valueOf(Integer type) { + return Arrays.stream(values()) + .filter(item -> item.getType().equals(type)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/CooperationTypeEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/CooperationTypeEnum.java new file mode 100644 index 0000000..d1b035f --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/CooperationTypeEnum.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum CooperationTypeEnum { + COOPERATED(0, "合作"), + NON_COOPERATED(1, "非合作"); + + private final Integer type; + private final String name; + + public static CooperationTypeEnum valueOf(Integer type) { + return Arrays.stream(values()) + .filter(item -> item.getType().equals(type)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/CostBearerEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/CostBearerEnum.java new file mode 100644 index 0000000..a5ef08e --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/CostBearerEnum.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum CostBearerEnum { + CUSTOMER(0, "客户承担"), + COMPANY(1, "羚牛承担"), + SELF_SETTLE(2, "自行结算"); + + private final Integer type; + private final String name; + + public static CostBearerEnum valueOf(Integer type) { + return Arrays.stream(values()) + .filter(item -> item.getType().equals(type)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/DeductionStatusEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/DeductionStatusEnum.java new file mode 100644 index 0000000..c000404 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/DeductionStatusEnum.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum DeductionStatusEnum { + NOT_DEDUCTED(0, "未扣款"), + DEDUCTED(1, "已扣款"); + + private final Integer status; + private final String name; + + public static DeductionStatusEnum valueOf(Integer status) { + return Arrays.stream(values()) + .filter(item -> item.getStatus().equals(status)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/EnergyTypeEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/EnergyTypeEnum.java new file mode 100644 index 0000000..f51d8d9 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/EnergyTypeEnum.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum EnergyTypeEnum { + HYDROGEN(0, "氢费"), + ELECTRIC(1, "电费"), + ETC(2, "ETC"); + + private final Integer type; + private final String name; + + public static EnergyTypeEnum valueOf(Integer type) { + return Arrays.stream(values()) + .filter(item -> item.getType().equals(type)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/ErrorCodeConstants.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/ErrorCodeConstants.java new file mode 100644 index 0000000..cd62d83 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/ErrorCodeConstants.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.energy.enums; + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +public interface ErrorCodeConstants { + // ========== 加氢记录 1-050-000-000 ========== + ErrorCode HYDROGEN_RECORD_NOT_EXISTS = new ErrorCode(1_050_000_000, "加氢记录不存在"); + ErrorCode HYDROGEN_RECORD_IMPORT_EMPTY = new ErrorCode(1_050_000_001, "导入数据为空"); + ErrorCode HYDROGEN_RECORD_DUPLICATE = new ErrorCode(1_050_000_002, "存在重复导入记录"); + + // ========== 加氢明细 1-050-001-000 ========== + ErrorCode HYDROGEN_DETAIL_NOT_EXISTS = new ErrorCode(1_050_001_000, "加氢明细不存在"); + ErrorCode HYDROGEN_DETAIL_ALREADY_AUDITED = new ErrorCode(1_050_001_001, "明细已审核,不可重复审核"); + + // ========== 能源账单 1-050-002-000 ========== + ErrorCode ENERGY_BILL_NOT_EXISTS = new ErrorCode(1_050_002_000, "能源账单不存在"); + ErrorCode ENERGY_BILL_NOT_DRAFT = new ErrorCode(1_050_002_001, "账单非草稿状态,不可删除"); + ErrorCode ENERGY_BILL_ALREADY_AUDITED = new ErrorCode(1_050_002_002, "账单已审核"); + ErrorCode ENERGY_BILL_NO_DETAILS = new ErrorCode(1_050_002_003, "无可生成账单的明细"); + + // ========== 能源账户 1-050-003-000 ========== + ErrorCode ENERGY_ACCOUNT_NOT_EXISTS = new ErrorCode(1_050_003_000, "能源账户不存在"); + ErrorCode ENERGY_ACCOUNT_VERSION_CONFLICT = new ErrorCode(1_050_003_001, "账户余额更新冲突,请重试"); + + // ========== 价格管理 1-050-004-000 ========== + ErrorCode STATION_PRICE_NOT_EXISTS = new ErrorCode(1_050_004_000, "站点价格不存在"); + ErrorCode STATION_PRICE_DUPLICATE = new ErrorCode(1_050_004_001, "同一站点同一客户同一生效日期已存在价格"); + + // ========== 站点配置 1-050-005-000 ========== + ErrorCode STATION_CONFIG_NOT_EXISTS = new ErrorCode(1_050_005_000, "站点配置不存在"); + ErrorCode STATION_CONFIG_DUPLICATE = new ErrorCode(1_050_005_001, "该站点配置已存在"); +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/FlowTypeEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/FlowTypeEnum.java new file mode 100644 index 0000000..f0195ac --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/FlowTypeEnum.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum FlowTypeEnum { + RECHARGE(0, "充值"), + DEDUCTION(1, "扣款"), + REVERSAL(2, "冲正"), + REMIT(3, "汇款"), + REFUND(4, "退款"); + + private final Integer type; + private final String name; + + public static FlowTypeEnum valueOf(Integer type) { + return Arrays.stream(values()) + .filter(item -> item.getType().equals(type)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/MatchStatusEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/MatchStatusEnum.java new file mode 100644 index 0000000..1e8e3ea --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/MatchStatusEnum.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum MatchStatusEnum { + UNMATCHED(0, "未匹配"), + MATCHED(1, "已匹配"), + UNMATCHABLE(2, "无法匹配"); + + private final Integer status; + private final String name; + + public static MatchStatusEnum valueOf(Integer status) { + return Arrays.stream(values()) + .filter(item -> item.getStatus().equals(status)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/PayMethodEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/PayMethodEnum.java new file mode 100644 index 0000000..186ff3f --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/PayMethodEnum.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum PayMethodEnum { + PREPAID(0, "预充值"), + MONTHLY(1, "月结算"); + + private final Integer type; + private final String name; + + public static PayMethodEnum valueOf(Integer type) { + return Arrays.stream(values()) + .filter(item -> item.getType().equals(type)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/PaymentStatusEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/PaymentStatusEnum.java new file mode 100644 index 0000000..0ad3436 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/PaymentStatusEnum.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum PaymentStatusEnum { + UNPAID(0, "未支付"), + PARTIAL(1, "部分支付"), + PAID(2, "已支付"); + + private final Integer status; + private final String name; + + public static PaymentStatusEnum valueOf(Integer status) { + return Arrays.stream(values()) + .filter(item -> item.getStatus().equals(status)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/SettlementStatusEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/SettlementStatusEnum.java new file mode 100644 index 0000000..c630e50 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/SettlementStatusEnum.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum SettlementStatusEnum { + NOT_SETTLED(0, "未结算"), + SETTLED(1, "已结算"); + + private final Integer status; + private final String name; + + public static SettlementStatusEnum valueOf(Integer status) { + return Arrays.stream(values()) + .filter(item -> item.getStatus().equals(status)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/SourceTypeEnum.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/SourceTypeEnum.java new file mode 100644 index 0000000..bef2dba --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/enums/SourceTypeEnum.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.energy.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum SourceTypeEnum { + EXCEL(0, "Excel导入"), + WEB(1, "Web录入"), + API(2, "API对接"), + OCR(3, "OCR识别"); + + private final Integer type; + private final String name; + + public static SourceTypeEnum valueOf(Integer type) { + return Arrays.stream(values()) + .filter(item -> item.getType().equals(type)) + .findFirst().orElse(null); + } +} diff --git a/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/package-info.java b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/package-info.java new file mode 100644 index 0000000..bdae697 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-api/src/main/java/cn/iocoder/yudao/module/energy/package-info.java @@ -0,0 +1,4 @@ +/** + * 能源账单 API 模块,定义枚举、错误码等 + */ +package cn.iocoder.yudao.module.energy; diff --git a/yudao-module-energy/yudao-module-energy-server/pom.xml b/yudao-module-energy/yudao-module-energy-server/pom.xml new file mode 100644 index 0000000..45ba784 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/pom.xml @@ -0,0 +1,132 @@ + + + + yudao-module-energy + cn.iocoder.cloud + ${revision} + + 4.0.0 + yudao-module-energy-server + jar + + ${project.artifactId} + 能源账单业务实现 + https://github.com/YunaiV/yudao-cloud + + + + + cn.iocoder.cloud + yudao-spring-boot-starter-env + + + + + cn.iocoder.cloud + yudao-module-energy-api + ${revision} + + + + + cn.iocoder.cloud + yudao-module-system-api + ${revision} + + + + + cn.iocoder.cloud + yudao-module-infra-api + ${revision} + + + + + cn.iocoder.cloud + yudao-spring-boot-starter-biz-tenant + + + + + cn.iocoder.cloud + yudao-spring-boot-starter-security + + + + org.springframework.boot + spring-boot-starter-validation + + + + + cn.iocoder.cloud + yudao-spring-boot-starter-mybatis + + + + + cn.iocoder.cloud + yudao-spring-boot-starter-rpc + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + cn.iocoder.cloud + yudao-spring-boot-starter-job + + + + + cn.iocoder.cloud + yudao-spring-boot-starter-mq + + + + + cn.iocoder.cloud + yudao-spring-boot-starter-test + test + + + + + cn.iocoder.cloud + yudao-spring-boot-starter-excel + + + + + + ${project.artifactId} + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + repackage + + + + + + + diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/EnergyAccountController.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/EnergyAccountController.java new file mode 100644 index 0000000..313ec20 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/EnergyAccountController.java @@ -0,0 +1,89 @@ +package cn.iocoder.yudao.module.energy.controller.admin.account; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.account.vo.*; +import cn.iocoder.yudao.module.energy.convert.account.EnergyAccountConvert; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyAccountDO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyAccountFlowDO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyProjectAccountDO; +import cn.iocoder.yudao.module.energy.service.account.EnergyAccountService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.math.BigDecimal; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 能源账户管理") +@RestController +@RequestMapping("/energy/account") +@Validated +public class EnergyAccountController { + + @Resource + private EnergyAccountService accountService; + + @GetMapping("/page") + @Operation(summary = "获得账户分页") + @PreAuthorize("@ss.hasPermission('energy:account:query')") + public CommonResult> getAccountPage(@Valid EnergyAccountPageReqVO pageReqVO) { + PageResult pageResult = accountService.getAccountPage(pageReqVO); + return success(EnergyAccountConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/get") + @Operation(summary = "获得账户详情") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('energy:account:query')") + public CommonResult getAccount(@RequestParam("id") Long id) { + EnergyAccountDO account = accountService.getAccount(id); + return success(EnergyAccountConvert.INSTANCE.convert(account)); + } + + @PostMapping("/recharge") + @Operation(summary = "账户充值") + @PreAuthorize("@ss.hasPermission('energy:account:recharge')") + public CommonResult recharge(@RequestParam("customerId") Long customerId, + @RequestParam("amount") BigDecimal amount, + @RequestParam(value = "remark", required = false) String remark) { + accountService.recharge(customerId, amount, null, null, remark); + return success(true); + } + + @PutMapping("/update-threshold") + @Operation(summary = "更新预警阈值") + @PreAuthorize("@ss.hasPermission('energy:account:update')") + public CommonResult updateThreshold(@RequestParam("id") Long id, + @RequestParam("threshold") BigDecimal threshold) { + accountService.updateThreshold(id, threshold); + return success(true); + } + + // ===== 项目账户 ===== + + @GetMapping("/project/list") + @Operation(summary = "获得项目账户列表") + @Parameter(name = "accountId", description = "总账户ID", required = true) + @PreAuthorize("@ss.hasPermission('energy:account:query')") + public CommonResult> getProjectAccountList(@RequestParam("accountId") Long accountId) { + List list = accountService.getProjectAccountsByAccountId(accountId); + return success(cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList(list, EnergyAccountConvert.INSTANCE::convert)); + } + + // ===== 流水查询 ===== + + @GetMapping("/flow/page") + @Operation(summary = "获得流水分页") + @PreAuthorize("@ss.hasPermission('energy:account:query')") + public CommonResult> getFlowPage(@Valid EnergyAccountFlowPageReqVO pageReqVO) { + return success(accountService.getFlowPage(pageReqVO)); + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountFlowPageReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountFlowPageReqVO.java new file mode 100644 index 0000000..62fdee5 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountFlowPageReqVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.energy.controller.admin.account.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 账户流水分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class EnergyAccountFlowPageReqVO extends PageParam { + @Schema(description = "总账户ID") + private Long accountId; + @Schema(description = "项目账户ID") + private Long projectAccountId; + @Schema(description = "流水类型") + private Integer flowType; + @Schema(description = "业务类型") + private Integer bizType; + @Schema(description = "开始时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountPageReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountPageReqVO.java new file mode 100644 index 0000000..8cca160 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountPageReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.energy.controller.admin.account.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 能源账户分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class EnergyAccountPageReqVO extends PageParam { + @Schema(description = "客户ID") + private Long customerId; + @Schema(description = "账户状态") + private Integer accountStatus; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountRespVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountRespVO.java new file mode 100644 index 0000000..485285f --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountRespVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.energy.controller.admin.account.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 能源账户 Response VO") +@Data +public class EnergyAccountRespVO { + @Schema(description = "主键ID") + private Long id; + @Schema(description = "客户ID") + private Long customerId; + @Schema(description = "当前余额") + private BigDecimal balance; + @Schema(description = "初始余额") + private BigDecimal initBalance; + @Schema(description = "累计充值") + private BigDecimal accumulatedRecharge; + @Schema(description = "累计氢费") + private BigDecimal accumulatedHydrogen; + @Schema(description = "累计电费") + private BigDecimal accumulatedElectric; + @Schema(description = "累计消费") + private BigDecimal accumulatedConsume; + @Schema(description = "提醒阈值") + private BigDecimal reminderThreshold; + @Schema(description = "账户状态") + private Integer accountStatus; + @Schema(description = "最后充值日期") + private LocalDate lastRechargeDate; + @Schema(description = "创建时间") + private LocalDateTime createTime; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountSaveReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountSaveReqVO.java new file mode 100644 index 0000000..1dc93b2 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyAccountSaveReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.energy.controller.admin.account.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 能源账户创建 Request VO") +@Data +public class EnergyAccountSaveReqVO { + @Schema(description = "客户ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "客户不能为空") + private Long customerId; + @Schema(description = "初始余额") + private BigDecimal initBalance; + @Schema(description = "提醒阈值") + private BigDecimal reminderThreshold; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyProjectAccountRespVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyProjectAccountRespVO.java new file mode 100644 index 0000000..7a6b994 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/account/vo/EnergyProjectAccountRespVO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.energy.controller.admin.account.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 项目账户 Response VO") +@Data +public class EnergyProjectAccountRespVO { + @Schema(description = "主键ID") + private Long id; + @Schema(description = "关联总账户ID") + private Long accountId; + @Schema(description = "合同ID") + private Long contractId; + @Schema(description = "项目名称") + private String projectName; + @Schema(description = "项目余额") + private BigDecimal projectBalance; + @Schema(description = "累计划账金额") + private BigDecimal projectRemitAmount; + @Schema(description = "累计氢费") + private BigDecimal projectHydrogenAmount; + @Schema(description = "累计电费") + private BigDecimal projectElectricAmount; + @Schema(description = "累计消费") + private BigDecimal projectConsumeAmount; + @Schema(description = "提醒阈值") + private BigDecimal reminderThreshold; + @Schema(description = "账户状态") + private Integer accountStatus; + @Schema(description = "创建时间") + private LocalDateTime createTime; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/EnergyBillController.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/EnergyBillController.java new file mode 100644 index 0000000..279224e --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/EnergyBillController.java @@ -0,0 +1,104 @@ +package cn.iocoder.yudao.module.energy.controller.admin.bill; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.bill.vo.*; +import cn.iocoder.yudao.module.energy.convert.bill.EnergyBillConvert; +import cn.iocoder.yudao.module.energy.dal.dataobject.bill.EnergyBillDO; +import cn.iocoder.yudao.module.energy.service.bill.EnergyBillService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 能源账单管理") +@RestController +@RequestMapping("/energy/bill") +@Validated +public class EnergyBillController { + + @Resource + private EnergyBillService billService; + + @GetMapping("/page") + @Operation(summary = "获得账单分页") + @PreAuthorize("@ss.hasPermission('energy:bill:query')") + public CommonResult> getBillPage(@Valid EnergyBillPageReqVO pageReqVO) { + PageResult pageResult = billService.getBillPage(pageReqVO); + return success(EnergyBillConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/get") + @Operation(summary = "获得账单详情") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('energy:bill:query')") + public CommonResult getBill(@RequestParam("id") Long id) { + EnergyBillDO bill = billService.getBill(id); + return success(EnergyBillConvert.INSTANCE.convert(bill)); + } + + @PostMapping("/generate") + @Operation(summary = "生成账单") + @PreAuthorize("@ss.hasPermission('energy:bill:create')") + public CommonResult generateBill(@Valid @RequestBody EnergyBillGenerateReqVO reqVO) { + return success(billService.generateBill(reqVO)); + } + + @PostMapping("/batch-generate") + @Operation(summary = "批量生成账单") + @PreAuthorize("@ss.hasPermission('energy:bill:create')") + public CommonResult> batchGenerateBills(@Valid @RequestBody List reqVOs) { + return success(billService.batchGenerateBills(reqVOs)); + } + + @PutMapping("/update") + @Operation(summary = "更新账单") + @PreAuthorize("@ss.hasPermission('energy:bill:update')") + public CommonResult updateBill(@Valid @RequestBody EnergyBillSaveReqVO reqVO) { + billService.updateBill(reqVO); + return success(true); + } + + @PostMapping("/audit") + @Operation(summary = "审核账单") + @PreAuthorize("@ss.hasPermission('energy:bill:audit')") + public CommonResult auditBill(@RequestParam("id") Long id, + @RequestParam("approved") Boolean approved, + @RequestParam(value = "remark", required = false) String remark) { + billService.auditBill(id, approved, remark); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除账单") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('energy:bill:delete')") + public CommonResult deleteBill(@RequestParam("id") Long id) { + billService.deleteBill(id); + return success(true); + } + + @PostMapping("/adjustment/create") + @Operation(summary = "创建调整行") + @PreAuthorize("@ss.hasPermission('energy:bill:update')") + public CommonResult createAdjustment(@Valid @RequestBody EnergyBillAdjustmentSaveReqVO reqVO) { + return success(billService.createAdjustment(reqVO)); + } + + @DeleteMapping("/adjustment/delete") + @Operation(summary = "删除调整行") + @Parameter(name = "id", description = "调整行ID", required = true) + @PreAuthorize("@ss.hasPermission('energy:bill:update')") + public CommonResult deleteAdjustment(@RequestParam("id") Long id) { + billService.deleteAdjustment(id); + return success(true); + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillAdjustmentSaveReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillAdjustmentSaveReqVO.java new file mode 100644 index 0000000..fbe7e45 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillAdjustmentSaveReqVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.energy.controller.admin.bill.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 账单调整行创建 Request VO") +@Data +public class EnergyBillAdjustmentSaveReqVO { + @Schema(description = "账单ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "账单不能为空") + private Long billId; + @Schema(description = "关联明细ID") + private Long detailId; + @Schema(description = "调整类型", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "调整类型不能为空") + private Integer adjustmentType; + @Schema(description = "调整金额", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "调整金额不能为空") + private BigDecimal amount; + @Schema(description = "调整原因") + private String reason; + @Schema(description = "附件URL") + private String attachmentUrls; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillGenerateReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillGenerateReqVO.java new file mode 100644 index 0000000..f4d2ec4 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillGenerateReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.energy.controller.admin.bill.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import java.time.LocalDate; + +@Schema(description = "管理后台 - 能源账单生成 Request VO") +@Data +public class EnergyBillGenerateReqVO { + @Schema(description = "能源类型", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "能源类型不能为空") + private Integer energyType; + @Schema(description = "客户ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "客户不能为空") + private Long customerId; + @Schema(description = "合同ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "合同不能为空") + private Long contractId; + @Schema(description = "加氢站ID") + private Long stationId; + @Schema(description = "账单周期开始", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "账单周期开始不能为空") + private LocalDate billPeriodStart; + @Schema(description = "账单周期结束", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "账单周期结束不能为空") + private LocalDate billPeriodEnd; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillPageReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillPageReqVO.java new file mode 100644 index 0000000..b9581ae --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillPageReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.energy.controller.admin.bill.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDate; + +@Schema(description = "管理后台 - 能源账单分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class EnergyBillPageReqVO extends PageParam { + @Schema(description = "能源类型") + private Integer energyType; + @Schema(description = "客户ID") + private Long customerId; + @Schema(description = "加氢站ID") + private Long stationId; + @Schema(description = "账单状态") + private Integer status; + @Schema(description = "审核状态") + private Integer auditStatus; + @Schema(description = "账单周期") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate[] billPeriod; + @Schema(description = "合作模式") + private Integer cooperationType; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillRespVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillRespVO.java new file mode 100644 index 0000000..733ce77 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillRespVO.java @@ -0,0 +1,64 @@ +package cn.iocoder.yudao.module.energy.controller.admin.bill.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 能源账单 Response VO") +@Data +public class EnergyBillRespVO { + @Schema(description = "主键ID") + private Long id; + @Schema(description = "账单编号") + private String billCode; + @Schema(description = "能源类型") + private Integer energyType; + @Schema(description = "客户ID") + private Long customerId; + @Schema(description = "客户名称") + private String customerName; + @Schema(description = "合同ID") + private Long contractId; + @Schema(description = "加氢站ID") + private Long stationId; + @Schema(description = "站点名称") + private String stationName; + @Schema(description = "合作模式(1=预充值 2=月结算)") + private Integer cooperationType; + @Schema(description = "账单周期开始") + private LocalDate billPeriodStart; + @Schema(description = "账单周期结束") + private LocalDate billPeriodEnd; + @Schema(description = "应收总额") + private BigDecimal receivableAmount; + @Schema(description = "实收总额") + private BigDecimal actualAmount; + @Schema(description = "调整总额") + private BigDecimal adjustmentAmount; + @Schema(description = "已收金额") + private BigDecimal paidAmount; + @Schema(description = "总加氢量") + private BigDecimal totalQuantity; + @Schema(description = "明细条数") + private Integer detailCount; + @Schema(description = "账单状态") + private Integer status; + @Schema(description = "审核状态") + private Integer auditStatus; + @Schema(description = "提交状态") + private Integer submitStatus; + @Schema(description = "支付状态") + private Integer paymentStatus; + @Schema(description = "审核人ID") + private Long auditorId; + @Schema(description = "审核时间") + private LocalDateTime auditTime; + @Schema(description = "审核备注") + private String auditRemark; + @Schema(description = "生成时间") + private LocalDateTime generateTime; + @Schema(description = "创建时间") + private LocalDateTime createTime; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillSaveReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillSaveReqVO.java new file mode 100644 index 0000000..42c3084 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/bill/vo/EnergyBillSaveReqVO.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.energy.controller.admin.bill.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - 能源账单更新 Request VO") +@Data +public class EnergyBillSaveReqVO { + @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "账单ID不能为空") + private Long id; + @Schema(description = "审核备注") + private String auditRemark; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/EnergyStationConfigController.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/EnergyStationConfigController.java new file mode 100644 index 0000000..97ec796 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/EnergyStationConfigController.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.module.energy.controller.admin.config; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.config.vo.EnergyStationConfigPageReqVO; +import cn.iocoder.yudao.module.energy.controller.admin.config.vo.EnergyStationConfigRespVO; +import cn.iocoder.yudao.module.energy.controller.admin.config.vo.EnergyStationConfigSaveReqVO; +import cn.iocoder.yudao.module.energy.convert.config.EnergyStationConfigConvert; +import cn.iocoder.yudao.module.energy.dal.dataobject.config.EnergyStationConfigDO; +import cn.iocoder.yudao.module.energy.service.config.EnergyStationConfigService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 加氢站配置") +@RestController +@RequestMapping("/energy/station-config") +@Validated +public class EnergyStationConfigController { + + @Resource + private EnergyStationConfigService stationConfigService; + + @PostMapping("/create") + @Operation(summary = "创建站点配置") + @PreAuthorize("@ss.hasPermission('energy:station-config:create')") + public CommonResult createConfig(@Valid @RequestBody EnergyStationConfigSaveReqVO createReqVO) { + return success(stationConfigService.createConfig(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新站点配置") + @PreAuthorize("@ss.hasPermission('energy:station-config:update')") + public CommonResult updateConfig(@Valid @RequestBody EnergyStationConfigSaveReqVO updateReqVO) { + stationConfigService.updateConfig(updateReqVO); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得站点配置") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('energy:station-config:query')") + public CommonResult getConfig(@RequestParam("id") Long id) { + EnergyStationConfigDO config = stationConfigService.getConfig(id); + return success(EnergyStationConfigConvert.INSTANCE.convert(config)); + } + + @GetMapping("/page") + @Operation(summary = "获得站点配置分页") + @PreAuthorize("@ss.hasPermission('energy:station-config:query')") + public CommonResult> getConfigPage(@Valid EnergyStationConfigPageReqVO pageReqVO) { + PageResult pageResult = stationConfigService.getConfigPage(pageReqVO); + return success(EnergyStationConfigConvert.INSTANCE.convertPage(pageResult)); + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/vo/EnergyStationConfigPageReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/vo/EnergyStationConfigPageReqVO.java new file mode 100644 index 0000000..faa556c --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/vo/EnergyStationConfigPageReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.energy.controller.admin.config.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 加氢站配置分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class EnergyStationConfigPageReqVO extends PageParam { + @Schema(description = "加氢站ID") + private Long stationId; + @Schema(description = "是否自动扣款") + private Boolean autoDeduct; + @Schema(description = "合作类型") + private Integer cooperationType; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/vo/EnergyStationConfigRespVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/vo/EnergyStationConfigRespVO.java new file mode 100644 index 0000000..51fc640 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/vo/EnergyStationConfigRespVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.energy.controller.admin.config.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 加氢站配置 Response VO") +@Data +public class EnergyStationConfigRespVO { + @Schema(description = "主键ID") + private Long id; + @Schema(description = "加氢站ID") + private Long stationId; + @Schema(description = "是否自动扣款") + private Boolean autoDeduct; + @Schema(description = "合作类型") + private Integer cooperationType; + @Schema(description = "站点名称") + private String stationName; + @Schema(description = "自动匹配开关") + private Boolean autoMatch; + @Schema(description = "备注") + private String remark; + @Schema(description = "创建时间") + private LocalDateTime createTime; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/vo/EnergyStationConfigSaveReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/vo/EnergyStationConfigSaveReqVO.java new file mode 100644 index 0000000..aaa4d13 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/config/vo/EnergyStationConfigSaveReqVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.energy.controller.admin.config.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - 加氢站配置创建/更新 Request VO") +@Data +public class EnergyStationConfigSaveReqVO { + @Schema(description = "主键ID") + private Long id; + @Schema(description = "加氢站ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "加氢站不能为空") + private Long stationId; + @Schema(description = "是否自动扣款", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "是否自动扣款不能为空") + private Boolean autoDeduct; + @Schema(description = "合作类型") + private Integer cooperationType; + @Schema(description = "自动匹配开关") + private Boolean autoMatch; + @Schema(description = "备注") + private String remark; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/HydrogenDetailController.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/HydrogenDetailController.java new file mode 100644 index 0000000..8d1ef66 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/HydrogenDetailController.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.energy.controller.admin.detail; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.detail.vo.*; +import cn.iocoder.yudao.module.energy.convert.detail.HydrogenDetailConvert; +import cn.iocoder.yudao.module.energy.dal.dataobject.detail.EnergyHydrogenDetailDO; +import cn.iocoder.yudao.module.energy.service.detail.HydrogenDetailService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 加氢明细管理") +@RestController +@RequestMapping("/energy/hydrogen-detail") +@Validated +public class HydrogenDetailController { + + @Resource + private HydrogenDetailService hydrogenDetailService; + + @GetMapping("/page") + @Operation(summary = "获得明细分页") + @PreAuthorize("@ss.hasPermission('energy:hydrogen-detail:query')") + public CommonResult> getDetailPage(@Valid HydrogenDetailPageReqVO pageReqVO) { + PageResult pageResult = hydrogenDetailService.getDetailPage(pageReqVO); + return success(HydrogenDetailConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/get") + @Operation(summary = "获得明细详情") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('energy:hydrogen-detail:query')") + public CommonResult getDetail(@RequestParam("id") Long id) { + EnergyHydrogenDetailDO detail = hydrogenDetailService.getDetail(id); + return success(HydrogenDetailConvert.INSTANCE.convert(detail)); + } + + @PutMapping("/update") + @Operation(summary = "更新明细") + @PreAuthorize("@ss.hasPermission('energy:hydrogen-detail:update')") + public CommonResult updateDetail(@Valid @RequestBody HydrogenDetailSaveReqVO reqVO) { + hydrogenDetailService.updateDetail(reqVO); + return success(true); + } + + @PostMapping("/audit") + @Operation(summary = "审核明细") + @PreAuthorize("@ss.hasPermission('energy:hydrogen-detail:audit')") + public CommonResult auditDetail(@RequestParam("id") Long id, + @RequestParam("approved") Boolean approved, + @RequestParam(value = "remark", required = false) String remark) { + hydrogenDetailService.audit(id, approved, remark); + return success(true); + } + + @PostMapping("/batch-audit") + @Operation(summary = "批量审核明细") + @PreAuthorize("@ss.hasPermission('energy:hydrogen-detail:audit')") + public CommonResult batchAuditDetail(@RequestParam("ids") List ids, + @RequestParam("approved") Boolean approved, + @RequestParam(value = "remark", required = false) String remark) { + hydrogenDetailService.batchAudit(ids, approved, remark); + return success(true); + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/vo/HydrogenDetailPageReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/vo/HydrogenDetailPageReqVO.java new file mode 100644 index 0000000..5278d30 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/vo/HydrogenDetailPageReqVO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.energy.controller.admin.detail.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDate; + +@Schema(description = "管理后台 - 加氢明细分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class HydrogenDetailPageReqVO extends PageParam { + @Schema(description = "加氢站ID") + private Long stationId; + @Schema(description = "客户ID") + private Long customerId; + @Schema(description = "车牌号") + private String plateNumber; + @Schema(description = "审核状态") + private Integer auditStatus; + @Schema(description = "扣款状态") + private Integer deductionStatus; + @Schema(description = "结算状态") + private Integer settlementStatus; + @Schema(description = "账单ID") + private Long billId; + @Schema(description = "加氢日期范围") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate[] hydrogenDate; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/vo/HydrogenDetailRespVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/vo/HydrogenDetailRespVO.java new file mode 100644 index 0000000..6bdd321 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/vo/HydrogenDetailRespVO.java @@ -0,0 +1,58 @@ +package cn.iocoder.yudao.module.energy.controller.admin.detail.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 加氢明细 Response VO") +@Data +public class HydrogenDetailRespVO { + @Schema(description = "主键ID") + private Long id; + @Schema(description = "关联原始记录ID") + private Long recordId; + @Schema(description = "加氢站ID") + private Long stationId; + @Schema(description = "车辆ID") + private Long vehicleId; + @Schema(description = "车牌号") + private String plateNumber; + @Schema(description = "加氢日期") + private LocalDate hydrogenDate; + @Schema(description = "加氢量(KG)") + private BigDecimal hydrogenQuantity; + @Schema(description = "成本单价") + private BigDecimal costPrice; + @Schema(description = "成本金额") + private BigDecimal costAmount; + @Schema(description = "对客单价") + private BigDecimal customerPrice; + @Schema(description = "对客金额") + private BigDecimal customerAmount; + @Schema(description = "合同ID") + private Long contractId; + @Schema(description = "客户ID") + private Long customerId; + @Schema(description = "项目名称") + private String projectName; + @Schema(description = "费用承担方") + private Integer costBearer; + @Schema(description = "支付方式") + private Integer payMethod; + @Schema(description = "审核状态") + private Integer auditStatus; + @Schema(description = "审核备注") + private String auditRemark; + @Schema(description = "扣款状态") + private Integer deductionStatus; + @Schema(description = "结算状态") + private Integer settlementStatus; + @Schema(description = "账单ID") + private Long billId; + @Schema(description = "备注") + private String remark; + @Schema(description = "创建时间") + private LocalDateTime createTime; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/vo/HydrogenDetailSaveReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/vo/HydrogenDetailSaveReqVO.java new file mode 100644 index 0000000..0e47c44 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/detail/vo/HydrogenDetailSaveReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.energy.controller.admin.detail.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 加氢明细编辑 Request VO") +@Data +public class HydrogenDetailSaveReqVO { + @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "明细ID不能为空") + private Long id; + @Schema(description = "成本单价") + private BigDecimal costPrice; + @Schema(description = "对客单价") + private BigDecimal customerPrice; + @Schema(description = "备注") + private String remark; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/EnergyStationPriceController.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/EnergyStationPriceController.java new file mode 100644 index 0000000..fe0ce60 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/EnergyStationPriceController.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.module.energy.controller.admin.price; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.price.vo.*; +import cn.iocoder.yudao.module.energy.convert.price.EnergyStationPriceConvert; +import cn.iocoder.yudao.module.energy.dal.dataobject.price.EnergyStationPriceDO; +import cn.iocoder.yudao.module.energy.service.price.EnergyStationPriceService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDate; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 加氢站价格管理") +@RestController +@RequestMapping("/energy/station-price") +@Validated +public class EnergyStationPriceController { + + @Resource + private EnergyStationPriceService stationPriceService; + + @PostMapping("/create") + @Operation(summary = "创建价格") + @PreAuthorize("@ss.hasPermission('energy:station-price:create')") + public CommonResult createPrice(@Valid @RequestBody EnergyStationPriceSaveReqVO createReqVO) { + return success(stationPriceService.createPrice(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新价格") + @PreAuthorize("@ss.hasPermission('energy:station-price:update')") + public CommonResult updatePrice(@Valid @RequestBody EnergyStationPriceSaveReqVO updateReqVO) { + stationPriceService.updatePrice(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除价格") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('energy:station-price:delete')") + public CommonResult deletePrice(@RequestParam("id") Long id) { + stationPriceService.deletePrice(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得价格") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('energy:station-price:query')") + public CommonResult getPrice(@RequestParam("id") Long id) { + EnergyStationPriceDO price = stationPriceService.getPrice(id); + return success(EnergyStationPriceConvert.INSTANCE.convert(price)); + } + + @GetMapping("/page") + @Operation(summary = "获得价格分页") + @PreAuthorize("@ss.hasPermission('energy:station-price:query')") + public CommonResult> getPricePage(@Valid EnergyStationPricePageReqVO pageReqVO) { + PageResult pageResult = stationPriceService.getPricePage(pageReqVO); + return success(EnergyStationPriceConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/get-effective") + @Operation(summary = "获取生效价格") + @PreAuthorize("@ss.hasPermission('energy:station-price:query')") + public CommonResult getEffectivePrice( + @RequestParam("stationId") Long stationId, + @RequestParam("customerId") Long customerId, + @RequestParam("date") LocalDate date) { + EnergyStationPriceDO price = stationPriceService.getEffectivePrice(stationId, customerId, date); + return success(EnergyStationPriceConvert.INSTANCE.convert(price)); + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/vo/EnergyStationPricePageReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/vo/EnergyStationPricePageReqVO.java new file mode 100644 index 0000000..37fda96 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/vo/EnergyStationPricePageReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.energy.controller.admin.price.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 加氢站价格分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class EnergyStationPricePageReqVO extends PageParam { + @Schema(description = "加氢站ID") + private Long stationId; + @Schema(description = "客户ID") + private Long customerId; + @Schema(description = "状态") + private Integer status; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/vo/EnergyStationPriceRespVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/vo/EnergyStationPriceRespVO.java new file mode 100644 index 0000000..3d18070 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/vo/EnergyStationPriceRespVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.energy.controller.admin.price.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 加氢站价格 Response VO") +@Data +public class EnergyStationPriceRespVO { + @Schema(description = "主键ID") + private Long id; + @Schema(description = "加氢站ID") + private Long stationId; + @Schema(description = "客户ID") + private Long customerId; + @Schema(description = "成本价") + private BigDecimal costPrice; + @Schema(description = "对客价") + private BigDecimal customerPrice; + @Schema(description = "生效日期") + private LocalDate effectiveDate; + @Schema(description = "失效日期") + private LocalDate expiryDate; + @Schema(description = "状态") + private Integer status; + @Schema(description = "创建时间") + private LocalDateTime createTime; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/vo/EnergyStationPriceSaveReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/vo/EnergyStationPriceSaveReqVO.java new file mode 100644 index 0000000..e782f1a --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/price/vo/EnergyStationPriceSaveReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.energy.controller.admin.price.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDate; + +@Schema(description = "管理后台 - 加氢站价格创建/更新 Request VO") +@Data +public class EnergyStationPriceSaveReqVO { + @Schema(description = "主键ID") + private Long id; + @Schema(description = "加氢站ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "加氢站不能为空") + private Long stationId; + @Schema(description = "客户ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "客户不能为空") + private Long customerId; + @Schema(description = "成本价", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "成本价不能为空") + private BigDecimal costPrice; + @Schema(description = "对客价", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "对客价不能为空") + private BigDecimal customerPrice; + @Schema(description = "生效日期", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "生效日期不能为空") + private LocalDate effectiveDate; + @Schema(description = "失效日期") + private LocalDate expiryDate; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/HydrogenRecordController.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/HydrogenRecordController.java new file mode 100644 index 0000000..821b870 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/HydrogenRecordController.java @@ -0,0 +1,105 @@ +package cn.iocoder.yudao.module.energy.controller.admin.record; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.energy.controller.admin.record.vo.*; +import cn.iocoder.yudao.module.energy.convert.record.HydrogenRecordConvert; +import cn.iocoder.yudao.module.energy.dal.dataobject.record.EnergyHydrogenRecordDO; +import cn.iocoder.yudao.module.energy.service.record.HydrogenRecordService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 加氢记录管理") +@RestController +@RequestMapping("/energy/hydrogen-record") +@Validated +public class HydrogenRecordController { + + @Resource + private HydrogenRecordService hydrogenRecordService; + + @PostMapping("/create") + @Operation(summary = "创建加氢记录") + @PreAuthorize("@ss.hasPermission('energy:hydrogen-record:create')") + public CommonResult createRecord(@Valid @RequestBody HydrogenRecordSaveReqVO createReqVO) { + return success(hydrogenRecordService.createRecord(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新加氢记录") + @PreAuthorize("@ss.hasPermission('energy:hydrogen-record:update')") + public CommonResult updateRecord(@Valid @RequestBody HydrogenRecordSaveReqVO updateReqVO) { + hydrogenRecordService.updateRecord(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除加氢记录") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('energy:hydrogen-record:delete')") + public CommonResult deleteRecord(@RequestParam("id") Long id) { + hydrogenRecordService.deleteRecord(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得加氢记录") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('energy:hydrogen-record:query')") + public CommonResult getRecord(@RequestParam("id") Long id) { + EnergyHydrogenRecordDO record = hydrogenRecordService.getRecord(id); + return success(HydrogenRecordConvert.INSTANCE.convert(record)); + } + + @GetMapping("/page") + @Operation(summary = "获得加氢记录分页") + @PreAuthorize("@ss.hasPermission('energy:hydrogen-record:query')") + public CommonResult> getRecordPage(@Valid HydrogenRecordPageReqVO pageReqVO) { + PageResult pageResult = hydrogenRecordService.getRecordPage(pageReqVO); + return success(HydrogenRecordConvert.INSTANCE.convertPage(pageResult)); + } + + @Deprecated // 被 import-preview + import-confirm + import-progress 三步流程替代 + @PostMapping("/import") + @Operation(summary = "Excel 批量导入") + @PreAuthorize("@ss.hasPermission('energy:hydrogen-record:import')") + public CommonResult> importExcel( + @RequestParam("stationId") Long stationId, + @RequestParam("file") MultipartFile file) throws Exception { + List list = ExcelUtils.read(file, HydrogenRecordImportVO.class); + String batchNo = generateBatchNo(); + Map result = hydrogenRecordService.importRecords(stationId, list, batchNo); + return success(result); + } + + @PutMapping("/match") + @Operation(summary = "手动匹配车辆") + @PreAuthorize("@ss.hasPermission('energy:hydrogen-record:update')") + public CommonResult matchRecord(@RequestParam("id") Long id, + @RequestParam("vehicleId") Long vehicleId, + @RequestParam("customerId") Long customerId) { + hydrogenRecordService.matchRecord(id, vehicleId, customerId); + return success(true); + } + + private String generateBatchNo() { + return "IMP" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + + UUID.randomUUID().toString().substring(0, 4).toUpperCase(); + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordExcelVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordExcelVO.java new file mode 100644 index 0000000..7195d38 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordExcelVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.energy.controller.admin.record.vo; + +import cn.idev.excel.annotation.ExcelProperty; +import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Data +public class HydrogenRecordExcelVO { + @ExcelProperty("车牌号") + private String plateNumber; + @ExcelProperty("加氢日期") + private LocalDate hydrogenDate; + @ExcelProperty("加氢量(KG)") + private BigDecimal hydrogenQuantity; + @ExcelProperty("单价") + private BigDecimal unitPrice; + @ExcelProperty("金额") + private BigDecimal amount; + @ExcelProperty("里程数") + private BigDecimal mileage; + @ExcelProperty("数据来源") + private String sourceTypeName; + @ExcelProperty("匹配状态") + private String matchStatusName; + @ExcelProperty("创建时间") + private LocalDateTime createTime; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordImportVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordImportVO.java new file mode 100644 index 0000000..aa80acd --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordImportVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.controller.admin.record.vo; + +import cn.idev.excel.annotation.ExcelProperty; +import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDate; + +@Data +public class HydrogenRecordImportVO { + @ExcelProperty("车牌号") + private String plateNumber; + @ExcelProperty("加氢日期") + private LocalDate hydrogenDate; + @ExcelProperty("加氢量(KG)") + private BigDecimal hydrogenQuantity; + @ExcelProperty("单价") + private BigDecimal unitPrice; + @ExcelProperty("金额") + private BigDecimal amount; + @ExcelProperty("里程数") + private BigDecimal mileage; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordPageReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordPageReqVO.java new file mode 100644 index 0000000..d0caedd --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordPageReqVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.energy.controller.admin.record.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDate; + +@Schema(description = "管理后台 - 加氢记录分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class HydrogenRecordPageReqVO extends PageParam { + @Schema(description = "加氢站ID") + private Long stationId; + @Schema(description = "车牌号") + private String plateNumber; + @Schema(description = "匹配状态") + private Integer matchStatus; + @Schema(description = "数据来源") + private Integer sourceType; + @Schema(description = "加氢日期范围") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private LocalDate[] hydrogenDate; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordRespVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordRespVO.java new file mode 100644 index 0000000..d2e95d7 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordRespVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.energy.controller.admin.record.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 加氢记录 Response VO") +@Data +public class HydrogenRecordRespVO { + @Schema(description = "主键ID") + private Long id; + @Schema(description = "加氢站ID") + private Long stationId; + @Schema(description = "车牌号") + private String plateNumber; + @Schema(description = "加氢日期") + private LocalDate hydrogenDate; + @Schema(description = "加氢量(KG)") + private BigDecimal hydrogenQuantity; + @Schema(description = "单价") + private BigDecimal unitPrice; + @Schema(description = "金额") + private BigDecimal amount; + @Schema(description = "里程数") + private BigDecimal mileage; + @Schema(description = "数据来源") + private Integer sourceType; + @Schema(description = "匹配状态") + private Integer matchStatus; + @Schema(description = "车辆ID") + private Long vehicleId; + @Schema(description = "客户ID") + private Long customerId; + @Schema(description = "导入批次号") + private String uploadBatchNo; + @Schema(description = "创建时间") + private LocalDateTime createTime; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordSaveReqVO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordSaveReqVO.java new file mode 100644 index 0000000..4a4de67 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/controller/admin/record/vo/HydrogenRecordSaveReqVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.energy.controller.admin.record.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDate; + +@Schema(description = "管理后台 - 加氢记录创建/更新 Request VO") +@Data +public class HydrogenRecordSaveReqVO { + @Schema(description = "主键ID") + private Long id; + @Schema(description = "加氢站ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "加氢站不能为空") + private Long stationId; + @Schema(description = "车牌号", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "车牌号不能为空") + private String plateNumber; + @Schema(description = "加氢日期", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "加氢日期不能为空") + private LocalDate hydrogenDate; + @Schema(description = "加氢量(KG)", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "加氢量不能为空") + private BigDecimal hydrogenQuantity; + @Schema(description = "单价", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "单价不能为空") + private BigDecimal unitPrice; + @Schema(description = "金额", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "金额不能为空") + private BigDecimal amount; + @Schema(description = "里程数") + private BigDecimal mileage; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/account/EnergyAccountConvert.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/account/EnergyAccountConvert.java new file mode 100644 index 0000000..1c8c39c --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/account/EnergyAccountConvert.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.energy.convert.account; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.account.vo.EnergyAccountRespVO; +import cn.iocoder.yudao.module.energy.controller.admin.account.vo.EnergyProjectAccountRespVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyAccountDO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyProjectAccountDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface EnergyAccountConvert { + EnergyAccountConvert INSTANCE = Mappers.getMapper(EnergyAccountConvert.class); + EnergyAccountRespVO convert(EnergyAccountDO bean); + PageResult convertPage(PageResult page); + EnergyProjectAccountRespVO convert(EnergyProjectAccountDO bean); + PageResult convertProjectPage(PageResult page); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/bill/EnergyBillConvert.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/bill/EnergyBillConvert.java new file mode 100644 index 0000000..5cc0f81 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/bill/EnergyBillConvert.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.energy.convert.bill; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.bill.vo.EnergyBillRespVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.bill.EnergyBillDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface EnergyBillConvert { + EnergyBillConvert INSTANCE = Mappers.getMapper(EnergyBillConvert.class); + EnergyBillRespVO convert(EnergyBillDO bean); + PageResult convertPage(PageResult page); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/config/EnergyStationConfigConvert.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/config/EnergyStationConfigConvert.java new file mode 100644 index 0000000..9730f38 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/config/EnergyStationConfigConvert.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.energy.convert.config; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.config.vo.EnergyStationConfigRespVO; +import cn.iocoder.yudao.module.energy.controller.admin.config.vo.EnergyStationConfigSaveReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.config.EnergyStationConfigDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface EnergyStationConfigConvert { + EnergyStationConfigConvert INSTANCE = Mappers.getMapper(EnergyStationConfigConvert.class); + EnergyStationConfigDO convert(EnergyStationConfigSaveReqVO bean); + EnergyStationConfigRespVO convert(EnergyStationConfigDO bean); + PageResult convertPage(PageResult page); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/detail/HydrogenDetailConvert.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/detail/HydrogenDetailConvert.java new file mode 100644 index 0000000..780337b --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/detail/HydrogenDetailConvert.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.energy.convert.detail; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.detail.vo.HydrogenDetailRespVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.detail.EnergyHydrogenDetailDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface HydrogenDetailConvert { + HydrogenDetailConvert INSTANCE = Mappers.getMapper(HydrogenDetailConvert.class); + HydrogenDetailRespVO convert(EnergyHydrogenDetailDO bean); + PageResult convertPage(PageResult page); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/price/EnergyStationPriceConvert.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/price/EnergyStationPriceConvert.java new file mode 100644 index 0000000..f1f39b0 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/price/EnergyStationPriceConvert.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.energy.convert.price; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.price.vo.EnergyStationPriceRespVO; +import cn.iocoder.yudao.module.energy.controller.admin.price.vo.EnergyStationPriceSaveReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.price.EnergyStationPriceDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface EnergyStationPriceConvert { + EnergyStationPriceConvert INSTANCE = Mappers.getMapper(EnergyStationPriceConvert.class); + EnergyStationPriceDO convert(EnergyStationPriceSaveReqVO bean); + EnergyStationPriceRespVO convert(EnergyStationPriceDO bean); + PageResult convertPage(PageResult page); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/record/HydrogenRecordConvert.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/record/HydrogenRecordConvert.java new file mode 100644 index 0000000..b237216 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/convert/record/HydrogenRecordConvert.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.energy.convert.record; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.record.vo.HydrogenRecordRespVO; +import cn.iocoder.yudao.module.energy.controller.admin.record.vo.HydrogenRecordSaveReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.record.EnergyHydrogenRecordDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface HydrogenRecordConvert { + HydrogenRecordConvert INSTANCE = Mappers.getMapper(HydrogenRecordConvert.class); + EnergyHydrogenRecordDO convert(HydrogenRecordSaveReqVO bean); + HydrogenRecordRespVO convert(EnergyHydrogenRecordDO bean); + PageResult convertPage(PageResult page); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/account/EnergyAccountDO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/account/EnergyAccountDO.java new file mode 100644 index 0000000..e078b4c --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/account/EnergyAccountDO.java @@ -0,0 +1,86 @@ +package cn.iocoder.yudao.module.energy.dal.dataobject.account; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; +import java.time.LocalDate; + +/** + * 能源账户 DO + */ +@TableName("energy_account") +@KeySequence("energy_account_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EnergyAccountDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + + /** + * 客户ID + */ + private Long customerId; + + /** + * 余额 + */ + private BigDecimal balance; + + /** + * 初始余额 + */ + private BigDecimal initBalance; + + /** + * 累计充值金额 + */ + private BigDecimal accumulatedRecharge; + + /** + * 累计加氢金额 + */ + private BigDecimal accumulatedHydrogen; + + /** + * 累计充电金额 + */ + private BigDecimal accumulatedElectric; + + /** + * 累计消费金额 + */ + private BigDecimal accumulatedConsume; + + /** + * 余额预警阈值 + */ + private BigDecimal reminderThreshold; + + /** + * 账户状态 + */ + private Integer accountStatus; + + /** + * 最后充值日期 + */ + private LocalDate lastRechargeDate; + + /** + * 乐观锁版本号(手动控制,不使用 @Version 注解) + */ + private Integer version; + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/account/EnergyAccountFlowDO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/account/EnergyAccountFlowDO.java new file mode 100644 index 0000000..8a32a31 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/account/EnergyAccountFlowDO.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.energy.dal.dataobject.account; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; + +/** + * 账户流水 DO + */ +@TableName("energy_account_flow") +@KeySequence("energy_account_flow_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EnergyAccountFlowDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + + /** + * 账户ID + */ + private Long accountId; + + /** + * 项目账户ID + */ + private Long projectAccountId; + + /** + * 流水类型 + */ + private Integer flowType; + + /** + * 金额 + */ + private BigDecimal amount; + + /** + * 变更前余额 + */ + private BigDecimal balanceBefore; + + /** + * 变更后余额 + */ + private BigDecimal balanceAfter; + + /** + * 变更前项目余额 + */ + private BigDecimal projectBalanceBefore; + + /** + * 变更后项目余额 + */ + private BigDecimal projectBalanceAfter; + + /** + * 业务类型 + */ + private Integer bizType; + + /** + * 业务ID + */ + private Long bizId; + + /** + * 业务编号 + */ + private String bizCode; + + /** + * 备注 + */ + private String remark; + + /** + * 操作人ID + */ + private Long operatorId; + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/account/EnergyProjectAccountDO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/account/EnergyProjectAccountDO.java new file mode 100644 index 0000000..5712c9c --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/account/EnergyProjectAccountDO.java @@ -0,0 +1,85 @@ +package cn.iocoder.yudao.module.energy.dal.dataobject.account; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; + +/** + * 能源项目账户 DO + */ +@TableName("energy_project_account") +@KeySequence("energy_project_account_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EnergyProjectAccountDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + + /** + * 账户ID + */ + private Long accountId; + + /** + * 合同ID + */ + private Long contractId; + + /** + * 项目名称 + */ + private String projectName; + + /** + * 项目余额 + */ + private BigDecimal projectBalance; + + /** + * 项目汇款总额 + */ + private BigDecimal projectRemitAmount; + + /** + * 项目加氢金额 + */ + private BigDecimal projectHydrogenAmount; + + /** + * 项目充电金额 + */ + private BigDecimal projectElectricAmount; + + /** + * 项目消费总额 + */ + private BigDecimal projectConsumeAmount; + + /** + * 余额预警阈值 + */ + private BigDecimal reminderThreshold; + + /** + * 账户状态 + */ + private Integer accountStatus; + + /** + * 乐观锁版本号(手动控制,不使用 @Version 注解) + */ + private Integer version; + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/bill/EnergyBillAdjustmentDO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/bill/EnergyBillAdjustmentDO.java new file mode 100644 index 0000000..165abaf --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/bill/EnergyBillAdjustmentDO.java @@ -0,0 +1,71 @@ +package cn.iocoder.yudao.module.energy.dal.dataobject.bill; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 账单调整记录 DO + */ +@TableName("energy_bill_adjustment") +@KeySequence("energy_bill_adjustment_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EnergyBillAdjustmentDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + + /** + * 账单ID + */ + private Long billId; + + /** + * 明细ID + */ + private Long detailId; + + /** + * 调整类型 + */ + private Integer adjustmentType; + + /** + * 调整金额 + */ + private BigDecimal amount; + + /** + * 调整原因 + */ + private String reason; + + /** + * 附件URLs + */ + private String attachmentUrls; + + /** + * 操作人ID + */ + private Long operatorId; + + /** + * 操作时间 + */ + private LocalDateTime operateTime; + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/bill/EnergyBillDO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/bill/EnergyBillDO.java new file mode 100644 index 0000000..5f46375 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/bill/EnergyBillDO.java @@ -0,0 +1,162 @@ +package cn.iocoder.yudao.module.energy.dal.dataobject.bill; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * 能源账单 DO + */ +@TableName("energy_bill") +@KeySequence("energy_bill_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EnergyBillDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + + /** + * 账单编号 + */ + private String billCode; + + /** + * 能源类型 + */ + private Integer energyType; + + /** + * 客户ID + */ + private Long customerId; + + /** + * 客户名称 + */ + private String customerName; + + /** + * 合同ID + */ + private Long contractId; + + /** + * 站点ID + */ + private Long stationId; + + /** + * 站点名称 + */ + private String stationName; + + /** + * 合作模式(1=预充值 2=月结算) + */ + private Integer cooperationType; + + /** + * 账单周期开始 + */ + private LocalDate billPeriodStart; + + /** + * 账单周期结束 + */ + private LocalDate billPeriodEnd; + + /** + * 应收金额 + */ + private BigDecimal receivableAmount; + + /** + * 实收金额 + */ + private BigDecimal actualAmount; + + /** + * 调整金额 + */ + private BigDecimal adjustmentAmount; + + /** + * 已付金额 + */ + private BigDecimal paidAmount; + + /** + * 总用量 + */ + private BigDecimal totalQuantity; + + /** + * 明细条数 + */ + private Integer detailCount; + + /** + * 账单状态 + */ + private Integer status; + + /** + * 审核状态 + */ + private Integer auditStatus; + + /** + * 提交状态 + */ + private Integer submitStatus; + + /** + * 付款状态 + */ + private Integer paymentStatus; + + /** + * 审核人ID + */ + private Long auditorId; + + /** + * 审核时间 + */ + private LocalDateTime auditTime; + + /** + * 审核备注 + */ + private String auditRemark; + + /** + * 提交时间 + */ + private LocalDateTime submitTime; + + /** + * 生成时间 + */ + private LocalDateTime generateTime; + + /** + * YOS账单编号 + */ + private String yosBillCode; + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/config/EnergyStationConfigDO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/config/EnergyStationConfigDO.java new file mode 100644 index 0000000..4a24f49 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/config/EnergyStationConfigDO.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.energy.dal.dataobject.config; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 站点配置 DO + */ +@TableName("energy_station_config") +@KeySequence("energy_station_config_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EnergyStationConfigDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + + /** + * 站点ID + */ + private Long stationId; + + /** + * 是否自动扣费 + */ + private Boolean autoDeduct; + + /** + * 合作类型 + */ + private Integer cooperationType; + + /** + * 自动匹配开关 + */ + private Boolean autoMatch; + + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/detail/EnergyHydrogenDetailDO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/detail/EnergyHydrogenDetailDO.java new file mode 100644 index 0000000..d4ba370 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/detail/EnergyHydrogenDetailDO.java @@ -0,0 +1,136 @@ +package cn.iocoder.yudao.module.energy.dal.dataobject.detail; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; +import java.time.LocalDate; + +/** + * 加氢明细 DO + */ +@TableName("energy_hydrogen_detail") +@KeySequence("energy_hydrogen_detail_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EnergyHydrogenDetailDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + + /** + * 加氢记录ID + */ + private Long recordId; + + /** + * 加氢站ID + */ + private Long stationId; + + /** + * 车辆ID + */ + private Long vehicleId; + + /** + * 车牌号 + */ + private String plateNumber; + + /** + * 加氢日期 + */ + private LocalDate hydrogenDate; + + /** + * 加氢量(kg) + */ + private BigDecimal hydrogenQuantity; + + /** + * 成本价 + */ + private BigDecimal costPrice; + + /** + * 成本金额 + */ + private BigDecimal costAmount; + + /** + * 客户价 + */ + private BigDecimal customerPrice; + + /** + * 客户金额 + */ + private BigDecimal customerAmount; + + /** + * 合同ID + */ + private Long contractId; + + /** + * 客户ID + */ + private Long customerId; + + /** + * 项目名称 + */ + private String projectName; + + /** + * 费用承担方 + */ + private Integer costBearer; + + /** + * 支付方式 + */ + private Integer payMethod; + + /** + * 审核状态 + */ + private Integer auditStatus; + + /** + * 审核备注 + */ + private String auditRemark; + + /** + * 扣费状态 + */ + private Integer deductionStatus; + + /** + * 结算状态 + */ + private Integer settlementStatus; + + /** + * 账单ID + */ + private Long billId; + + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/price/EnergyStationPriceDO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/price/EnergyStationPriceDO.java new file mode 100644 index 0000000..e7262a7 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/price/EnergyStationPriceDO.java @@ -0,0 +1,66 @@ +package cn.iocoder.yudao.module.energy.dal.dataobject.price; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; +import java.time.LocalDate; + +/** + * 站点价格 DO + */ +@TableName("energy_station_price") +@KeySequence("energy_station_price_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EnergyStationPriceDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + + /** + * 站点ID + */ + private Long stationId; + + /** + * 客户ID + */ + private Long customerId; + + /** + * 成本价 + */ + private BigDecimal costPrice; + + /** + * 客户价 + */ + private BigDecimal customerPrice; + + /** + * 生效日期 + */ + private LocalDate effectiveDate; + + /** + * 失效日期 + */ + private LocalDate expiryDate; + + /** + * 状态 + */ + private Integer status; + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/record/EnergyHydrogenRecordDO.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/record/EnergyHydrogenRecordDO.java new file mode 100644 index 0000000..51d09ea --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/dataobject/record/EnergyHydrogenRecordDO.java @@ -0,0 +1,91 @@ +package cn.iocoder.yudao.module.energy.dal.dataobject.record; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; +import java.time.LocalDate; + +/** + * 加氢记录 DO + */ +@TableName("energy_hydrogen_record") +@KeySequence("energy_hydrogen_record_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class EnergyHydrogenRecordDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + + /** + * 加氢站ID + */ + private Long stationId; + + /** + * 车牌号 + */ + private String plateNumber; + + /** + * 加氢日期 + */ + private LocalDate hydrogenDate; + + /** + * 加氢量(kg) + */ + private BigDecimal hydrogenQuantity; + + /** + * 单价 + */ + private BigDecimal unitPrice; + + /** + * 金额 + */ + private BigDecimal amount; + + /** + * 里程(km) + */ + private BigDecimal mileage; + + /** + * 来源类型 + */ + private Integer sourceType; + + /** + * 匹配状态 + */ + private Integer matchStatus; + + /** + * 车辆ID + */ + private Long vehicleId; + + /** + * 客户ID + */ + private Long customerId; + + /** + * 上传批次号 + */ + private String uploadBatchNo; + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/account/EnergyAccountFlowMapper.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/account/EnergyAccountFlowMapper.java new file mode 100644 index 0000000..cc97f61 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/account/EnergyAccountFlowMapper.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.energy.dal.mysql.account; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.energy.controller.admin.account.vo.EnergyAccountFlowPageReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyAccountFlowDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface EnergyAccountFlowMapper extends BaseMapperX { + + default PageResult selectPage(EnergyAccountFlowPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(EnergyAccountFlowDO::getAccountId, reqVO.getAccountId()) + .eqIfPresent(EnergyAccountFlowDO::getProjectAccountId, reqVO.getProjectAccountId()) + .eqIfPresent(EnergyAccountFlowDO::getFlowType, reqVO.getFlowType()) + .eqIfPresent(EnergyAccountFlowDO::getBizType, reqVO.getBizType()) + .betweenIfPresent(EnergyAccountFlowDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(EnergyAccountFlowDO::getId)); + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/account/EnergyAccountMapper.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/account/EnergyAccountMapper.java new file mode 100644 index 0000000..5b4dc01 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/account/EnergyAccountMapper.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.energy.dal.mysql.account; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.energy.controller.admin.account.vo.EnergyAccountPageReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyAccountDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface EnergyAccountMapper extends BaseMapperX { + + default EnergyAccountDO selectByCustomerId(Long customerId) { + return selectOne(EnergyAccountDO::getCustomerId, customerId); + } + + default PageResult selectPage(EnergyAccountPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(EnergyAccountDO::getCustomerId, reqVO.getCustomerId()) + .eqIfPresent(EnergyAccountDO::getAccountStatus, reqVO.getAccountStatus()) + .orderByDesc(EnergyAccountDO::getId)); + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/account/EnergyProjectAccountMapper.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/account/EnergyProjectAccountMapper.java new file mode 100644 index 0000000..3ab7604 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/account/EnergyProjectAccountMapper.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.dal.mysql.account; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyProjectAccountDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface EnergyProjectAccountMapper extends BaseMapperX { + + default EnergyProjectAccountDO selectByContractId(Long contractId) { + return selectOne(EnergyProjectAccountDO::getContractId, contractId); + } + + default List selectListByAccountId(Long accountId) { + return selectList(new LambdaQueryWrapperX() + .eq(EnergyProjectAccountDO::getAccountId, accountId)); + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/bill/EnergyBillAdjustmentMapper.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/bill/EnergyBillAdjustmentMapper.java new file mode 100644 index 0000000..b7c3fec --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/bill/EnergyBillAdjustmentMapper.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.energy.dal.mysql.bill; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.energy.dal.dataobject.bill.EnergyBillAdjustmentDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface EnergyBillAdjustmentMapper extends BaseMapperX { + + default List selectListByBillId(Long billId) { + return selectList(new LambdaQueryWrapperX() + .eq(EnergyBillAdjustmentDO::getBillId, billId)); + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/bill/EnergyBillMapper.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/bill/EnergyBillMapper.java new file mode 100644 index 0000000..acafd0c --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/bill/EnergyBillMapper.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.energy.dal.mysql.bill; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.energy.controller.admin.bill.vo.EnergyBillPageReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.bill.EnergyBillDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface EnergyBillMapper extends BaseMapperX { + + default PageResult selectPage(EnergyBillPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(EnergyBillDO::getEnergyType, reqVO.getEnergyType()) + .eqIfPresent(EnergyBillDO::getCustomerId, reqVO.getCustomerId()) + .eqIfPresent(EnergyBillDO::getStationId, reqVO.getStationId()) + .eqIfPresent(EnergyBillDO::getStatus, reqVO.getStatus()) + .eqIfPresent(EnergyBillDO::getAuditStatus, reqVO.getAuditStatus()) + .betweenIfPresent(EnergyBillDO::getBillPeriodStart, reqVO.getBillPeriod()) + .orderByDesc(EnergyBillDO::getId)); + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/config/EnergyStationConfigMapper.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/config/EnergyStationConfigMapper.java new file mode 100644 index 0000000..6fa9481 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/config/EnergyStationConfigMapper.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.energy.dal.mysql.config; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.energy.controller.admin.config.vo.EnergyStationConfigPageReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.config.EnergyStationConfigDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface EnergyStationConfigMapper extends BaseMapperX { + + default EnergyStationConfigDO selectByStationId(Long stationId) { + return selectOne(EnergyStationConfigDO::getStationId, stationId); + } + + default PageResult selectPage(EnergyStationConfigPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(EnergyStationConfigDO::getStationId, reqVO.getStationId()) + .eqIfPresent(EnergyStationConfigDO::getAutoDeduct, reqVO.getAutoDeduct()) + .eqIfPresent(EnergyStationConfigDO::getCooperationType, reqVO.getCooperationType()) + .orderByDesc(EnergyStationConfigDO::getId)); + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/detail/EnergyHydrogenDetailMapper.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/detail/EnergyHydrogenDetailMapper.java new file mode 100644 index 0000000..001a5fd --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/detail/EnergyHydrogenDetailMapper.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.energy.dal.mysql.detail; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.energy.controller.admin.detail.vo.HydrogenDetailPageReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.detail.EnergyHydrogenDetailDO; +import org.apache.ibatis.annotations.Mapper; + +import java.time.LocalDate; +import java.util.List; + +@Mapper +public interface EnergyHydrogenDetailMapper extends BaseMapperX { + + default PageResult selectPage(HydrogenDetailPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(EnergyHydrogenDetailDO::getStationId, reqVO.getStationId()) + .eqIfPresent(EnergyHydrogenDetailDO::getCustomerId, reqVO.getCustomerId()) + .likeIfPresent(EnergyHydrogenDetailDO::getPlateNumber, reqVO.getPlateNumber()) + .eqIfPresent(EnergyHydrogenDetailDO::getAuditStatus, reqVO.getAuditStatus()) + .eqIfPresent(EnergyHydrogenDetailDO::getDeductionStatus, reqVO.getDeductionStatus()) + .eqIfPresent(EnergyHydrogenDetailDO::getSettlementStatus, reqVO.getSettlementStatus()) + .eqIfPresent(EnergyHydrogenDetailDO::getBillId, reqVO.getBillId()) + .betweenIfPresent(EnergyHydrogenDetailDO::getHydrogenDate, reqVO.getHydrogenDate()) + .orderByDesc(EnergyHydrogenDetailDO::getId)); + } + + default List selectListByBillId(Long billId) { + return selectList(new LambdaQueryWrapperX() + .eq(EnergyHydrogenDetailDO::getBillId, billId)); + } + + default List selectUnbilledByCondition(Long customerId, Long contractId, Long stationId, LocalDate startDate, LocalDate endDate) { + return selectList(new LambdaQueryWrapperX() + .eq(EnergyHydrogenDetailDO::getCustomerId, customerId) + .eq(EnergyHydrogenDetailDO::getContractId, contractId) + .eqIfPresent(EnergyHydrogenDetailDO::getStationId, stationId) + .ge(EnergyHydrogenDetailDO::getHydrogenDate, startDate) + .le(EnergyHydrogenDetailDO::getHydrogenDate, endDate) + .eq(EnergyHydrogenDetailDO::getAuditStatus, 1) + .eq(EnergyHydrogenDetailDO::getDeductionStatus, 1) + .isNull(EnergyHydrogenDetailDO::getBillId)); + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/price/EnergyStationPriceMapper.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/price/EnergyStationPriceMapper.java new file mode 100644 index 0000000..12d8320 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/price/EnergyStationPriceMapper.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.energy.dal.mysql.price; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.energy.controller.admin.price.vo.EnergyStationPricePageReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.price.EnergyStationPriceDO; +import org.apache.ibatis.annotations.Mapper; + +import java.time.LocalDate; + +@Mapper +public interface EnergyStationPriceMapper extends BaseMapperX { + + default PageResult selectPage(EnergyStationPricePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(EnergyStationPriceDO::getStationId, reqVO.getStationId()) + .eqIfPresent(EnergyStationPriceDO::getCustomerId, reqVO.getCustomerId()) + .eqIfPresent(EnergyStationPriceDO::getStatus, reqVO.getStatus()) + .orderByDesc(EnergyStationPriceDO::getId)); + } + + default EnergyStationPriceDO selectEffective(Long stationId, Long customerId, LocalDate date) { + return selectOne(new LambdaQueryWrapperX() + .eq(EnergyStationPriceDO::getStationId, stationId) + .eq(EnergyStationPriceDO::getCustomerId, customerId) + .le(EnergyStationPriceDO::getEffectiveDate, date) + .and(w -> w.ge(EnergyStationPriceDO::getExpiryDate, date) + .or().isNull(EnergyStationPriceDO::getExpiryDate)) + .eq(EnergyStationPriceDO::getStatus, 0) + .orderByDesc(EnergyStationPriceDO::getEffectiveDate) + .last("LIMIT 1")); + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/record/EnergyHydrogenRecordMapper.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/record/EnergyHydrogenRecordMapper.java new file mode 100644 index 0000000..e175bde --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/dal/mysql/record/EnergyHydrogenRecordMapper.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.energy.dal.mysql.record; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.energy.controller.admin.record.vo.HydrogenRecordPageReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.record.EnergyHydrogenRecordDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface EnergyHydrogenRecordMapper extends BaseMapperX { + + default PageResult selectPage(HydrogenRecordPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(EnergyHydrogenRecordDO::getStationId, reqVO.getStationId()) + .likeIfPresent(EnergyHydrogenRecordDO::getPlateNumber, reqVO.getPlateNumber()) + .eqIfPresent(EnergyHydrogenRecordDO::getMatchStatus, reqVO.getMatchStatus()) + .eqIfPresent(EnergyHydrogenRecordDO::getSourceType, reqVO.getSourceType()) + .betweenIfPresent(EnergyHydrogenRecordDO::getHydrogenDate, reqVO.getHydrogenDate()) + .orderByDesc(EnergyHydrogenRecordDO::getId)); + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/BillApprovedEvent.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/BillApprovedEvent.java new file mode 100644 index 0000000..c7a3dcd --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/BillApprovedEvent.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.energy.event; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; + +@Getter +@AllArgsConstructor +public class BillApprovedEvent { + private final Long billId; + private final List detailIds; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/BillCreatedEvent.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/BillCreatedEvent.java new file mode 100644 index 0000000..3114600 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/BillCreatedEvent.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.energy.event; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; + +@Getter +@AllArgsConstructor +public class BillCreatedEvent { + private final Long billId; + private final List detailIds; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/DeductionCompletedEvent.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/DeductionCompletedEvent.java new file mode 100644 index 0000000..d865a74 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/DeductionCompletedEvent.java @@ -0,0 +1,10 @@ +package cn.iocoder.yudao.module.energy.event; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class DeductionCompletedEvent { + private final Long detailId; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/DetailAuditedEvent.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/DetailAuditedEvent.java new file mode 100644 index 0000000..ab3f2c0 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/DetailAuditedEvent.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.energy.event; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.math.BigDecimal; + +@Getter +@AllArgsConstructor +public class DetailAuditedEvent { + private final Long detailId; + private final Long stationId; + private final Long customerId; + private final Long contractId; + private final BigDecimal customerAmount; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/DetailCreatedEvent.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/DetailCreatedEvent.java new file mode 100644 index 0000000..0732db0 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/DetailCreatedEvent.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.energy.event; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.math.BigDecimal; + +@Getter +@AllArgsConstructor +public class DetailCreatedEvent { + private final Long detailId; + private final Long stationId; + private final Long customerId; + private final Long contractId; + private final BigDecimal customerAmount; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/RecordImportedEvent.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/RecordImportedEvent.java new file mode 100644 index 0000000..a1cf9d7 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/RecordImportedEvent.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.energy.event; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import java.util.List; + +@Getter +@AllArgsConstructor +public class RecordImportedEvent { + private final Long stationId; + private final List recordIds; + private final String batchNo; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/RecordMatchedEvent.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/RecordMatchedEvent.java new file mode 100644 index 0000000..1394757 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/event/RecordMatchedEvent.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.energy.event; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class RecordMatchedEvent { + private final Long recordId; + private final Long stationId; + private final Long vehicleId; + private final Long customerId; + private final String plateNumber; +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/framework/security/config/SecurityConfiguration.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/framework/security/config/SecurityConfiguration.java new file mode 100644 index 0000000..26dd935 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/framework/security/config/SecurityConfiguration.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.energy.framework.security.config; + +import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; + +/** + * Energy 模块的 Security 配置 + */ +@Configuration("energySecurityConfiguration") +public class SecurityConfiguration { + + @Bean("energyAuthorizeRequestsCustomizer") + public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() { + return new AuthorizeRequestsCustomizer() { + @Override + public void customize(AuthorizeHttpRequestsConfigurer.AuthorizationManagerRequestMatcherRegistry registry) { + // Swagger 接口文档 + registry.requestMatchers("/v3/api-docs/**").permitAll() + .requestMatchers("/webjars/**").permitAll() + .requestMatchers("/swagger-ui").permitAll() + .requestMatchers("/swagger-ui/**").permitAll(); + } + }; + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/framework/web/config/EnergyWebConfiguration.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/framework/web/config/EnergyWebConfiguration.java new file mode 100644 index 0000000..dbd962d --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/framework/web/config/EnergyWebConfiguration.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.models.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Energy 模块的 Web 配置 + */ +@Configuration(proxyBeanMethods = false) +public class EnergyWebConfiguration { + + /** + * energy-server 模块的 API 分组 + */ + @Bean + public GroupedOpenApi energyGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("energy"); + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/job/AccountWarningJob.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/job/AccountWarningJob.java new file mode 100644 index 0000000..83969e8 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/job/AccountWarningJob.java @@ -0,0 +1,85 @@ +package cn.iocoder.yudao.module.energy.job; + +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyAccountDO; +import cn.iocoder.yudao.module.energy.dal.mysql.account.EnergyAccountMapper; +import cn.iocoder.yudao.module.energy.enums.AccountStatusEnum; +import com.xxl.job.core.handler.annotation.XxlJob; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 账户余额预警定时任务 + * + * 功能: + * 1. 检查正常账户,余额低于预警阈值则更新为预警状态 + * 2. 检查正常账户,余额小于0则更新为欠费状态 + * 3. 检查预警/欠费账户,余额恢复正常则更新为正常状态 + */ +@Component +@Slf4j +public class AccountWarningJob { + + @Resource + private EnergyAccountMapper accountMapper; + + @XxlJob("accountWarningJob") + @TenantJob + public void execute() { + log.info("[accountWarningJob] 开始执行账户余额预警检查"); + + try { + int warningCount = 0; + int overdueCount = 0; + int normalCount = 0; + + // 1. 检查正常账户,余额低于阈值则更新为预警/欠费 + List normalAccounts = accountMapper.selectList(new LambdaQueryWrapperX() + .eq(EnergyAccountDO::getAccountStatus, AccountStatusEnum.NORMAL.getStatus()) + .isNotNull(EnergyAccountDO::getReminderThreshold)); + for (EnergyAccountDO account : normalAccounts) { + if (account.getBalance().compareTo(BigDecimal.ZERO) < 0) { + updateStatus(account.getId(), AccountStatusEnum.OVERDUE.getStatus()); + overdueCount++; + log.info("[accountWarningJob] 账户 {} 余额为负,更新为欠费状态", account.getId()); + } else if (account.getBalance().compareTo(account.getReminderThreshold()) < 0) { + updateStatus(account.getId(), AccountStatusEnum.WARNING.getStatus()); + warningCount++; + log.info("[accountWarningJob] 账户 {} 余额低于预警阈值,更新为预警状态", account.getId()); + } + } + + // 2. 检查预警/欠费账户,余额恢复则更新为正常 + List abnormalAccounts = accountMapper.selectList(new LambdaQueryWrapperX() + .in(EnergyAccountDO::getAccountStatus, + AccountStatusEnum.WARNING.getStatus(), + AccountStatusEnum.OVERDUE.getStatus()) + .isNotNull(EnergyAccountDO::getReminderThreshold)); + for (EnergyAccountDO account : abnormalAccounts) { + if (account.getBalance().compareTo(account.getReminderThreshold()) >= 0 + && account.getBalance().compareTo(BigDecimal.ZERO) >= 0) { + updateStatus(account.getId(), AccountStatusEnum.NORMAL.getStatus()); + normalCount++; + log.info("[accountWarningJob] 账户 {} 余额已恢复,更新为正常状态", account.getId()); + } + } + + log.info("[accountWarningJob] 执行完成: 新增预警={}, 新增欠费={}, 恢复正常={}", warningCount, overdueCount, normalCount); + } catch (Exception e) { + log.error("[accountWarningJob] 执行失败", e); + } + } + + private void updateStatus(Long accountId, Integer status) { + EnergyAccountDO update = new EnergyAccountDO(); + update.setId(accountId); + update.setAccountStatus(status); + accountMapper.updateById(update); + } + +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/listener/AccountEventListener.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/listener/AccountEventListener.java new file mode 100644 index 0000000..5368552 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/listener/AccountEventListener.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.energy.listener; + +import cn.iocoder.yudao.module.energy.dal.dataobject.config.EnergyStationConfigDO; +import cn.iocoder.yudao.module.energy.dal.mysql.config.EnergyStationConfigMapper; +import cn.iocoder.yudao.module.energy.enums.DeductionStatusEnum; +import cn.iocoder.yudao.module.energy.event.DetailAuditedEvent; +import cn.iocoder.yudao.module.energy.event.DetailCreatedEvent; +import cn.iocoder.yudao.module.energy.service.account.EnergyAccountService; +import cn.iocoder.yudao.module.energy.service.detail.HydrogenDetailService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionPhase; +import org.springframework.transaction.event.TransactionalEventListener; + +@Component +@Slf4j +public class AccountEventListener { + + @Resource + private EnergyAccountService accountService; + @Resource + private EnergyStationConfigMapper stationConfigMapper; + @Resource + private HydrogenDetailService detailService; + + /** + * 明细创建完成 → 若配置自动扣款则扣款 + * BEFORE_COMMIT: 资金操作,必须同事务 + */ + @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT) + public void onDetailCreated(DetailCreatedEvent event) { + EnergyStationConfigDO config = stationConfigMapper.selectByStationId(event.getStationId()); + if (config != null && Boolean.TRUE.equals(config.getAutoDeduct())) { + log.info("[onDetailCreated] auto deduct: detailId={}, amount={}", event.getDetailId(), event.getCustomerAmount()); + accountService.deduct(event.getCustomerId(), event.getContractId(), + event.getCustomerAmount(), event.getDetailId(), null, "加氢自动扣款"); + detailService.updateDeductionStatus(event.getDetailId(), DeductionStatusEnum.DEDUCTED.getStatus()); + } + } + + /** + * 明细审核通过 → 若配置审核后扣款则扣款 + * BEFORE_COMMIT: 资金操作,必须同事务 + */ + @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT) + public void onDetailAudited(DetailAuditedEvent event) { + EnergyStationConfigDO config = stationConfigMapper.selectByStationId(event.getStationId()); + if (config != null && !Boolean.TRUE.equals(config.getAutoDeduct())) { + log.info("[onDetailAudited] audit-then-deduct: detailId={}, amount={}", event.getDetailId(), event.getCustomerAmount()); + accountService.deduct(event.getCustomerId(), event.getContractId(), + event.getCustomerAmount(), event.getDetailId(), null, "审核后扣款"); + detailService.updateDeductionStatus(event.getDetailId(), DeductionStatusEnum.DEDUCTED.getStatus()); + } + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/listener/BillEventListener.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/listener/BillEventListener.java new file mode 100644 index 0000000..898735d --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/listener/BillEventListener.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.energy.listener; + +import cn.iocoder.yudao.module.energy.enums.SettlementStatusEnum; +import cn.iocoder.yudao.module.energy.event.BillApprovedEvent; +import cn.iocoder.yudao.module.energy.event.BillCreatedEvent; +import cn.iocoder.yudao.module.energy.service.detail.HydrogenDetailService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionalEventListener; + +@Component +@Slf4j +public class BillEventListener { + + @Resource + private HydrogenDetailService detailService; + + /** + * 账单生成完成 → 更新明细的 billId + * AFTER_COMMIT: 非资金操作 + */ + @TransactionalEventListener + public void onBillCreated(BillCreatedEvent event) { + log.info("[onBillCreated] billId={}, detailCount={}", event.getBillId(), event.getDetailIds().size()); + detailService.updateBillId(event.getDetailIds(), event.getBillId()); + } + + /** + * 账单审核通过 → 更新明细结算状态 + * AFTER_COMMIT: 非资金操作 + */ + @TransactionalEventListener + public void onBillApproved(BillApprovedEvent event) { + log.info("[onBillApproved] billId={}", event.getBillId()); + detailService.updateSettlementStatus(event.getDetailIds(), SettlementStatusEnum.SETTLED.getStatus()); + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/listener/DetailEventListener.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/listener/DetailEventListener.java new file mode 100644 index 0000000..fff088e --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/listener/DetailEventListener.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.energy.listener; + +import cn.iocoder.yudao.module.energy.event.RecordImportedEvent; +import cn.iocoder.yudao.module.energy.event.RecordMatchedEvent; +import cn.iocoder.yudao.module.energy.service.detail.HydrogenDetailService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionalEventListener; + +@Component +@Slf4j +public class DetailEventListener { + + @Resource + private HydrogenDetailService hydrogenDetailService; + + /** + * 记录导入完成 → 触发自动匹配(占位,后续实现批量自动匹配) + * AFTER_COMMIT: 非资金操作 + */ + @TransactionalEventListener + public void onRecordImported(RecordImportedEvent event) { + log.info("[onRecordImported] stationId={}, recordCount={}, batchNo={}", + event.getStationId(), event.getRecordIds().size(), event.getBatchNo()); + // TODO: 后续接入 asset 模块实现批量自动匹配 + // hydrogenRecordService.batchMatch(event.getRecordIds()); + } + + /** + * 记录匹配完成 → 创建明细 + * AFTER_COMMIT: 明细创建在独立事务中 + */ + @TransactionalEventListener + public void onRecordMatched(RecordMatchedEvent event) { + log.info("[onRecordMatched] recordId={}, vehicleId={}, customerId={}", + event.getRecordId(), event.getVehicleId(), event.getCustomerId()); + hydrogenDetailService.createFromRecord(event); + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/account/EnergyAccountService.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/account/EnergyAccountService.java new file mode 100644 index 0000000..44f3740 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/account/EnergyAccountService.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.energy.service.account; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.account.vo.EnergyAccountFlowPageReqVO; +import cn.iocoder.yudao.module.energy.controller.admin.account.vo.EnergyAccountPageReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyAccountDO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyAccountFlowDO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyProjectAccountDO; +import java.math.BigDecimal; +import java.util.List; + +public interface EnergyAccountService { + PageResult getAccountPage(EnergyAccountPageReqVO reqVO); + EnergyAccountDO getAccount(Long id); + EnergyAccountDO getOrCreateByCustomerId(Long customerId); + EnergyProjectAccountDO getOrCreateByContractId(Long accountId, Long contractId, String projectName); + List getProjectAccountsByAccountId(Long accountId); + void deduct(Long customerId, Long contractId, BigDecimal amount, Long bizId, String bizCode, String remark); + void recharge(Long customerId, BigDecimal amount, Long bizId, String bizCode, String remark); + void updateThreshold(Long id, BigDecimal threshold); + PageResult getFlowPage(EnergyAccountFlowPageReqVO reqVO); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/account/EnergyAccountServiceImpl.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/account/EnergyAccountServiceImpl.java new file mode 100644 index 0000000..778d841 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/account/EnergyAccountServiceImpl.java @@ -0,0 +1,273 @@ +package cn.iocoder.yudao.module.energy.service.account; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.account.vo.EnergyAccountFlowPageReqVO; +import cn.iocoder.yudao.module.energy.controller.admin.account.vo.EnergyAccountPageReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyAccountDO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyAccountFlowDO; +import cn.iocoder.yudao.module.energy.dal.dataobject.account.EnergyProjectAccountDO; +import cn.iocoder.yudao.module.energy.dal.mysql.account.EnergyAccountFlowMapper; +import cn.iocoder.yudao.module.energy.dal.mysql.account.EnergyAccountMapper; +import cn.iocoder.yudao.module.energy.dal.mysql.account.EnergyProjectAccountMapper; +import cn.iocoder.yudao.module.energy.enums.AccountStatusEnum; +import cn.iocoder.yudao.module.energy.enums.BizTypeEnum; +import cn.iocoder.yudao.module.energy.enums.FlowTypeEnum; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.energy.enums.ErrorCodeConstants.*; + +@Service +@Validated +@Slf4j +public class EnergyAccountServiceImpl implements EnergyAccountService { + + @Resource + private EnergyAccountMapper accountMapper; + @Resource + private EnergyProjectAccountMapper projectAccountMapper; + @Resource + private EnergyAccountFlowMapper accountFlowMapper; + + @Override + public PageResult getAccountPage(EnergyAccountPageReqVO reqVO) { + return accountMapper.selectPage(reqVO); + } + + @Override + public EnergyAccountDO getAccount(Long id) { + return accountMapper.selectById(id); + } + + @Override + public EnergyAccountDO getOrCreateByCustomerId(Long customerId) { + EnergyAccountDO account = accountMapper.selectByCustomerId(customerId); + if (account != null) { + return account; + } + // Auto-create + account = EnergyAccountDO.builder() + .customerId(customerId) + .balance(BigDecimal.ZERO) + .initBalance(BigDecimal.ZERO) + .accumulatedRecharge(BigDecimal.ZERO) + .accumulatedHydrogen(BigDecimal.ZERO) + .accumulatedElectric(BigDecimal.ZERO) + .accumulatedConsume(BigDecimal.ZERO) + .accountStatus(AccountStatusEnum.NORMAL.getStatus()) + .version(0) + .build(); + accountMapper.insert(account); + return account; + } + + @Override + public EnergyProjectAccountDO getOrCreateByContractId(Long accountId, Long contractId, String projectName) { + EnergyProjectAccountDO projectAccount = projectAccountMapper.selectByContractId(contractId); + if (projectAccount != null) { + return projectAccount; + } + projectAccount = EnergyProjectAccountDO.builder() + .accountId(accountId) + .contractId(contractId) + .projectName(projectName) + .projectBalance(BigDecimal.ZERO) + .projectRemitAmount(BigDecimal.ZERO) + .projectHydrogenAmount(BigDecimal.ZERO) + .projectElectricAmount(BigDecimal.ZERO) + .projectConsumeAmount(BigDecimal.ZERO) + .accountStatus(AccountStatusEnum.NORMAL.getStatus()) + .version(0) + .build(); + projectAccountMapper.insert(projectAccount); + return projectAccount; + } + + @Override + public List getProjectAccountsByAccountId(Long accountId) { + return projectAccountMapper.selectListByAccountId(accountId); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deduct(Long customerId, Long contractId, BigDecimal amount, Long bizId, String bizCode, String remark) { + // 1. getOrCreate 总账户 + EnergyAccountDO account = getOrCreateByCustomerId(customerId); + BigDecimal balanceBefore = account.getBalance(); + BigDecimal balanceAfter = balanceBefore.subtract(amount).setScale(2, RoundingMode.HALF_UP); + + // 2. 乐观锁更新总账户余额(重试3次) + boolean updated = updateAccountWithRetry(account, balanceAfter, amount, true); + if (!updated) { + throw exception(ENERGY_ACCOUNT_VERSION_CONFLICT); + } + // Re-read for correct balanceBefore after retry + if (!balanceBefore.equals(account.getBalance())) { + balanceBefore = account.getBalance(); + balanceAfter = balanceBefore.subtract(amount).setScale(2, RoundingMode.HALF_UP); + } + + // 3. 更新项目账户 + BigDecimal projectBalanceBefore = null; + BigDecimal projectBalanceAfter = null; + Long projectAccountId = null; + if (contractId != null) { + EnergyProjectAccountDO projectAccount = getOrCreateByContractId(account.getId(), contractId, null); + projectBalanceBefore = projectAccount.getProjectBalance(); + projectBalanceAfter = projectBalanceBefore.subtract(amount).setScale(2, RoundingMode.HALF_UP); + boolean projectUpdated = updateProjectAccountWithRetry(projectAccount, projectBalanceAfter, amount, true); + if (!projectUpdated) { + throw exception(ENERGY_ACCOUNT_VERSION_CONFLICT); + } + projectAccountId = projectAccount.getId(); + } + + // 4. 写流水 + accountFlowMapper.insert(EnergyAccountFlowDO.builder() + .accountId(account.getId()) + .projectAccountId(projectAccountId) + .flowType(FlowTypeEnum.DEDUCTION.getType()) + .amount(amount) + .balanceBefore(balanceBefore) + .balanceAfter(balanceAfter) + .projectBalanceBefore(projectBalanceBefore) + .projectBalanceAfter(projectBalanceAfter) + .bizType(BizTypeEnum.HYDROGEN_DEDUCTION.getType()) + .bizId(bizId) + .bizCode(bizCode) + .remark(remark) + .build()); + + // 5. 更新账户状态 + updateAccountStatus(account.getId(), balanceAfter); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void recharge(Long customerId, BigDecimal amount, Long bizId, String bizCode, String remark) { + EnergyAccountDO account = getOrCreateByCustomerId(customerId); + BigDecimal balanceBefore = account.getBalance(); + BigDecimal balanceAfter = balanceBefore.add(amount).setScale(2, RoundingMode.HALF_UP); + + // Optimistic lock update + int retryCount = 0; + while (retryCount < 3) { + int rows = accountMapper.update(null, new LambdaUpdateWrapper() + .set(EnergyAccountDO::getBalance, balanceAfter) + .set(EnergyAccountDO::getAccumulatedRecharge, account.getAccumulatedRecharge().add(amount)) + .set(EnergyAccountDO::getLastRechargeDate, LocalDate.now()) + .set(EnergyAccountDO::getVersion, account.getVersion() + 1) + .eq(EnergyAccountDO::getId, account.getId()) + .eq(EnergyAccountDO::getVersion, account.getVersion())); + if (rows > 0) break; + retryCount++; + account = accountMapper.selectById(account.getId()); + balanceBefore = account.getBalance(); + balanceAfter = balanceBefore.add(amount).setScale(2, RoundingMode.HALF_UP); + } + if (retryCount >= 3) { + throw exception(ENERGY_ACCOUNT_VERSION_CONFLICT); + } + + // Write flow + accountFlowMapper.insert(EnergyAccountFlowDO.builder() + .accountId(account.getId()) + .flowType(FlowTypeEnum.RECHARGE.getType()) + .amount(amount) + .balanceBefore(balanceBefore) + .balanceAfter(balanceAfter) + .bizType(BizTypeEnum.RECHARGE.getType()) + .bizId(bizId) + .bizCode(bizCode) + .remark(remark) + .build()); + + // Update status + updateAccountStatus(account.getId(), balanceAfter); + } + + @Override + public void updateThreshold(Long id, BigDecimal threshold) { + EnergyAccountDO account = accountMapper.selectById(id); + if (account == null) { + throw exception(ENERGY_ACCOUNT_NOT_EXISTS); + } + accountMapper.update(null, new LambdaUpdateWrapper() + .set(EnergyAccountDO::getReminderThreshold, threshold) + .eq(EnergyAccountDO::getId, id)); + } + + @Override + public PageResult getFlowPage(EnergyAccountFlowPageReqVO reqVO) { + return accountFlowMapper.selectPage(reqVO); + } + + // ===== Private helpers ===== + + private boolean updateAccountWithRetry(EnergyAccountDO account, BigDecimal balanceAfter, BigDecimal amount, boolean isDeduction) { + int retryCount = 0; + while (retryCount < 3) { + LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper() + .set(EnergyAccountDO::getBalance, balanceAfter) + .set(EnergyAccountDO::getAccumulatedHydrogen, account.getAccumulatedHydrogen().add(amount)) + .set(EnergyAccountDO::getAccumulatedConsume, account.getAccumulatedConsume().add(amount)) + .set(EnergyAccountDO::getVersion, account.getVersion() + 1) + .eq(EnergyAccountDO::getId, account.getId()) + .eq(EnergyAccountDO::getVersion, account.getVersion()); + int rows = accountMapper.update(null, wrapper); + if (rows > 0) return true; + retryCount++; + account = accountMapper.selectById(account.getId()); + BigDecimal newBalance = account.getBalance().subtract(amount).setScale(2, RoundingMode.HALF_UP); + // Update for next iteration + balanceAfter = newBalance; + } + return false; + } + + private boolean updateProjectAccountWithRetry(EnergyProjectAccountDO projectAccount, BigDecimal balanceAfter, BigDecimal amount, boolean isDeduction) { + int retryCount = 0; + while (retryCount < 3) { + LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper() + .set(EnergyProjectAccountDO::getProjectBalance, balanceAfter) + .set(EnergyProjectAccountDO::getProjectHydrogenAmount, projectAccount.getProjectHydrogenAmount().add(amount)) + .set(EnergyProjectAccountDO::getProjectConsumeAmount, projectAccount.getProjectConsumeAmount().add(amount)) + .set(EnergyProjectAccountDO::getVersion, projectAccount.getVersion() + 1) + .eq(EnergyProjectAccountDO::getId, projectAccount.getId()) + .eq(EnergyProjectAccountDO::getVersion, projectAccount.getVersion()); + int rows = projectAccountMapper.update(null, wrapper); + if (rows > 0) return true; + retryCount++; + projectAccount = projectAccountMapper.selectById(projectAccount.getId()); + balanceAfter = projectAccount.getProjectBalance().subtract(amount).setScale(2, RoundingMode.HALF_UP); + } + return false; + } + + private void updateAccountStatus(Long accountId, BigDecimal currentBalance) { + EnergyAccountDO account = accountMapper.selectById(accountId); + Integer newStatus; + if (currentBalance.compareTo(BigDecimal.ZERO) < 0) { + newStatus = AccountStatusEnum.OVERDUE.getStatus(); + } else if (account.getReminderThreshold() != null + && currentBalance.compareTo(account.getReminderThreshold()) <= 0) { + newStatus = AccountStatusEnum.WARNING.getStatus(); + } else { + newStatus = AccountStatusEnum.NORMAL.getStatus(); + } + if (!newStatus.equals(account.getAccountStatus())) { + accountMapper.update(null, new LambdaUpdateWrapper() + .set(EnergyAccountDO::getAccountStatus, newStatus) + .eq(EnergyAccountDO::getId, accountId)); + } + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/bill/EnergyBillService.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/bill/EnergyBillService.java new file mode 100644 index 0000000..da06d1b --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/bill/EnergyBillService.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.energy.service.bill; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.bill.vo.*; +import cn.iocoder.yudao.module.energy.dal.dataobject.bill.EnergyBillDO; +import java.util.List; + +public interface EnergyBillService { + Long generateBill(EnergyBillGenerateReqVO reqVO); + List batchGenerateBills(List reqVOs); + PageResult getBillPage(EnergyBillPageReqVO reqVO); + EnergyBillDO getBill(Long id); + void updateBill(EnergyBillSaveReqVO reqVO); + void deleteBill(Long id); + void auditBill(Long id, Boolean approved, String remark); + Long createAdjustment(EnergyBillAdjustmentSaveReqVO reqVO); + void deleteAdjustment(Long adjustmentId); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/bill/EnergyBillServiceImpl.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/bill/EnergyBillServiceImpl.java new file mode 100644 index 0000000..60683ec --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/bill/EnergyBillServiceImpl.java @@ -0,0 +1,215 @@ +package cn.iocoder.yudao.module.energy.service.bill; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.bill.vo.*; +import cn.iocoder.yudao.module.energy.dal.dataobject.bill.EnergyBillAdjustmentDO; +import cn.iocoder.yudao.module.energy.dal.dataobject.bill.EnergyBillDO; +import cn.iocoder.yudao.module.energy.dal.dataobject.detail.EnergyHydrogenDetailDO; +import cn.iocoder.yudao.module.energy.dal.mysql.bill.EnergyBillAdjustmentMapper; +import cn.iocoder.yudao.module.energy.dal.mysql.bill.EnergyBillMapper; +import cn.iocoder.yudao.module.energy.dal.mysql.detail.EnergyHydrogenDetailMapper; +import cn.iocoder.yudao.module.energy.enums.*; +import cn.iocoder.yudao.module.energy.event.BillApprovedEvent; +import cn.iocoder.yudao.module.energy.event.BillCreatedEvent; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.energy.enums.ErrorCodeConstants.*; + +@Service +@Validated +@Slf4j +public class EnergyBillServiceImpl implements EnergyBillService { + + @Resource + private EnergyBillMapper billMapper; + @Resource + private EnergyBillAdjustmentMapper adjustmentMapper; + @Resource + private EnergyHydrogenDetailMapper detailMapper; + @Resource + private ApplicationEventPublisher eventPublisher; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long generateBill(EnergyBillGenerateReqVO reqVO) { + // 1. Query unbilled, audited, deducted details + List details = detailMapper.selectUnbilledByCondition( + reqVO.getCustomerId(), reqVO.getContractId(), reqVO.getStationId(), + reqVO.getBillPeriodStart(), reqVO.getBillPeriodEnd()); + if (details.isEmpty()) { + throw exception(ENERGY_BILL_NO_DETAILS); + } + + // 2. Calculate totals + BigDecimal receivableAmount = details.stream() + .map(EnergyHydrogenDetailDO::getCustomerAmount) + .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal totalQuantity = details.stream() + .map(EnergyHydrogenDetailDO::getHydrogenQuantity) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // 3. Create bill (draft status) + EnergyBillDO bill = EnergyBillDO.builder() + .billCode(generateBillCode()) + .energyType(reqVO.getEnergyType()) + .customerId(reqVO.getCustomerId()) + .contractId(reqVO.getContractId()) + .stationId(reqVO.getStationId()) + .billPeriodStart(reqVO.getBillPeriodStart()) + .billPeriodEnd(reqVO.getBillPeriodEnd()) + .receivableAmount(receivableAmount) + .actualAmount(receivableAmount) + .adjustmentAmount(BigDecimal.ZERO) + .paidAmount(BigDecimal.ZERO) + .totalQuantity(totalQuantity) + .detailCount(details.size()) + .status(BillStatusEnum.DRAFT.getStatus()) + .auditStatus(BillAuditStatusEnum.PENDING.getStatus()) + .submitStatus(BillSubmitStatusEnum.NOT_SUBMITTED.getStatus()) + .paymentStatus(PaymentStatusEnum.UNPAID.getStatus()) + .generateTime(LocalDateTime.now()) + .build(); + billMapper.insert(bill); + + // 4. Publish event to update detail billIds + List detailIds = details.stream().map(EnergyHydrogenDetailDO::getId).toList(); + eventPublisher.publishEvent(new BillCreatedEvent(bill.getId(), detailIds)); + + return bill.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public List batchGenerateBills(List reqVOs) { + List billIds = new ArrayList<>(); + for (EnergyBillGenerateReqVO reqVO : reqVOs) { + try { + billIds.add(generateBill(reqVO)); + } catch (Exception e) { + log.warn("[batchGenerateBills] Failed for customer={}, contract={}", + reqVO.getCustomerId(), reqVO.getContractId(), e); + } + } + return billIds; + } + + @Override + public PageResult getBillPage(EnergyBillPageReqVO reqVO) { + return billMapper.selectPage(reqVO); + } + + @Override + public EnergyBillDO getBill(Long id) { + return billMapper.selectById(id); + } + + @Override + public void updateBill(EnergyBillSaveReqVO reqVO) { + EnergyBillDO bill = validateBillExists(reqVO.getId()); + bill.setAuditRemark(reqVO.getAuditRemark()); + billMapper.updateById(bill); + } + + @Override + public void deleteBill(Long id) { + EnergyBillDO bill = validateBillExists(id); + if (!BillStatusEnum.DRAFT.getStatus().equals(bill.getStatus())) { + throw exception(ENERGY_BILL_NOT_DRAFT); + } + billMapper.deleteById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void auditBill(Long id, Boolean approved, String remark) { + EnergyBillDO bill = validateBillExists(id); + if (!BillAuditStatusEnum.PENDING.getStatus().equals(bill.getAuditStatus())) { + throw exception(ENERGY_BILL_ALREADY_AUDITED); + } + + Integer newAuditStatus = approved ? BillAuditStatusEnum.APPROVED.getStatus() : BillAuditStatusEnum.REJECTED.getStatus(); + Integer newStatus = approved ? BillStatusEnum.GENERATED.getStatus() : bill.getStatus(); + + bill.setAuditStatus(newAuditStatus); + bill.setStatus(newStatus); + bill.setAuditRemark(remark); + bill.setAuditTime(LocalDateTime.now()); + billMapper.updateById(bill); + + // If approved, publish event to update detail settlement status + if (approved) { + List details = detailMapper.selectListByBillId(id); + List detailIds = details.stream().map(EnergyHydrogenDetailDO::getId).toList(); + eventPublisher.publishEvent(new BillApprovedEvent(id, detailIds)); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createAdjustment(EnergyBillAdjustmentSaveReqVO reqVO) { + EnergyBillDO bill = validateBillExists(reqVO.getBillId()); + + EnergyBillAdjustmentDO adjustment = EnergyBillAdjustmentDO.builder() + .billId(reqVO.getBillId()) + .detailId(reqVO.getDetailId()) + .adjustmentType(reqVO.getAdjustmentType()) + .amount(reqVO.getAmount()) + .reason(reqVO.getReason()) + .attachmentUrls(reqVO.getAttachmentUrls()) + .operateTime(LocalDateTime.now()) + .build(); + adjustmentMapper.insert(adjustment); + + // Update bill amounts + BigDecimal delta = AdjustmentTypeEnum.INCREASE.getType().equals(reqVO.getAdjustmentType()) + ? reqVO.getAmount() : reqVO.getAmount().negate(); + bill.setAdjustmentAmount(bill.getAdjustmentAmount().add(delta)); + bill.setActualAmount(bill.getReceivableAmount().add(bill.getAdjustmentAmount())); + billMapper.updateById(bill); + + return adjustment.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteAdjustment(Long adjustmentId) { + EnergyBillAdjustmentDO adjustment = adjustmentMapper.selectById(adjustmentId); + if (adjustment == null) return; + + EnergyBillDO bill = billMapper.selectById(adjustment.getBillId()); + if (bill != null) { + // Reverse the adjustment + BigDecimal delta = AdjustmentTypeEnum.INCREASE.getType().equals(adjustment.getAdjustmentType()) + ? adjustment.getAmount().negate() : adjustment.getAmount(); + bill.setAdjustmentAmount(bill.getAdjustmentAmount().add(delta)); + bill.setActualAmount(bill.getReceivableAmount().add(bill.getAdjustmentAmount())); + billMapper.updateById(bill); + } + adjustmentMapper.deleteById(adjustmentId); + } + + private EnergyBillDO validateBillExists(Long id) { + EnergyBillDO bill = billMapper.selectById(id); + if (bill == null) { + throw exception(ENERGY_BILL_NOT_EXISTS); + } + return bill; + } + + private String generateBillCode() { + return "EB" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + + UUID.randomUUID().toString().substring(0, 4).toUpperCase(); + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/config/EnergyStationConfigService.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/config/EnergyStationConfigService.java new file mode 100644 index 0000000..16cbd83 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/config/EnergyStationConfigService.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.energy.service.config; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.config.vo.EnergyStationConfigPageReqVO; +import cn.iocoder.yudao.module.energy.controller.admin.config.vo.EnergyStationConfigSaveReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.config.EnergyStationConfigDO; + +public interface EnergyStationConfigService { + Long createConfig(EnergyStationConfigSaveReqVO createReqVO); + void updateConfig(EnergyStationConfigSaveReqVO updateReqVO); + EnergyStationConfigDO getConfig(Long id); + PageResult getConfigPage(EnergyStationConfigPageReqVO pageReqVO); + EnergyStationConfigDO getByStationId(Long stationId); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/config/EnergyStationConfigServiceImpl.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/config/EnergyStationConfigServiceImpl.java new file mode 100644 index 0000000..71e25b0 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/config/EnergyStationConfigServiceImpl.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.module.energy.service.config; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.config.vo.EnergyStationConfigPageReqVO; +import cn.iocoder.yudao.module.energy.controller.admin.config.vo.EnergyStationConfigSaveReqVO; +import cn.iocoder.yudao.module.energy.convert.config.EnergyStationConfigConvert; +import cn.iocoder.yudao.module.energy.dal.dataobject.config.EnergyStationConfigDO; +import cn.iocoder.yudao.module.energy.dal.mysql.config.EnergyStationConfigMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.energy.enums.ErrorCodeConstants.*; + +@Service +@Validated +public class EnergyStationConfigServiceImpl implements EnergyStationConfigService { + + @Resource + private EnergyStationConfigMapper stationConfigMapper; + + @Override + public Long createConfig(EnergyStationConfigSaveReqVO createReqVO) { + // 校验站点唯一 + EnergyStationConfigDO existing = stationConfigMapper.selectByStationId(createReqVO.getStationId()); + if (existing != null) { + throw exception(STATION_CONFIG_DUPLICATE); + } + EnergyStationConfigDO config = EnergyStationConfigConvert.INSTANCE.convert(createReqVO); + stationConfigMapper.insert(config); + return config.getId(); + } + + @Override + public void updateConfig(EnergyStationConfigSaveReqVO updateReqVO) { + validateConfigExists(updateReqVO.getId()); + EnergyStationConfigDO updateObj = EnergyStationConfigConvert.INSTANCE.convert(updateReqVO); + stationConfigMapper.updateById(updateObj); + } + + @Override + public EnergyStationConfigDO getConfig(Long id) { + return stationConfigMapper.selectById(id); + } + + @Override + public PageResult getConfigPage(EnergyStationConfigPageReqVO pageReqVO) { + return stationConfigMapper.selectPage(pageReqVO); + } + + @Override + public EnergyStationConfigDO getByStationId(Long stationId) { + return stationConfigMapper.selectByStationId(stationId); + } + + private void validateConfigExists(Long id) { + if (stationConfigMapper.selectById(id) == null) { + throw exception(STATION_CONFIG_NOT_EXISTS); + } + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/detail/HydrogenDetailService.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/detail/HydrogenDetailService.java new file mode 100644 index 0000000..f5dddac --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/detail/HydrogenDetailService.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.energy.service.detail; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.detail.vo.HydrogenDetailPageReqVO; +import cn.iocoder.yudao.module.energy.controller.admin.detail.vo.HydrogenDetailSaveReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.detail.EnergyHydrogenDetailDO; +import cn.iocoder.yudao.module.energy.event.RecordMatchedEvent; +import java.util.List; + +public interface HydrogenDetailService { + void createFromRecord(RecordMatchedEvent event); + void updateDetail(HydrogenDetailSaveReqVO reqVO); + PageResult getDetailPage(HydrogenDetailPageReqVO pageReqVO); + EnergyHydrogenDetailDO getDetail(Long id); + void audit(Long id, Boolean approved, String remark); + void batchAudit(List ids, Boolean approved, String remark); + void updateDeductionStatus(Long detailId, Integer status); + void updateBillId(List detailIds, Long billId); + void updateSettlementStatus(List detailIds, Integer status); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/detail/HydrogenDetailServiceImpl.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/detail/HydrogenDetailServiceImpl.java new file mode 100644 index 0000000..bc30c45 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/detail/HydrogenDetailServiceImpl.java @@ -0,0 +1,181 @@ +package cn.iocoder.yudao.module.energy.service.detail; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.detail.vo.HydrogenDetailPageReqVO; +import cn.iocoder.yudao.module.energy.controller.admin.detail.vo.HydrogenDetailSaveReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.detail.EnergyHydrogenDetailDO; +import cn.iocoder.yudao.module.energy.dal.dataobject.record.EnergyHydrogenRecordDO; +import cn.iocoder.yudao.module.energy.dal.dataobject.price.EnergyStationPriceDO; +import cn.iocoder.yudao.module.energy.dal.mysql.detail.EnergyHydrogenDetailMapper; +import cn.iocoder.yudao.module.energy.dal.mysql.record.EnergyHydrogenRecordMapper; +import cn.iocoder.yudao.module.energy.enums.AuditStatusEnum; +import cn.iocoder.yudao.module.energy.enums.CostBearerEnum; +import cn.iocoder.yudao.module.energy.enums.DeductionStatusEnum; +import cn.iocoder.yudao.module.energy.enums.PayMethodEnum; +import cn.iocoder.yudao.module.energy.event.DetailAuditedEvent; +import cn.iocoder.yudao.module.energy.event.DetailCreatedEvent; +import cn.iocoder.yudao.module.energy.event.RecordMatchedEvent; +import cn.iocoder.yudao.module.energy.service.price.EnergyStationPriceService; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.energy.enums.ErrorCodeConstants.*; + +@Service +@Validated +@Slf4j +public class HydrogenDetailServiceImpl implements HydrogenDetailService { + + @Resource + private EnergyHydrogenDetailMapper detailMapper; + @Resource + private EnergyHydrogenRecordMapper recordMapper; + @Resource + private EnergyStationPriceService stationPriceService; + @Resource + private ApplicationEventPublisher eventPublisher; + + @Override + @Transactional(rollbackFor = Exception.class) + public void createFromRecord(RecordMatchedEvent event) { + // 1. Get original record + EnergyHydrogenRecordDO record = recordMapper.selectById(event.getRecordId()); + if (record == null) { + log.warn("[createFromRecord] record not found: {}", event.getRecordId()); + return; + } + + // 2. Get price + EnergyStationPriceDO price = stationPriceService.getEffectivePrice( + event.getStationId(), event.getCustomerId(), record.getHydrogenDate()); + BigDecimal costPrice = price != null ? price.getCostPrice() : record.getUnitPrice(); + BigDecimal customerPrice = price != null ? price.getCustomerPrice() : record.getUnitPrice(); + + // 3. Calculate amounts + BigDecimal costAmount = record.getHydrogenQuantity().multiply(costPrice).setScale(2, RoundingMode.HALF_UP); + BigDecimal customerAmount = record.getHydrogenQuantity().multiply(customerPrice).setScale(2, RoundingMode.HALF_UP); + + // 4. Build detail - NOTE: contractId, costBearer, payMethod would normally come from asset/rental API + // For now, use defaults. TODO: integrate with asset module for contract lookup + EnergyHydrogenDetailDO detail = EnergyHydrogenDetailDO.builder() + .recordId(event.getRecordId()) + .stationId(event.getStationId()) + .vehicleId(event.getVehicleId()) + .plateNumber(event.getPlateNumber()) + .hydrogenDate(record.getHydrogenDate()) + .hydrogenQuantity(record.getHydrogenQuantity()) + .costPrice(costPrice) + .costAmount(costAmount) + .customerPrice(customerPrice) + .customerAmount(customerAmount) + .customerId(event.getCustomerId()) + .costBearer(CostBearerEnum.CUSTOMER.getType()) + .payMethod(PayMethodEnum.PREPAID.getType()) + .auditStatus(AuditStatusEnum.PENDING.getStatus()) + .deductionStatus(DeductionStatusEnum.NOT_DEDUCTED.getStatus()) + .settlementStatus(0) // NOT_SETTLED + .build(); + detailMapper.insert(detail); + + // 5. Publish event (BEFORE_COMMIT listener will handle auto-deduction if configured) + eventPublisher.publishEvent(new DetailCreatedEvent( + detail.getId(), event.getStationId(), event.getCustomerId(), + detail.getContractId(), customerAmount)); + } + + @Override + public void updateDetail(HydrogenDetailSaveReqVO reqVO) { + validateDetailExists(reqVO.getId()); + EnergyHydrogenDetailDO updateObj = new EnergyHydrogenDetailDO(); + updateObj.setId(reqVO.getId()); + if (reqVO.getCostPrice() != null) { + updateObj.setCostPrice(reqVO.getCostPrice()); + } + if (reqVO.getCustomerPrice() != null) { + updateObj.setCustomerPrice(reqVO.getCustomerPrice()); + } + if (reqVO.getRemark() != null) { + updateObj.setRemark(reqVO.getRemark()); + } + detailMapper.updateById(updateObj); + } + + @Override + public PageResult getDetailPage(HydrogenDetailPageReqVO pageReqVO) { + return detailMapper.selectPage(pageReqVO); + } + + @Override + public EnergyHydrogenDetailDO getDetail(Long id) { + return detailMapper.selectById(id); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void audit(Long id, Boolean approved, String remark) { + EnergyHydrogenDetailDO detail = validateDetailExists(id); + if (!AuditStatusEnum.PENDING.getStatus().equals(detail.getAuditStatus())) { + throw exception(HYDROGEN_DETAIL_ALREADY_AUDITED); + } + Integer newStatus = approved ? AuditStatusEnum.APPROVED.getStatus() : AuditStatusEnum.REJECTED.getStatus(); + detailMapper.update(null, new LambdaUpdateWrapper() + .set(EnergyHydrogenDetailDO::getAuditStatus, newStatus) + .set(EnergyHydrogenDetailDO::getAuditRemark, remark) + .eq(EnergyHydrogenDetailDO::getId, id)); + + // If approved, publish event for deduction + if (approved) { + eventPublisher.publishEvent(new DetailAuditedEvent( + id, detail.getStationId(), detail.getCustomerId(), + detail.getContractId(), detail.getCustomerAmount())); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void batchAudit(List ids, Boolean approved, String remark) { + for (Long id : ids) { + audit(id, approved, remark); + } + } + + @Override + public void updateDeductionStatus(Long detailId, Integer status) { + detailMapper.update(null, new LambdaUpdateWrapper() + .set(EnergyHydrogenDetailDO::getDeductionStatus, status) + .eq(EnergyHydrogenDetailDO::getId, detailId)); + } + + @Override + public void updateBillId(List detailIds, Long billId) { + if (detailIds == null || detailIds.isEmpty()) return; + detailMapper.update(null, new LambdaUpdateWrapper() + .set(EnergyHydrogenDetailDO::getBillId, billId) + .in(EnergyHydrogenDetailDO::getId, detailIds)); + } + + @Override + public void updateSettlementStatus(List detailIds, Integer status) { + if (detailIds == null || detailIds.isEmpty()) return; + detailMapper.update(null, new LambdaUpdateWrapper() + .set(EnergyHydrogenDetailDO::getSettlementStatus, status) + .in(EnergyHydrogenDetailDO::getId, detailIds)); + } + + private EnergyHydrogenDetailDO validateDetailExists(Long id) { + EnergyHydrogenDetailDO detail = detailMapper.selectById(id); + if (detail == null) { + throw exception(HYDROGEN_DETAIL_NOT_EXISTS); + } + return detail; + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/price/EnergyStationPriceService.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/price/EnergyStationPriceService.java new file mode 100644 index 0000000..ba4cf6d --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/price/EnergyStationPriceService.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.energy.service.price; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.price.vo.EnergyStationPricePageReqVO; +import cn.iocoder.yudao.module.energy.controller.admin.price.vo.EnergyStationPriceSaveReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.price.EnergyStationPriceDO; +import java.time.LocalDate; + +public interface EnergyStationPriceService { + Long createPrice(EnergyStationPriceSaveReqVO createReqVO); + void updatePrice(EnergyStationPriceSaveReqVO updateReqVO); + void deletePrice(Long id); + EnergyStationPriceDO getPrice(Long id); + PageResult getPricePage(EnergyStationPricePageReqVO pageReqVO); + EnergyStationPriceDO getEffectivePrice(Long stationId, Long customerId, LocalDate date); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/price/EnergyStationPriceServiceImpl.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/price/EnergyStationPriceServiceImpl.java new file mode 100644 index 0000000..ef035df --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/price/EnergyStationPriceServiceImpl.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.energy.service.price; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.price.vo.EnergyStationPricePageReqVO; +import cn.iocoder.yudao.module.energy.controller.admin.price.vo.EnergyStationPriceSaveReqVO; +import cn.iocoder.yudao.module.energy.convert.price.EnergyStationPriceConvert; +import cn.iocoder.yudao.module.energy.dal.dataobject.price.EnergyStationPriceDO; +import cn.iocoder.yudao.module.energy.dal.mysql.price.EnergyStationPriceMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; +import java.time.LocalDate; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.energy.enums.ErrorCodeConstants.*; + +@Service +@Validated +public class EnergyStationPriceServiceImpl implements EnergyStationPriceService { + + @Resource + private EnergyStationPriceMapper stationPriceMapper; + + @Override + public Long createPrice(EnergyStationPriceSaveReqVO createReqVO) { + // Validate unique constraint: station + customer + effectiveDate + validatePriceUnique(createReqVO.getStationId(), createReqVO.getCustomerId(), createReqVO.getEffectiveDate(), null); + EnergyStationPriceDO price = EnergyStationPriceConvert.INSTANCE.convert(createReqVO); + price.setStatus(0); // 生效中 + stationPriceMapper.insert(price); + return price.getId(); + } + + @Override + public void updatePrice(EnergyStationPriceSaveReqVO updateReqVO) { + validatePriceExists(updateReqVO.getId()); + validatePriceUnique(updateReqVO.getStationId(), updateReqVO.getCustomerId(), updateReqVO.getEffectiveDate(), updateReqVO.getId()); + EnergyStationPriceDO updateObj = EnergyStationPriceConvert.INSTANCE.convert(updateReqVO); + stationPriceMapper.updateById(updateObj); + } + + @Override + public void deletePrice(Long id) { + validatePriceExists(id); + stationPriceMapper.deleteById(id); + } + + @Override + public EnergyStationPriceDO getPrice(Long id) { + return stationPriceMapper.selectById(id); + } + + @Override + public PageResult getPricePage(EnergyStationPricePageReqVO pageReqVO) { + return stationPriceMapper.selectPage(pageReqVO); + } + + @Override + public EnergyStationPriceDO getEffectivePrice(Long stationId, Long customerId, LocalDate date) { + return stationPriceMapper.selectEffective(stationId, customerId, date); + } + + private void validatePriceExists(Long id) { + if (stationPriceMapper.selectById(id) == null) { + throw exception(STATION_PRICE_NOT_EXISTS); + } + } + + private void validatePriceUnique(Long stationId, Long customerId, LocalDate effectiveDate, Long excludeId) { + EnergyStationPriceDO existing = stationPriceMapper.selectEffective(stationId, customerId, effectiveDate); + if (existing != null && !existing.getId().equals(excludeId)) { + throw exception(STATION_PRICE_DUPLICATE); + } + } +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/record/HydrogenRecordService.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/record/HydrogenRecordService.java new file mode 100644 index 0000000..75a359f --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/record/HydrogenRecordService.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.energy.service.record; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.record.vo.HydrogenRecordImportVO; +import cn.iocoder.yudao.module.energy.controller.admin.record.vo.HydrogenRecordPageReqVO; +import cn.iocoder.yudao.module.energy.controller.admin.record.vo.HydrogenRecordSaveReqVO; +import cn.iocoder.yudao.module.energy.dal.dataobject.record.EnergyHydrogenRecordDO; +import java.util.List; +import java.util.Map; + +public interface HydrogenRecordService { + Long createRecord(HydrogenRecordSaveReqVO createReqVO); + void updateRecord(HydrogenRecordSaveReqVO updateReqVO); + void deleteRecord(Long id); + EnergyHydrogenRecordDO getRecord(Long id); + PageResult getRecordPage(HydrogenRecordPageReqVO pageReqVO); + Map importRecords(Long stationId, List list, String batchNo); + void matchRecord(Long id, Long vehicleId, Long customerId); +} diff --git a/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/record/HydrogenRecordServiceImpl.java b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/record/HydrogenRecordServiceImpl.java new file mode 100644 index 0000000..2ee0328 --- /dev/null +++ b/yudao-module-energy/yudao-module-energy-server/src/main/java/cn/iocoder/yudao/module/energy/service/record/HydrogenRecordServiceImpl.java @@ -0,0 +1,129 @@ +package cn.iocoder.yudao.module.energy.service.record; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.energy.controller.admin.record.vo.HydrogenRecordImportVO; +import cn.iocoder.yudao.module.energy.controller.admin.record.vo.HydrogenRecordPageReqVO; +import cn.iocoder.yudao.module.energy.controller.admin.record.vo.HydrogenRecordSaveReqVO; +import cn.iocoder.yudao.module.energy.convert.record.HydrogenRecordConvert; +import cn.iocoder.yudao.module.energy.dal.dataobject.record.EnergyHydrogenRecordDO; +import cn.iocoder.yudao.module.energy.dal.mysql.record.EnergyHydrogenRecordMapper; +import cn.iocoder.yudao.module.energy.enums.MatchStatusEnum; +import cn.iocoder.yudao.module.energy.enums.SourceTypeEnum; +import cn.iocoder.yudao.module.energy.event.RecordImportedEvent; +import cn.iocoder.yudao.module.energy.event.RecordMatchedEvent; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import java.util.*; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.energy.enums.ErrorCodeConstants.*; + +@Service +@Validated +@Slf4j +public class HydrogenRecordServiceImpl implements HydrogenRecordService { + + @Resource + private EnergyHydrogenRecordMapper hydrogenRecordMapper; + @Resource + private ApplicationEventPublisher eventPublisher; + + @Override + public Long createRecord(HydrogenRecordSaveReqVO createReqVO) { + EnergyHydrogenRecordDO record = HydrogenRecordConvert.INSTANCE.convert(createReqVO); + record.setSourceType(SourceTypeEnum.WEB.getType()); + record.setMatchStatus(MatchStatusEnum.UNMATCHED.getStatus()); + hydrogenRecordMapper.insert(record); + return record.getId(); + } + + @Override + public void updateRecord(HydrogenRecordSaveReqVO updateReqVO) { + validateRecordExists(updateReqVO.getId()); + EnergyHydrogenRecordDO updateObj = HydrogenRecordConvert.INSTANCE.convert(updateReqVO); + hydrogenRecordMapper.updateById(updateObj); + } + + @Override + public void deleteRecord(Long id) { + validateRecordExists(id); + hydrogenRecordMapper.deleteById(id); + } + + @Override + public EnergyHydrogenRecordDO getRecord(Long id) { + return hydrogenRecordMapper.selectById(id); + } + + @Override + public PageResult getRecordPage(HydrogenRecordPageReqVO pageReqVO) { + return hydrogenRecordMapper.selectPage(pageReqVO); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Map importRecords(Long stationId, List list, String batchNo) { + if (list == null || list.isEmpty()) { + throw exception(HYDROGEN_RECORD_IMPORT_EMPTY); + } + int successCount = 0; + int failCount = 0; + List recordIds = new ArrayList<>(); + for (HydrogenRecordImportVO importVO : list) { + try { + EnergyHydrogenRecordDO record = EnergyHydrogenRecordDO.builder() + .stationId(stationId) + .plateNumber(importVO.getPlateNumber()) + .hydrogenDate(importVO.getHydrogenDate()) + .hydrogenQuantity(importVO.getHydrogenQuantity()) + .unitPrice(importVO.getUnitPrice()) + .amount(importVO.getAmount()) + .mileage(importVO.getMileage()) + .sourceType(SourceTypeEnum.EXCEL.getType()) + .matchStatus(MatchStatusEnum.UNMATCHED.getStatus()) + .uploadBatchNo(batchNo) + .build(); + hydrogenRecordMapper.insert(record); + recordIds.add(record.getId()); + successCount++; + } catch (Exception e) { + log.warn("[importRecords] Failed to import record: {}", importVO, e); + failCount++; + } + } + // Publish event + if (!recordIds.isEmpty()) { + eventPublisher.publishEvent(new RecordImportedEvent(stationId, recordIds, batchNo)); + } + Map result = new HashMap<>(); + result.put("success", successCount); + result.put("fail", failCount); + return result; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void matchRecord(Long id, Long vehicleId, Long customerId) { + EnergyHydrogenRecordDO record = validateRecordExists(id); + hydrogenRecordMapper.updateById(EnergyHydrogenRecordDO.builder() + .id(id) + .vehicleId(vehicleId) + .customerId(customerId) + .matchStatus(MatchStatusEnum.MATCHED.getStatus()) + .build()); + // Publish event + eventPublisher.publishEvent(new RecordMatchedEvent(id, record.getStationId(), vehicleId, customerId, record.getPlateNumber())); + } + + private EnergyHydrogenRecordDO validateRecordExists(Long id) { + EnergyHydrogenRecordDO record = hydrogenRecordMapper.selectById(id); + if (record == null) { + throw exception(HYDROGEN_RECORD_NOT_EXISTS); + } + return record; + } +}