feat(energy): 新增 cooperation_type 和 auto_match 字段,标记旧导入接口废弃
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
3
sql/energy/energy_alter_frontend.sql
Normal file
3
sql/energy/energy_alter_frontend.sql
Normal file
@@ -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;
|
||||
23
yudao-module-energy/pom.xml
Normal file
23
yudao-module-energy/pom.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>yudao-module-energy</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>能源账单模块,包含加氢记录、费用明细、账单管理、账户管理等功能</description>
|
||||
<url>https://github.com/YunaiV/yudao-cloud</url>
|
||||
|
||||
<modules>
|
||||
<module>yudao-module-energy-api</module>
|
||||
<module>yudao-module-energy-server</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
39
yudao-module-energy/yudao-module-energy-api/pom.xml
Normal file
39
yudao-module-energy/yudao-module-energy-api/pom.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yudao-module-energy</artifactId>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>yudao-module-energy-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>能源账单 API,定义枚举、错误码等</description>
|
||||
<url>https://github.com/YunaiV/yudao-cloud</url>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-web</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 参数校验 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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, "该站点配置已存在");
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* 能源账单 API 模块,定义枚举、错误码等
|
||||
*/
|
||||
package cn.iocoder.yudao.module.energy;
|
||||
132
yudao-module-energy/yudao-module-energy-server/pom.xml
Normal file
132
yudao-module-energy/yudao-module-energy-server/pom.xml
Normal file
@@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yudao-module-energy</artifactId>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>yudao-module-energy-server</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>能源账单业务实现</description>
|
||||
<url>https://github.com/YunaiV/yudao-cloud</url>
|
||||
|
||||
<dependencies>
|
||||
<!-- 环境配置 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-env</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 能源账单 API -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-module-energy-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 系统模块 API -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-module-system-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 基础设施模块 API -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-module-infra-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Cloud 基础 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- RPC 远程调用相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-rpc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Registry 注册中心相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Config 配置中心相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Job 定时任务相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-job</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 消息队列相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-mq</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test 测试相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-excel</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- 设置构建的 jar 包名 -->
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -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<PageResult<EnergyAccountRespVO>> getAccountPage(@Valid EnergyAccountPageReqVO pageReqVO) {
|
||||
PageResult<EnergyAccountDO> 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<EnergyAccountRespVO> 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<Boolean> 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<Boolean> 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<List<EnergyProjectAccountRespVO>> getProjectAccountList(@RequestParam("accountId") Long accountId) {
|
||||
List<EnergyProjectAccountDO> 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<PageResult<EnergyAccountFlowDO>> getFlowPage(@Valid EnergyAccountFlowPageReqVO pageReqVO) {
|
||||
return success(accountService.getFlowPage(pageReqVO));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<PageResult<EnergyBillRespVO>> getBillPage(@Valid EnergyBillPageReqVO pageReqVO) {
|
||||
PageResult<EnergyBillDO> 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<EnergyBillRespVO> 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<Long> generateBill(@Valid @RequestBody EnergyBillGenerateReqVO reqVO) {
|
||||
return success(billService.generateBill(reqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/batch-generate")
|
||||
@Operation(summary = "批量生成账单")
|
||||
@PreAuthorize("@ss.hasPermission('energy:bill:create')")
|
||||
public CommonResult<List<Long>> batchGenerateBills(@Valid @RequestBody List<EnergyBillGenerateReqVO> reqVOs) {
|
||||
return success(billService.batchGenerateBills(reqVOs));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新账单")
|
||||
@PreAuthorize("@ss.hasPermission('energy:bill:update')")
|
||||
public CommonResult<Boolean> updateBill(@Valid @RequestBody EnergyBillSaveReqVO reqVO) {
|
||||
billService.updateBill(reqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/audit")
|
||||
@Operation(summary = "审核账单")
|
||||
@PreAuthorize("@ss.hasPermission('energy:bill:audit')")
|
||||
public CommonResult<Boolean> 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<Boolean> deleteBill(@RequestParam("id") Long id) {
|
||||
billService.deleteBill(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/adjustment/create")
|
||||
@Operation(summary = "创建调整行")
|
||||
@PreAuthorize("@ss.hasPermission('energy:bill:update')")
|
||||
public CommonResult<Long> 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<Boolean> deleteAdjustment(@RequestParam("id") Long id) {
|
||||
billService.deleteAdjustment(id);
|
||||
return success(true);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<Long> createConfig(@Valid @RequestBody EnergyStationConfigSaveReqVO createReqVO) {
|
||||
return success(stationConfigService.createConfig(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新站点配置")
|
||||
@PreAuthorize("@ss.hasPermission('energy:station-config:update')")
|
||||
public CommonResult<Boolean> 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<EnergyStationConfigRespVO> 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<PageResult<EnergyStationConfigRespVO>> getConfigPage(@Valid EnergyStationConfigPageReqVO pageReqVO) {
|
||||
PageResult<EnergyStationConfigDO> pageResult = stationConfigService.getConfigPage(pageReqVO);
|
||||
return success(EnergyStationConfigConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<PageResult<HydrogenDetailRespVO>> getDetailPage(@Valid HydrogenDetailPageReqVO pageReqVO) {
|
||||
PageResult<EnergyHydrogenDetailDO> 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<HydrogenDetailRespVO> 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<Boolean> updateDetail(@Valid @RequestBody HydrogenDetailSaveReqVO reqVO) {
|
||||
hydrogenDetailService.updateDetail(reqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/audit")
|
||||
@Operation(summary = "审核明细")
|
||||
@PreAuthorize("@ss.hasPermission('energy:hydrogen-detail:audit')")
|
||||
public CommonResult<Boolean> 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<Boolean> batchAuditDetail(@RequestParam("ids") List<Long> ids,
|
||||
@RequestParam("approved") Boolean approved,
|
||||
@RequestParam(value = "remark", required = false) String remark) {
|
||||
hydrogenDetailService.batchAudit(ids, approved, remark);
|
||||
return success(true);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<Long> createPrice(@Valid @RequestBody EnergyStationPriceSaveReqVO createReqVO) {
|
||||
return success(stationPriceService.createPrice(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新价格")
|
||||
@PreAuthorize("@ss.hasPermission('energy:station-price:update')")
|
||||
public CommonResult<Boolean> 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<Boolean> 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<EnergyStationPriceRespVO> 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<PageResult<EnergyStationPriceRespVO>> getPricePage(@Valid EnergyStationPricePageReqVO pageReqVO) {
|
||||
PageResult<EnergyStationPriceDO> pageResult = stationPriceService.getPricePage(pageReqVO);
|
||||
return success(EnergyStationPriceConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
@GetMapping("/get-effective")
|
||||
@Operation(summary = "获取生效价格")
|
||||
@PreAuthorize("@ss.hasPermission('energy:station-price:query')")
|
||||
public CommonResult<EnergyStationPriceRespVO> 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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<Long> createRecord(@Valid @RequestBody HydrogenRecordSaveReqVO createReqVO) {
|
||||
return success(hydrogenRecordService.createRecord(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新加氢记录")
|
||||
@PreAuthorize("@ss.hasPermission('energy:hydrogen-record:update')")
|
||||
public CommonResult<Boolean> 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<Boolean> 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<HydrogenRecordRespVO> 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<PageResult<HydrogenRecordRespVO>> getRecordPage(@Valid HydrogenRecordPageReqVO pageReqVO) {
|
||||
PageResult<EnergyHydrogenRecordDO> 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<Map<String, Integer>> importExcel(
|
||||
@RequestParam("stationId") Long stationId,
|
||||
@RequestParam("file") MultipartFile file) throws Exception {
|
||||
List<HydrogenRecordImportVO> list = ExcelUtils.read(file, HydrogenRecordImportVO.class);
|
||||
String batchNo = generateBatchNo();
|
||||
Map<String, Integer> result = hydrogenRecordService.importRecords(stationId, list, batchNo);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
@PutMapping("/match")
|
||||
@Operation(summary = "手动匹配车辆")
|
||||
@PreAuthorize("@ss.hasPermission('energy:hydrogen-record:update')")
|
||||
public CommonResult<Boolean> 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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<EnergyAccountRespVO> convertPage(PageResult<EnergyAccountDO> page);
|
||||
EnergyProjectAccountRespVO convert(EnergyProjectAccountDO bean);
|
||||
PageResult<EnergyProjectAccountRespVO> convertProjectPage(PageResult<EnergyProjectAccountDO> page);
|
||||
}
|
||||
@@ -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<EnergyBillRespVO> convertPage(PageResult<EnergyBillDO> page);
|
||||
}
|
||||
@@ -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<EnergyStationConfigRespVO> convertPage(PageResult<EnergyStationConfigDO> page);
|
||||
}
|
||||
@@ -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<HydrogenDetailRespVO> convertPage(PageResult<EnergyHydrogenDetailDO> page);
|
||||
}
|
||||
@@ -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<EnergyStationPriceRespVO> convertPage(PageResult<EnergyStationPriceDO> page);
|
||||
}
|
||||
@@ -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<HydrogenRecordRespVO> convertPage(PageResult<EnergyHydrogenRecordDO> page);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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<EnergyAccountFlowDO> {
|
||||
|
||||
default PageResult<EnergyAccountFlowDO> selectPage(EnergyAccountFlowPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<EnergyAccountFlowDO>()
|
||||
.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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<EnergyAccountDO> {
|
||||
|
||||
default EnergyAccountDO selectByCustomerId(Long customerId) {
|
||||
return selectOne(EnergyAccountDO::getCustomerId, customerId);
|
||||
}
|
||||
|
||||
default PageResult<EnergyAccountDO> selectPage(EnergyAccountPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<EnergyAccountDO>()
|
||||
.eqIfPresent(EnergyAccountDO::getCustomerId, reqVO.getCustomerId())
|
||||
.eqIfPresent(EnergyAccountDO::getAccountStatus, reqVO.getAccountStatus())
|
||||
.orderByDesc(EnergyAccountDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<EnergyProjectAccountDO> {
|
||||
|
||||
default EnergyProjectAccountDO selectByContractId(Long contractId) {
|
||||
return selectOne(EnergyProjectAccountDO::getContractId, contractId);
|
||||
}
|
||||
|
||||
default List<EnergyProjectAccountDO> selectListByAccountId(Long accountId) {
|
||||
return selectList(new LambdaQueryWrapperX<EnergyProjectAccountDO>()
|
||||
.eq(EnergyProjectAccountDO::getAccountId, accountId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<EnergyBillAdjustmentDO> {
|
||||
|
||||
default List<EnergyBillAdjustmentDO> selectListByBillId(Long billId) {
|
||||
return selectList(new LambdaQueryWrapperX<EnergyBillAdjustmentDO>()
|
||||
.eq(EnergyBillAdjustmentDO::getBillId, billId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<EnergyBillDO> {
|
||||
|
||||
default PageResult<EnergyBillDO> selectPage(EnergyBillPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<EnergyBillDO>()
|
||||
.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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<EnergyStationConfigDO> {
|
||||
|
||||
default EnergyStationConfigDO selectByStationId(Long stationId) {
|
||||
return selectOne(EnergyStationConfigDO::getStationId, stationId);
|
||||
}
|
||||
|
||||
default PageResult<EnergyStationConfigDO> selectPage(EnergyStationConfigPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<EnergyStationConfigDO>()
|
||||
.eqIfPresent(EnergyStationConfigDO::getStationId, reqVO.getStationId())
|
||||
.eqIfPresent(EnergyStationConfigDO::getAutoDeduct, reqVO.getAutoDeduct())
|
||||
.eqIfPresent(EnergyStationConfigDO::getCooperationType, reqVO.getCooperationType())
|
||||
.orderByDesc(EnergyStationConfigDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<EnergyHydrogenDetailDO> {
|
||||
|
||||
default PageResult<EnergyHydrogenDetailDO> selectPage(HydrogenDetailPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<EnergyHydrogenDetailDO>()
|
||||
.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<EnergyHydrogenDetailDO> selectListByBillId(Long billId) {
|
||||
return selectList(new LambdaQueryWrapperX<EnergyHydrogenDetailDO>()
|
||||
.eq(EnergyHydrogenDetailDO::getBillId, billId));
|
||||
}
|
||||
|
||||
default List<EnergyHydrogenDetailDO> selectUnbilledByCondition(Long customerId, Long contractId, Long stationId, LocalDate startDate, LocalDate endDate) {
|
||||
return selectList(new LambdaQueryWrapperX<EnergyHydrogenDetailDO>()
|
||||
.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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<EnergyStationPriceDO> {
|
||||
|
||||
default PageResult<EnergyStationPriceDO> selectPage(EnergyStationPricePageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<EnergyStationPriceDO>()
|
||||
.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<EnergyStationPriceDO>()
|
||||
.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"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<EnergyHydrogenRecordDO> {
|
||||
|
||||
default PageResult<EnergyHydrogenRecordDO> selectPage(HydrogenRecordPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<EnergyHydrogenRecordDO>()
|
||||
.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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Long> detailIds;
|
||||
}
|
||||
@@ -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<Long> detailIds;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<Long> recordIds;
|
||||
private final String batchNo;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
|
||||
// Swagger 接口文档
|
||||
registry.requestMatchers("/v3/api-docs/**").permitAll()
|
||||
.requestMatchers("/webjars/**").permitAll()
|
||||
.requestMatchers("/swagger-ui").permitAll()
|
||||
.requestMatchers("/swagger-ui/**").permitAll();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<EnergyAccountDO> normalAccounts = accountMapper.selectList(new LambdaQueryWrapperX<EnergyAccountDO>()
|
||||
.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<EnergyAccountDO> abnormalAccounts = accountMapper.selectList(new LambdaQueryWrapperX<EnergyAccountDO>()
|
||||
.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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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<EnergyAccountDO> getAccountPage(EnergyAccountPageReqVO reqVO);
|
||||
EnergyAccountDO getAccount(Long id);
|
||||
EnergyAccountDO getOrCreateByCustomerId(Long customerId);
|
||||
EnergyProjectAccountDO getOrCreateByContractId(Long accountId, Long contractId, String projectName);
|
||||
List<EnergyProjectAccountDO> 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<EnergyAccountFlowDO> getFlowPage(EnergyAccountFlowPageReqVO reqVO);
|
||||
}
|
||||
@@ -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<EnergyAccountDO> 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<EnergyProjectAccountDO> 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<EnergyAccountDO>()
|
||||
.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<EnergyAccountDO>()
|
||||
.set(EnergyAccountDO::getReminderThreshold, threshold)
|
||||
.eq(EnergyAccountDO::getId, id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<EnergyAccountFlowDO> 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<EnergyAccountDO> wrapper = new LambdaUpdateWrapper<EnergyAccountDO>()
|
||||
.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<EnergyProjectAccountDO> wrapper = new LambdaUpdateWrapper<EnergyProjectAccountDO>()
|
||||
.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<EnergyAccountDO>()
|
||||
.set(EnergyAccountDO::getAccountStatus, newStatus)
|
||||
.eq(EnergyAccountDO::getId, accountId));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Long> batchGenerateBills(List<EnergyBillGenerateReqVO> reqVOs);
|
||||
PageResult<EnergyBillDO> 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);
|
||||
}
|
||||
@@ -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<EnergyHydrogenDetailDO> 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<Long> detailIds = details.stream().map(EnergyHydrogenDetailDO::getId).toList();
|
||||
eventPublisher.publishEvent(new BillCreatedEvent(bill.getId(), detailIds));
|
||||
|
||||
return bill.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<Long> batchGenerateBills(List<EnergyBillGenerateReqVO> reqVOs) {
|
||||
List<Long> 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<EnergyBillDO> 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<EnergyHydrogenDetailDO> details = detailMapper.selectListByBillId(id);
|
||||
List<Long> 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();
|
||||
}
|
||||
}
|
||||
@@ -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<EnergyStationConfigDO> getConfigPage(EnergyStationConfigPageReqVO pageReqVO);
|
||||
EnergyStationConfigDO getByStationId(Long stationId);
|
||||
}
|
||||
@@ -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<EnergyStationConfigDO> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<EnergyHydrogenDetailDO> getDetailPage(HydrogenDetailPageReqVO pageReqVO);
|
||||
EnergyHydrogenDetailDO getDetail(Long id);
|
||||
void audit(Long id, Boolean approved, String remark);
|
||||
void batchAudit(List<Long> ids, Boolean approved, String remark);
|
||||
void updateDeductionStatus(Long detailId, Integer status);
|
||||
void updateBillId(List<Long> detailIds, Long billId);
|
||||
void updateSettlementStatus(List<Long> detailIds, Integer status);
|
||||
}
|
||||
@@ -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<EnergyHydrogenDetailDO> 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<EnergyHydrogenDetailDO>()
|
||||
.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<Long> 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<EnergyHydrogenDetailDO>()
|
||||
.set(EnergyHydrogenDetailDO::getDeductionStatus, status)
|
||||
.eq(EnergyHydrogenDetailDO::getId, detailId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBillId(List<Long> detailIds, Long billId) {
|
||||
if (detailIds == null || detailIds.isEmpty()) return;
|
||||
detailMapper.update(null, new LambdaUpdateWrapper<EnergyHydrogenDetailDO>()
|
||||
.set(EnergyHydrogenDetailDO::getBillId, billId)
|
||||
.in(EnergyHydrogenDetailDO::getId, detailIds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSettlementStatus(List<Long> detailIds, Integer status) {
|
||||
if (detailIds == null || detailIds.isEmpty()) return;
|
||||
detailMapper.update(null, new LambdaUpdateWrapper<EnergyHydrogenDetailDO>()
|
||||
.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;
|
||||
}
|
||||
}
|
||||
@@ -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<EnergyStationPriceDO> getPricePage(EnergyStationPricePageReqVO pageReqVO);
|
||||
EnergyStationPriceDO getEffectivePrice(Long stationId, Long customerId, LocalDate date);
|
||||
}
|
||||
@@ -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<EnergyStationPriceDO> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user