diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 58593ed..b0702df 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -6,18 +6,23 @@ + + + + - - + + + \ No newline at end of file diff --git a/base-commons/common-core/pom.xml b/base-commons/common-core/pom.xml index e62e974..622723c 100644 --- a/base-commons/common-core/pom.xml +++ b/base-commons/common-core/pom.xml @@ -28,7 +28,10 @@ org.hibernate.validator hibernate-validator - + + org.apache.poi + poi-ooxml + org.springframework diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/Dto/ResultUtil.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/Dto/ResultUtil.java index fda5c54..37b4cec 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/Dto/ResultUtil.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/Dto/ResultUtil.java @@ -22,4 +22,8 @@ public class ResultUtil { log.error("当前请求出现异常{}", result.getMsg()); return null; } + + public static Boolean verifyCode(Result result){ + return CodeMsg.SUCCESS.getCode().equals(result.getCode()); + } } diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/Dto/order/OrderBillListVo.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/Dto/order/OrderBillListVo.java new file mode 100644 index 0000000..9bdbae7 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/Dto/order/OrderBillListVo.java @@ -0,0 +1,77 @@ +package com.evotech.hd.common.core.Dto.order; + +import com.evotech.hd.common.core.excel.Excel; +import com.evotech.hd.common.core.utils.Collections; +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * 类 + * + * @ClassName:OrderListVo + * @date: 2025年05月16日 13:54 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Data +@Schema(name = "电子账单") +public class OrderBillListVo { + /*** + * 结算总金额 + */ + @Schema(description = "订单总额") + Double orderTotalAmount; + /*** + * 站点名称 + */ + @Schema(description = "站点名称") + @Excel(name="站点名称") + String stationName; + /*** + * 车牌号 + */ + @Schema(description = "车牌号") + @Excel(name="车牌号") + String plateNum; + /*** + * 换电人 + */ + @Schema(description = "换电人") + @Excel(name="换电人") + String preName; + + /*** + * 换电次数 + */ + @Schema(description = "换电次数") + Integer orderNum; + /*** + * 换电时间 + */ + @Schema(description = "换电时间") + @Excel(name="换电时间", dateFormat ="yyyy-MM-dd HH:mm:ss") + Date orderTime; + /*** + * 订单金额 + */ + @Schema(description = "订单金额") + Integer orderAmount; + + @Excel(name="订单金额", isStatistics = true) + @JsonIgnore + Double orderAmountExcel; + /*** + * 订单状态 + */ + @Schema(description = "订单状态") + Integer status; + @Schema(description = "换电订单详情") + List childList = Collections.emptyList();; + + +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java index c7b1423..d4143cb 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/constant/HDConstant.java @@ -6,12 +6,14 @@ public interface HDConstant { * 全局删除标识-已删除 */ final static Integer DELETE_YES = 1; - /*** * 全局删除标识-未删除 */ final static Integer DELETE_NO = 0; + final static String PUBLIC_KEY="public_key"; + final static String PRIVATE_KEY="private_key"; + /*** * 大华设备相关CONSTANT */ diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/cloud/OrderDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/cloud/OrderDao.java index d46eeac..4b8b260 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/cloud/OrderDao.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/cloud/OrderDao.java @@ -43,4 +43,6 @@ public interface OrderDao extends BaseMapper { Double homeFindOrderAmountData(@Param("date") Date date); List findOrderListByStatus(@Param("status") Integer status); + + List findBillList(@Param("companyCode") String companyCode, @Param("orderTimeEnd")String orderTimeEnd); } diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/cloud/OrderSwapBatteryDao.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/cloud/OrderSwapBatteryDao.java index dc65d99..33d8281 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/cloud/OrderSwapBatteryDao.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/dao/cloud/OrderSwapBatteryDao.java @@ -1,38 +1,32 @@ -//package com.evotech.hd.common.core.dao.cloud; -// -//import com.baomidou.mybatisplus.core.mapper.BaseMapper; -//import com.evotech.hd.common.core.Dto.request.HomeRequestDto; -//import com.evotech.hd.common.core.Dto.result.home.*; -//import com.evotech.hd.common.core.constant.HDConstant; -//import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery; -//import com.evotech.hd.common.core.permission.DataScope; -//import com.evotech.hd.common.core.permission.DataScopes; -//import org.apache.ibatis.annotations.Param; -// -//import java.util.Date; -//import java.util.List; -// -///** -// * @author zrb -// * @since 2024-11-22 -// */ -//@DataScopes({ -// @DataScope(permissionObject = HDConstant.OPERATOR_ROLE_CODE, permissionScopeName = "station_code", permissionScopeRedisKey = HDConstant.PermissionConstant.PERMISSION_STATION_CODE), -// @DataScope(permissionObject = HDConstant.COMPANY_ROLE_CODE, permissionScopeName = "plate_num", permissionScopeRedisKey = HDConstant.PermissionConstant.PERMISSION_CAR_CODE), -//}) -////@DataScopeOpenMethod(openMethod = true, methodName = {"homeFindHalfYearAmountData"}) -//public interface OrderSwapBatteryDao extends BaseMapper { -// +package com.evotech.hd.common.core.dao.cloud; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery; +import com.evotech.hd.common.core.permission.DataScope; +import com.evotech.hd.common.core.permission.DataScopes; + +/** + * @author zrb + * @since 2024-11-22 + */ +@DataScopes({ + @DataScope(permissionObject = HDConstant.OPERATOR_ROLE_CODE, permissionScopeName = "station_code", permissionScopeRedisKey = HDConstant.PermissionConstant.PERMISSION_STATION_CODE), + @DataScope(permissionObject = HDConstant.COMPANY_ROLE_CODE, permissionScopeName = "plate_num", permissionScopeRedisKey = HDConstant.PermissionConstant.PERMISSION_CAR_CODE), +}) +//@DataScopeOpenMethod(openMethod = true, methodName = {"homeFindHalfYearAmountData"}) +public interface OrderSwapBatteryDao extends BaseMapper { + // // List homeFindProportionData(@Param("params") HomeRequestDto params); // // List homeFindAmountData(@Param("params") HomeRequestDto params); // // List homeFindHalfYearOrderData(@Param("params") HomeRequestDto params); -// -//// @DataScope(permissionObject = HDConstant.OPERATOR_ROLE_CODE, tableAlias = "osb", permissionScopeName = "station_code", permissionScopeRedisKey = HDConstant.PermissionConstant.PERMISSION_STATION_CODE) + +// @DataScope(permissionObject = HDConstant.OPERATOR_ROLE_CODE, tableAlias = "osb", permissionScopeName = "station_code", permissionScopeRedisKey = HDConstant.PermissionConstant.PERMISSION_STATION_CODE) // List homeFindHalfYearAmountData(@Param("params") HomeRequestDto params); -// //因为站端不需要显示金额, 所有重新写一个 + //因为站端不需要显示金额, 所有重新写一个 // List homeFindHalfYearStationAmountData(@Param("params") HomeRequestDto params); // // Long homeFindOrderCountData(@Param("date") Date date); @@ -40,4 +34,4 @@ // Double homeFindOrderAmountData(@Param("date") Date date); // // List findOrderListByStatus(@Param("status") Integer status); -//} +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java index 7102857..3441a39 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStation.java @@ -57,6 +57,10 @@ public class BatteryStation extends BaseEntity implements Serializable { @Schema(description = "地址-区县") private String addressArea; + @Schema(description = "区划编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "区划编码不能为空") + private String divisionNo; + @Schema(description = "注册日期") private String registerDate; diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDc.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDc.java index 86905fc..635f578 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDc.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/BatteryStationDc.java @@ -70,7 +70,7 @@ public class BatteryStationDc extends BaseEntity implements Serializable { private Integer soc; @Schema(description = "电池仓位号") - private Integer dccNo; + private String dccNo; @Schema(description = "删除标志:1-已删除,0-未删除", hidden = true) private Integer delFlag; diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBattery.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBattery.java index 45f1ef1..56fa6c2 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBattery.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/OrderSwapBattery.java @@ -1,162 +1,162 @@ -//package com.evotech.hd.common.core.entity.cloud; -// -//import com.baomidou.mybatisplus.annotation.TableField; -//import com.baomidou.mybatisplus.annotation.TableName; -//import com.evotech.hd.common.core.entity.BaseEntity; -//import com.fasterxml.jackson.annotation.JsonFormat; -//import io.swagger.v3.oas.annotations.media.Schema; -//import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -//import jakarta.validation.constraints.NotBlank; -//import jakarta.validation.constraints.NotNull; -//import lombok.Data; -//import org.springframework.format.annotation.DateTimeFormat; -// -//import java.io.Serializable; -//import java.math.BigDecimal; -//import java.util.Date; -// -///** -// * @author zrb -// * @since 2024-11-22 -// */ -//@Data -//@TableName("hd_cloud_manage.yt_t_order_swap_battery") -//@Schema(name = "换电订单信息表") -//public class OrderSwapBattery extends BaseEntity implements Serializable { -// -// private static final long serialVersionUID = 1L; -// -// @Schema(description = "预约订单ID") -// private Integer orderPreId; -// -// @Schema(description = "预约用户") -// private String orderPreUid; -// -// @Schema(description = "预约用户名称") -// private String orderPreUname; -// -// @Schema(description = "预约用户手机") -// private String orderPrePhone; -// -// @Schema(description = "类型:1-换电,2-充电", requiredMode = RequiredMode.REQUIRED) -// @NotNull(message = "订单类型不能为空") -// private Integer orderType; -// -// @Schema(description = "订单编码", hidden = true) -// private String orderNo; -// -// @Schema(description = "车牌号", requiredMode = RequiredMode.REQUIRED) -// @NotBlank(message = "车牌号不能为空") -// private String plateNum; -// -// @Schema(description = "订单时间", example = "yyyy-MM-dd HH:mm:ss") -// @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") -// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") -// private Date orderTime; -// -// @Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED) -// @NotBlank(message = "换电站编码不能为空") -// private String stationCode; -// -// @Schema(description = "换电站名称", requiredMode = RequiredMode.REQUIRED) -// @NotBlank(message = "换电站名称不能为空") -// private String stationName; -// -// @Schema(description = "金额账号") -// private String accountCode; -// -// @Schema(description = "订单金额") -// private Integer amount; -// -// @Schema(description = "订单状态:1-已创建,2-换电中,3-换电完成,4-充电中,5-充电完成,6-待结算,7-已完成,9-已取消, -1-退款") -// private Integer status; -// -// @Schema(description = "计算费用方式:1-ODO,2-SOC,3-按电量") -// private Integer feeType; -// -// @Schema(description = "基础费用") -// private BigDecimal basicFee; -// -// @Schema(description = "服务开始时间") -// @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") -// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") -// private Date serviceTimeBegin; -// -// @Schema(description = "服务结束时间") -// @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") -// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") -// private Date serviceTimeEnd; -// -// @Schema(description = "服务费") -// private BigDecimal serviceFee; -// -// @Schema(description = "费用标准") -// private String feeStandardJson; -// @Schema(description = "费用标准详情") -// @TableField(exist = false) -// private BatteryStationHdFeeStandard feeStandardDetail; -// -// @Schema(description = "上次租赁电池时车辆里程") -// private BigDecimal lastRentBatCarOdo; -// -// @Schema(description = "归还电池时车辆里程") -// private BigDecimal nowReturnBatCarOdo; -// -// @Schema(description = "按ODO换电费") -// private BigDecimal odoAmount; -// -// @Schema(description = "充电开始时间") -// @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") -// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") -// private Date chargeTimeBegin; -// -// @Schema(description = "充电结束时间") -// @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") -// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") -// private Date chargeTimeEnd; -// -// @Schema(description = "总充电量") -// private BigDecimal electAmount; -// -// @Schema(description = "租借电池包仓位") -// private Integer rentBatNo; -// -// @Schema(description = "租用电池包编码") -// private String rentBatCode; -// -// @Schema(description = "租用电池包SOC") -// private Integer rentBatSoc; -// -// @Schema(description = "归还电池包编码") -// private String returnBatCode; -// -// @Schema(description = "归还电池包仓位") -// private Integer returnBatNo; -// -// @Schema(description = "归还电池包SOC") -// private Integer returnBatSoc; -// -// @Schema(description = "归还电池租出时soc") -// private Integer returnBatRentSoc; -// -// @Schema(description = "归还电池租出的换电站编码") -// private String returnBatRentStationCode; -// -// @Schema(description = "归还电池租出的换电站") -// private String returnBatRentStationName; -// -// @Schema(description = "换电模式:1-全自动,2-半自动,3-人工干预 ") -// private Integer changeMode; -// -// @Schema(description = "换电车道 1-A 车道;2-B 车道") -// private Integer changeLane; -// -// @Schema(description = "删除状态:1-已删除,0-未删除", hidden = true) -// private Integer delFlag; -// -// @Schema(description = "交易编码", hidden = true) -// private String tradeNo; -// -// @Schema(description = "备注信息") -// private String remark; -//} +package com.evotech.hd.common.core.entity.cloud; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.evotech.hd.common.core.entity.BaseEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * @author zrb + * @since 2024-11-22 + */ +@Data +@TableName("hd_cloud_manage.yt_t_order_swap_battery") +@Schema(name = "换电订单信息表") +public class OrderSwapBattery extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "预约订单ID") + private Integer orderPreId; + + @Schema(description = "预约用户") + private String orderPreUid; + + @Schema(description = "预约用户名称") + private String orderPreUname; + + @Schema(description = "预约用户手机") + private String orderPrePhone; + + @Schema(description = "类型:1-换电,2-充电", requiredMode = RequiredMode.REQUIRED) + @NotNull(message = "订单类型不能为空") + private Integer orderType; + + @Schema(description = "订单编码", hidden = true) + private String orderNo; + + @Schema(description = "车牌号", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "车牌号不能为空") + private String plateNum; + + @Schema(description = "订单时间", example = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date orderTime; + + @Schema(description = "换电站编码", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "换电站编码不能为空") + private String stationCode; + + @Schema(description = "换电站名称", requiredMode = RequiredMode.REQUIRED) + @NotBlank(message = "换电站名称不能为空") + private String stationName; + + @Schema(description = "金额账号") + private String accountCode; + + @Schema(description = "订单金额") + private Integer amount; + + @Schema(description = "订单状态:1-已创建,2-换电中,3-换电完成,4-充电中,5-充电完成,6-待结算,7-已完成,9-已取消, -1-退款") + private Integer status; + + @Schema(description = "计算费用方式:1-ODO,2-SOC,3-按电量") + private Integer feeType; + + @Schema(description = "基础费用") + private BigDecimal basicFee; + + @Schema(description = "服务开始时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date serviceTimeBegin; + + @Schema(description = "服务结束时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date serviceTimeEnd; + + @Schema(description = "服务费") + private BigDecimal serviceFee; + + @Schema(description = "费用标准") + private String feeStandardJson; + @Schema(description = "费用标准详情") + @TableField(exist = false) + private BatteryStationHdFeeStandard feeStandardDetail; + + @Schema(description = "上次租赁电池时车辆里程") + private BigDecimal lastRentBatCarOdo; + + @Schema(description = "归还电池时车辆里程") + private BigDecimal nowReturnBatCarOdo; + + @Schema(description = "按ODO换电费") + private BigDecimal odoAmount; + + @Schema(description = "充电开始时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date chargeTimeBegin; + + @Schema(description = "充电结束时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") + private Date chargeTimeEnd; + + @Schema(description = "总充电量") + private BigDecimal electAmount; + + @Schema(description = "租借电池包仓位") + private Integer rentBatNo; + + @Schema(description = "租用电池包编码") + private String rentBatCode; + + @Schema(description = "租用电池包SOC") + private Integer rentBatSoc; + + @Schema(description = "归还电池包编码") + private String returnBatCode; + + @Schema(description = "归还电池包仓位") + private Integer returnBatNo; + + @Schema(description = "归还电池包SOC") + private Integer returnBatSoc; + + @Schema(description = "归还电池租出时soc") + private Integer returnBatRentSoc; + + @Schema(description = "归还电池租出的换电站编码") + private String returnBatRentStationCode; + + @Schema(description = "归还电池租出的换电站") + private String returnBatRentStationName; + + @Schema(description = "换电模式:1-全自动,2-半自动,3-人工干预 ") + private Integer changeMode; + + @Schema(description = "换电车道 1-A 车道;2-B 车道") + private Integer changeLane; + + @Schema(description = "删除状态:1-已删除,0-未删除", hidden = true) + private Integer delFlag; + + @Schema(description = "交易编码", hidden = true) + private String tradeNo; + + @Schema(description = "备注信息") + private String remark; +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/TradeDetail.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/TradeDetail.java index 1073ec7..d5f4fe2 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/TradeDetail.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/TradeDetail.java @@ -24,6 +24,9 @@ public class TradeDetail extends BaseEntity implements Serializable { @Schema(description = "换电站编码") private String stationCode; + @Schema(description = "交易人微信Id") + private String plateCompanyCode; + @Schema(description = "交易人name") private String trader; @@ -36,7 +39,7 @@ public class TradeDetail extends BaseEntity implements Serializable { @Schema(description = "交易类型:1-充值,2-订单消费,3-退款, 9-提现") private Integer tradeType; - @Schema(description = "支付方式:1-账户余额,2-微信,3-支付宝,4-网银,5 -充电补偿") + @Schema(description = "支付方式:1-账户余额,2-微信,3-支付宝,4-网银,5 -充电补偿, 6-公对公转账") private Integer payType; @Schema(description = "微信支付API类型") private String wechatPayApiType; @@ -68,7 +71,7 @@ public class TradeDetail extends BaseEntity implements Serializable { @Schema(description = "微信支付订单号") private String transactionId; - @Schema(description = "支付结果,暂用微信结果的枚举类型") + @Schema(description = "支付结果,暂用微信结果的枚举类型, 新增 paymentInProgress 结算中类型") private String payResult; @Schema(description = "付款人编码,对于个人账户,交易发起人和付款人一般是同一人。公司账户交易发起人是公司,付款人可能是 微信账户") @@ -94,8 +97,8 @@ public class TradeDetail extends BaseEntity implements Serializable { @Schema(description = "订单总描述") private String description; - - + @Schema(description = "状态: edit-编辑中, submit-提交. finish-完成, reject-打回") + private String status; // @Schema(description = "在微信等支付网关创建支付订单时失败,返回的失败原因") diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/request/PageListWalletRequest.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/request/PageListWalletRequest.java index 3ef79ce..104348a 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/request/PageListWalletRequest.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/cloud/request/PageListWalletRequest.java @@ -28,4 +28,7 @@ public class PageListWalletRequest extends BasePageRequest { @Schema(description = "引入站点") private String stationCode; + @Schema(description = "客户电话") + private String phone; + } diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/order/BaseOrder.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/order/BaseOrder.java index 2899da9..7a9fc96 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/order/BaseOrder.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/entity/order/BaseOrder.java @@ -56,4 +56,8 @@ public class BaseOrder extends IdEntity { * 支付的回调信息 */ private String notifyInfo; + /*** + * 交易编码 + */ + private String tradeNo; } diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/OrderStatusEnums.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/OrderStatusEnums.java index fc5e2ac..5d65657 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/OrderStatusEnums.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/OrderStatusEnums.java @@ -16,6 +16,8 @@ public enum OrderStatusEnums implements BaseEnum { FINISH(7, "已完成"), + SETTLEMENT_IN_PROGRESS(8, "结算中"), + CANCLE(9, "已取消"), REFUND(-1, "订单退款"), diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/PayTypeEnums.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/PayTypeEnums.java index 5e2f0bd..d3a1d19 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/PayTypeEnums.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/PayTypeEnums.java @@ -9,6 +9,9 @@ public enum PayTypeEnums { ALIPAY(3, "支付宝"), BANK(4, "网银"), + CHARGING_COMPENSATION(5, "充电补偿"), + + BUSINESS_TO_BUSINESS(6, "公对公"), OTHER(9, "其他"); diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/SwapBatteryStepEnum.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/SwapBatteryStepEnum.java index c973df0..55f7b39 100644 --- a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/SwapBatteryStepEnum.java +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/enums/SwapBatteryStepEnum.java @@ -18,13 +18,13 @@ public enum SwapBatteryStepEnum implements BaseEnum{ INSTITUTIONS_FOR_CHINA(3, "对中机构"), - GET_NEW_ELECTRICITY(4, "取新电"), + DISMANTLE_OLD_ELECTRICITY(4, "拆旧电"), - DISMANTLE_OLD_ELECTRICITY(5, "拆旧电"), + DISCHARGE_OLD_ELECTRICITY(5, "放旧电"), - INSTALL_NEW_ELECTRICITY(6, "装新电"), + GET_NEW_ELECTRICITY(6, "取新电"), - DISCHARGE_OLD_ELECTRICITY(7, "放旧电"), + INSTALL_NEW_ELECTRICITY(7, "装新电"), COMPLETED(8, "完成"), diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/Excel.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/Excel.java new file mode 100644 index 0000000..1fb39fa --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/Excel.java @@ -0,0 +1,203 @@ +package com.evotech.hd.common.core.excel; + +import com.evotech.hd.common.core.excel.handler.ExcelFieldHandlerAdapter; +import com.evotech.hd.common.core.excel.handler.ExcelHandlerAdapter; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.math.BigDecimal; + +/** + * 自定义导出Excel数据注解 + * + * @author evo + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel +{ + /** + * 导出时在excel中排序 + */ + public int sort() default Integer.MAX_VALUE; + + /** + * 导出到Excel中的名字. + */ + public String name() default ""; + + /** + * 日期格式, 如: yyyy-MM-dd + */ + public String dateFormat() default ""; + + /** + * 如果是字典类型,请设置字典的type值 (如: sys_user_sex) + */ + public String dictType() default ""; + + /** + * 读取内容转表达式 (如: 0=男,1=女,2=未知) + */ + public String readConverterExp() default ""; + + /** + * 分隔符,读取字符串组内容 + */ + public String separator() default ","; + + /** + * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) + */ + public int scale() default -1; + + /** + * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN + */ + public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; + + /** + * 导出时在excel中每个列的高度 + */ + public double height() default 14; + + /** + * 导出时在excel中每个列的宽度 + */ + public double width() default 16; + + /** + * 文字后缀,如% 90 变成90% + */ + public String suffix() default ""; + + /** + * 当值为空时,字段的默认值 + */ + public String defaultValue() default ""; + + /** + * 提示信息 + */ + public String prompt() default ""; + + /** + * 设置只能选择不能输入的列内容. + */ + public String[] combo() default {}; + + /** + * 是否从字典读数据到combo,默认不读取,如读取需要设置dictType注解. + */ + public boolean comboReadDict() default false; + + /** + * 是否需要纵向合并单元格,应对需求:含有list集合单元格) + */ + public boolean needMerge() default false; + + /** + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. + */ + public boolean isExport() default true; + + /** + * 另一个类中的属性名称,支持多级获取,以小数点隔开 + */ + public String targetAttr() default ""; + + /** + * 是否自动统计数据,在最后追加一行统计数据总和 + */ + public boolean isStatistics() default false; + + /** + * 导出类型(0数字 1字符串 2图片) + */ + public ColumnType cellType() default ColumnType.STRING; + + /** + * 导出列头背景颜色 + */ + public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT; + + /** + * 导出列头字体颜色 + */ + public IndexedColors headerColor() default IndexedColors.WHITE; + + /** + * 导出单元格背景颜色 + */ + public IndexedColors backgroundColor() default IndexedColors.WHITE; + + /** + * 导出单元格字体颜色 + */ + public IndexedColors color() default IndexedColors.BLACK; + + /** + * 导出字段对齐方式 + */ + public HorizontalAlignment align() default HorizontalAlignment.CENTER; + + /** + * 自定义数据处理器 + */ + public Class handler() default ExcelHandlerAdapter.class; + + /** + * 自定义数据处理器 + */ + public boolean customExcelField() default false; + /** + * 自定义数据处理器 + */ + public Class excelFieldHandler() default ExcelFieldHandlerAdapter.class; + + /** + * 自定义数据处理器参数 + */ + public String[] args() default {}; + + /** + * 字段类型(0:导出导入;1:仅导出;2:仅导入) + */ + Type type() default Type.ALL; + + public enum Type + { + ALL(0), EXPORT(1), IMPORT(2); + private final int value; + + Type(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } + + public enum ColumnType + { + NUMERIC(0), STRING(1), IMAGE(2), TEXT(3); + private final int value; + + ColumnType(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/Excels.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/Excels.java new file mode 100644 index 0000000..57a9193 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/Excels.java @@ -0,0 +1,18 @@ +package com.evotech.hd.common.core.excel; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解集 + * + * @author evo + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels +{ + public Excel[] value(); +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/handler/ExcelFieldHandlerAdapter.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/handler/ExcelFieldHandlerAdapter.java new file mode 100644 index 0000000..1b71010 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/handler/ExcelFieldHandlerAdapter.java @@ -0,0 +1,17 @@ +package com.evotech.hd.common.core.excel.handler; + +import java.util.List; + +/** + * 特殊出具处理接口 + * + * @ClassName:ExcelFieldHandlerAdapter + * @date: 2025年07月12日 10:40 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +public interface ExcelFieldHandlerAdapter { + + List buildExcel(); +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/handler/ExcelHandlerAdapter.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/handler/ExcelHandlerAdapter.java new file mode 100644 index 0000000..1ba3ed0 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/excel/handler/ExcelHandlerAdapter.java @@ -0,0 +1,24 @@ +package com.evotech.hd.common.core.excel.handler; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Workbook; + +/** + * Excel数据格式处理适配器 + * + * @author evo + */ +public interface ExcelHandlerAdapter +{ + /** + * 格式化 + * + * @param value 单元格数据值 + * @param args excel注解args参数组 + * @param cell 单元格对象 + * @param wb 工作簿对象 + * + * @return 处理后的值 + */ + Object format(Object value, String[] args, Cell cell, Workbook wb); +} diff --git a/base-commons/common-core/src/main/java/com/evotech/hd/common/core/utils/DataUtils.java b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/utils/DataUtils.java new file mode 100644 index 0000000..ff716d4 --- /dev/null +++ b/base-commons/common-core/src/main/java/com/evotech/hd/common/core/utils/DataUtils.java @@ -0,0 +1,30 @@ +package com.evotech.hd.common.core.utils; + + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; + +import java.math.BigDecimal; + +/** + * 类 + * + * @ClassName:DataUtils + * @date: 2025年06月03日 10:25 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +public class DataUtils { + + public static final BigDecimal DEFAULT_VALUE = new BigDecimal(0); + + + public static T findDefaultValue(T v, T dv){ + if(ObjectUtils.isNotEmpty(v)){ + return v; + } + return dv; + } + +} diff --git a/cloud-manage-server/pom.xml b/cloud-manage-server/pom.xml index ef61e5f..35dba84 100644 --- a/cloud-manage-server/pom.xml +++ b/cloud-manage-server/pom.xml @@ -41,7 +41,7 @@ org.springframework.cloud spring-cloud-starter-openfeign - + org.springframework.boot spring-boot-starter-integration diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/CloudManageServerApplication.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/CloudManageServerApplication.java index 8d7a1b2..dce8d37 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/CloudManageServerApplication.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/CloudManageServerApplication.java @@ -3,13 +3,15 @@ package com.evotech.hd.cloud; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableScheduling; -@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, MongoAutoConfiguration.class, MongoDataAutoConfiguration.class}) @EnableDiscoveryClient @ComponentScan("com.evotech.hd.**") @MapperScan({"com.evotech.hd.cloud.dao.**", "com.evotech.hd.common.core.dao.**"}) diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderPerController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderPerController.java index d69560e..9b7f92c 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderPerController.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderPerController.java @@ -55,7 +55,7 @@ public class OrderPerController { @PostMapping("/cancel") @ApiOperationSupport(order = 2) public Result cancelPre(@NotNull Integer id) { - return orderSwapBatteryPreService.cancelPre(id, 3); + return orderSwapBatteryPreService.updateStatusById(id, 3); } diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderSwapBatteryController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderSwapBatteryController.java index 0c8ce5a..17b3778 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderSwapBatteryController.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/OrderSwapBatteryController.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.evotech.hd.cloud.entity.vo.NativePayVO; import com.evotech.hd.cloud.service.OrderService; import com.evotech.hd.common.core.Dto.Result; +import com.evotech.hd.common.core.Dto.order.OrderBillListVo; import com.evotech.hd.common.core.Dto.order.OrderDetailVo; import com.evotech.hd.common.core.Dto.order.OrderListVo; import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryStep; @@ -83,22 +84,13 @@ public class OrderSwapBatteryController { +// @Operation(summary = "公司订单扫码支付") +// @PostMapping({"/wechat/nativepay"}) +// @ApiOperationSupport(order = 13) +// public Result companyNativePay(@RequestBody NativePayVO prePay) { +// return orderService.companyNativePay(prePay); +// } - @Operation(summary = "公司订单余额支付") - @PostMapping({"/companywallet/pay"}) - @ApiOperationSupport(order = 12) - public Result companyWalletPay(@RequestParam String orderNo, String wuid, String uname) { - // TODO - return null; - } - - - @Operation(summary = "公司订单扫码支付") - @PostMapping({"/wechat/nativepay"}) - @ApiOperationSupport(order = 13) - public Result companyNativePay(@RequestBody NativePayVO prePay) { - return orderService.companyNativePay(prePay); - } @Operation(summary = "扫码支付订单查询状态") @GetMapping("/paystatus/query") @@ -141,4 +133,27 @@ public class OrderSwapBatteryController { return orderService.one(orderNo); } + + @Operation(summary = "电子对账单") + @GetMapping("/bill/list") + @ApiOperationSupport(order = 6) + public Result> billList(String companyCode, String orderTimeEnd) { + return orderService.billList(companyCode, orderTimeEnd); + } + + @Operation(summary = "下载电子对账单") + @PostMapping("/bill/download") + @ApiOperationSupport(order = 6) + public void billDownload(String companyCode, String orderTimeEnd) { + orderService.excelBillList(companyCode, orderTimeEnd); + } + + + + @Operation(summary = "公司订单扫码支付") + @PostMapping({"/wechat/nativepay"}) + @ApiOperationSupport(order = 13) + public Result companyNativePay(@RequestBody NativePayVO prePay) { + return orderService.companyNativePay(prePay); + } } diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/TradeController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/TradeController.java index 5b33c9a..310fdef 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/TradeController.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/order/TradeController.java @@ -50,6 +50,20 @@ public class TradeController { public Result update(@ParameterObject TradeDetail td) { return tradeService.update(td); } + + @Operation(summary = "提交") + @PostMapping({"/submit"}) + @ApiOperationSupport(order = 3) + public Result submit(@ParameterObject TradeDetail td) { + return tradeService.submit(td); + } + + @Operation(summary = "审核") + @PostMapping({"/approve"}) + @ApiOperationSupport(order = 3) + public Result approve(Integer id, @RequestParam Integer type) { + return tradeService.approve(id,type); + } @Operation(summary = "查询") @GetMapping("/list") diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/test/TestController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/test/TestController.java index fbf0c57..ffd321d 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/test/TestController.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/controller/test/TestController.java @@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.evotech.hd.cloud.dao.BatteryStationDao; import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao; import com.evotech.hd.cloud.dao.VehicleWechatUserRelationDao; @@ -13,20 +14,27 @@ import com.evotech.hd.cloud.mqtt.message.MessageTopic; import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader; import com.evotech.hd.cloud.mqtt.message.processor.strategy.MqttStrategyExchangeProcessor; import com.evotech.hd.cloud.mqtt.message.processor.strategy.impl.state.MqttStateChargingDataExchangeProcessor; +import com.evotech.hd.cloud.service.OrderService; import com.evotech.hd.cloud.service.TradeService; import com.evotech.hd.cloud.utils.components.SwapOrderBasicFeeComponent; import com.evotech.hd.common.core.Dto.Result; import com.evotech.hd.common.core.dao.cloud.OrderDao; import com.evotech.hd.common.core.dao.cloud.OrderDetailDao; +import com.evotech.hd.common.core.dao.cloud.OrderSwapBatteryDao; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBattery; +import com.evotech.hd.common.core.entity.order.Order; +import com.evotech.hd.common.core.entity.order.OrderDetail; import com.evotech.hd.common.core.utils.Collections; +import com.evotech.hd.common.core.utils.DataUtils; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import io.swagger.v3.oas.annotations.Operation; import jakarta.annotation.Resource; -import org.apache.commons.lang3.ObjectUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.web.bind.annotation.*; -import java.math.BigDecimal; import java.util.Date; +import java.util.List; import java.util.Map; /** @@ -54,11 +62,13 @@ public class TestController { private ApplicationContext applicationContext; @Resource TradeService tradeService; + @Resource + OrderService orderService; // @Resource // MongoDBService mongoDBService; -// @Resource -// private OrderSwapBatteryDao orderSwapBatteryDao; + @Resource + private OrderSwapBatteryDao orderSwapBatteryDao; @Autowired private OrderDao orderDao; @Autowired @@ -184,58 +194,1386 @@ public class TestController { return new Result().success(DHRequestUtil.storeList(page, pageSize)); } + @Operation(summary = "下载电子对账单") + @GetMapping("/bill/download") + @ApiOperationSupport(order = 6) + public void billDownload(String companyCode) { + orderService.excelBillList(companyCode, ""); + } + @GetMapping("/copy/order") public Result copyOrder(@RequestParam String stationCode) { -// for (OrderSwapBattery orderSwapBattery : orderSwapBatteryDao.selectList(new LambdaQueryWrapper().eq(OrderSwapBattery::getStationCode, stationCode))){ -// Order order = new Order(); -// order.setStationCode(orderSwapBattery.getStationCode()); -// order.setStationName(orderSwapBattery.getStationName()); -// order.setOrderNo(orderSwapBattery.getOrderNo()); -// order.setOrderPreId(orderSwapBattery.getOrderPreId()); -// order.setPreWechatId(orderSwapBattery.getOrderPreUid()); -// order.setOrderPreUname(orderSwapBattery.getOrderPreUname()); -// order.setPlateNum(orderSwapBattery.getPlateNum()); -// order.setOrderTime(orderSwapBattery.getOrderTime()); -// order.setOrderType(orderSwapBattery.getOrderType()); -// order.setStatus(orderSwapBattery.getStatus()); -// order.setDelFlag(orderSwapBattery.getDelFlag()); -// order.setOrderAmount(orderSwapBattery.getAmount()); -// orderDao.insert(order); -// -// OrderDetail detail = new OrderDetail(); -// detail.setOrderId(order.getPkId()); -// detail.setFeeType(orderSwapBattery.getFeeType()); -// detail.setOrderFee(findDefaultValue(orderSwapBattery.getBasicFee(), DEFAULT_VALUE).intValue()); -// detail.setServiceFee(findDefaultValue(orderSwapBattery.getServiceFee(), DEFAULT_VALUE).intValue()); -// detail.setServiceTimeBegin(orderSwapBattery.getServiceTimeBegin()); -// detail.setServiceTimeEnd(orderSwapBattery.getServiceTimeEnd()); -// detail.setOrderTimeBegin(orderSwapBattery.getServiceTimeBegin()); -// detail.setOrderTimeEnd(orderSwapBattery.getServiceTimeEnd()); -// detail.setFeeStandard(orderSwapBattery.getFeeStandardJson()); -// detail.setElectricityQuantity(findDefaultValue(orderSwapBattery.getElectAmount(), DEFAULT_VALUE).doubleValue()); -// detail.setRentBatNo(String.valueOf(orderSwapBattery.getRentBatNo())); -// detail.setRentBatNo(String.valueOf(orderSwapBattery.getRentBatNo())); -// detail.setRentBatCode(String.valueOf(orderSwapBattery.getRentBatCode())); -// detail.setRentBatSoc(Double.valueOf(findDefaultValue(orderSwapBattery.getRentBatSoc(),0))); -// -// detail.setReturnBatNo(String.valueOf(orderSwapBattery.getReturnBatNo())); -// detail.setReturnBatCode(String.valueOf(orderSwapBattery.getReturnBatCode())); -// detail.setReturnBatSoc(Double.valueOf(findDefaultValue(orderSwapBattery.getReturnBatSoc(),0))); -// detail.setChangeMode(orderSwapBattery.getChangeMode()); -// detail.setChangeLane(orderSwapBattery.getChangeLane()); -// orderDetailDao.insert(detail); -// } + for (OrderSwapBattery orderSwapBattery : orderSwapBatteryDao.selectList(new LambdaQueryWrapper().eq(OrderSwapBattery::getStationCode, stationCode))){ + Order order = new Order(); + order.setStationCode(orderSwapBattery.getStationCode()); + order.setStationName(orderSwapBattery.getStationName()); + order.setOrderNo(orderSwapBattery.getOrderNo()); + order.setOrderPreId(orderSwapBattery.getOrderPreId()); + order.setPreWechatId(orderSwapBattery.getOrderPreUid()); + order.setOrderPreUname(orderSwapBattery.getOrderPreUname()); + order.setPlateNum(orderSwapBattery.getPlateNum()); + order.setOrderTime(orderSwapBattery.getOrderTime()); + order.setOrderType(orderSwapBattery.getOrderType()); + order.setStatus(orderSwapBattery.getStatus()); + order.setDelFlag(orderSwapBattery.getDelFlag()); + order.setOrderAmount(orderSwapBattery.getAmount()); + orderDao.insert(order); + + OrderDetail detail = new OrderDetail(); + detail.setOrderId(order.getPkId()); + detail.setFeeType(orderSwapBattery.getFeeType()); + detail.setOrderFee(DataUtils.findDefaultValue(orderSwapBattery.getBasicFee(), DataUtils.DEFAULT_VALUE).intValue()); + detail.setServiceFee(DataUtils.findDefaultValue(orderSwapBattery.getServiceFee(), DataUtils.DEFAULT_VALUE).intValue()); + detail.setServiceTimeBegin(orderSwapBattery.getServiceTimeBegin()); + detail.setServiceTimeEnd(orderSwapBattery.getServiceTimeEnd()); + detail.setOrderTimeBegin(orderSwapBattery.getServiceTimeBegin()); + detail.setOrderTimeEnd(orderSwapBattery.getServiceTimeEnd()); + detail.setFeeStandard(orderSwapBattery.getFeeStandardJson()); + detail.setElectricityQuantity(DataUtils.findDefaultValue(orderSwapBattery.getElectAmount(), DataUtils.DEFAULT_VALUE).doubleValue()); + detail.setRentBatNo(String.valueOf(orderSwapBattery.getRentBatNo())); + detail.setRentBatNo(String.valueOf(orderSwapBattery.getRentBatNo())); + detail.setRentBatCode(String.valueOf(orderSwapBattery.getRentBatCode())); + detail.setRentBatSoc(Double.valueOf(DataUtils.findDefaultValue(orderSwapBattery.getRentBatSoc(),0))); + + detail.setReturnBatNo(String.valueOf(orderSwapBattery.getReturnBatNo())); + detail.setReturnBatCode(String.valueOf(orderSwapBattery.getReturnBatCode())); + detail.setReturnBatSoc(Double.valueOf(DataUtils.findDefaultValue(orderSwapBattery.getReturnBatSoc(),0))); + detail.setChangeMode(orderSwapBattery.getChangeMode()); + detail.setChangeLane(orderSwapBattery.getChangeLane()); + orderDetailDao.insert(detail); + } return new Result().success("成功"); } - public static final BigDecimal DEFAULT_VALUE = new BigDecimal(0); - - - public static T findDefaultValue(T v, T dv){ - if(ObjectUtils.isNotEmpty(v)){ - return v; + public static void main(String[] args) { + String orders = "YTSON-DL-0032025052813563830787C,8;" + + "YTSON-DL-0032025052813563830787C,9;" + + "YTSON-DL-0032025052814191986870A,10;" + + "YTSON-DL-0032025052914525086211A,11;" + + "YTSON-DL-0032025053016082727972B,12;" + + "YTSON-DL-0032025053017292611182A,13;" + + "YTSON-DL-0032025052813563830787C,14;" + + "YTSON-DL-0032025052814191986870A,15;" + + "YTSON-DL-0032025052914525086211A,16;" + + "YTSON-DL-0032025053016082727972B,17;" + + "YTSON-DL-0032025053017292611182A,18;" + + "YTSON-DL-0032025060318381086505A,19;" + + "YTSON-DL-0032025060318475367795C,20;" + + "YTSON-DL-0032025060318581319490A,21;" + + "YTSON-DL-0032025060416152040496B,22;" + + "YTSON-DL-0032025060510480880521B,23;" + + "YTSON-DL-0032025060614535165597A,24;" + + "YTSON-DL-0032025060615304264910A,25;" + + "YTSON-DL-0032025060615563221221A,26;" + + "YTSON-DL-0032025060616225013049A,27;" + + "YTSON-DL-0032025060616371815254A,28;" + + "YTSON-DL-0032025060616464587053B,29;" + + "YTSON-DL-0032025060616534303633A,30;" + + "YTSON-DL-0032025061209000232209B,31;" + + "YTSON-DL-0032025061209065342120C,32;" + + "YTSON-DL-0032025061209103403562B,33;" + + "YTSON-DL-0032025061209140765869C,34;" + + "YTSON-DL-0032025061209173788054A,35;" + + "YTSON-DL-0032025061209464529086C,36;" + + "YTSON-DL-0032025061209501959843C,37;" + + "YTSON-DL-0032025061209540144860B,38;" + + "YTSON-DL-0032025061209574651930C,39;" + + "YTSON-DL-0032025061210013387730A,40;" + + "YTSON-DL-0032025061210052418642C,41;" + + "YTSON-DL-0032025061210091049142B,42;" + + "YTSON-DL-0032025061210124653861C,43;" + + "YTSON-DL-0032025061210161919848C,44;" + + "YTSON-DL-0032025061210200719896A,45;" + + "YTSON-DL-0032025061210233974969C,46;" + + "YTSON-DL-0032025061210271097567C,47;" + + "YTSON-DL-0032025061210304429887C,48;" + + "YTSON-DL-0032025061210341947652C,49;" + + "YTSON-DL-0032025061210375534422A,50;" + + "YTSON-DL-0032025061210413590211C,51;" + + "YTSON-DL-0032025061210450933151A,52;" + + "YTSON-DL-0032025061210484120666B,53;" + + "YTSON-DL-0032025061210521880597A,54;" + + "YTSON-DL-0032025061210555175219C,55;" + + "YTSON-DL-0032025061210593988683B,56;" + + "YTSON-DL-0032025061211060104365C,57;" + + "YTSON-DL-0032025061211093377694C,58;" + + "YTSON-DL-0032025061211130490912A,59;" + + "YTSON-DL-0032025061211164842433C,60;" + + "YTSON-DL-0032025061214400331542C,61;" + + "YTSON-DL-0032025061214433444865A,62;" + + "YTSON-DL-0032025061214474493400B,63;" + + "YTSON-DL-0032025061214513702179C,64;" + + "YTSON-DL-0032025061214551971838A,65;" + + "YTSON-DL-0032025061214585691354B,66;" + + "YTSON-DL-0032025061215023296203C,67;" + + "YTSON-DL-0032025061215061959272C,68;" + + "YTSON-DL-0032025061215100893834B,69;" + + "YTSON-DL-0032025061215135278677B,70;" + + "YTSON-DL-0032025061215172410771B,71;" + + "YTSON-DL-0032025061215205311423A,72;" + + "YTSON-DL-0032025061215243187416B,73;" + + "YTSON-DL-0032025061215275867945A,74;" + + "YTSON-DL-0032025061215312923792A,75;" + + "YTSON-DL-0032025061215350588775A,76;" + + "YTSON-DL-0032025061215383420718A,77;" + + "YTSON-DL-0032025061215421822108C,78;" + + "YTSON-DL-0032025061215455295346B,79;" + + "YTSON-DL-0032025061215492419641A,80;" + + "YTSON-DL-0032025061215525275901B,81;" + + "YTSON-DL-0032025061215562371923B,82;" + + "YTSON-DL-0032025061215595407997C,83;" + + "YTSON-DL-0032025061216032435792B,84;" + + "YTSON-DL-0032025061216065405763B,85;" + + "YTSON-DL-0032025061216102784606A,86;" + + "YTSON-DL-0032025061216135850871B,87;" + + "YTSON-DL-0032025061216173472239A,88;" + + "YTSON-DL-0032025061216210499659C,89;" + + "YTSON-DL-0032025061216244239782A,90;" + + "YTSON-DL-0032025061216282773687B,91;" + + "YTSON-DL-0032025061308565309199B,92;" + + "YTSON-DL-0032025061309003392191C,93;" + + "YTSON-DL-0032025061309040685991A,94;" + + "YTSON-DL-0032025061309074923705A,95;" + + "YTSON-DL-0032025061309114087247C,96;" + + "YTSON-DL-0032025061309151510014A,97;" + + "YTSON-DL-0032025061309170255959A,98;" + + "YTSON-DL-0032025061309205258683A,99;" + + "YTSON-DL-0032025061309242264238A,100;" + + "YTSON-DL-0032025061309275433028B,101;" + + "YTSON-DL-0032025061309312175786A,102;" + + "YTSON-DL-0032025061309345282254A,103;" + + "YTSON-DL-0032025061309382165541B,104;" + + "YTSON-DL-0032025061309415460657C,105;" + + "YTSON-DL-0032025061309452008754C,106;" + + "YTSON-DL-0032025061309533498416A,107;" + + "YTSON-DL-0032025061309565873248C,108;" + + "YTSON-DL-0032025061310002457556A,109;" + + "YTSON-DL-0032025061310040002463A,110;" + + "YTSON-DL-0032025061310073900230C,111;" + + "YTSON-DL-0032025061310110526991A,112;" + + "YTSON-DL-0032025061310143528866B,113;" + + "YTSON-DL-0032025061310180723400B,114;" + + "YTSON-DL-0032025061310214095626A,115;" + + "YTSON-DL-0032025061310252097790A,116;" + + "YTSON-DL-0032025061310284584622B,117;" + + "YTSON-DL-0032025061310321742723A,118;" + + "YTSON-DL-0032025061310354813559A,119;" + + "YTSON-DL-0032025061310410568931C,120;" + + "YTSON-DL-0032025061310443334553A,121;" + + "YTSON-DL-0032025061310480342055C,122;" + + "YTSON-DL-0032025061310513247600A,123;" + + "YTSON-DL-0032025061310551502028A,124;" + + "YTSON-DL-0032025061310584707372B,125;" + + "YTSON-DL-0032025061311021980039C,126;" + + "YTSON-DL-0032025061311055393584C,127;" + + "YTSON-DL-0032025061311092864354A,128;" + + "YTSON-DL-0032025061314393450255C,129;" + + "YTSON-DL-0032025061314431569212C,130;" + + "YTSON-DL-0032025061314464875586C,131;" + + "YTSON-DL-0032025061314501632911A,132;" + + "YTSON-DL-0032025061314534120487B,133;" + + "YTSON-DL-0032025061314570802788B,134;" + + "YTSON-DL-0032025061315003696391B,135;" + + "YTSON-DL-0032025061315040404138C,136;" + + "YTSON-DL-0032025061315072878596A,137;" + + "YTSON-DL-0032025061315105420913C,138;" + + "YTSON-DL-0032025061315142194191B,139;" + + "YTSON-DL-0032025061315175030025A,140;" + + "YTSON-DL-0032025061315211978831B,141;" + + "YTSON-DL-0032025061315244691834C,142;" + + "YTSON-DL-0032025061315281873564C,143;" + + "YTSON-DL-0032025061315314359003B,144;" + + "YTSON-DL-0032025061315351284222B,145;" + + "YTSON-DL-0032025061315383820188C,146;" + + "YTSON-DL-0032025061315420481599A,147;" + + "YTSON-DL-0032025061315453596806B,148;" + + "YTSON-DL-0032025061315490378302B,149;" + + "YTSON-DL-0032025061315522398385A,150;" + + "YTSON-DL-0032025061315555301759A,151;" + + "YTSON-DL-0032025061315591759772C,152;" + + "YTSON-DL-0032025061316024251570B,153;" + + "YTSON-DL-0032025061316060857263B,154;" + + "YTSON-DL-0032025061316093412885B,155;" + + "YTSON-DL-0032025061316130397526C,156;" + + "YTSON-DL-0032025061316171987896B,157;" + + "YTSON-DL-0032025061316204502230C,158;" + + "YTSON-DL-0032025061316241021656C,159;" + + "YTSON-DL-0032025061316273451167A,160;" + + "YTSON-DL-0032025061414123728800A,161;" + + "YTSON-DL-0032025061414160587656B,162;" + + "YTSON-DL-0032025061414192741367B,163;" + + "YTSON-DL-0032025061414230586830B,164;" + + "YTSON-DL-0032025061414292131382B,165;" + + "YTSON-DL-0032025061414324689788C,166;" + + "YTSON-DL-0032025061414361226698C,167;" + + "YTSON-DL-0032025061414412720539C,168;" + + "YTSON-DL-0032025061416023333988C,169;" + + "YTSON-DL-0032025061608402729007A,170;" + + "YTSON-DL-0032025061608435189183B,171;" + + "YTSON-DL-0032025061608571719917B,172;" + + "YTSON-DL-0032025061609004322504C,173;" + + "YTSON-DL-0032025061609041233797A,174;" + + "YTSON-DL-0032025061609074148701A,175;" + + "YTSON-DL-0032025061609110464981A,176;" + + "YTSON-DL-0032025061609144600277A,177;" + + "YTSON-DL-0032025061609190395948A,178;" + + "YTSON-DL-0032025061609222762377B,179;" + + "YTSON-DL-0032025061609260193318C,180;" + + "YTSON-DL-0032025061609292744730B,181;" + + "YTSON-DL-0032025061609330341288B,182;" + + "YTSON-DL-0032025061609363910734C,183;" + + "YTSON-DL-0032025061609400897521C,184;" + + "YTSON-DL-0032025061609434591067C,185;" + + "YTSON-DL-0032025061609471563873B,186;" + + "YTSON-DL-0032025061609504526960B,187;" + + "YTSON-DL-0032025061609541209980B,188;" + + "YTSON-DL-0032025061609573666353C,189;" + + "YTSON-DL-0032025061610010408465C,190;" + + "YTSON-DL-0032025061610043120251A,191;" + + "YTSON-DL-0032025061610073329246B,192;" + + "YTSON-DL-0032025061610105328089A,193;" + + "YTSON-DL-0032025061610142597256B,194;" + + "YTSON-DL-0032025061610175980594A,195;" + + "YTSON-DL-0032025061614355557231B,196;" + + "YTSON-DL-0032025061614393823092A,197;" + + "YTSON-DL-0032025061614432243310A,198;" + + "YTSON-DL-0032025061614464632613B,199;" + + "YTSON-DL-0032025061614513133045C,200;" + + "YTSON-DL-0032025061614550262880B,201;" + + "YTSON-DL-0032025061614582650091A,202;" + + "YTSON-DL-0032025061615015165986C,203;" + + "YTSON-DL-0032025061615051634706A,204;" + + "YTSON-DL-0032025061615083659861A,205;" + + "YTSON-DL-0032025061615120081603C,206;" + + "YTSON-DL-0032025061615152639770C,207;" + + "YTSON-DL-0032025061615185258181B,208;" + + "YTSON-DL-0032025061615221240303A,209;" + + "YTSON-DL-0032025061615253594447A,210;" + + "YTSON-DL-0032025061615323278365B,211;" + + "YTSON-DL-0032025061615355482583C,212;" + + "YTSON-DL-0032025061615391760239B,213;" + + "YTSON-DL-0032025061615424243493C,214;" + + "YTSON-DL-0032025061615460158588C,215;" + + "YTSON-DL-0032025061615492200068B,216;" + + "YTSON-DL-0032025061615524360881A,217;" + + "YTSON-DL-0032025061615560265130B,218;" + + "YTSON-DL-0032025061615592705478C,219;" + + "YTSON-DL-0032025061616025500679C,220;" + + "YTSON-DL-0032025061708370501384B,221;" + + "YTSON-DL-0032025061708403176682A,222;" + + "YTSON-DL-0032025061708431940081B,223;" + + "YTSON-DL-0032025061708464626311B,224;" + + "YTSON-DL-0032025061708501576398B,225;" + + "YTSON-DL-0032025061708534120985C,226;" + + "YTSON-DL-0032025061708570675963C,227;" + + "YTSON-DL-0032025061709003621278B,228;" + + "YTSON-DL-0032025061709040185869C,229;" + + "YTSON-DL-0032025061709072600346B,230;" + + "YTSON-DL-0032025061709105263462B,231;" + + "YTSON-DL-0032025062008504149794C,232;" + + "YTSON-DL-0032025062008543553945A,233;" + + "YTSON-DL-0032025062008580975531C,234;" + + "YTSON-DL-0032025062009013291761C,235;" + + "YTSON-DL-0032025062009045542648C,236;" + + "YTSON-DL-0032025062009082286392B,237;" + + "YTSON-DL-0032025062009121132841C,238;" + + "YTSON-DL-0032025062009451692987C,239;" + + "YTSON-DL-0032025062009484790748B,240;" + + "YTSON-DL-0032025062009520922512B,241;" + + "YTSON-DL-0032025062009553426884A,242;" + + "YTSON-DL-0032025062010001168932A,243;" + + "YTSON-DL-0032025062010040286637B,244;" + + "YTSON-DL-0032025062010073377996A,245;" + + "YTSON-DL-0032025062010105410033A,246;" + + "YTSON-DL-0032025062010141791581C,247;" + + "YTSON-DL-0032025062010182967982C,248;" + + "YTSON-DL-0032025062010220821278C,249;" + + "YTSON-DL-0032025062010285752027A,250;" + + "YTSON-DL-0032025062010322855854A,251;" + + "YTSON-DL-0032025062010355371937B,252;" + + "YTSON-DL-0032025062010393124259A,253;" + + "YTSON-DL-0032025062010425225707B,254;" + + "YTSON-DL-0032025062010462124479C,255;" + + "YTSON-DL-0032025062010494957367C,256;" + + "YTSON-DL-0032025062010531416344B,257;" + + "YTSON-DL-0032025062010563370683B,258;" + + "YTSON-DL-0032025062010595085684B,259;" + + "YTSON-DL-0032025062011030929798C,260;" + + "YTSON-DL-0032025062011063516240C,261;" + + "YTSON-DL-0032025062014394512621C,262;" + + "YTSON-DL-0032025062014430454877B,263;" + + "YTSON-DL-0032025062014462022901B,264;" + + "YTSON-DL-0032025062014494127108A,265;" + + "YTSON-DL-0032025062014534904395A,266;" + + "YTSON-DL-0032025062014570972085C,267;" + + "YTSON-DL-0032025062015005940406A,268;" + + "YTSON-DL-0032025062015042476570A,269;" + + "YTSON-DL-0032025062015074442542C,270;" + + "YTSON-DL-0032025062015110837800B,271;" + + "YTSON-DL-0032025062015145988917C,272;" + + "YTSON-DL-0032025062015182514924B,273;" + + "YTSON-DL-0032025062015213972816A,274;" + + "YTSON-DL-0032025062015250659172A,275;" + + "YTSON-DL-0032025062015331420870A,276;" + + "YTSON-DL-0032025062015363958428C,277;" + + "YTSON-DL-0032025062015400216033C,278;" + + "YTSON-DL-0032025062015431986927C,279;" + + "YTSON-DL-0032025062015464130005C,280;" + + "YTSON-DL-0032025062015500001190B,281;" + + "YTSON-DL-0032025062015532243157A,282;" + + "YTSON-DL-0032025062016060276618C,283;" + + "YTSON-DL-0032025062016093956556C,284;" + + "YTSON-DL-0032025062016125963020A,285;" + + "YTSON-DL-0032025062016163023222C,286;" + + "YTSON-DL-0032025062016195469040B,287;" + + "YTSON-DL-0032025062016231991731A,288;" + + "YTSON-DL-0032025062016263886945B,289;" + + "YTSON-DL-0032025062016300601343B,290;" + + "YTSON-DL-0032025062109393238311A,291;" + + "YTSON-DL-0032025062109424703740B,292;" + + "YTSON-DL-0032025062109461469570B,293;" + + "YTSON-DL-0032025062109533864818B,294;" + + "YTSON-DL-0032025062109570317195A,295;" + + "YTSON-DL-0032025062111000554467A,296;" + + "YTSON-DL-0032025062111032468666C,297;" + + "YTSON-DL-0032025062111071073337A,298;" + + "YTSON-DL-0032025062111102659129C,299;" + + "YTSON-DL-0032025062111134719983C,300;" + + "YTSON-DL-0032025062111170387262B,301;" + + "YTSON-DL-0032025062111202900076B,302;" + + "YTSON-DL-0032025062111234804092C,303;" + + "YTSON-DL-0032025062111270517832C,304;" + + "YTSON-DL-0032025062111302236716A,305;" + + "YTSON-DL-0032025062111335337486B,306;" + + "YTSON-DL-0032025062111371294878C,307;" + + "YTSON-DL-0032025062111403844666A,308;" + + "YTSON-DL-0032025062111435719789A,309;" + + "YTSON-DL-0032025062111471897742B,310;" + + "YTSON-DL-0032025062111565064380C,311;" + + "YTSON-DL-0032025062112000833869A,312;" + + "YTSON-DL-0032025062112344966339C,313;" + + "YTSON-DL-0032025062309200845356B,314;" + + "YTSON-DL-0032025062309233385746B,315;" + + "YTSON-DL-0032025062309270774445C,316;" + + "YTSON-DL-0032025062309302934748C,317;" + + "YTSON-DL-0032025062309335314056B,318;" + + "YTSON-DL-0032025062309372039970B,319;" + + "YTSON-DL-0032025062309404242931B,320;" + + "YTSON-DL-0032025062309440828128C,321;" + + "YTSON-DL-0032025062309472386908B,322;" + + "YTSON-DL-0032025062309503731165C,323;" + + "YTSON-DL-0032025062309535335710C,324;" + + "YTSON-DL-0032025062309571245914A,325;" + + "YTSON-DL-0032025062310003344717A,326;" + + "YTSON-DL-0032025062310060944178C,327;" + + "YTSON-DL-0032025062310093288557A,328;" + + "YTSON-DL-0032025062310125536910C,329;" + + "YTSON-DL-0032025062310162023829A,330;" + + "YTSON-DL-0032025062310193835587A,331;" + + "YTSON-DL-0032025062310225425843C,332;" + + "YTSON-DL-0032025062310262181728C,333;" + + "YTSON-DL-0032025062310294460834C,334;" + + "YTSON-DL-0032025062310330547378C,335;" + + "YTSON-DL-0032025062310362864868A,336;" + + "YTSON-DL-0032025062310400190506A,337;" + + "YTSON-DL-0032025062310433748839B,338;" + + "YTSON-DL-0032025062314150824847B,339;" + + "YTSON-DL-0032025062314182850296A,340;" + + "YTSON-DL-0032025062314214668582C,341;" + + "YTSON-DL-0032025062314251853756A,342;" + + "YTSON-DL-0032025062314290195456B,343;" + + "YTSON-DL-0032025062314340126340A,344;" + + "YTSON-DL-0032025062314430112086B,345;" + + "YTSON-DL-0032025062314461745562A,346;" + + "YTSON-DL-0032025062314494363174A,347;" + + "YTSON-DL-0032025062314530879566B,348;" + + "YTSON-DL-0032025062314562637094A,349;" + + "YTSON-DL-0032025062314594883665C,350;" + + "YTSON-DL-0032025062315031733556B,351;" + + "YTSON-DL-0032025062315064364081B,352;" + + "YTSON-DL-0032025062315100712957B,353;" + + "YTSON-DL-0032025062315133160296A,354;" + + "YTSON-DL-0032025062315165220680A,355;" + + "YTSON-DL-0032025062315200669861B,356;" + + "YTSON-DL-0032025062315232244194B,357;" + + "YTSON-DL-0032025062315264678852C,358;" + + "YTSON-DL-0032025062315301338468A,359;" + + "YTSON-DL-0032025062315333163927A,360;" + + "YTSON-DL-0032025062315364742429A,361;" + + "YTSON-DL-0032025062315400680103B,362;" + + "YTSON-DL-0032025062315433509626A,363;" + + "YTSON-DL-0032025062315465398230C,364;" + + "YTSON-DL-0032025062315503403096B,365;" + + "YTSON-DL-0032025062315535283727C,366;" + + "YTSON-DL-0032025062315571222774B,367;" + + "YTSON-DL-0032025062316032593410B,368;" + + "YTSON-DL-0032025062316064638587A,369;" + + "YTSON-DL-0032025062316100424551C,370;" + + "YTSON-DL-0032025062316132431497A,371;" + + "YTSON-DL-0032025062316164248184C,372;" + + "YTSON-DL-0032025062316200106037B,373;" + + "YTSON-DL-0032025062316232280605C,374;" + + "YTSON-DL-0032025062316264678726B,375;" + + "YTSON-DL-0032025062409042817119C,376;" + + "YTSON-DL-0032025062409074764791B,377;" + + "YTSON-DL-0032025062409105811331C,378;" + + "YTSON-DL-0032025062409141840308A,379;" + + "YTSON-DL-0032025062409173780177B,380;" + + "YTSON-DL-0032025062409205929150A,381;" + + "YTSON-DL-0032025062409242278260B,382;" + + "YTSON-DL-0032025062413113085105C,383;" + + "YTSON-DL-0032025062413145427160B,384;" + + "YTSON-DL-0032025062413181691386C,385;" + + "YTSON-DL-0032025062413213945184B,386;" + + "YTSON-DL-0032025062413251529835A,387;" + + "YTSON-DL-0032025062413283960615B,388;" + + "YTSON-DL-0032025062413320094294B,389;" + + "YTSON-DL-0032025062413353968266C,390;" + + "YTSON-DL-0032025062413390124087A,391;" + + "YTSON-DL-0032025062413423589559A,392;" + + "YTSON-DL-0032025062413460303640A,393;" + + "YTSON-DL-0032025062413492657425A,394;" + + "YTSON-DL-0032025062414012258434A,395;" + + "YTSON-DL-0032025062414045119432C,396;" + + "YTSON-DL-0032025062414225593979C,397;" + + "YTSON-DL-0032025062414261907521C,398;" + + "YTSON-DL-0032025062414294661528C,399;" + + "YTSON-DL-0032025062414333441387A,400;" + + "YTSON-DL-0032025062414365513772C,401;" + + "YTSON-DL-0032025062414404204128C,402;" + + "YTSON-DL-0032025062414440716676A,403;" + + "YTSON-DL-0032025062414473101528A,404;" + + "YTSON-DL-0032025062414505294626B,405;" + + "YTSON-DL-0032025062414542897579A,406;" + + "YTSON-DL-0032025062414575519112C,407;" + + "YTSON-DL-0032025062415011548403A,408;" + + "YTSON-DL-0032025062415044123680B,409;" + + "YTSON-DL-0032025062415080614601C,410;" + + "YTSON-DL-0032025062415112672843A,411;" + + "YTSON-DL-0032025062415145153027C,412;" + + "YTSON-DL-0032025062415181108551A,413;" + + "YTSON-DL-0032025062415215296721B,414;" + + "YTSON-DL-0032025062415251754404A,415;" + + "YTSON-DL-0032025062415284644442C,416;" + + "YTSON-DL-0032025062508421856647A,417;" + + "YTSON-DL-0032025062508454691102C,418;" + + "YTSON-DL-0032025062508493192020B,419;" + + "YTSON-DL-0032025062508525289543A,420;" + + "YTSON-DL-0032025062508561765829B,421;" + + "YTSON-DL-0032025062508593691854B,422;" + + "YTSON-DL-0032025062509025656571C,423;" + + "YTSON-DL-0032025062509061757041B,424;" + + "YTSON-DL-0032025062509093980361B,425;" + + "YTSON-DL-0032025062509154823471B,426;" + + "YTSON-DL-0032025062509190154798C,427;" + + "YTSON-DL-0032025062509222793180C,428;" + + "YTSON-DL-0032025062509254900919B,429;" + + "YTSON-DL-0032025062509290691773B,430;" + + "YTSON-DL-0032025062509323068812C,431;" + + "YTSON-DL-0032025062509355169564A,432;" + + "YTSON-DL-0032025062509394837563C,433;" + + "YTSON-DL-0032025062509431359536C,434;" + + "YTSON-DL-0032025062509463347612B,435;" + + "YTSON-DL-0032025062509495218890C,436;" + + "YTSON-DL-0032025062509531248409A,437;" + + "YTSON-DL-0032025062509563728606B,438;" + + "YTSON-DL-0032025062509595809742B,439;" + + "YTSON-DL-0032025062510033607659C,440;" + + "YTSON-DL-0032025062510055790273B,441;" + + "YTSON-DL-0032025062510092903493B,442;" + + "YTSON-DL-0032025062510124761186B,443;" + + "YTSON-DL-0032025062510160802224B,444;" + + "YTSON-DL-0032025062510221339148C,445;" + + "YTSON-DL-0032025062510252780415B,446;" + + "YTSON-DL-0032025062510290067375B,447;" + + "YTSON-DL-0032025062513474009831B,448;" + + "YTSON-DL-0032025062513510493456A,449;" + + "YTSON-DL-0032025062513542524495A,450;" + + "YTSON-DL-0032025062513574915039B,451;" + + "YTSON-DL-0032025062514011554392C,452;" + + "YTSON-DL-0032025062514043535279A,453;" + + "YTSON-DL-0032025062514075065394B,454;" + + "YTSON-DL-0032025062514113545946C,455;" + + "YTSON-DL-0032025062514145526616A,456;" + + "YTSON-DL-0032025062514181996202A,457;" + + "YTSON-DL-0032025062514214673572A,458;" + + "YTSON-DL-0032025062514252087370C,459;" + + "YTSON-DL-0032025062514284073036C,460;" + + "YTSON-DL-0032025062514320057529B,461;" + + "YTSON-DL-0032025062514351984564C,462;" + + "YTSON-DL-0032025062514384046156A,463;" + + "YTSON-DL-0032025062514422447852B,464;" + + "YTSON-DL-0032025062514454571409A,465;" + + "YTSON-DL-0032025062514490478970C,466;" + + "YTSON-DL-0032025062514522515312B,467;" + + "YTSON-DL-0032025062608463056523C,468;" + + "YTSON-DL-0032025062608495403760A,469;" + + "YTSON-DL-0032025062608550968243A,470;" + + "YTSON-DL-0032025062608582753043C,471;" + + "YTSON-DL-0032025062609015213502A,472;" + + "YTSON-DL-0032025062609051355992C,473;" + + "YTSON-DL-0032025062609084343147B,474;" + + "YTSON-DL-0032025062609120786260C,475;" + + "YTSON-DL-0032025062609152828223B,476;" + + "YTSON-DL-0032025062616024963998A,477;" + + "YTSON-DL-0032025062616062188821C,478;" + + "YTSON-DL-0032025062616094520575C,479;" + + "YTSON-DL-0032025062616131516042B,480;" + + "YTSON-DL-0032025062616163750280B,481;" + + "YTSON-DL-0032025062616195786194A,482;" + + "YTSON-DL-0032025062616231804818C,483;" + + "YTSON-DL-0032025062616264112397A,484;" + + "YTSON-DL-0032025062616300351371B,485;" + + "YTSON-DL-0032025062616332718645C,486;" + + "YTSON-DL-0032025062616365196610A,487;" + + "YTSON-DL-0032025062616402809195B,488;" + + "YTSON-DL-0032025062709060965220A,489;" + + "YTSON-DL-0032025062709090027992C,490;" + + "YTSON-DL-0032025062709385586452B,491;" + + "YTSON-DL-0032025062709422747161B,492;" + + "YTSON-DL-0032025062709455261995B,493;" + + "YTSON-DL-0032025062709484883477A,494;" + + "YTSON-DL-0032025062710111607067B,495;" + + "YTSON-DL-0032025062710144097859A,496;" + + "YTSON-DL-0032025062710180240976A,497;" + + "YTSON-DL-0032025062710212554919C,498;" + + "YTSON-DL-0032025062710244776537C,499;" + + "YTSON-DL-0032025062710281177265B,500;" + + "YTSON-DL-0032025062710313820935B,501;" + + "YTSON-DL-0032025062710350063862A,502;" + + "YTSON-DL-0032025062710382270498B,503;" + + "YTSON-DL-0032025062710421025754B,504;" + + "YTSON-DL-0032025062710453722760A,505;" + + "YTSON-DL-0032025062710490199919C,506;" + + "YTSON-DL-0032025062710522804190C,507;" + + "YTSON-DL-0032025062710555173293C,508;" + + "YTSON-DL-0032025062710591279398A,509;" + + "YTSON-DL-0032025062711024241564A,510;" + + "YTSON-DL-0032025062711060677103A,511;" + + "YTSON-DL-0032025062711093141793C,512;" + + "YTSON-DL-0032025062711125735847C,513;" + + "YTSON-DL-0032025062711162730339A,514;" + + "YTSON-DL-0032025062711195358154C,515;" + + "YTSON-DL-0032025062711231741986B,516;" + + "YTSON-DL-0032025062711273040684A,517;" + + "YTSON-DL-0032025062711312779910A,518;" + + "YTSON-DL-0032025062711345303634B,519;" + + "YTSON-DL-0032025062711381755062B,520;" + + "YTSON-DL-0032025062711414211153C,521;" + + "YTSON-DL-0032025062711450674629C,522;" + + "YTSON-DL-0032025062711482675313B,523;" + + "YTSON-DL-0032025062711514694404A,524;" + + "YTSON-DL-0032025062711551247820B,525;" + + "YTSON-DL-0032025062809343726677B,526;" + + "YTSON-DL-0032025062809381002126A,527;" + + "YTSON-DL-0032025062809413285398B,528;" + + "YTSON-DL-0032025062809445870682B,529;" + + "YTSON-DL-0032025062809482398305B,530;" + + "YTSON-DL-0032025062809514476014C,531;" + + "YTSON-DL-0032025062809550698603A,532;" + + "YTSON-DL-0032025062809582963251B,533;" + + "YTSON-DL-0032025062810015477839A,534;" + + "YTSON-DL-0032025062810053044170B,535;" + + "YTSON-DL-0032025062810085378988A,536;" + + "YTSON-DL-0032025062810121603050A,537;" + + "YTSON-DL-0032025062810154083220C,538;" + + "YTSON-DL-0032025062810190097555B,539;" + + "YTSON-DL-0032025062810222565477A,540;" + + "YTSON-DL-0032025062810255007226B,541;" + + "YTSON-DL-0032025062810291526285C,542;" + + "YTSON-DL-0032025062810324620340B,543;" + + "YTSON-DL-0032025062810361824448C,544;" + + "YTSON-DL-0032025062810400369362A,545;" + + "YTSON-DL-0032025062810432688746A,546;" + + "YTSON-DL-0032025062810465510787A,547;" + + "YTSON-DL-0032025062810502124038B,548;" + + "YTSON-DL-0032025062810583043394A,549;" + + "YTSON-DL-0032025062811015648000B,550;" + + "YTSON-DL-0032025062811052553843A,551;" + + "YTSON-DL-0032025062811090531783B,552;" + + "YTSON-DL-0032025062811122542218A,553;" + + "YTSON-DL-0032025062811194046821C,554;" + + "YTSON-DL-0032025062811230758815C,555;" + + "YTSON-DL-0032025062811263774059A,556;" + + "YTSON-DL-0032025062811300590202A,557;" + + "YTSON-DL-0032025062811333841550C,558;" + + "YTSON-DL-0032025062811371790407B,559;" + + "YTSON-DL-0032025062811404520167A,560;" + + "YTSON-DL-0032025062811440554907A,561;" + + "YTSON-DL-0032025062811473108484A,562;" + + "YTSON-DL-0032025062811505532233C,563;" + + "YTSON-DL-0032025062811542118833A,564;" + + "YTSON-DL-0032025062815025717176A,565;" + + "YTSON-DL-0032025062815064303765A,566;" + + "YTSON-DL-0032025062815100726867C,567;" + + "YTSON-DL-0032025062815132750508A,568;" + + "YTSON-DL-0032025062815164705553B,569;" + + "YTSON-DL-0032025062815200698733A,570;" + + "YTSON-DL-0032025062815233163494A,571;" + + "YTSON-DL-0032025062815264720413C,572;" + + "YTSON-DL-0032025062815300701750C,573;" + + "YTSON-DL-0032025062815333218376B,574;" + + "YTSON-DL-0032025062815365226247C,575;" + + "YTSON-DL-0032025062815401223478A,576;" + + "YTSON-DL-0032025062815433203163A,577;" + + "YTSON-DL-0032025062815464677722B,578;" + + "YTSON-DL-0032025062815500710352A,579;" + + "YTSON-DL-0032025062816071734351A,580;" + + "YTSON-DL-0032025062816103717600A,581;" + + "YTSON-DL-0032025062816140082192C,582;" + + "YTSON-DL-0032025062816171734474B,583;" + + "YTSON-DL-0032025062816203729745A,584;" + + "YTSON-DL-0032025062816235234776C,585;" + + "YTSON-DL-0032025062816272061405A,586;" + + "YTSON-DL-0032025062816311402038B,587;" + + "YTSON-DL-0032025062816344185365B,588;" + + "YTSON-DL-0032025070114083588931A,589;" + + "YTSON-DL-0032025070114121488808C,590;" + + "YTSON-DL-0032025070114153509055A,591;" + + "YTSON-DL-0032025070114185963887C,592;" + + "YTSON-DL-0032025070114221494985A,593;" + + "YTSON-DL-0032025070114253488401B,594;" + + "YTSON-DL-0032025070114285085216B,595;" + + "YTSON-DL-0032025070114321506832C,596;" + + "YTSON-DL-0032025070114353964481C,597;" + + "YTSON-DL-0032025070114385978769A,598;" + + "YTSON-DL-0032025070114422080533A,599;" + + "YTSON-DL-0032025070114454515095B,600;" + + "YTSON-DL-0032025070114490063666B,601;" + + "YTSON-DL-0032025070114522748009A,602;" + + "YTSON-DL-0032025070114555499152A,603;" + + "YTSON-DL-0032025070114591487647A,604;" + + "YTSON-DL-0032025070115024602888B,605;" + + "YTSON-DL-0032025070115061203862C,606;" + + "YTSON-DL-0032025070115102157617C,607;" + + "YTSON-DL-0032025070115135278117A,608;" + + "YTSON-DL-0032025070115171611505B,609;" + + "YTSON-DL-0032025070115300599273B,610;" + + "YTSON-DL-0032025070115333671759B,611;" + + "YTSON-DL-0032025070115370042968A,612;" + + "YTSON-DL-0032025070115401693204A,613;" + + "YTSON-DL-0032025070115434153787A,614;" + + "YTSON-DL-0032025070115471318679B,615;" + + "YTSON-DL-0032025070115503766867A,616;" + + "YTSON-DL-0032025070115535630966A,617;" + + "YTSON-DL-0032025070115572393072C,618;" + + "YTSON-DL-0032025070209570609769B,619;" + + "YTSON-DL-0032025070210003962745A,620;" + + "YTSON-DL-0032025070210051963243A,621;" + + "YTSON-DL-0032025070210083799233C,622;" + + "YTSON-DL-0032025070210125387695B,623;" + + "YTSON-DL-0032025070210162062823B,624;" + + "YTSON-DL-0032025070210194149599A,625;" + + "YTSON-DL-0032025070210231002548A,626;" + + "YTSON-DL-0032025070210264568902A,627;" + + "YTSON-DL-0032025070210300665171B,628;" + + "YTSON-DL-0032025070210381229054C,629;" + + "YTSON-DL-0032025070210413684814C,630;" + + "YTSON-DL-0032025070210462957099A,631;" + + "YTSON-DL-0032025070210495156101B,632;" + + "YTSON-DL-0032025070210531153832A,633;" + + "YTSON-DL-0032025070210564254181C,634;" + + "YTSON-DL-0032025070211000103155A,635;" + + "YTSON-DL-0032025070211033281178A,636;" + + "YTSON-DL-0032025070211065734587A,637;" + + "YTSON-DL-0032025070211101854547A,638;" + + "YTSON-DL-0032025070211134124630B,639;" + + "YTSON-DL-0032025070211165812390B,640;" + + "YTSON-DL-0032025070211202193158C,641;" + + "YTSON-DL-0032025070211235154557B,642;" + + "YTSON-DL-0032025070211271177287B,643;" + + "YTSON-DL-0032025070215003098358A,644;" + + "YTSON-DL-0032025070215040816025C,645;" + + "YTSON-DL-0032025070215072761788C,646;" + + "YTSON-DL-0032025070215114902875A,647;" + + "YTSON-DL-0032025070215151301240B,648;" + + "YTSON-DL-0032025070215182734427B,649;" + + "YTSON-DL-0032025070215215331865C,650;" + + "YTSON-DL-0032025070215251635644A,651;" + + "YTSON-DL-0032025070215283796383B,652;" + + "YTSON-DL-0032025070215340151641C,653;" + + "YTSON-DL-0032025070215372361255B,654;" + + "YTSON-DL-0032025070215404341131C,655;" + + "YTSON-DL-0032025070215435831433C,656;" + + "YTSON-DL-0032025070215471827331C,657;" + + "YTSON-DL-0032025070215503797020C,658;" + + "YTSON-DL-0032025070215535483831B,659;" + + "YTSON-DL-0032025070215571441771C,660;" + + "YTSON-DL-0032025070216003611460C,661;" + + "YTSON-DL-0032025070216035878910B,662;" + + "YTSON-DL-0032025070216071400729C,663;" + + "YTSON-DL-0032025070216103371370C,664;" + + "YTSON-DL-0032025070216135918098B,665;" + + "YTSON-DL-0032025070216172403885B,666;" + + "YTSON-DL-0032025070216204442603B,667;" + + "YTSON-DL-0032025070216241442199A,668;" + + "YTSON-DL-0032025052813563830787C,670;" + + "YTSON-DL-0032025052814191986870A,671;" + + "YTSON-DL-0032025052914525086211A,672;" + + "YTSON-DL-0032025053016082727972B,673;" + + "YTSON-DL-0032025053017292611182A,674;" + + "YTSON-DL-0032025060318381086505A,675;" + + "YTSON-DL-0032025060318475367795C,676;" + + "YTSON-DL-0032025060318581319490A,677;" + + "YTSON-DL-0032025060416152040496B,678;" + + "YTSON-DL-0032025060510480880521B,679;" + + "YTSON-DL-0032025060614535165597A,680;" + + "YTSON-DL-0032025060615304264910A,681;" + + "YTSON-DL-0032025060615563221221A,682;" + + "YTSON-DL-0032025060616225013049A,683;" + + "YTSON-DL-0032025060616371815254A,684;" + + "YTSON-DL-0032025060616464587053B,685;" + + "YTSON-DL-0032025060616534303633A,686;" + + "YTSON-DL-0032025061209000232209B,687;" + + "YTSON-DL-0032025061209065342120C,688;" + + "YTSON-DL-0032025061209103403562B,689;" + + "YTSON-DL-0032025061209140765869C,690;" + + "YTSON-DL-0032025061209173788054A,691;" + + "YTSON-DL-0032025061209464529086C,692;" + + "YTSON-DL-0032025061209501959843C,693;" + + "YTSON-DL-0032025061209540144860B,694;" + + "YTSON-DL-0032025061209574651930C,695;" + + "YTSON-DL-0032025061210013387730A,696;" + + "YTSON-DL-0032025061210052418642C,697;" + + "YTSON-DL-0032025061210091049142B,698;" + + "YTSON-DL-0032025061210124653861C,699;" + + "YTSON-DL-0032025061210161919848C,700;" + + "YTSON-DL-0032025061210200719896A,701;" + + "YTSON-DL-0032025061210233974969C,702;" + + "YTSON-DL-0032025061210271097567C,703;" + + "YTSON-DL-0032025061210304429887C,704;" + + "YTSON-DL-0032025061210341947652C,705;" + + "YTSON-DL-0032025061210375534422A,706;" + + "YTSON-DL-0032025061210413590211C,707;" + + "YTSON-DL-0032025061210450933151A,708;" + + "YTSON-DL-0032025061210484120666B,709;" + + "YTSON-DL-0032025061210521880597A,710;" + + "YTSON-DL-0032025061210555175219C,711;" + + "YTSON-DL-0032025061210593988683B,712;" + + "YTSON-DL-0032025061211060104365C,713;" + + "YTSON-DL-0032025061211093377694C,714;" + + "YTSON-DL-0032025061211130490912A,715;" + + "YTSON-DL-0032025061211164842433C,716;" + + "YTSON-DL-0032025061214400331542C,717;" + + "YTSON-DL-0032025061214433444865A,718;" + + "YTSON-DL-0032025061214474493400B,719;" + + "YTSON-DL-0032025061214513702179C,720;" + + "YTSON-DL-0032025061214551971838A,721;" + + "YTSON-DL-0032025061214585691354B,722;" + + "YTSON-DL-0032025061215023296203C,723;" + + "YTSON-DL-0032025061215061959272C,724;" + + "YTSON-DL-0032025061215100893834B,725;" + + "YTSON-DL-0032025061215135278677B,726;" + + "YTSON-DL-0032025061215172410771B,727;" + + "YTSON-DL-0032025061215205311423A,728;" + + "YTSON-DL-0032025061215243187416B,729;" + + "YTSON-DL-0032025061215275867945A,730;" + + "YTSON-DL-0032025061215312923792A,731;" + + "YTSON-DL-0032025061215350588775A,732;" + + "YTSON-DL-0032025061215383420718A,733;" + + "YTSON-DL-0032025061215421822108C,734;" + + "YTSON-DL-0032025061215455295346B,735;" + + "YTSON-DL-0032025061215492419641A,736;" + + "YTSON-DL-0032025061215525275901B,737;" + + "YTSON-DL-0032025061215562371923B,738;" + + "YTSON-DL-0032025061215595407997C,739;" + + "YTSON-DL-0032025061216032435792B,740;" + + "YTSON-DL-0032025061216065405763B,741;" + + "YTSON-DL-0032025061216102784606A,742;" + + "YTSON-DL-0032025061216135850871B,743;" + + "YTSON-DL-0032025061216173472239A,744;" + + "YTSON-DL-0032025061216210499659C,745;" + + "YTSON-DL-0032025061216244239782A,746;" + + "YTSON-DL-0032025061216282773687B,747;" + + "YTSON-DL-0032025061308565309199B,748;" + + "YTSON-DL-0032025061309003392191C,749;" + + "YTSON-DL-0032025061309040685991A,750;" + + "YTSON-DL-0032025061309074923705A,751;" + + "YTSON-DL-0032025061309114087247C,752;" + + "YTSON-DL-0032025061309151510014A,753;" + + "YTSON-DL-0032025061309170255959A,754;" + + "YTSON-DL-0032025061309205258683A,755;" + + "YTSON-DL-0032025061309242264238A,756;" + + "YTSON-DL-0032025061309275433028B,757;" + + "YTSON-DL-0032025061309312175786A,758;" + + "YTSON-DL-0032025061309345282254A,759;" + + "YTSON-DL-0032025061309382165541B,760;" + + "YTSON-DL-0032025061309415460657C,761;" + + "YTSON-DL-0032025061309452008754C,762;" + + "YTSON-DL-0032025061309533498416A,763;" + + "YTSON-DL-0032025061309565873248C,764;" + + "YTSON-DL-0032025061310002457556A,765;" + + "YTSON-DL-0032025061310040002463A,766;" + + "YTSON-DL-0032025061310073900230C,767;" + + "YTSON-DL-0032025061310110526991A,768;" + + "YTSON-DL-0032025061310143528866B,769;" + + "YTSON-DL-0032025061310180723400B,770;" + + "YTSON-DL-0032025061310214095626A,771;" + + "YTSON-DL-0032025061310252097790A,772;" + + "YTSON-DL-0032025061310284584622B,773;" + + "YTSON-DL-0032025061310321742723A,774;" + + "YTSON-DL-0032025061310354813559A,775;" + + "YTSON-DL-0032025061310410568931C,776;" + + "YTSON-DL-0032025061310443334553A,777;" + + "YTSON-DL-0032025061310480342055C,778;" + + "YTSON-DL-0032025061310513247600A,779;" + + "YTSON-DL-0032025061310551502028A,780;" + + "YTSON-DL-0032025061310584707372B,781;" + + "YTSON-DL-0032025061311021980039C,782;" + + "YTSON-DL-0032025061311055393584C,783;" + + "YTSON-DL-0032025061311092864354A,784;" + + "YTSON-DL-0032025061314393450255C,785;" + + "YTSON-DL-0032025061314431569212C,786;" + + "YTSON-DL-0032025061314464875586C,787;" + + "YTSON-DL-0032025061314501632911A,788;" + + "YTSON-DL-0032025061314534120487B,789;" + + "YTSON-DL-0032025061314570802788B,790;" + + "YTSON-DL-0032025061315003696391B,791;" + + "YTSON-DL-0032025061315040404138C,792;" + + "YTSON-DL-0032025061315072878596A,793;" + + "YTSON-DL-0032025061315105420913C,794;" + + "YTSON-DL-0032025061315142194191B,795;" + + "YTSON-DL-0032025061315175030025A,796;" + + "YTSON-DL-0032025061315211978831B,797;" + + "YTSON-DL-0032025061315244691834C,798;" + + "YTSON-DL-0032025061315281873564C,799;" + + "YTSON-DL-0032025061315314359003B,800;" + + "YTSON-DL-0032025061315351284222B,801;" + + "YTSON-DL-0032025061315383820188C,802;" + + "YTSON-DL-0032025061315420481599A,803;" + + "YTSON-DL-0032025061315453596806B,804;" + + "YTSON-DL-0032025061315490378302B,805;" + + "YTSON-DL-0032025061315522398385A,806;" + + "YTSON-DL-0032025061315555301759A,807;" + + "YTSON-DL-0032025061315591759772C,808;" + + "YTSON-DL-0032025061316024251570B,809;" + + "YTSON-DL-0032025061316060857263B,810;" + + "YTSON-DL-0032025061316093412885B,811;" + + "YTSON-DL-0032025061316130397526C,812;" + + "YTSON-DL-0032025061316171987896B,813;" + + "YTSON-DL-0032025061316204502230C,814;" + + "YTSON-DL-0032025061316241021656C,815;" + + "YTSON-DL-0032025061316273451167A,816;" + + "YTSON-DL-0032025061414123728800A,817;" + + "YTSON-DL-0032025061414160587656B,818;" + + "YTSON-DL-0032025061414192741367B,819;" + + "YTSON-DL-0032025061414230586830B,820;" + + "YTSON-DL-0032025061414292131382B,821;" + + "YTSON-DL-0032025061414324689788C,822;" + + "YTSON-DL-0032025061414361226698C,823;" + + "YTSON-DL-0032025061414412720539C,824;" + + "YTSON-DL-0032025061416023333988C,825;" + + "YTSON-DL-0032025061608402729007A,826;" + + "YTSON-DL-0032025061608435189183B,827;" + + "YTSON-DL-0032025061608571719917B,828;" + + "YTSON-DL-0032025061609004322504C,829;" + + "YTSON-DL-0032025061609041233797A,830;" + + "YTSON-DL-0032025061609074148701A,831;" + + "YTSON-DL-0032025061609110464981A,832;" + + "YTSON-DL-0032025061609144600277A,833;" + + "YTSON-DL-0032025061609190395948A,834;" + + "YTSON-DL-0032025061609222762377B,835;" + + "YTSON-DL-0032025061609260193318C,836;" + + "YTSON-DL-0032025061609292744730B,837;" + + "YTSON-DL-0032025061609330341288B,838;" + + "YTSON-DL-0032025061609363910734C,839;" + + "YTSON-DL-0032025061609400897521C,840;" + + "YTSON-DL-0032025061609434591067C,841;" + + "YTSON-DL-0032025061609471563873B,842;" + + "YTSON-DL-0032025061609504526960B,843;" + + "YTSON-DL-0032025061609541209980B,844;" + + "YTSON-DL-0032025061609573666353C,845;" + + "YTSON-DL-0032025061610010408465C,846;" + + "YTSON-DL-0032025061610043120251A,847;" + + "YTSON-DL-0032025061610073329246B,848;" + + "YTSON-DL-0032025061610105328089A,849;" + + "YTSON-DL-0032025061610142597256B,850;" + + "YTSON-DL-0032025061610175980594A,851;" + + "YTSON-DL-0032025061614355557231B,852;" + + "YTSON-DL-0032025061614393823092A,853;" + + "YTSON-DL-0032025061614432243310A,854;" + + "YTSON-DL-0032025061614464632613B,855;" + + "YTSON-DL-0032025061614513133045C,856;" + + "YTSON-DL-0032025061614550262880B,857;" + + "YTSON-DL-0032025061614582650091A,858;" + + "YTSON-DL-0032025061615015165986C,859;" + + "YTSON-DL-0032025061615051634706A,860;" + + "YTSON-DL-0032025061615083659861A,861;" + + "YTSON-DL-0032025061615120081603C,862;" + + "YTSON-DL-0032025061615152639770C,863;" + + "YTSON-DL-0032025061615185258181B,864;" + + "YTSON-DL-0032025061615221240303A,865;" + + "YTSON-DL-0032025061615253594447A,866;" + + "YTSON-DL-0032025061615323278365B,867;" + + "YTSON-DL-0032025061615355482583C,868;" + + "YTSON-DL-0032025061615391760239B,869;" + + "YTSON-DL-0032025061615424243493C,870;" + + "YTSON-DL-0032025061615460158588C,871;" + + "YTSON-DL-0032025061615492200068B,872;" + + "YTSON-DL-0032025061615524360881A,873;" + + "YTSON-DL-0032025061615560265130B,874;" + + "YTSON-DL-0032025061615592705478C,875;" + + "YTSON-DL-0032025061616025500679C,876;" + + "YTSON-DL-0032025061708370501384B,877;" + + "YTSON-DL-0032025061708403176682A,878;" + + "YTSON-DL-0032025061708431940081B,879;" + + "YTSON-DL-0032025061708464626311B,880;" + + "YTSON-DL-0032025061708501576398B,881;" + + "YTSON-DL-0032025061708534120985C,882;" + + "YTSON-DL-0032025061708570675963C,883;" + + "YTSON-DL-0032025061709003621278B,884;" + + "YTSON-DL-0032025061709040185869C,885;" + + "YTSON-DL-0032025061709072600346B,886;" + + "YTSON-DL-0032025061709105263462B,887;" + + "YTSON-DL-0032025062008504149794C,888;" + + "YTSON-DL-0032025062008543553945A,889;" + + "YTSON-DL-0032025062008580975531C,890;" + + "YTSON-DL-0032025062009013291761C,891;" + + "YTSON-DL-0032025062009045542648C,892;" + + "YTSON-DL-0032025062009082286392B,893;" + + "YTSON-DL-0032025062009121132841C,894;" + + "YTSON-DL-0032025062009451692987C,895;" + + "YTSON-DL-0032025062009484790748B,896;" + + "YTSON-DL-0032025062009520922512B,897;" + + "YTSON-DL-0032025062009553426884A,898;" + + "YTSON-DL-0032025062010001168932A,899;" + + "YTSON-DL-0032025062010040286637B,900;" + + "YTSON-DL-0032025062010073377996A,901;" + + "YTSON-DL-0032025062010105410033A,902;" + + "YTSON-DL-0032025062010141791581C,903;" + + "YTSON-DL-0032025062010182967982C,904;" + + "YTSON-DL-0032025062010220821278C,905;" + + "YTSON-DL-0032025062010285752027A,906;" + + "YTSON-DL-0032025062010322855854A,907;" + + "YTSON-DL-0032025062010355371937B,908;" + + "YTSON-DL-0032025062010393124259A,909;" + + "YTSON-DL-0032025062010425225707B,910;" + + "YTSON-DL-0032025062010462124479C,911;" + + "YTSON-DL-0032025062010494957367C,912;" + + "YTSON-DL-0032025062010531416344B,913;" + + "YTSON-DL-0032025062010563370683B,914;" + + "YTSON-DL-0032025062010595085684B,915;" + + "YTSON-DL-0032025062011030929798C,916;" + + "YTSON-DL-0032025062011063516240C,917;" + + "YTSON-DL-0032025062014394512621C,918;" + + "YTSON-DL-0032025062014430454877B,919;" + + "YTSON-DL-0032025062014462022901B,920;" + + "YTSON-DL-0032025062014494127108A,921;" + + "YTSON-DL-0032025062014534904395A,922;" + + "YTSON-DL-0032025062014570972085C,923;" + + "YTSON-DL-0032025062015005940406A,924;" + + "YTSON-DL-0032025062015042476570A,925;" + + "YTSON-DL-0032025062015074442542C,926;" + + "YTSON-DL-0032025062015110837800B,927;" + + "YTSON-DL-0032025062015145988917C,928;" + + "YTSON-DL-0032025062015182514924B,929;" + + "YTSON-DL-0032025062015213972816A,930;" + + "YTSON-DL-0032025062015250659172A,931;" + + "YTSON-DL-0032025062015331420870A,932;" + + "YTSON-DL-0032025062015363958428C,933;" + + "YTSON-DL-0032025062015400216033C,934;" + + "YTSON-DL-0032025062015431986927C,935;" + + "YTSON-DL-0032025062015464130005C,936;" + + "YTSON-DL-0032025062015500001190B,937;" + + "YTSON-DL-0032025062015532243157A,938;" + + "YTSON-DL-0032025062016060276618C,939;" + + "YTSON-DL-0032025062016093956556C,940;" + + "YTSON-DL-0032025062016125963020A,941;" + + "YTSON-DL-0032025062016163023222C,942;" + + "YTSON-DL-0032025062016195469040B,943;" + + "YTSON-DL-0032025062016231991731A,944;" + + "YTSON-DL-0032025062016263886945B,945;" + + "YTSON-DL-0032025062016300601343B,946;" + + "YTSON-DL-0032025062109393238311A,947;" + + "YTSON-DL-0032025062109424703740B,948;" + + "YTSON-DL-0032025062109461469570B,949;" + + "YTSON-DL-0032025062109533864818B,950;" + + "YTSON-DL-0032025062109570317195A,951;" + + "YTSON-DL-0032025062111000554467A,952;" + + "YTSON-DL-0032025062111032468666C,953;" + + "YTSON-DL-0032025062111071073337A,954;" + + "YTSON-DL-0032025062111102659129C,955;" + + "YTSON-DL-0032025062111134719983C,956;" + + "YTSON-DL-0032025062111170387262B,957;" + + "YTSON-DL-0032025062111202900076B,958;" + + "YTSON-DL-0032025062111234804092C,959;" + + "YTSON-DL-0032025062111270517832C,960;" + + "YTSON-DL-0032025062111302236716A,961;" + + "YTSON-DL-0032025062111335337486B,962;" + + "YTSON-DL-0032025062111371294878C,963;" + + "YTSON-DL-0032025062111403844666A,964;" + + "YTSON-DL-0032025062111435719789A,965;" + + "YTSON-DL-0032025062111471897742B,966;" + + "YTSON-DL-0032025062111565064380C,967;" + + "YTSON-DL-0032025062112000833869A,968;" + + "YTSON-DL-0032025062112344966339C,969;" + + "YTSON-DL-0032025062309200845356B,970;" + + "YTSON-DL-0032025062309233385746B,971;" + + "YTSON-DL-0032025062309270774445C,972;" + + "YTSON-DL-0032025062309302934748C,973;" + + "YTSON-DL-0032025062309335314056B,974;" + + "YTSON-DL-0032025062309372039970B,975;" + + "YTSON-DL-0032025062309404242931B,976;" + + "YTSON-DL-0032025062309440828128C,977;" + + "YTSON-DL-0032025062309472386908B,978;" + + "YTSON-DL-0032025062309503731165C,979;" + + "YTSON-DL-0032025062309535335710C,980;" + + "YTSON-DL-0032025062309571245914A,981;" + + "YTSON-DL-0032025062310003344717A,982;" + + "YTSON-DL-0032025062310060944178C,983;" + + "YTSON-DL-0032025062310093288557A,984;" + + "YTSON-DL-0032025062310125536910C,985;" + + "YTSON-DL-0032025062310162023829A,986;" + + "YTSON-DL-0032025062310193835587A,987;" + + "YTSON-DL-0032025062310225425843C,988;" + + "YTSON-DL-0032025062310262181728C,989;" + + "YTSON-DL-0032025062310294460834C,990;" + + "YTSON-DL-0032025062310330547378C,991;" + + "YTSON-DL-0032025062310362864868A,992;" + + "YTSON-DL-0032025062310400190506A,993;" + + "YTSON-DL-0032025062310433748839B,994;" + + "YTSON-DL-0032025062314150824847B,995;" + + "YTSON-DL-0032025062314182850296A,996;" + + "YTSON-DL-0032025062314214668582C,997;" + + "YTSON-DL-0032025062314251853756A,998;" + + "YTSON-DL-0032025062314290195456B,999;" + + "YTSON-DL-0032025062314340126340A,1000;" + + "YTSON-DL-0032025062314430112086B,1001;" + + "YTSON-DL-0032025062314461745562A,1002;" + + "YTSON-DL-0032025062314494363174A,1003;" + + "YTSON-DL-0032025062314530879566B,1004;" + + "YTSON-DL-0032025062314562637094A,1005;" + + "YTSON-DL-0032025062314594883665C,1006;" + + "YTSON-DL-0032025062315031733556B,1007;" + + "YTSON-DL-0032025062315064364081B,1008;" + + "YTSON-DL-0032025062315100712957B,1009;" + + "YTSON-DL-0032025062315133160296A,1010;" + + "YTSON-DL-0032025062315165220680A,1011;" + + "YTSON-DL-0032025062315200669861B,1012;" + + "YTSON-DL-0032025062315232244194B,1013;" + + "YTSON-DL-0032025062315264678852C,1014;" + + "YTSON-DL-0032025062315301338468A,1015;" + + "YTSON-DL-0032025062315333163927A,1016;" + + "YTSON-DL-0032025062315364742429A,1017;" + + "YTSON-DL-0032025062315400680103B,1018;" + + "YTSON-DL-0032025062315433509626A,1019;" + + "YTSON-DL-0032025062315465398230C,1020;" + + "YTSON-DL-0032025062315503403096B,1021;" + + "YTSON-DL-0032025062315535283727C,1022;" + + "YTSON-DL-0032025062315571222774B,1023;" + + "YTSON-DL-0032025062316032593410B,1024;" + + "YTSON-DL-0032025062316064638587A,1025;" + + "YTSON-DL-0032025062316100424551C,1026;" + + "YTSON-DL-0032025062316132431497A,1027;" + + "YTSON-DL-0032025062316164248184C,1028;" + + "YTSON-DL-0032025062316200106037B,1029;" + + "YTSON-DL-0032025062316232280605C,1030;" + + "YTSON-DL-0032025062316264678726B,1031;" + + "YTSON-DL-0032025062409042817119C,1032;" + + "YTSON-DL-0032025062409074764791B,1033;" + + "YTSON-DL-0032025062409105811331C,1034;" + + "YTSON-DL-0032025062409141840308A,1035;" + + "YTSON-DL-0032025062409173780177B,1036;" + + "YTSON-DL-0032025062409205929150A,1037;" + + "YTSON-DL-0032025062409242278260B,1038;" + + "YTSON-DL-0032025062413113085105C,1039;" + + "YTSON-DL-0032025062413145427160B,1040;" + + "YTSON-DL-0032025062413181691386C,1041;" + + "YTSON-DL-0032025062413213945184B,1042;" + + "YTSON-DL-0032025062413251529835A,1043;" + + "YTSON-DL-0032025062413283960615B,1044;" + + "YTSON-DL-0032025062413320094294B,1045;" + + "YTSON-DL-0032025062413353968266C,1046;" + + "YTSON-DL-0032025062413390124087A,1047;" + + "YTSON-DL-0032025062413423589559A,1048;" + + "YTSON-DL-0032025062413460303640A,1049;" + + "YTSON-DL-0032025062413492657425A,1050;" + + "YTSON-DL-0032025062414012258434A,1051;" + + "YTSON-DL-0032025062414045119432C,1052;" + + "YTSON-DL-0032025062414225593979C,1053;" + + "YTSON-DL-0032025062414261907521C,1054;" + + "YTSON-DL-0032025062414294661528C,1055;" + + "YTSON-DL-0032025062414333441387A,1056;" + + "YTSON-DL-0032025062414365513772C,1057;" + + "YTSON-DL-0032025062414404204128C,1058;" + + "YTSON-DL-0032025062414440716676A,1059;" + + "YTSON-DL-0032025062414473101528A,1060;" + + "YTSON-DL-0032025062414505294626B,1061;" + + "YTSON-DL-0032025062414542897579A,1062;" + + "YTSON-DL-0032025062414575519112C,1063;" + + "YTSON-DL-0032025062415011548403A,1064;" + + "YTSON-DL-0032025062415044123680B,1065;" + + "YTSON-DL-0032025062415080614601C,1066;" + + "YTSON-DL-0032025062415112672843A,1067;" + + "YTSON-DL-0032025062415145153027C,1068;" + + "YTSON-DL-0032025062415181108551A,1069;" + + "YTSON-DL-0032025062415215296721B,1070;" + + "YTSON-DL-0032025062415251754404A,1071;" + + "YTSON-DL-0032025062415284644442C,1072;" + + "YTSON-DL-0032025062508421856647A,1073;" + + "YTSON-DL-0032025062508454691102C,1074;" + + "YTSON-DL-0032025062508493192020B,1075;" + + "YTSON-DL-0032025062508525289543A,1076;" + + "YTSON-DL-0032025062508561765829B,1077;" + + "YTSON-DL-0032025062508593691854B,1078;" + + "YTSON-DL-0032025062509025656571C,1079;" + + "YTSON-DL-0032025062509061757041B,1080;" + + "YTSON-DL-0032025062509093980361B,1081;" + + "YTSON-DL-0032025062509154823471B,1082;" + + "YTSON-DL-0032025062509190154798C,1083;" + + "YTSON-DL-0032025062509222793180C,1084;" + + "YTSON-DL-0032025062509254900919B,1085;" + + "YTSON-DL-0032025062509290691773B,1086;" + + "YTSON-DL-0032025062509323068812C,1087;" + + "YTSON-DL-0032025062509355169564A,1088;" + + "YTSON-DL-0032025062509394837563C,1089;" + + "YTSON-DL-0032025062509431359536C,1090;" + + "YTSON-DL-0032025062509463347612B,1091;" + + "YTSON-DL-0032025062509495218890C,1092;" + + "YTSON-DL-0032025062509531248409A,1093;" + + "YTSON-DL-0032025062509563728606B,1094;" + + "YTSON-DL-0032025062509595809742B,1095;" + + "YTSON-DL-0032025062510033607659C,1096;" + + "YTSON-DL-0032025062510055790273B,1097;" + + "YTSON-DL-0032025062510092903493B,1098;" + + "YTSON-DL-0032025062510124761186B,1099;" + + "YTSON-DL-0032025062510160802224B,1100;" + + "YTSON-DL-0032025062510221339148C,1101;" + + "YTSON-DL-0032025062510252780415B,1102;" + + "YTSON-DL-0032025062510290067375B,1103;" + + "YTSON-DL-0032025062513474009831B,1104;" + + "YTSON-DL-0032025062513510493456A,1105;" + + "YTSON-DL-0032025062513542524495A,1106;" + + "YTSON-DL-0032025062513574915039B,1107;" + + "YTSON-DL-0032025062514011554392C,1108;" + + "YTSON-DL-0032025062514043535279A,1109;" + + "YTSON-DL-0032025062514075065394B,1110;" + + "YTSON-DL-0032025062514113545946C,1111;" + + "YTSON-DL-0032025062514145526616A,1112;" + + "YTSON-DL-0032025062514181996202A,1113;" + + "YTSON-DL-0032025062514214673572A,1114;" + + "YTSON-DL-0032025062514252087370C,1115;" + + "YTSON-DL-0032025062514284073036C,1116;" + + "YTSON-DL-0032025062514320057529B,1117;" + + "YTSON-DL-0032025062514351984564C,1118;" + + "YTSON-DL-0032025062514384046156A,1119;" + + "YTSON-DL-0032025062514422447852B,1120;" + + "YTSON-DL-0032025062514454571409A,1121;" + + "YTSON-DL-0032025062514490478970C,1122;" + + "YTSON-DL-0032025062514522515312B,1123;" + + "YTSON-DL-0032025062608463056523C,1124;" + + "YTSON-DL-0032025062608495403760A,1125;" + + "YTSON-DL-0032025062608550968243A,1126;" + + "YTSON-DL-0032025062608582753043C,1127;" + + "YTSON-DL-0032025062609015213502A,1128;" + + "YTSON-DL-0032025062609051355992C,1129;" + + "YTSON-DL-0032025062609084343147B,1130;" + + "YTSON-DL-0032025062609120786260C,1131;" + + "YTSON-DL-0032025062609152828223B,1132;" + + "YTSON-DL-0032025062616024963998A,1133;" + + "YTSON-DL-0032025062616062188821C,1134;" + + "YTSON-DL-0032025062616094520575C,1135;" + + "YTSON-DL-0032025062616131516042B,1136;" + + "YTSON-DL-0032025062616163750280B,1137;" + + "YTSON-DL-0032025062616195786194A,1138;" + + "YTSON-DL-0032025062616231804818C,1139;" + + "YTSON-DL-0032025062616264112397A,1140;" + + "YTSON-DL-0032025062616300351371B,1141;" + + "YTSON-DL-0032025062616332718645C,1142;" + + "YTSON-DL-0032025062616365196610A,1143;" + + "YTSON-DL-0032025062616402809195B,1144;" + + "YTSON-DL-0032025062709060965220A,1145;" + + "YTSON-DL-0032025062709090027992C,1146;" + + "YTSON-DL-0032025062709385586452B,1147;" + + "YTSON-DL-0032025062709422747161B,1148;" + + "YTSON-DL-0032025062709455261995B,1149;" + + "YTSON-DL-0032025062709484883477A,1150;" + + "YTSON-DL-0032025062710111607067B,1151;" + + "YTSON-DL-0032025062710144097859A,1152;" + + "YTSON-DL-0032025062710180240976A,1153;" + + "YTSON-DL-0032025062710212554919C,1154;" + + "YTSON-DL-0032025062710244776537C,1155;" + + "YTSON-DL-0032025062710281177265B,1156;" + + "YTSON-DL-0032025062710313820935B,1157;" + + "YTSON-DL-0032025062710350063862A,1158;" + + "YTSON-DL-0032025062710382270498B,1159;" + + "YTSON-DL-0032025062710421025754B,1160;" + + "YTSON-DL-0032025062710453722760A,1161;" + + "YTSON-DL-0032025062710490199919C,1162;" + + "YTSON-DL-0032025062710522804190C,1163;" + + "YTSON-DL-0032025062710555173293C,1164;" + + "YTSON-DL-0032025062710591279398A,1165;" + + "YTSON-DL-0032025062711024241564A,1166;" + + "YTSON-DL-0032025062711060677103A,1167;" + + "YTSON-DL-0032025062711093141793C,1168;" + + "YTSON-DL-0032025062711125735847C,1169;" + + "YTSON-DL-0032025062711162730339A,1170;" + + "YTSON-DL-0032025062711195358154C,1171;" + + "YTSON-DL-0032025062711231741986B,1172;" + + "YTSON-DL-0032025062711273040684A,1173;" + + "YTSON-DL-0032025062711312779910A,1174;" + + "YTSON-DL-0032025062711345303634B,1175;" + + "YTSON-DL-0032025062711381755062B,1176;" + + "YTSON-DL-0032025062711414211153C,1177;" + + "YTSON-DL-0032025062711450674629C,1178;" + + "YTSON-DL-0032025062711482675313B,1179;" + + "YTSON-DL-0032025062711514694404A,1180;" + + "YTSON-DL-0032025062711551247820B,1181;" + + "YTSON-DL-0032025062809343726677B,1182;" + + "YTSON-DL-0032025062809381002126A,1183;" + + "YTSON-DL-0032025062809413285398B,1184;" + + "YTSON-DL-0032025062809445870682B,1185;" + + "YTSON-DL-0032025062809482398305B,1186;" + + "YTSON-DL-0032025062809514476014C,1187;" + + "YTSON-DL-0032025062809550698603A,1188;" + + "YTSON-DL-0032025062809582963251B,1189;" + + "YTSON-DL-0032025062810015477839A,1190;" + + "YTSON-DL-0032025062810053044170B,1191;" + + "YTSON-DL-0032025062810085378988A,1192;" + + "YTSON-DL-0032025062810121603050A,1193;" + + "YTSON-DL-0032025062810154083220C,1194;" + + "YTSON-DL-0032025062810190097555B,1195;" + + "YTSON-DL-0032025062810222565477A,1196;" + + "YTSON-DL-0032025062810255007226B,1197;" + + "YTSON-DL-0032025062810291526285C,1198;" + + "YTSON-DL-0032025062810324620340B,1199;" + + "YTSON-DL-0032025062810361824448C,1200;" + + "YTSON-DL-0032025062810400369362A,1201;" + + "YTSON-DL-0032025062810432688746A,1202;" + + "YTSON-DL-0032025062810465510787A,1203;" + + "YTSON-DL-0032025062810502124038B,1204;" + + "YTSON-DL-0032025062810583043394A,1205;" + + "YTSON-DL-0032025062811015648000B,1206;" + + "YTSON-DL-0032025062811052553843A,1207;" + + "YTSON-DL-0032025062811090531783B,1208;" + + "YTSON-DL-0032025062811122542218A,1209;" + + "YTSON-DL-0032025062811194046821C,1210;" + + "YTSON-DL-0032025062811230758815C,1211;" + + "YTSON-DL-0032025062811263774059A,1212;" + + "YTSON-DL-0032025062811300590202A,1213;" + + "YTSON-DL-0032025062811333841550C,1214;" + + "YTSON-DL-0032025062811371790407B,1215;" + + "YTSON-DL-0032025062811404520167A,1216;" + + "YTSON-DL-0032025062811440554907A,1217;" + + "YTSON-DL-0032025062811473108484A,1218;" + + "YTSON-DL-0032025062811505532233C,1219;" + + "YTSON-DL-0032025062811542118833A,1220;" + + "YTSON-DL-0032025062815025717176A,1221;" + + "YTSON-DL-0032025062815064303765A,1222;" + + "YTSON-DL-0032025062815100726867C,1223;" + + "YTSON-DL-0032025062815132750508A,1224;" + + "YTSON-DL-0032025062815164705553B,1225;" + + "YTSON-DL-0032025062815200698733A,1226;" + + "YTSON-DL-0032025062815233163494A,1227;" + + "YTSON-DL-0032025062815264720413C,1228;" + + "YTSON-DL-0032025062815300701750C,1229;" + + "YTSON-DL-0032025062815333218376B,1230;" + + "YTSON-DL-0032025062815365226247C,1231;" + + "YTSON-DL-0032025062815401223478A,1232;" + + "YTSON-DL-0032025062815433203163A,1233;" + + "YTSON-DL-0032025062815464677722B,1234;" + + "YTSON-DL-0032025062815500710352A,1235;" + + "YTSON-DL-0032025062816071734351A,1236;" + + "YTSON-DL-0032025062816103717600A,1237;" + + "YTSON-DL-0032025062816140082192C,1238;" + + "YTSON-DL-0032025062816171734474B,1239;" + + "YTSON-DL-0032025062816203729745A,1240;" + + "YTSON-DL-0032025062816235234776C,1241;" + + "YTSON-DL-0032025062816272061405A,1242;" + + "YTSON-DL-0032025062816311402038B,1243;" + + "YTSON-DL-0032025062816344185365B,1244;" + + "YTSON-DL-0032025070114083588931A,1245;" + + "YTSON-DL-0032025070114121488808C,1246;" + + "YTSON-DL-0032025070114153509055A,1247;" + + "YTSON-DL-0032025070114185963887C,1248;" + + "YTSON-DL-0032025070114221494985A,1249;" + + "YTSON-DL-0032025070114253488401B,1250;" + + "YTSON-DL-0032025070114285085216B,1251;" + + "YTSON-DL-0032025070114321506832C,1252;" + + "YTSON-DL-0032025070114353964481C,1253;" + + "YTSON-DL-0032025070114385978769A,1254;" + + "YTSON-DL-0032025070114422080533A,1255;" + + "YTSON-DL-0032025070114454515095B,1256;" + + "YTSON-DL-0032025070114490063666B,1257;" + + "YTSON-DL-0032025070114522748009A,1258;" + + "YTSON-DL-0032025070114555499152A,1259;" + + "YTSON-DL-0032025070114591487647A,1260;" + + "YTSON-DL-0032025070115024602888B,1261;" + + "YTSON-DL-0032025070115061203862C,1262;" + + "YTSON-DL-0032025070115102157617C,1263;" + + "YTSON-DL-0032025070115135278117A,1264;" + + "YTSON-DL-0032025070115171611505B,1265;" + + "YTSON-DL-0032025070115300599273B,1266;" + + "YTSON-DL-0032025070115333671759B,1267;" + + "YTSON-DL-0032025070115370042968A,1268;" + + "YTSON-DL-0032025070115401693204A,1269;" + + "YTSON-DL-0032025070115434153787A,1270;" + + "YTSON-DL-0032025070115471318679B,1271;" + + "YTSON-DL-0032025070115503766867A,1272;" + + "YTSON-DL-0032025070115535630966A,1273;" + + "YTSON-DL-0032025070115572393072C,1274;" + + "YTSON-DL-0032025070209570609769B,1275;" + + "YTSON-DL-0032025070210003962745A,1276;" + + "YTSON-DL-0032025070210051963243A,1277;" + + "YTSON-DL-0032025070210083799233C,1278;" + + "YTSON-DL-0032025070210125387695B,1279;" + + "YTSON-DL-0032025070210162062823B,1280;" + + "YTSON-DL-0032025070210194149599A,1281;" + + "YTSON-DL-0032025070210231002548A,1282;" + + "YTSON-DL-0032025070210264568902A,1283;" + + "YTSON-DL-0032025070210300665171B,1284;" + + "YTSON-DL-0032025070210381229054C,1285;" + + "YTSON-DL-0032025070210413684814C,1286;" + + "YTSON-DL-0032025070210462957099A,1287;" + + "YTSON-DL-0032025070210495156101B,1288;" + + "YTSON-DL-0032025070210531153832A,1289;" + + "YTSON-DL-0032025070210564254181C,1290;" + + "YTSON-DL-0032025070211000103155A,1291;" + + "YTSON-DL-0032025070211033281178A,1292;" + + "YTSON-DL-0032025070211065734587A,1293;" + + "YTSON-DL-0032025070211101854547A,1294;" + + "YTSON-DL-0032025070211134124630B,1295;" + + "YTSON-DL-0032025070211165812390B,1296;" + + "YTSON-DL-0032025070211202193158C,1297;" + + "YTSON-DL-0032025070211235154557B,1298;" + + "YTSON-DL-0032025070211271177287B,1299;" + + "YTSON-DL-0032025070215003098358A,1300;" + + "YTSON-DL-0032025070215040816025C,1301;" + + "YTSON-DL-0032025070215072761788C,1302;" + + "YTSON-DL-0032025070215114902875A,1303;" + + "YTSON-DL-0032025070215151301240B,1304;" + + "YTSON-DL-0032025070215182734427B,1305;" + + "YTSON-DL-0032025070215215331865C,1306;" + + "YTSON-DL-0032025070215251635644A,1307;" + + "YTSON-DL-0032025070215283796383B,1308;" + + "YTSON-DL-0032025070215340151641C,1309;" + + "YTSON-DL-0032025070215372361255B,1310;" + + "YTSON-DL-0032025070215404341131C,1311;" + + "YTSON-DL-0032025070215435831433C,1312;" + + "YTSON-DL-0032025070215471827331C,1313;" + + "YTSON-DL-0032025070215503797020C,1314;" + + "YTSON-DL-0032025070215535483831B,1315;" + + "YTSON-DL-0032025070215571441771C,1316;" + + "YTSON-DL-0032025070216003611460C,1317;" + + "YTSON-DL-0032025070216035878910B,1318;" + + "YTSON-DL-0032025070216071400729C,1319;" + + "YTSON-DL-0032025070216103371370C,1320;" + + "YTSON-DL-0032025070216135918098B,1321;" + + "YTSON-DL-0032025070216172403885B,1322;" + + "YTSON-DL-0032025070216204442603B,1323;" + + "YTSON-DL-0032025070216241442199A,1324"; + List noList = Collections.emptyList(); + List delList = Collections.emptyList(); + for (String no_id : orders.split(";")){ + String[] data = no_id.split(","); + if(noList.contains(data[0])){ + delList.add(data[1]); + continue; + } + noList.add(data[0]); } - return dv; - } + System.out.println("delete from yt_t_order where id in ("+String.join(",", delList)+")"); + } + } diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/vo/NativePayVO.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/vo/NativePayVO.java index de66213..5433617 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/vo/NativePayVO.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/entity/vo/NativePayVO.java @@ -1,8 +1,5 @@ package com.evotech.hd.cloud.entity.vo; -import java.util.Date; -import java.util.List; - import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; @@ -12,6 +9,9 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.Data; +import java.util.Date; +import java.util.List; + @Data @Schema(name = "Native下单参数") public class NativePayVO { @@ -21,6 +21,7 @@ public class NativePayVO { @Schema(description = "公司编码") private String ccode; + private String companyCode; @Schema(description = "订单总描述", requiredMode = RequiredMode.REQUIRED) @NotBlank @@ -59,5 +60,7 @@ public class NativePayVO { @Schema(description = "用户设备型号") private String deviceId; + @Schema(description = "订单结束时间") + String orderTimeEnd; } diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/EventFunctionTypesEnum.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/EventFunctionTypesEnum.java index 389cbd3..cfe1068 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/EventFunctionTypesEnum.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/enums/EventFunctionTypesEnum.java @@ -7,7 +7,8 @@ public enum EventFunctionTypesEnum { FUN_CHARGE_RECORD("chargeRecord", "chargeRecordConf", "充电事件记录"), FUN_SWAP_RECORD("swapRecord", "swapRecordConf", "换电事件记录"), FUN_WARN_RECORD("faultRecord", "faultRecordConf", "故障告警事件记录"), - FUN_ORDEREVENT("swapComplete", "swapCompleteConfirm", " 站端换电完成事件"); + FUN_ORDEREVENT("swapComplete", "swapCompleteConfirm", " 站端换电完成事件"), + FUN_PUSH_STATION_CONTRNL_DATA("", "pushReservation", " 推送站端事件"); String function; String reFunction; diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MessageTopic.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MessageTopic.java index 6ce4db7..4a17d71 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MessageTopic.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/MessageTopic.java @@ -19,6 +19,14 @@ public class MessageTopic implements Serializable { private String messageType; + public MessageTopic() { + } + + public MessageTopic( String stationCode, String messageType) { + this.stationCode = stationCode; + this.messageType = messageType; + } + @Override public String toString() { return businessType + "/" + stationCode + "/" + dataDirection + "/" + messageType; diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/processor/strategy/impl/event/MqttStrategyEventExchangeProcessor.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/processor/strategy/impl/event/MqttStrategyEventExchangeProcessor.java index b775ca7..1a50bca 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/processor/strategy/impl/event/MqttStrategyEventExchangeProcessor.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/mqtt/message/processor/strategy/impl/event/MqttStrategyEventExchangeProcessor.java @@ -23,7 +23,7 @@ public interface MqttStrategyEventExchangeProcessor extends MqttStrategyExchange default void sendAESMessage(MessageTopic topic, MqttMessageHeader header, EventFunctionTypesEnum typesEnum, MqttResponse response){ - topic.setMessageType(MqttMessageTypeEnum.CONFIRM.getType()); + topic.setMessageType(MqttMessageTypeEnum.EVENT.getType()); header.setFunction(typesEnum.getReFunction()); logger.info("\r\n=====>>>回复站端的EVENT消息--MQTT发送到消息主题:{},头部信息:{},message:{}", topic,header, JSONUtil.parseObj(response, new JSONConfig().setDateFormat(DatePattern.NORM_DATETIME_PATTERN))); sendAESMessage(topic, header, response); diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/OpenParams.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/OpenParams.java new file mode 100644 index 0000000..954b106 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/OpenParams.java @@ -0,0 +1,20 @@ +package com.evotech.hd.cloud.open; + +import lombok.Data; + +/** + * 类 + * + * @ClassName:OpenParams + * @date: 2025年08月19日 15:10 + * @author: andy.shi + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Data +public class OpenParams { + + private String stationCode; + private String sign; + private String data; + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/OpenStationController.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/OpenStationController.java new file mode 100644 index 0000000..b53495d --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/OpenStationController.java @@ -0,0 +1,52 @@ +package com.evotech.hd.cloud.open; + +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.asymmetric.Sign; +import cn.hutool.crypto.asymmetric.SignAlgorithm; +import com.alibaba.fastjson.JSONObject; +import com.evotech.hd.cloud.open.processor.StrategyFactory; +import com.evotech.hd.cloud.service.BatteryStationSecretKeyService; +import com.evotech.hd.common.core.Dto.Result; +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.utils.Collections; +import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Base64; +import java.util.Map; + +/** + * 类 + * + * @ClassName:OpenStationController + * @date: 2025年08月19日 15:07 + * @author: andy.shi + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Slf4j +@RestController +@RequestMapping("/open/station") +public class OpenStationController { + @Autowired + BatteryStationSecretKeyService batteryStationSecretKeyService; + @Autowired + private StrategyFactory strategyFactory; + + @PostMapping("/message") + public Result message(@Valid @RequestBody OpenParams params){ + Map secretKeyMap = batteryStationSecretKeyService.getStationSecretKeyByStationCode(params.getStationCode()); + if(Collections.isEmpty(secretKeyMap)){ + return Result.getInstance().error("未找到当前站端的秘钥信息"); + } + Sign verifier = SecureUtil.sign(SignAlgorithm.SHA256withRSA, null, secretKeyMap.get(HDConstant.PUBLIC_KEY)); + if(!verifier.verify(params.getData().getBytes(), Base64.getDecoder().decode(params.getSign()))){ + return Result.getInstance().error("当前信息已被篡改"); + } + return strategyFactory.exchange(JSONObject.parseObject(params.getData())); + } +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/StationMessageStrategyExchangeProcessor.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/StationMessageStrategyExchangeProcessor.java new file mode 100644 index 0000000..1d3d143 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/StationMessageStrategyExchangeProcessor.java @@ -0,0 +1,47 @@ +package com.evotech.hd.cloud.open.processor; + +import com.alibaba.fastjson.JSONObject; +import com.evotech.hd.common.core.Dto.Result; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 站控消息处理接口 + * + * @ClassName:StationMessageStrategyExchangeProcessor + * @date: 2025年08月20日 10:16 + * @author: andy.shi + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +public interface StationMessageStrategyExchangeProcessor { + + default boolean accept(String method){ + return getMethod().stream().filter(data-> data.equalsIgnoreCase(method)).count() > 0; + } + + /*** + * 默认读取子类除exchange 以外 所有的method + * 可以继承复写 + * 如 StationRunningStatusProcessor 子类之有一个exchange 可以复写 + * @return + */ + default List getMethod(){ + return Arrays.stream(this.getClass().getMethods()).filter(data-> !data.getName().equalsIgnoreCase("exchange")).map(data -> data.getName()).collect(Collectors.toList()); + } + + /*** + * 默认读取子类除exchange 以外 所有的method + * 可以继承复写 + * 如 StationRunningStatusProcessor 子类之有一个exchange 可以复写 + * @return + */ + default Result exchange(JSONObject json) throws Exception{ + Method method = this.getClass().getMethod(json.getString("method"), JSONObject.class); + return (Result) method.invoke(this, json); + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/StrategyFactory.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/StrategyFactory.java new file mode 100644 index 0000000..1c9d327 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/StrategyFactory.java @@ -0,0 +1,64 @@ +package com.evotech.hd.cloud.open.processor; + +/** + * 类 + * + * @ClassName:StrategyFactory + * @date: 2025年08月21日 14:11 + * @author: andy.shi + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ + +import com.alibaba.fastjson.JSONObject; +import com.evotech.hd.common.core.Dto.Result; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +/*** + * 策略工厂 + */ +@Component +public class StrategyFactory implements InitializingBean, ApplicationContextAware { + + private ApplicationContext applicationContext; + + private static final Map CONTEXT = new HashMap<>(); + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @Override + public void afterPropertiesSet(){ + // 手动将所有实现注册到工厂容器 + applicationContext.getBeansOfType(StationMessageStrategyExchangeProcessor.class) + .values() + .forEach(exchange -> CONTEXT.putIfAbsent(exchange.getClass().getSimpleName().toLowerCase(), exchange)); + } + + public Result exchange(JSONObject json) { + try { + StationMessageStrategyExchangeProcessor processor = CONTEXT.get(json.getString("class").toLowerCase()); + if (ObjectUtils.isEmpty(processor)){ + return Result.getInstance().error("当前接口不存在"); + } + if(processor.accept(json.getString("method"))){ + return processor.exchange(json); + } + return Result.getInstance().error("当前method不存在"); + } catch (Exception e) { + Throwable realException = e.getCause(); // 获取实际的异常 + realException.printStackTrace(); + e.printStackTrace(); + return Result.getInstance().error(e.getMessage()); + } + } +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/AlarmProcessor.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/AlarmProcessor.java new file mode 100644 index 0000000..601c308 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/AlarmProcessor.java @@ -0,0 +1,62 @@ +package com.evotech.hd.cloud.open.processor.impl; + +import com.alibaba.fastjson.JSONObject; +import com.evotech.hd.cloud.mqtt.enums.StateFunctionTypesEnum; +import com.evotech.hd.cloud.open.processor.StationMessageStrategyExchangeProcessor; +import com.evotech.hd.cloud.service.BatteryStationService; +import com.evotech.hd.common.constant.MongoConstant; +import com.evotech.hd.common.core.Dto.Result; +import com.evotech.hd.common.core.utils.Collections; +import com.evotech.hd.common.documnet.StationState; +import com.evotech.hd.common.service.MongoDBService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 告警信息处理类 + * + * @ClassName:AlarmProcessor + * @date: 2025年08月23日 14:58 + * @author: andy.shi + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Slf4j +@Service +public class AlarmProcessor implements StationMessageStrategyExchangeProcessor { + + @Resource + BatteryStationService batteryStationService; + @Resource + MongoDBService mongoDBService; + + @Override + public List getMethod() { + return Collections.asList("alarmMessage"); + } + + @Override + public Result exchange(JSONObject json) { +// BatteryStation batteryStation = batteryStationDao.selectOne(new LambdaQueryWrapper().eq(BatteryStation::getCode, json.getString("stationCode")), false); + try { + /*** + * state: 获取运行状态 1-运营;2-调试;3-检修; + * smoke: 获取烟感告警信号, 多个烟感状态,分割, 每个代表一个烟感的状态 0-未知;1-正常;2-告警 + * fire: 获取消防告警信号 0-未知;1-正常;2-告警 + */ + batteryStationService.updateStatusByAlarm(json.getString("stationCode"), json.getInteger("state"), json.getString("smoke"), json.getInteger("fire")); + } catch (Exception e) { + log.error("更改云端数据信息出错"+e.getMessage()); + }finally { + StationState document = new StationState(json.toJSONString()); + document.setId(String.valueOf(System.currentTimeMillis())); + document.setStationCode(json.getString("stationCode")); + mongoDBService.save(MongoConstant.STATION_INFO_BASE, StateFunctionTypesEnum.FUN_STATION_STATE.getFunction(), document); + + } + + return null; + } +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/OrderSwapBatteryPreProcessor.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/OrderSwapBatteryPreProcessor.java new file mode 100644 index 0000000..b98a9d0 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/OrderSwapBatteryPreProcessor.java @@ -0,0 +1,94 @@ +package com.evotech.hd.cloud.open.processor.impl; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.evotech.hd.cloud.dao.BatteryStationDao; +import com.evotech.hd.cloud.open.processor.StationMessageStrategyExchangeProcessor; +import com.evotech.hd.cloud.service.OrderSwapBatteryPreService; +import com.evotech.hd.cloud.service.WechatUserService; +import com.evotech.hd.common.core.Dto.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStation; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre; +import com.evotech.hd.common.core.entity.wechat.WechatUser; +import jakarta.annotation.Resource; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; + +/** + * 站端新增预约订单 + * + * @ClassName:AddOrderSwapBatteryPreProcessor + * @date: 2025年08月20日 15:56 + * @author: andy.shi + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Service +public class OrderSwapBatteryPreProcessor implements StationMessageStrategyExchangeProcessor { + @Resource + WechatUserService wechatUserService; + @Resource + private BatteryStationDao batteryStationDao; + @Resource + OrderSwapBatteryPreService orderSwapBatteryPreService; + + /*** + * 取消预约单, 禁止删除, 反射调用 + * @param json + * @return + */ + public Result orderSwapBatteryPreUpdateStatus(JSONObject json){ + return orderSwapBatteryPreService.updateStatusById(json.getInteger("pkId"), json.getInteger("status")); + } + + /*** + * 新增预约单 禁止删除, 反射调用 + * @param json + * @return + */ + public Result orderSwapBatteryPreAdd(JSONObject json){ + BatteryStation batteryStation = batteryStationDao.selectOne(new LambdaQueryWrapper().eq(BatteryStation::getCode, json.getString("stationCode")), false); + if(ObjectUtils.isEmpty(batteryStation)){ + return Result.getInstance().error("未找到站点信息, 站端编码异常"); + } + OrderSwapBatteryPre orderSwapBatteryPre = JSONObject.parseObject(json.toJSONString(), OrderSwapBatteryPre.class); + //添加预约单 + WechatUser wechatUser =wechatUserService.selectUcode(orderSwapBatteryPre.getPhone(),orderSwapBatteryPre.getUname()); + if(ObjectUtils.isEmpty(wechatUser)){ + return Result.getInstance().error("未找到预约人信息"); + } + orderSwapBatteryPre.setUcode(wechatUser.getWuid()); + orderSwapBatteryPre.setUname(wechatUser.getName()); + orderSwapBatteryPre.setSourceId(String.valueOf(batteryStation.getPkId())); + Result saveResult = orderSwapBatteryPreService.addOrderSwapBatteryPre(orderSwapBatteryPre); + if(saveResult.getData()){ + return Result.getInstance().build(JSONObject.class).success(JSONObject.parseObject(JSONObject.toJSONString(orderSwapBatteryPre))); + } + return Result.getInstance().build(JSONObject.class).error(saveResult.getMsg()); + } + + /*** + * 查询预约单, 禁止删除, 反射调用 + * @param json + * @return + */ + public Result findOrderSwapBatteryPre(JSONObject json){ + try { + Date limitDate = json.getDate("limitDate"); + LambdaQueryWrapper query = new LambdaQueryWrapper().eq(OrderSwapBatteryPre::getStationCode, json.getString("stationCode")).eq(OrderSwapBatteryPre::getStatus,1).ne(OrderSwapBatteryPre::getSource,3); + if(limitDate != null){ + query.apply(" DATE_FORMAT(reservation_time,'%Y-%m-%d') >= {0}", DateFormatUtils.format(limitDate, "yyyy-MM-dd")); + } + List orderSwapBatteryPre = orderSwapBatteryPreService.list(query); + return Result.getInstance().build(JSONArray.class).success((JSONArray)JSONArray.toJSON(orderSwapBatteryPre)); + } catch (Exception e) { + e.printStackTrace(); + return Result.getInstance().build(JSONObject.class).error("查询云端预约单信息失败"); + } + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/OrderSwapProcessor.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/OrderSwapProcessor.java new file mode 100644 index 0000000..3f66bb5 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/OrderSwapProcessor.java @@ -0,0 +1,95 @@ +package com.evotech.hd.cloud.open.processor.impl; + +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.evotech.hd.cloud.mqtt.message.MessageTopic; +import com.evotech.hd.cloud.mqtt.message.processor.strategy.impl.state.MqttStateSwapStepDataExchangeProcessor; +import com.evotech.hd.cloud.open.processor.StationMessageStrategyExchangeProcessor; +import com.evotech.hd.cloud.service.OrderService; +import com.evotech.hd.cloud.service.OrderSwapBatteryPreService; +import com.evotech.hd.cloud.service.OrderSwapBatteryStepService; +import com.evotech.hd.common.core.Dto.Result; +import com.evotech.hd.common.core.Dto.ResultUtil; +import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre; +import com.evotech.hd.common.core.entity.order.Order; +import com.evotech.hd.common.core.enums.OrderStatusEnums; +import com.evotech.hd.common.core.enums.SwapBatteryStepEnum; +import com.evotech.hd.common.core.utils.Collections; +import com.evotech.hd.common.redis.utils.RedisServiceUtils; +import jakarta.annotation.Resource; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.stereotype.Service; + +import java.util.Date; + +/** + * 换电订单类 + * + * @ClassName:OrderSwapProcessor + * @date: 2025年08月21日 13:19 + * @author: andy.shi + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Service +public class OrderSwapProcessor implements StationMessageStrategyExchangeProcessor { + @Resource + OrderSwapBatteryPreService orderSwapBatteryPreService; + @Resource + OrderService orderService; + @Resource + private OrderSwapBatteryStepService orderSwapBatteryStepService; + @Resource + private MqttStateSwapStepDataExchangeProcessor mqttStateSwapStepDataExchangeProcessor; + + /*** + * 新增换电单 禁止删除, 反射调用 + * @param json + * @return + */ + public Result orderSwapAdd(JSONObject json){ + String errorMsg = ""; + OrderSwapBatteryPre orderSwapBatteryPre = orderSwapBatteryPreService.getById(json.getInteger("preId")); + Order order = orderService.getOne(new LambdaQueryWrapper() + .eq(Order::getPlateNum, orderSwapBatteryPre.getPlateNum()) + .eq(Order::getStationCode, orderSwapBatteryPre.getStationCode()) + .eq(Order::getOrderPreId, orderSwapBatteryPre.getPkId()) + .in(Order::getStatus, Collections.asList(OrderStatusEnums.CREATE.getCode(), OrderStatusEnums.SWAP.getCode()))); + if (ObjectUtils.isNotEmpty(order)) { + return Result.getInstance().build(JSONObject.class).success((JSONObject)JSONObject.toJSON(order)); + }else{ + Result result = orderService.addOrderByPre(orderSwapBatteryPre); + //如果不等于成功 + if(ResultUtil.verifyCode(result)){ + order = result.getData(); + //走到此处, 证明上面逻辑没有问题, 需要删除预约单过期标识 + RedisServiceUtils.del("preorder:expire:"+orderSwapBatteryPre.getPkId()); + //更新预约单为到店使用 + orderSwapBatteryPre.setStatus(2); + orderSwapBatteryPreService.updateById(orderSwapBatteryPre); + orderSwapBatteryStepService.addOrderSwapBatteryStepBySwapComplete(order.getOrderNo(), SwapBatteryStepEnum.VEHICLES_ENTER_STATION.getKey(), new Date()); + return Result.getInstance().build(JSONObject.class).success((JSONObject)JSONObject.toJSON(order)); + } + errorMsg = result.getMsg(); + } + return Result.getInstance().build(JSONObject.class).error(errorMsg, null); + } + + /*** + * 车辆到位信息 + * @param json + * @return + */ + public Result arrivalSignal(JSONObject json){ + try { + Order order = orderService.getById(json.getInteger("preId")); + json.put("orderNo", order.getOrderNo()); + mqttStateSwapStepDataExchangeProcessor.exchange(new MessageTopic(json.getString("stationCode")+"_WEB站推送", "http"), null, JSONUtil.parseObj(json.toJSONString())); + return Result.getInstance().build(Boolean.class).success(true); + } catch (Exception e) { + e.printStackTrace();; + return Result.getInstance().build(Boolean.class).error(e.getMessage(), null); + } + + } +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/StationRunningStatusProcessor.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/StationRunningStatusProcessor.java new file mode 100644 index 0000000..9643f7d --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/open/processor/impl/StationRunningStatusProcessor.java @@ -0,0 +1,49 @@ +package com.evotech.hd.cloud.open.processor.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.evotech.hd.cloud.dao.BatteryStationDao; +import com.evotech.hd.cloud.open.processor.StationMessageStrategyExchangeProcessor; +import com.evotech.hd.cloud.service.BatteryStationService; +import com.evotech.hd.common.core.Dto.Result; +import com.evotech.hd.common.core.entity.cloud.BatteryStation; +import com.evotech.hd.common.core.utils.Collections; +import jakarta.annotation.Resource; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 站端调整运行.停运状态 + * + * @ClassName:StationRunningStatusProcessor + * @date: 2025年08月20日 10:18 + * @author: andy.shi + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Service +public class StationRunningStatusProcessor implements StationMessageStrategyExchangeProcessor { + + @Autowired + BatteryStationService batteryStationService; + @Resource + private BatteryStationDao batteryStationDao; + + @Override + public List getMethod() { + return Collections.asList("updateStationRunningStatus"); + } + + @Override + public Result exchange(JSONObject json) { + BatteryStation batteryStation = batteryStationDao.selectOne(new LambdaQueryWrapper().eq(BatteryStation::getCode, json.getString("stationCode")), false); + if(ObjectUtils.isEmpty(batteryStation)){ + return Result.getInstance().error("未找到站点信息, 站端编码异常"); + } + //修改运行状态, 1为正常运营, 4为指令停运 + batteryStation.setStatus(json.getBoolean("status") ? 1 : 4); + return batteryStationService.update(batteryStation); + } +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationSecretKeyService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationSecretKeyService.java new file mode 100644 index 0000000..32744c0 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/BatteryStationSecretKeyService.java @@ -0,0 +1,8 @@ +package com.evotech.hd.cloud.service; + +import java.util.Map; + +public interface BatteryStationSecretKeyService { + + public Map getStationSecretKeyByStationCode(String stationCode); +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderService.java index d465ee5..2fa36e5 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderService.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.evotech.hd.cloud.entity.vo.NativePayVO; import com.evotech.hd.common.core.Dto.Result; +import com.evotech.hd.common.core.Dto.order.OrderBillListVo; import com.evotech.hd.common.core.Dto.order.OrderDetailVo; import com.evotech.hd.common.core.Dto.order.OrderListVo; import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre; @@ -76,4 +77,8 @@ public interface OrderService extends IService { Result one(String orderNo); Result getOneByOrderNo(String orderNo); + + Result> billList(String companyCode, String orderTimeEnd); + + void excelBillList(String companyCode, String orderTimeEnd); } diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderSwapBatteryPreService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderSwapBatteryPreService.java index f1bd5b6..af0160b 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderSwapBatteryPreService.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/OrderSwapBatteryPreService.java @@ -25,7 +25,7 @@ public interface OrderSwapBatteryPreService extends IService> list(PageListSwapOrderPreRequest plsopr); - public Result cancelPre(Integer id, Integer status); + public Result updateStatusById(Integer id, Integer status); List findOrderSwapBatteryPreList(String stationCode); diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/TradeService.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/TradeService.java index c9972ee..6d01d96 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/TradeService.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/TradeService.java @@ -15,7 +15,11 @@ public interface TradeService extends IService { public Result delete(Integer id); public Result update(TradeDetail td); - + + public Result submit(TradeDetail td); + + public Result approve(Integer id, Integer type); + public Result> list(PageListTradeRequest pltr); public List tradeList(PageListTradeRequest pltr); diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationSecretKeyServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationSecretKeyServiceImpl.java new file mode 100644 index 0000000..c68910f --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationSecretKeyServiceImpl.java @@ -0,0 +1,38 @@ +package com.evotech.hd.cloud.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.evotech.hd.cloud.dao.BatteryStationSecretKeyDao; +import com.evotech.hd.cloud.entity.BatteryStationSecretKey; +import com.evotech.hd.cloud.service.BatteryStationSecretKeyService; +import com.evotech.hd.common.core.constant.HDConstant; +import com.evotech.hd.common.core.utils.Collections; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service +@Slf4j +public class BatteryStationSecretKeyServiceImpl implements BatteryStationSecretKeyService { + + + @Resource + private BatteryStationSecretKeyDao batteryStationSecretKeyDao; + + + @Override + public Map getStationSecretKeyByStationCode(String stationCode) { + BatteryStationSecretKey existingKey = batteryStationSecretKeyDao.selectOne( + new QueryWrapper() + .eq("type", 1) + .eq("station_code", stationCode), + false + ); + if (existingKey != null) { + // 如果存在密钥对,则直接返回 + return Collections.asMap(HDConstant.PUBLIC_KEY, existingKey.getPublicKey(),HDConstant.PRIVATE_KEY, existingKey.getPrivateKey()); + } + return Collections.emptyMap(); + } +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java index 07ab48d..be5f019 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/BatteryStationServiceImpl.java @@ -3,7 +3,7 @@ package com.evotech.hd.cloud.service.impl; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.IoUtil; -import cn.hutool.crypto.KeyUtil; +import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -188,7 +188,7 @@ public class BatteryStationServiceImpl implements BatteryStationService { return new Result>().success(map); } else { // 如果不存在密钥对,则生成新的密钥对 - KeyPair keyPair = KeyUtil.generateKeyPair(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue()); + KeyPair keyPair = SecureUtil.generateKeyPair(AsymmetricAlgorithm.RSA.getValue()); // 将私钥转换为Base64编码的字符串 String privatekeyBase64String = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()); // 将公钥转换为Base64编码的字符串 @@ -373,7 +373,7 @@ public class BatteryStationServiceImpl implements BatteryStationService { //如果消防没有报警, 检查烟感 if(!isAlarm){ //因为烟感有多个, 所以一个烟感报警,及存在报警信息 - isAlarm = Collections.asList(smoke.split(",")).contains(MongoConstant.ErrorCode.STATION_ALARM_CODE); + isAlarm = org.apache.commons.lang3.StringUtils.isNotEmpty(smoke) && Collections.asList(smoke.split(",")).contains(MongoConstant.ErrorCode.STATION_ALARM_CODE); if(isAlarm){ alarmMsg.append("烟感报警"); } diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/HomeServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/HomeServiceImpl.java index 1394ff3..8e96165 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/HomeServiceImpl.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/HomeServiceImpl.java @@ -21,11 +21,13 @@ import com.evotech.hd.common.core.entity.cloud.*; import com.evotech.hd.common.core.entity.resource.ProxyOperater; import com.evotech.hd.common.core.entity.wechat.WechatUser; import com.evotech.hd.common.core.utils.Collections; +import com.evotech.hd.common.core.utils.DataUtils; import com.evotech.hd.common.documnet.StationState; import com.evotech.hd.common.redis.utils.RedisUtil; import com.evotech.hd.common.service.MongoDBService; import jakarta.annotation.Resource; import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; @@ -235,7 +237,7 @@ public class HomeServiceImpl implements HomeService { //待结算订单数量 data.setPendingOrderNum(Long.valueOf(orderInfo.size())); //待结算订单金额 - data.setPendingOrderAmount(orderInfo.stream().collect(Collectors.summingDouble( i-> i.getSwapAmount()))); + data.setPendingOrderAmount(orderInfo.stream().collect(Collectors.summingDouble( i-> DataUtils.findDefaultValue(i.getSwapAmount(), DataUtils.DEFAULT_VALUE.doubleValue())))); //待结算订单信息 data.setOrderList(orderInfo); @@ -253,16 +255,29 @@ public class HomeServiceImpl implements HomeService { if(Collections.isNotEmpty(alarmList)){ StationState stationState= alarmList.get(0); //报警信息 - JSONObject alarmJSONObject = JSONObject.parseObject(alarmList.get(0).getValue()); + JSONObject alarmJSONObject = JSONObject.parseObject(stationState.getValue()); Integer fire = alarmJSONObject.getInteger("fire"); - if(MongoConstant.ErrorCode.STATION_ALARM_CODE.equals(fire)){ - alarm.setAlarmType("消防告警"); - }else{ - String smoke = alarmJSONObject.getString("smoke"); - if(Collections.asList(smoke.split(",")).contains(String.valueOf(MongoConstant.ErrorCode.STATION_ALARM_CODE))){ - alarm.setAlarmType("烟感告警"); - } + List alarmMessage = Collections.emptyList(); + if(ObjectUtils.isNotEmpty(fire) && MongoConstant.ErrorCode.STATION_ALARM_CODE.equals(fire)){ + alarmMessage.add("消防告警"); } + String smoke = alarmJSONObject.getString("smoke"); + if(StringUtils.isNotEmpty(smoke) && Collections.asList(smoke.split(",")).contains(String.valueOf(MongoConstant.ErrorCode.STATION_ALARM_CODE))){ + alarmMessage.add("烟感告警"); + } + Integer water = alarmJSONObject.getInteger("water"); + if(ObjectUtils.isNotEmpty(water) && MongoConstant.ErrorCode.STATION_ALARM_CODE.equals(water)){ + alarmMessage.add("水浸告警"); + } + Integer thunder = alarmJSONObject.getInteger("thunder"); + if(ObjectUtils.isNotEmpty(thunder) && MongoConstant.ErrorCode.STATION_ALARM_CODE.equals(thunder)){ + alarmMessage.add("雷击信号"); + } + Integer stop = alarmJSONObject.getInteger("stop"); + if(ObjectUtils.isNotEmpty(stop) && MongoConstant.ErrorCode.STATION_ALARM_CODE.equals(stop)){ + alarmMessage.add("急停信号"); + } + alarm.setAlarmType(String.join(";", alarmMessage)); alarm.setAlarmTime(DateUtil.format(new Date(Long.valueOf(stationState.getId())), "yyyy-MM-dd HH:mm:ss")); } }); diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderServiceImpl.java index daa97f2..8959ed0 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderServiceImpl.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderServiceImpl.java @@ -7,6 +7,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONConfig; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -28,9 +29,11 @@ import com.evotech.hd.cloud.service.TradeService; import com.evotech.hd.cloud.service.WalletAccountService; import com.evotech.hd.cloud.service.rpc.WechatService; import com.evotech.hd.cloud.utils.CommonUtil; +import com.evotech.hd.cloud.utils.ExcelUtil; import com.evotech.hd.cloud.utils.ParamServiceUtils; import com.evotech.hd.cloud.utils.components.SwapOrderBasicFeeComponent; import com.evotech.hd.common.core.Dto.Result; +import com.evotech.hd.common.core.Dto.order.OrderBillListVo; import com.evotech.hd.common.core.Dto.order.OrderDetailVo; import com.evotech.hd.common.core.Dto.order.OrderListVo; import com.evotech.hd.common.core.constant.HDConstant; @@ -41,10 +44,15 @@ import com.evotech.hd.common.core.entity.cloud.request.BatterySwapResponse; import com.evotech.hd.common.core.entity.cloud.request.PageListSwapOrderRequest; import com.evotech.hd.common.core.entity.order.Order; import com.evotech.hd.common.core.entity.order.OrderDetail; +import com.evotech.hd.common.core.entity.resource.auth.AuthUser; import com.evotech.hd.common.core.enums.CodeMsg; import com.evotech.hd.common.core.enums.OrderStatusEnums; import com.evotech.hd.common.core.enums.PayTypeEnums; import com.evotech.hd.common.core.enums.TradeTypeEnums; +import com.evotech.hd.common.core.utils.Collections; +import com.evotech.hd.common.core.utils.DataUtils; +import com.evotech.hd.common.permission.util.RedisPermissionUtils; +import com.evotech.hd.common.permission.util.SpringUtil; import com.evotech.hd.common.redis.utils.RedisServiceUtils; import com.evotech.hd.common.web.util.EnumUtils; import jakarta.annotation.Resource; @@ -115,8 +123,9 @@ public class OrderServiceImpl extends ServiceImpl implements Or .ge(ObjectUtils.isNotEmpty(plsor.getOrderTimeBegin()), Order::getOrderTime, plsor.getOrderTimeBegin()) .le(ObjectUtils.isNotEmpty(plsor.getOrderTimeEnd()), Order::getOrderTime, plsor.getOrderTimeEnd()) .eq(StringUtils.isNotEmpty(plsor.getStationCode()), Order::getStationCode, plsor.getStationCode()) - .eq(StringUtils.isNotEmpty(plsor.getTradeNo()), Order::getNotifyOrderNo, plsor.getTradeNo()) + .eq(StringUtils.isNotEmpty(plsor.getTradeNo()), Order::getTradeNo, plsor.getTradeNo()) .eq(StringUtils.isNotEmpty(plsor.getStatus()), Order::getStatus, plsor.getStatus()) + .eq(StringUtils.isNotEmpty(plsor.getUserId()), Order::getPreWechatId, plsor.getUserId()) .ne(Order::getDelFlag, 1) .orderByDesc(Order::getOrderTime)); @@ -379,7 +388,7 @@ public class OrderServiceImpl extends ServiceImpl implements Or // 修改订单状态 order.setStatus(OrderStatusEnums.FINISH.getCode()); //交易编码 - //order.setTradeNo(trade.getOutTradeNo()); + order.setTradeNo(trade.getOutTradeNo()); order.setUpdateTime(new Date()); orderDao.updateById(order); log.info("订单支付成功, 订单编号: {}", order.getOrderNo()); @@ -393,8 +402,20 @@ public class OrderServiceImpl extends ServiceImpl implements Or } @Override - public Result companyNativePay(NativePayVO prePay) { - return wechatService.wechatNativePay(prePay); + public Result companyNativePay(NativePayVO prePay) { + + List list = getBaseMapper().findBillList(prePay.getCcode(), prePay.getOrderTimeEnd()); + if(Collections.isNotEmpty(list)){ + prePay.setTotal(list.stream().collect(Collectors.summingDouble(d-> DataUtils.findDefaultValue(d.getOrderAmount(), DataUtils.DEFAULT_VALUE.intValue()))).intValue()); + prePay.setTotal(1); + Result result = wechatService.wechatNativePay(prePay); + if(CodeMsg.SUCCESS.getCode().equals(result.getCode())){ + JSONObject res = JSON.parseObject(result.getData()); + settlementInProgress(list, res.getString("OutTradeNo"), PayTypeEnums.WECHAT.getCode()); + } + return result; + } + return Result.getInstance().build(String.class).error("为找到订单信息"); } @Override @@ -427,21 +448,20 @@ public class OrderServiceImpl extends ServiceImpl implements Or @Override public Result checkList(PageListSwapOrderRequest plsor) { Page page = new Page(plsor.getPageNo(), plsor.getPageSize()); - List statusList = new ArrayList<>(); - String strs = "1,2,3,4,5,6"; - if (StringUtils.isBlank(strs)) {//订单状态"已完成"之前的状态 - statusList = Arrays.asList(strs.split(",")).stream().map(Integer::valueOf).toList(); - } +// String strs = "1,2,3,4,5,6"; +// if (StringUtils.isBlank(strs)) {//订单状态"已完成"之前的状态 +// statusList = Arrays.asList(strs.split(",")).stream().map(Integer::valueOf).toList(); +// } page = orderDao.selectPage(page, new QueryWrapper() - .eq(StringUtils.isBlank(plsor.getOrderNo()), "order_no", plsor.getOrderNo()) - .eq(StringUtils.isBlank(plsor.getPlateNum()), "plate_num", plsor.getPlateNum()) - .in(!statusList.isEmpty(), "status", statusList) + .eq(StringUtils.isNotBlank(plsor.getOrderNo()), "order_no", plsor.getOrderNo()) + .eq(StringUtils.isNotBlank(plsor.getPlateNum()), "plate_num", plsor.getPlateNum()) + .in("status", Collections.asList(1,2,3,4,5,6)) .ge(plsor.getOrderTimeBegin() != null, "order_time", plsor.getOrderTimeBegin()) .le(plsor.getOrderTimeEnd() != null, "order_time", plsor.getOrderTimeEnd()) - .eq(StringUtils.isBlank(plsor.getStationCode()), "station_code", plsor.getStationCode()) - .like(StringUtils.isBlank(plsor.getStationName()), "station_name", plsor.getStationName()) - .eq(StringUtils.isBlank(plsor.getUserId()), "order_pre_uid", plsor.getUserId()) - .eq(StringUtils.isBlank(plsor.getTradeNo()), "trade_no", plsor.getTradeNo()) + .eq(StringUtils.isNotBlank(plsor.getStationCode()), "station_code", plsor.getStationCode()) + .like(StringUtils.isNotBlank(plsor.getStationName()), "station_name", plsor.getStationName()) + .eq(StringUtils.isNotBlank(plsor.getUserId()), "pre_wechat_id", plsor.getUserId()) + .eq(StringUtils.isNotBlank(plsor.getTradeNo()), "trade_no", plsor.getTradeNo()) .ne("del_flag", 1) .orderByDesc("pk_id")); if (!page.getRecords().isEmpty()) { @@ -449,8 +469,8 @@ public class OrderServiceImpl extends ServiceImpl implements Or } Page page1 = new Page(plsor.getPageNo(), plsor.getPageSize()); page1 = orderSwapBatteryPreDao.selectPage(page1, new QueryWrapper() - .eq(StringUtils.isBlank("1"), "status", "1") - .eq(StringUtils.isBlank(plsor.getPlateNum()), "plate_num", plsor.getPlateNum()) + .eq("status", "1") + .eq(StringUtils.isNotBlank(plsor.getPlateNum()), "plate_num", plsor.getPlateNum()) .orderByDesc("pk_id")); if (!page1.getRecords().isEmpty()) { return new Result().error("该车辆有预约成功的订单,请处理后重试!"); @@ -514,6 +534,90 @@ public class OrderServiceImpl extends ServiceImpl implements Or BeanUtils.copyProperties(orderDetail, orderDetailVo); return new Result().success(orderDetailVo); } + + @Override + public Result> billList(String companyCode, String orderTimeEnd) { + + List resultList = Collections.emptyList(); + + List list = getBaseMapper().findBillList(companyCode, orderTimeEnd); + if(Collections.isNotEmpty(list)){ + Map> dataMap = list.stream().collect(Collectors.groupingBy(d->d.getPlateNum())); + + for(List mapList : dataMap.values()){ + OrderBillListVo result = new OrderBillListVo(); + result.setPlateNum(mapList.get(0).getPlateNum()); + result.setOrderTotalAmount(mapList.stream().collect(Collectors.summingDouble(d-> DataUtils.findDefaultValue(d.getOrderAmount(), DataUtils.DEFAULT_VALUE.intValue())))); + result.setStatus(mapList.get(0).getStatus()); + result.setOrderNum(mapList.size()); + List childList = Collections.emptyList(); + for(Order order : mapList){ + OrderBillListVo resultChild = new OrderBillListVo(); + BeanUtils.copyProperties(order, resultChild); + resultChild.setPreName(order.getOrderPreUname()); + childList.add(resultChild); + } + result.setChildList(childList); + resultList.add(result); + } + } + return Result.getInstance().buildList(OrderBillListVo.class).success(resultList); + } + + @Override + public void excelBillList(String companyCode, String orderTimeEnd) { + List resultList = Collections.emptyList(); + + List list = getBaseMapper().findBillList(companyCode, orderTimeEnd); + if(Collections.isNotEmpty(list)){ + list = list.stream().sorted(Comparator.comparing(Order::getStationName)).collect(Collectors.toList()); + + for(Order order : list){ + OrderBillListVo result = new OrderBillListVo(); + BeanUtils.copyProperties(order, result); + result.setPreName(order.getOrderPreUname()); + result.setOrderAmountExcel((result.getOrderAmount() == null || result.getOrderAmount() == 0) ? 0d : new BigDecimal(result.getOrderAmount()).divide(new BigDecimal(100)).doubleValue()); + resultList.add(result); + } + } + + ExcelUtil util = new ExcelUtil(OrderBillListVo.class); + util.exportExcel(SpringUtil.getResponse(), resultList,"电子账单"); + + settlementInProgress(list, null, PayTypeEnums.BUSINESS_TO_BUSINESS.getCode()); + } + + + public void settlementInProgress(List list, String outTradeNo, Integer payType){ + //执行完导出后. 所有的订单信息,全部更新为结算中 + AuthUser user = RedisPermissionUtils.getUser(); + TradeDetail trade = new TradeDetail(); + trade.setOutTradeNo(StringUtils.isEmpty(outTradeNo) ? com.evotech.hd.common.core.utils.CommonUtil.payTradeNo(2) : outTradeNo); + trade.setTrader(user.getName()); + trade.setTraderCode(user.getUid()); + trade.setTradeType(TradeTypeEnums.PAYORDER.getCode()); + trade.setOrderCount(1); + trade.setTradeAmount(list.stream().collect(Collectors.summingInt(d-> DataUtils.findDefaultValue(d.getOrderAmount(), DataUtils.DEFAULT_VALUE.intValue())))); + trade.setPayType(payType); + trade.setPayResult("paymentInProgress"); + trade.setPayTime(new Date()); + trade.setStatus("edit"); + tradeService.add(trade); +// list.stream().forEach(data ->{ +// data.setTradeNo(trade.getOutTradeNo()); +// if(PayTypeEnums.BUSINESS_TO_BUSINESS.getCode() == payType){ +// data.setStatus(OrderStatusEnums.SETTLEMENT_IN_PROGRESS.getCode()); +// } +// }); +// updateBatchById(list); + Order order = list.get(0); + order.setTradeNo(trade.getOutTradeNo()); + if(PayTypeEnums.BUSINESS_TO_BUSINESS.getCode() == payType){ + order.setStatus(OrderStatusEnums.SETTLEMENT_IN_PROGRESS.getCode()); + } + updateById(order); + } + } diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderSwapBatteryPreServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderSwapBatteryPreServiceImpl.java index 71a02ef..fc0ef90 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderSwapBatteryPreServiceImpl.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/OrderSwapBatteryPreServiceImpl.java @@ -9,6 +9,13 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.evotech.hd.cloud.dao.BatteryStationDao; import com.evotech.hd.cloud.dao.OrderSwapBatteryPreDao; import com.evotech.hd.cloud.dao.VehicleInfoDao; +import com.evotech.hd.cloud.dao.VehicleWechatUserRelationDao; +import com.evotech.hd.cloud.mqtt.enums.EventFunctionTypesEnum; +import com.evotech.hd.cloud.mqtt.enums.MqttMessageTypeEnum; +import com.evotech.hd.cloud.mqtt.message.MessageTopic; +import com.evotech.hd.cloud.mqtt.message.MqttMessageHeader; +import com.evotech.hd.cloud.mqtt.message.dto.newer.req.MqttResponse; +import com.evotech.hd.cloud.mqtt.message.processor.strategy.impl.event.MqttStrategyEventExchangeProcessor; import com.evotech.hd.cloud.service.OrderSwapBatteryPreService; import com.evotech.hd.cloud.utils.CloudTemplateMessageUtils; import com.evotech.hd.common.core.Dto.Result; @@ -17,6 +24,7 @@ import com.evotech.hd.common.core.dao.wechat.WechatUserDao; import com.evotech.hd.common.core.entity.cloud.BatteryStation; import com.evotech.hd.common.core.entity.cloud.OrderSwapBatteryPre; import com.evotech.hd.common.core.entity.cloud.VehicleInfo; +import com.evotech.hd.common.core.entity.cloud.VehicleWechatUserRelation; import com.evotech.hd.common.core.entity.cloud.request.PageListSwapOrderPreRequest; import com.evotech.hd.common.core.entity.order.Order; import com.evotech.hd.common.core.entity.wechat.WechatUser; @@ -24,6 +32,7 @@ import com.evotech.hd.common.core.enums.CodeMsg; import com.evotech.hd.common.redis.utils.RedisServiceUtils; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @@ -51,7 +60,10 @@ public class OrderSwapBatteryPreServiceImpl extends ServiceImpl().error("未找到车辆信息", false); } - // 2. 检查预约人 if (!wechatUserDao.exists(new LambdaQueryWrapper().ne(WechatUser::getPhoneNumber, " ").isNotNull(WechatUser::getPhoneNumber).eq(WechatUser::getWuid, orderSwapBatteryPre.getUcode()))) { return new Result().error("用户认证信息不全!", false); } + + //检查用户是否拥有当前车辆换电的权限 + if (!vehicleWechatUserRelationDao.exists(new LambdaQueryWrapper().eq(VehicleWechatUserRelation::getPlateNum, orderSwapBatteryPre.getPlateNum()).eq(VehicleWechatUserRelation::getUcode, orderSwapBatteryPre.getUcode()))){ + return new Result().error("当前车辆不在您的名下!", false); + } + //判断换电站是否运营 status 不等于 1 则证明换电站未运营 if (batteryStationDao.exists(new LambdaQueryWrapper().eq(BatteryStation::getCode, orderSwapBatteryPre.getStationCode()).ne(BatteryStation::getStatus, 1))) { return new Result().error("该换电站未运营!", false); @@ -132,11 +149,30 @@ public class OrderSwapBatteryPreServiceImpl extends ServiceImpl().success(true); } return new Result().error("添加预约换电订单出错!", false); } + @Async + void pushStationControl(OrderSwapBatteryPre orderSwapBatteryPre){ + MessageTopic topic = new MessageTopic(); + topic.setStationCode(orderSwapBatteryPre.getStationCode()); + + MqttResponse response = new MqttResponse(); + // 订单状态更新处理 + response.setCode(MqttResponse.PUBLIC_SUCCESS); + response.setData(orderSwapBatteryPre); + + MqttMessageHeader header = new MqttMessageHeader(); + header.setTimeStamp(String.valueOf(System.currentTimeMillis())); + header.setIndex(String.valueOf(MqttMessageTypeEnum.EVENT.getId())); + mqttStrategyEventExchangeProcessor.sendAESMessage(topic , header, EventFunctionTypesEnum.FUN_PUSH_STATION_CONTRNL_DATA, response); + } + + @Override public Result> list(PageListSwapOrderPreRequest plsopr) { Page page = new Page(plsopr.getPageNo(), plsopr.getPageSize()); @@ -157,7 +193,7 @@ public class OrderSwapBatteryPreServiceImpl extends ServiceImpl cancelPre(Integer id, Integer status) { + public Result updateStatusById(Integer id, Integer status) { OrderSwapBatteryPre osbp = new OrderSwapBatteryPre(); osbp.setPkId(id); osbp.setStatus(status != null? status : 3); diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/TradeServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/TradeServiceImpl.java index eb681d0..d492d3c 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/TradeServiceImpl.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/TradeServiceImpl.java @@ -1,23 +1,30 @@ package com.evotech.hd.cloud.service.impl; import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.evotech.hd.cloud.dao.TradeDetailDao; import com.evotech.hd.cloud.entity.request.PageListTradeRequest; +import com.evotech.hd.cloud.service.TaxPointService; import com.evotech.hd.cloud.service.TradeService; import com.evotech.hd.cloud.service.newthread.GZHTemplateMessageService; import com.evotech.hd.cloud.service.newthread.WechatPayNotifyHandleService; import com.evotech.hd.common.core.Dto.Result; +import com.evotech.hd.common.core.constant.HDConstant; import com.evotech.hd.common.core.dao.cloud.OrderDao; import com.evotech.hd.common.core.entity.cloud.TradeDetail; +import com.evotech.hd.common.core.entity.order.Order; import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.common.core.enums.OrderStatusEnums; +import com.evotech.hd.common.core.utils.Collections; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import java.util.Date; @@ -34,6 +41,8 @@ public class TradeServiceImpl extends ServiceImpl i @Resource private GZHTemplateMessageService gzhTemplateMessageService; @Resource + TaxPointService taxPointService; + @Resource private OrderDao orderDao; @Override public Result add(TradeDetail td) { @@ -66,6 +75,45 @@ public class TradeServiceImpl extends ServiceImpl i return new Result().error("更新交易失败!"); } + @Override + public Result submit(TradeDetail td) { + td.setStatus("submit"); + return update(td); + } + + @Override + public Result approve(Integer id, Integer type) { + TradeDetail td = new TradeDetail(); + td.setStatus(type ==1 ? "finish" : "reject"); + td.setPkId(id); + Result result = update(td); + if(result.getData() != null && result.getData() ==1){ + td = getById(id); + List orderList = orderDao.selectList(new LambdaQueryWrapper().eq(Order::getTradeNo, td.getOutTradeNo())); + if(Collections.isNotEmpty(orderList)){ + orderList.stream().forEach(data ->{ + data.setStatus(OrderStatusEnums.FINISH.getCode()); + }); + orderDao.updateById(orderList); + //税点信息记录 + orderList.stream().forEach(order->{ + try { + taxPointService.addTaxPoint(order.getPkId(), order.getOrderNo(), Double.valueOf(order.getOrderAmount()), order.getStationCode()); + } catch (Exception e) { + log.error("生成税点信息异常,订单信息{}; 异常信息{}", JSON.toJSONString(order), e.getMessage()); + } + }); + + + } + + + + + } + return result; + } + @Override public Result > list(PageListTradeRequest pltr) { Page page = new Page(pltr.getPageNo(), pltr.getPageSize()); @@ -120,7 +168,28 @@ public class TradeServiceImpl extends ServiceImpl i Result result = payNotifyHandleService.payNotifyBusinessHandle(tradeDetail); //只有当整体数据处理成功之后, 才保存交易记录, 防止出现异常,二次请求进来数据无法处理 if(CodeMsg.SUCCESS.getCode().equals(result.getCode())){ - add(tradeDetail); + TradeDetail detail = tradeDetailDao.selectOne(new LambdaQueryWrapper().eq(TradeDetail::getOutTradeNo, tradeDetail.getOutTradeNo()).eq(TradeDetail::getDelFlag, HDConstant.DELETE_NO)); + tradeDetail.setStatus("finish"); + if(ObjectUtils.isEmpty(detail)){ + add(tradeDetail); + }else{ + detail.setStatus("finish"); + detail.setAppid(tradeDetail.getAppid()); + detail.setBankType(tradeDetail.getBankType()); + detail.setMchid(tradeDetail.getMchid()); + detail.setTransactionId(tradeDetail.getTransactionId()); + detail.setTradeAmount(tradeDetail.getTradeAmount()); + detail.setWechatPayApiType(tradeDetail.getWechatPayApiType()); + detail.setPayResult(tradeDetail.getPayResult()); + detail.setPayTime(tradeDetail.getPayTime()); + detail.setTradeMessage(tradeDetail.getTradeMessage()); + detail.setPayWechatId(tradeDetail.getPayWechatId()); + detail.setTrader(tradeDetail.getTrader()); + detail.setTraderCode(tradeDetail.getTraderCode()); + + update(detail); + } + } return result; } catch (Exception e) { diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/VehicleServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/VehicleServiceImpl.java index 91af678..abae2bb 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/VehicleServiceImpl.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/VehicleServiceImpl.java @@ -92,7 +92,7 @@ public class VehicleServiceImpl extends ServiceImpl .eq(StringUtils.hasText(plvr.getPhone()), "phone", plvr.getPhone()) .eq(StringUtils.hasText(plvr.getCcode()), "ccode", plvr.getCcode()) .ne("del_flag", 1) - .orderByAsc("plate_num")); + .orderByDesc("ctime")); if (page.getRecords().isEmpty()) { return new Result>().error(CodeMsg.DATABASE_RESULT_NULL); } diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/WalletAccountServiceImpl.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/WalletAccountServiceImpl.java index 9efcd44..a86a59d 100644 --- a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/WalletAccountServiceImpl.java +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/service/impl/WalletAccountServiceImpl.java @@ -24,6 +24,7 @@ import com.evotech.hd.common.core.entity.cloud.vo.WalletAccountVO; import com.evotech.hd.common.core.entity.wechat.WechatPayAttach; import com.evotech.hd.common.core.entity.wechat.WechatUser; import com.evotech.hd.common.core.enums.CodeMsg; +import com.evotech.hd.common.core.utils.DataUtils; import com.evotech.hd.common.core.utils.SnowflakeUtil; import jakarta.annotation.Resource; import org.slf4j.Logger; @@ -119,8 +120,11 @@ public class WalletAccountServiceImpl extends ServiceImpl() - .eq("code", wa.getCode()) + int n = walletAccountDao.update(wa1, new UpdateWrapper() + .set(org.apache.commons.lang3.StringUtils.isNotEmpty(wa.getAccName()), "acc_name",wa.getAccName()) + .set("gift_amount",wa.getGiftAmount()) + .set("recharge_Amount",wa.getRechargeAmount()) + .eq(org.apache.commons.lang3.StringUtils.isNotEmpty(wa.getCode()), "code", wa.getCode()) .eq("pk_id", wa.getPkId())); if (n == 1) { return new Result().success(n); @@ -131,10 +135,21 @@ public class WalletAccountServiceImpl extends ServiceImpl> list(PageListWalletRequest plwr) { + + if((org.apache.commons.lang3.StringUtils.isNotEmpty(plwr.getPhone()) || org.apache.commons.lang3.StringUtils.isNotEmpty(plwr.getAccName())) && org.apache.commons.lang3.StringUtils.isEmpty(plwr.getOwnerId())){ + plwr.setOwnerId("-1"); + WechatUser wechatUser = wechatUserDao.selectOne(new QueryWrapper() + .eq(StringUtils.hasText(plwr.getPhone()), "phone_number", plwr.getPhone()) + .or(StringUtils.hasText(plwr.getAccName()), i -> i.and(j -> j.eq("name", plwr.getAccName())) + .or(j -> j.eq("nick_name", plwr.getAccName())))); + if (wechatUser != null) { + plwr.setOwnerId(wechatUser.getWuid()); + } + } Page page = new Page<>(plwr.getPageNo(), plwr.getPageSize()); QueryWrapper queryWrapper = new QueryWrapper() .eq(StringUtils.hasText(plwr.getCode()), "code", plwr.getCode()) - .like(StringUtils.hasText(plwr.getAccName()), "acc_name", plwr.getAccName()) + //.like(StringUtils.hasText(plwr.getAccName()), "acc_name", plwr.getAccName()) .eq(StringUtils.hasText(plwr.getStationCode()), "station_code", plwr.getStationCode()) .eq(plwr.getOwnerType() != null, "owner_type", plwr.getOwnerType()) .eq(StringUtils.hasText(plwr.getOwnerId()), "owner_id", plwr.getOwnerId()) @@ -150,6 +165,7 @@ public class WalletAccountServiceImpl extends ServiceImpl().error("未知的支付类型"); } else if (tradeDetail.getTradeType() == 9) { @@ -190,8 +189,40 @@ public class WechatPayNotifyHandleService { * 一般企业多条付款 * @param tradeDetail */ - private void nativePayHandle(TradeDetail tradeDetail) { - List list = preOrderRelationSwapOrderDao.selectList(new QueryWrapper().eq("out_trade_no", tradeDetail.getOutTradeNo())); + private Result nativePayHandle(TradeDetail tradeDetail) { + try { + if (TradeResultEnums.SUCCESS.getName().equals(tradeDetail.getPayResult())) { + List list = orderDao.selectList(new LambdaQueryWrapper().eq(Order::getTradeNo, tradeDetail.getOutTradeNo()).select(Order::getPkId)); + List orderIdList = list.stream().map(i -> i.getPkId()).toList(); + orderDao.update(new UpdateWrapper().in("pk_id", orderIdList) + .set("status", OrderStatusEnums.FINISH.getCode())); + try { + list.stream().forEach(order -> { + //税点信息记录 + try { + taxPointService.addTaxPoint(order.getPkId(), order.getOrderNo(), Double.valueOf(order.getOrderAmount()), order.getStationCode()); + } catch (Exception e) { + log.error("生成税点信息异常,订单信息{}; 异常信息{}", JSON.toJSONString(order), e.getMessage()); + } + }); + } catch (Exception e) { + log.error("nativePay 生成税点信息异常,异常信息{}", e.getMessage()); + } + + return new Result().success("ok"); + } else { + return new Result().error("微信支付结果未成功" + tradeDetail.getPayResult()); + } + }catch (Exception e) { + log.error("===>>>支付订单存在问题:{}", JSONUtil.toJsonStr(tradeDetail)); + return new Result().error("支付订单存在问题"+ e.getMessage()); + } + + + + + + /*List list = preOrderRelationSwapOrderDao.selectList(new QueryWrapper().eq("out_trade_no", tradeDetail.getOutTradeNo())); List orderNoList = list.stream().map(i -> i.getOrderNo()).toList(); List orderList = orderDao.selectList(new QueryWrapper() .eq("status", 6).in("order_no", orderNoList)); @@ -214,7 +245,10 @@ public class WechatPayNotifyHandleService { }); } catch (Exception e) { log.error("nativePay 生成税点信息异常,异常信息{}", e.getMessage()); - } + }*/ + + + // 发送公众号消息,发给企业绑定的微信号 // templateMessageService.orderMessageSend(one, 3); } diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/DateUtils.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/DateUtils.java new file mode 100644 index 0000000..c491dab --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/DateUtils.java @@ -0,0 +1,321 @@ +package com.evotech.hd.cloud.utils; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.lang.management.ManagementFactory; +import java.math.BigDecimal; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.*; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +/** + * 时间工具类 + * + * @author evo + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils +{ + public static String YYYY = "yyyy"; + + public static String YYYY_MM = "yyyy-MM"; + + public static String YYYY_MM_DD = "yyyy-MM-dd"; + + public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + private static String[] parsePatterns = { + "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", + "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; + + /** + * 获取当前Date型日期 + * + * @return Date() 当前日期 + */ + public static Date getNowDate() + { + return new Date(); + } + + /** + * 获取当前日期, 默认格式为yyyy-MM-dd + * + * @return String + */ + public static String getDate() + { + return dateTimeNow(YYYY_MM_DD); + } + + public static final String getTime() + { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + public static final String dateTimeNow() + { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + public static final String dateTimeNow(final String format) + { + return parseDateToStr(format, new Date()); + } + + public static final String dateTime(final Date date) + { + return parseDateToStr(YYYY_MM_DD, date); + } + + public static final String parseDateToStr(final String format, final Date date) + { + return new SimpleDateFormat(format).format(date); + } + + public static final Date dateTime(final String format, final String ts) + { + try + { + return new SimpleDateFormat(format).parse(ts); + } + catch (ParseException e) + { + throw new RuntimeException(e); + } + } + + /** + * 日期路径 即年/月/日 如2018/08/08 + */ + public static final String datePath() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy/MM/dd"); + } + + /** + * 日期路径 即年/月/日 如20180808 + */ + public static final String dateTime() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMdd"); + } + + /** + * 日期型字符串转化为日期 格式 + */ + public static Date parseDate(Object str) + { + if (str == null) + { + return null; + } + try + { + return parseDate(str.toString(), parsePatterns); + } + catch (ParseException e) + { + return null; + } + } + + /** + * 获取服务器启动时间 + */ + public static Date getServerStartDate() + { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 计算相差天数 + */ + public static int differentDaysByMillisecond(Date date1, Date date2) + { + return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24))); + } + + /** + * 计算时间差 + * + * @param endDate 最后时间 + * @param startTime 开始时间 + * @return 时间差(天/小时/分钟) + */ + public static String timeDistance(Date endDate, Date startTime) + { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - startTime.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒//输出结果 + // long sec = diff % nd % nh % nm / ns; + return day + "天" + hour + "小时" + min + "分钟"; + } + + /** + * 增加 LocalDateTime ==> Date + */ + public static Date toDate(LocalDateTime temporalAccessor) + { + ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } + + /** + * 增加 LocalDate ==> Date + */ + public static Date toDate(LocalDate temporalAccessor) + { + LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); + ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } + + + public static Integer getBetweenYear(Date start, Date end, Integer offsetDay){ + Calendar cal1 = Calendar.getInstance(); + cal1.setTime(start); + Long days = new BigDecimal(getBetweenDays(start, end)).add(new BigDecimal(offsetDay)).longValue(); + int yearsDiff = 0; + long remainingDays = days; + while (remainingDays >= 365) { + int year = cal1.get(Calendar.YEAR) + yearsDiff; + //int daysInYear = ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ? 366 : 365; + int daysInYear = 365; + if (remainingDays >= daysInYear) { + remainingDays -= daysInYear; + yearsDiff++; + } else { + break; + } + } + + return yearsDiff; + } + + public static Integer getBetweenYearByDays(Date start, Date end){ + return getBetweenYear(start, end, 0); + } + + public static Integer getBetweenMonth(Date start, Date end){ + Calendar currentDate = Calendar.getInstance(); + currentDate.setTime(start); + + // 将输入的Date转换为Calendar以便获取年月信息 + Calendar endCalendar = Calendar.getInstance(); + endCalendar.setTime(end); + // 计算年份差和月份差 + int yearsDiff = endCalendar.get(Calendar.YEAR) - currentDate.get(Calendar.YEAR); + int monthsDiff = endCalendar.get(Calendar.MONTH) - currentDate.get(Calendar.MONTH); + + // 调整月份差,考虑到年份差可能影响实际的月份数差异 + monthsDiff += yearsDiff * 12; + + return monthsDiff; + } + + public static Date getMonthFirst(Date date){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.DAY_OF_MONTH, 1); + return calendar.getTime(); + } + + public static Date getMonthEnd(Date date){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.DAY_OF_MONTH, 1); + calendar.add(Calendar.MONTH, 1); + calendar.add(Calendar.DAY_OF_MONTH, -1); + return calendar.getTime(); + } + + public static Integer getYear(Date date){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + return calendar.get(Calendar.YEAR); + } + + public static Integer getMonth(Date date){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + return calendar.get(Calendar.MONTH)+1; + } + + public static Integer getMonthDays(Date date){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.DAY_OF_MONTH,1); + return calendar.getActualMaximum(Calendar.DAY_OF_MONTH); + } + + public static Long getBetweenDays(Date start, Date end){ + Calendar currentDate = Calendar.getInstance(); + currentDate.setTime(start); + + // 将输入的Date转换为Calendar以便获取年月信息 + Calendar endCalendar = Calendar.getInstance(); + endCalendar.setTime(end); + return calculateDifferenceInDays(endCalendar, currentDate); + } + + public static Long getBetweenMinutes(Date start, Date end){ + Calendar currentDate = Calendar.getInstance(); + currentDate.setTime(start); + // 将输入的Date转换为Calendar以便获取年月信息 + Calendar endCalendar = Calendar.getInstance(); + endCalendar.setTime(end); + long diffInMillis = endCalendar.getTimeInMillis() - currentDate.getTimeInMillis(); + return diffInMillis / (60 * 1000); + } + + public static long calculateDifferenceInDays(Calendar date1, Calendar date2) { + long diffInMillies = Math.abs(date1.getTimeInMillis() - date2.getTimeInMillis()); + return diffInMillies / (24 * 60 * 60 * 1000); // 将毫秒转换为天 + } + + public static List getCurrentMonthAndDays(){ + return getMonthAndDays(DateUtils.getNowDate()); + } + public static List getMonthAndDays(Date date){ + List dayList = new ArrayList(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); + SimpleDateFormat sdfm = new SimpleDateFormat("yyyy-MM"); + for(int p=1;p<=days;p++){ + try{ + String rq = sdfm.format(date)+"-"; + if(p < 10){ + rq += "0" + p; + }else { + rq += p; + } + dayList.add(rq); + }catch (Exception e){ + e.printStackTrace(); + } + } + return dayList; + } + +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/ExcelUtil.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/ExcelUtil.java new file mode 100644 index 0000000..342a93d --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/ExcelUtil.java @@ -0,0 +1,1506 @@ +package com.evotech.hd.cloud.utils; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.exceptions.UtilException; +import com.evotech.hd.common.core.Dto.Result; +import com.evotech.hd.common.core.excel.Excel; +import com.evotech.hd.common.core.excel.Excel.ColumnType; +import com.evotech.hd.common.core.excel.Excel.Type; +import com.evotech.hd.common.core.excel.Excels; +import com.evotech.hd.common.core.excel.handler.ExcelHandlerAdapter; +import com.evotech.hd.common.core.utils.Collections; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.RegExUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.ooxml.POIXMLDocumentPart; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.*; +import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; +/** + * Excel相关处理 + * + * @author evo + */ +public class ExcelUtil +{ + private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); + + public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; + + public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; + + /** + * 用于dictType属性数据存储,避免重复查缓存 + */ + public Map sysDictMap = new HashMap(); + + /** + * Excel sheet最大行数,默认65536 + */ + public static final int sheetSize = 65536; + + /** + * 工作表名称 + */ + private String sheetName; + + /** + * 导出类型(EXPORT:导出数据;IMPORT:导入模板) + */ + private Type type; + + /** + * 工作薄对象 + */ + private Workbook wb; + + /** + * 工作表对象 + */ + private Sheet sheet; + + /** + * 样式列表 + */ + private Map styles; + + /** + * 导入导出数据列表 + */ + private List list; + + /** + * 注解列表 + */ + private List fields; + + /** + * 当前行号 + */ + private int rownum; + + /** + * 标题 + */ + private String title; + + /** + * 最大高度 + */ + private short maxHeight; + + /** + * 合并后最后行数 + */ + private int subMergedLastRowNum = 0; + + /** + * 合并后开始行数 + */ + private int subMergedFirstRowNum = 1; + + /** + * 对象的子列表方法 + */ + private Method subMethod; + + /** + * 对象的子列表属性 + */ + private List subFields; + + /** + * 统计列表 + */ + private Map statistics = new HashMap(); + + /** + * 数字格式 + */ + private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); + + /** + * 实体对象 + */ + public Class clazz; + + /** + * 需要排除列属性 + */ + public String[] excludeFields; + + public ExcelUtil(Class clazz) + { + this.clazz = clazz; + } + + /** + * 隐藏Excel中列属性 + * + * @param fields 列属性名 示例[单个"name"/多个"id","name"] + * @throws Exception + */ + public void hideColumn(String... fields) + { + this.excludeFields = fields; + } + + public void init(List list, String sheetName, String title, Type type) + { + if (list == null) + { + list = new ArrayList(); + } + this.list = list; + this.sheetName = sheetName; + this.type = type; + this.title = title; + createExcelField(); + createWorkbook(); + createTitle(); + createSubHead(); + } + + /** + * 创建excel第一行标题 + */ + public void createTitle() + { + if (StringUtils.isNotEmpty(title)) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + int titleLastCol = this.fields.size() - 1; + if (isSubList()) + { + titleLastCol = titleLastCol + subFields.size() - 1; + } + Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); + titleRow.setHeightInPoints(30); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellStyle(styles.get("title")); + titleCell.setCellValue(title); + sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), titleLastCol)); + } + } + + /** + * 创建对象的子列表名称 + */ + public void createSubHead() + { + if (isSubList()) + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + Row subRow = sheet.createRow(rownum); + int excelNum = 0; + for (Object[] objects : fields) + { + Excel attr = (Excel) objects[1]; + Cell headCell1 = subRow.createCell(excelNum); + headCell1.setCellValue(attr.name()); + headCell1.setCellStyle(styles.get(String.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + excelNum++; + } + int headFirstRow = excelNum - 1; + int headLastRow = headFirstRow + subFields.size() - 1; + if (headLastRow > headFirstRow) + { + sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, headFirstRow, headLastRow)); + } + rownum++; + } + } + + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public Result exportExcel(List list, String sheetName) + { + return exportExcel(list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public Result exportExcel(List list, String sheetName, String title) + { + this.init(list, sheetName, title, Type.EXPORT); + return exportExcel(); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName) + { + exportExcel(response, list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName, String title) + { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + this.init(list, sheetName, title, Type.EXPORT); + exportExcel(response); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @return 结果 + */ + public Result importTemplateExcel(String sheetName) + { + return importTemplateExcel(sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public Result importTemplateExcel(String sheetName, String title) + { + this.init(null, sheetName, title, Type.IMPORT); + return exportExcel(); + } + +// /** +// * 对list数据源将其里面的数据导入到excel表单 +// * +// * @param sheetName 工作表的名称 +// * @return 结果 +// */ +// public void importTemplateExcel(HttpServletResponse response, String sheetName) +// { +// importTemplateExcel(response, sheetName, StringUtils.EMPTY); +// } + +// /** +// * 对list数据源将其里面的数据导入到excel表单 +// * +// * @param sheetName 工作表的名称 +// * @param title 标题 +// * @return 结果 +// */ +// public void importTemplateExcel(HttpServletResponse response, String sheetName, String title) +// { +// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); +// response.setCharacterEncoding("utf-8"); +// this.init(null, sheetName, title, Type.IMPORT); +// exportExcel(response); +// } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public void exportExcel(HttpServletResponse response) + { + try + { + writeSheet(); + wb.write(response.getOutputStream()); + } + catch (Exception e) + { + log.error("导出Excel异常{}", e.getMessage()); + } + finally + { + IOUtils.closeQuietly(wb); + } + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @return 结果 + */ + public Result exportExcel() + { + OutputStream out = null; + try + { + writeSheet(); + String filename = encodingFilename(sheetName); + out = new FileOutputStream(getAbsoluteFile(filename)); + wb.write(out); + return Result.getInstance().build(String.class).success(filename); + } + catch (Exception e) + { + log.error("导出Excel异常{}", e.getMessage()); + throw new UtilException("导出Excel失败,请联系网站管理员!"); + } + finally + { + IOUtils.closeQuietly(wb); + IOUtils.closeQuietly(out); + } + } + + /** + * 创建写入数据到Sheet + */ + public void writeSheet() + { + // 取出一共有多少个sheet. + int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize)); + for (int index = 0; index < sheetNo; index++) + { + createSheet(sheetNo, index); + + // 产生一行 + Row row = sheet.createRow(rownum); + int column = 0; + // 写入各个字段的列头名称 + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + this.createHeadCell(subExcel, row, column++); + } + } + else + { + this.createHeadCell(excel, row, column++); + } + } + if (Type.EXPORT.equals(type)) + { + fillExcelData(index, row); + addStatisticsRow(); + } + } + } + + /** + * 填充excel数据 + * + * @param index 序号 + * @param row 单元格行 + */ + @SuppressWarnings("unchecked") + public void fillExcelData(int index, Row row) + { + int startNo = index * sheetSize; + int endNo = Math.min(startNo + sheetSize, list.size()); + int rowNo = (1 + rownum) - startNo; + for (int i = startNo; i < endNo; i++) + { + rowNo = isSubList() ? (i > 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo; + row = sheet.createRow(rowNo); + // 得到导出对象. + T vo = (T) list.get(i); + Collection subList = null; + if (isSubList()) + { + if (isSubListValue(vo)) + { + subList = getListCellValue(vo); + subMergedLastRowNum = subMergedLastRowNum + subList.size(); + } + else + { + subMergedFirstRowNum++; + subMergedLastRowNum++; + } + } + int column = 0; + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType()) && Collections.isNotEmpty(subList)) + { + boolean subFirst = false; + for (Object obj : subList) + { + if (subFirst) + { + rowNo++; + row = sheet.createRow(rowNo); + } + List subFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Excel.class); + int subIndex = 0; + for (Field subField : subFields) + { + if (subField.isAnnotationPresent(Excel.class)) + { + subField.setAccessible(true); + Excel attr = subField.getAnnotation(Excel.class); + this.addCell(attr, row, (T) obj, subField, column + subIndex); + } + subIndex++; + } + subFirst = true; + } + this.subMergedFirstRowNum = this.subMergedFirstRowNum + subList.size(); + } + else + { + this.addCell(excel, row, vo, field, column++); + } + } + } + } + + /** + * 创建表格样式 + * + * @param wb 工作薄对象 + * @return 样式列表 + */ + private Map createStyles(Workbook wb) + { + // 写入各条记录,每条记录对应excel表中的一行 + Map styles = new HashMap(); + CellStyle style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("Arial"); + titleFont.setFontHeightInPoints((short) 16); + titleFont.setBold(true); + style.setFont(titleFont); + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + styles.put("title", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + style.setFont(dataFont); + styles.put("data", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + Font totalFont = wb.createFont(); + totalFont.setFontName("Arial"); + totalFont.setFontHeightInPoints((short) 10); + style.setFont(totalFont); + styles.put("total", style); + + styles.putAll(annotationHeaderStyles(wb, styles)); + + styles.putAll(annotationDataStyles(wb)); + + return styles; + } + + /** + * 根据Excel注解创建表格头样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationHeaderStyles(Workbook wb, Map styles) + { + Map headerStyles = new HashMap(); + for (Object[] os : fields) + { + Excel excel = (Excel) os[1]; + String key = String.format("header_{}_{}", excel.headerColor(), excel.headerBackgroundColor()); + if (!headerStyles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.cloneStyleFrom(styles.get("data")); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setFillForegroundColor(excel.headerBackgroundColor().index); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + Font headerFont = wb.createFont(); + headerFont.setFontName("Arial"); + headerFont.setFontHeightInPoints((short) 10); + headerFont.setBold(true); + headerFont.setColor(excel.headerColor().index); + style.setFont(headerFont); + // 设置表格头单元格文本形式 + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + headerStyles.put(key, style); + } + } + return headerStyles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param wb 工作薄对象 + * @return 自定义样式列表 + */ + private Map annotationDataStyles(Workbook wb) + { + Map styles = new HashMap(); + for (Object[] os : fields) + { + Field field = (Field) os[0]; + Excel excel = (Excel) os[1]; + if (Collection.class.isAssignableFrom(field.getType())) + { + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + List subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + for (Field subField : subFields) + { + Excel subExcel = subField.getAnnotation(Excel.class); + annotationDataStyles(styles, subField, subExcel); + } + } + else + { + annotationDataStyles(styles, field, excel); + } + } + return styles; + } + + /** + * 根据Excel注解创建表格列样式 + * + * @param styles 自定义样式列表 + * @param field 属性列信息 + * @param excel 注解信息 + */ + public void annotationDataStyles(Map styles, Field field, Excel excel) + { + String key = String.format("data_{}_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor(), excel.cellType()); + if (!styles.containsKey(key)) + { + CellStyle style = wb.createCellStyle(); + style.setAlignment(excel.align()); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + style.setFillForegroundColor(excel.backgroundColor().getIndex()); + Font dataFont = wb.createFont(); + dataFont.setFontName("Arial"); + dataFont.setFontHeightInPoints((short) 10); + dataFont.setColor(excel.color().index); + style.setFont(dataFont); + if (Excel.ColumnType.TEXT == excel.cellType()) + { + DataFormat dataFormat = wb.createDataFormat(); + style.setDataFormat(dataFormat.getFormat("@")); + } + styles.put(key, style); + } + } + + /** + * 创建单元格 + */ + public Cell createHeadCell(Excel attr, Row row, int column) + { + // 创建列 + Cell cell = row.createCell(column); + // 写入列信息 + cell.setCellValue(attr.name()); + setDataValidation(attr, row, column); + cell.setCellStyle(styles.get(String.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()))); + if (isSubList()) + { + // 填充默认样式,防止合并单元格样式失效 + sheet.setDefaultColumnStyle(column, styles.get(String.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType()))); + if (attr.needMerge()) + { + sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column)); + } + } + return cell; + } + + /** + * 设置单元格信息 + * + * @param value 单元格值 + * @param attr 注解相关 + * @param cell 单元格信息 + */ + public void setCellVo(Object value, Excel attr, Cell cell) + { + if (ColumnType.STRING == attr.cellType() || ColumnType.TEXT == attr.cellType()) + { + String cellValue = Convert.toStr(value); + // 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。 + if (StringUtils.startsWithAny(cellValue, FORMULA_STR)) + { + cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0"); + } + if (value instanceof Collection && StringUtils.equals("[]", cellValue)) + { + cellValue = StringUtils.EMPTY; + } + cell.setCellValue(StringUtils.isEmpty(cellValue) ? attr.defaultValue() : cellValue + attr.suffix()); + } + else if (ColumnType.NUMERIC == attr.cellType()) + { + if (ObjectUtils.isNotEmpty(value)) + { + cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value)); + } + } + } + + + /** + * 创建表格样式 + */ + public void setDataValidation(Excel attr, Row row, int column) + { + if (attr.name().indexOf("注:") >= 0) + { + sheet.setColumnWidth(column, 6000); + } + else + { + // 设置列宽 + sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); + } + if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0 || attr.comboReadDict()) + { + String[] comboArray = attr.combo(); + if (attr.comboReadDict()) + { +// if (!sysDictMap.containsKey("combo_" + attr.dictType())) +// { +// String labels = DictUtils.getDictLabels(attr.dictType()); +// sysDictMap.put("combo_" + attr.dictType(), labels); +// } +// String val = sysDictMap.get("combo_" + attr.dictType()); +// comboArray = StringUtils.split(val, DictUtils.SEPARATOR); + } + if (comboArray.length > 15 || StringUtils.join(comboArray).length() > 255) + { + // 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到 + setXSSFValidationWithHidden(sheet, comboArray, attr.prompt(), 1, 100, column, column); + } + else + { + // 提示信息或只能选择不能输入的列内容. + setPromptOrValidation(sheet, comboArray, attr.prompt(), 1, 100, column, column); + } + } + } + + /** + * 添加单元格 + */ + public Cell addCell(Excel attr, Row row, T vo, Field field, int column) + { + Cell cell = null; + try + { + // 设置行高 + row.setHeight(maxHeight); + // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. + if (attr.isExport()) + { + // 创建cell + cell = row.createCell(column); + if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge()) + { + CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column); + sheet.addMergedRegion(cellAddress); + } + cell.setCellStyle(styles.get(String.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType()))); + + // 用于读取对象中的属性 + Object value = getTargetValue(vo, field, attr); + String dateFormat = attr.dateFormat(); + String readConverterExp = attr.readConverterExp(); + String separator = attr.separator(); + String dictType = attr.dictType(); + if (StringUtils.isNotEmpty(dateFormat) && ObjectUtils.isNotEmpty(value)) + { + cell.setCellValue(parseDateToStr(dateFormat, value)); + } + else if (StringUtils.isNotEmpty(readConverterExp) && ObjectUtils.isNotEmpty(value)) + { + cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator)); + } + else if (StringUtils.isNotEmpty(dictType) && ObjectUtils.isNotEmpty(value)) + { + if (!sysDictMap.containsKey(dictType + value)) + { + String lable = convertDictByExp(Convert.toStr(value), dictType, separator); + sysDictMap.put(dictType + value, lable); + } + cell.setCellValue(sysDictMap.get(dictType + value)); + } + else if (value instanceof BigDecimal && -1 != attr.scale()) + { + cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue()); + } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell)); + } + else + { + // 设置列类型 + setCellVo(value, attr, cell); + } + addStatisticsData(column, Convert.toStr(value), attr); + } + } + catch (Exception e) + { + log.error("导出Excel失败{}", e); + } + return cell; + } + + /** + * 设置 POI XSSFSheet 单元格提示或选择框 + * + * @param sheet 表单 + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, + int firstCol, int endCol) + { + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) : helper.createCustomConstraint("DD1"); + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + sheet.addValidationData(dataValidation); + } + + /** + * 设置某些列的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框). + * + * @param sheet 要设置的sheet. + * @param textlist 下拉框显示的内容 + * @param promptContent 提示内容 + * @param firstRow 开始行 + * @param endRow 结束行 + * @param firstCol 开始列 + * @param endCol 结束列 + */ + public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol) + { + String hideSheetName = "combo_" + firstCol + "_" + endCol; + Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据 + for (int i = 0; i < textlist.length; i++) + { + hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]); + } + // 创建名称,可被其他单元格引用 + Name name = wb.createName(); + name.setNameName(hideSheetName + "_data"); + name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length); + DataValidationHelper helper = sheet.getDataValidationHelper(); + // 加载下拉列表内容 + DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data"); + // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 + CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); + // 数据有效性对象 + DataValidation dataValidation = helper.createValidation(constraint, regions); + if (StringUtils.isNotEmpty(promptContent)) + { + // 如果设置了提示信息则鼠标放上去提示 + dataValidation.createPromptBox("", promptContent); + dataValidation.setShowPromptBox(true); + } + // 处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) + { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } + else + { + dataValidation.setSuppressDropDownArrow(false); + } + + sheet.addValidationData(dataValidation); + // 设置hiddenSheet隐藏 + wb.setSheetHidden(wb.getSheetIndex(hideSheet), true); + } + + /** + * 解析导出值 0=男,1=女,2=未知 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String convertByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[0].equals(value)) + { + propertyString.append(itemArray[1] + separator); + break; + } + } + } + else + { + if (itemArray[0].equals(propertyValue)) + { + return itemArray[1]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 反向解析值 男=0,女=1,未知=2 + * + * @param propertyValue 参数值 + * @param converterExp 翻译注解 + * @param separator 分隔符 + * @return 解析后值 + */ + public static String reverseByExp(String propertyValue, String converterExp, String separator) + { + StringBuilder propertyString = new StringBuilder(); + String[] convertSource = converterExp.split(","); + for (String item : convertSource) + { + String[] itemArray = item.split("="); + if (StringUtils.containsAny(propertyValue, separator)) + { + for (String value : propertyValue.split(separator)) + { + if (itemArray[1].equals(value)) + { + propertyString.append(itemArray[0] + separator); + break; + } + } + } + else + { + if (itemArray[1].equals(propertyValue)) + { + return itemArray[0]; + } + } + } + return StringUtils.stripEnd(propertyString.toString(), separator); + } + + /** + * 解析字典值 + * + * @param dictValue 字典值 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典标签 + */ + public static String convertDictByExp(String dictValue, String dictType, String separator) + { + return ""; //DictUtils.getDictLabel(dictType, dictValue, separator); + } + + /** + * 反向解析值字典值 + * + * @param dictLabel 字典标签 + * @param dictType 字典类型 + * @param separator 分隔符 + * @return 字典值 + */ + public static String reverseDictByExp(String dictLabel, String dictType, String separator) + { + return ""; //DictUtils.getDictValue(dictType, dictLabel, separator); + } + + /** + * 数据处理器 + * + * @param value 数据值 + * @param excel 数据注解 + * @return + */ + public String dataFormatHandlerAdapter(Object value, Excel excel, Cell cell) + { + try + { + Object instance = excel.handler().newInstance(); + Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class }); + value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb); + } + catch (Exception e) + { + log.error("不能格式化数据 " + excel.handler(), e.getMessage()); + } + return Convert.toStr(value); + } + + /** + * 合计统计信息 + */ + private void addStatisticsData(Integer index, String text, Excel entity) + { + if (entity != null && entity.isStatistics()) + { + Double temp = 0D; + if (!statistics.containsKey(index)) + { + statistics.put(index, temp); + } + try + { + temp = Double.valueOf(text); + } + catch (NumberFormatException e) + { + } + statistics.put(index, statistics.get(index) + temp); + } + } + + /** + * 创建统计行 + */ + public void addStatisticsRow() + { + if (statistics.size() > 0) + { + Row row = sheet.createRow(sheet.getLastRowNum() + 1); + Set keys = statistics.keySet(); + Cell cell = row.createCell(0); + cell.setCellStyle(styles.get("total")); + cell.setCellValue("合计"); + + for (Integer key : keys) + { + cell = row.createCell(key); + cell.setCellStyle(styles.get("total")); + cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key))); + } + statistics.clear(); + } + } + + /** + * 编码文件名 + */ + public String encodingFilename(String filename) + { + filename = UUID.randomUUID() + "_" + filename + ".xlsx"; + return filename; + } + + /** + * 获取下载路径 + * + * @param filename 文件名称 + */ + public String getAbsoluteFile(String filename) + { + String downloadPath = YTConfig.getDownloadPath() + filename; + File desc = new File(downloadPath); + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + return downloadPath; + } + + /** + * 获取bean中的属性值 + * + * @param vo 实体对象 + * @param field 字段 + * @param excel 注解 + * @return 最终的属性值 + * @throws Exception + */ + private Object getTargetValue(T vo, Field field, Excel excel) throws Exception + { + Object o = field.get(vo); + if (StringUtils.isNotEmpty(excel.targetAttr())) + { + String target = excel.targetAttr(); + if (target.contains(".")) + { + String[] targets = target.split("[.]"); + for (String name : targets) + { + o = getValue(o, name); + } + } + else + { + o = getValue(o, target); + } + } + return o; + } + + /** + * 以类的属性的get方法方法形式获取值 + * + * @param o + * @param name + * @return value + * @throws Exception + */ + private Object getValue(Object o, String name) throws Exception + { + if (ObjectUtils.isNotEmpty(o) && StringUtils.isNotEmpty(name)) + { + Class clazz = o.getClass(); + Field field = clazz.getDeclaredField(name); + field.setAccessible(true); + o = field.get(o); + } + return o; + } + + /** + * 得到所有定义字段 + */ + private void createExcelField() + { + this.fields = getFields(); + this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); + this.maxHeight = getRowHeight(); + } + + /** + * 获取字段注解信息 + */ + public List getFields() + { + List fields = new ArrayList(); + List tempFields = new ArrayList<>(); + tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); + tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); + for (Field field : tempFields) + { + if (!ArrayUtils.contains(this.excludeFields, field.getName())) + { + // 单注解 + if (field.isAnnotationPresent(Excel.class)) + { + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + if (Collection.class.isAssignableFrom(field.getType())) + { + subMethod = getSubMethod(field.getName(), clazz); + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class subClass = (Class) pt.getActualTypeArguments()[0]; + this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class); + } + } + + // 多注解 + if (field.isAnnotationPresent(Excels.class)) + { + Excels attrs = field.getAnnotation(Excels.class); + Excel[] excels = attrs.value(); + for (Excel attr : excels) + { + if (!ArrayUtils.contains(this.excludeFields, field.getName() + "." + attr.targetAttr()) + && (attr != null && (attr.type() == Type.ALL || attr.type() == type))) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } + } + } + } + } + return fields; + } + + /** + * 根据注解获取最大行高 + */ + public short getRowHeight() + { + double maxHeight = 0; + for (Object[] os : this.fields) + { + Excel excel = (Excel) os[1]; + maxHeight = Math.max(maxHeight, excel.height()); + } + return (short) (maxHeight * 20); + } + + /** + * 创建一个工作簿 + */ + public void createWorkbook() + { + this.wb = new SXSSFWorkbook(500); + this.sheet = wb.createSheet(); + wb.setSheetName(0, sheetName); + this.styles = createStyles(wb); + } + + /** + * 创建工作表 + * + * @param sheetNo sheet数量 + * @param index 序号 + */ + public void createSheet(int sheetNo, int index) + { + // 设置工作表的名称. + if (sheetNo > 1 && index > 0) + { + this.sheet = wb.createSheet(); + this.createTitle(); + wb.setSheetName(index, sheetName + index); + } + } + + /** + * 获取单元格值 + * + * @param row 获取的行 + * @param column 获取单元格列号 + * @return 单元格值 + */ + public Object getCellValue(Row row, int column) + { + if (row == null) + { + return row; + } + Object val = ""; + try + { + Cell cell = row.getCell(column); + if (ObjectUtils.isNotEmpty(cell)) + { + if (cell.getCellType() == CellType.NUMERIC || cell.getCellType() == CellType.FORMULA) + { + val = cell.getNumericCellValue(); + if (DateUtil.isCellDateFormatted(cell)) + { + val = DateUtil.getJavaDate((Double) val); // POI Excel 日期格式转换 + } + else + { + if ((Double) val % 1 != 0) + { + val = new BigDecimal(val.toString()); + } + else + { + val = new DecimalFormat("0").format(val); + } + } + } + else if (cell.getCellType() == CellType.STRING) + { + val = cell.getStringCellValue(); + } + else if (cell.getCellType() == CellType.BOOLEAN) + { + val = cell.getBooleanCellValue(); + } + else if (cell.getCellType() == CellType.ERROR) + { + val = cell.getErrorCellValue(); + } + + } + } + catch (Exception e) + { + return val; + } + return val; + } + + /** + * 判断是否是空行 + * + * @param row 判断的行 + * @return + */ + private boolean isRowEmpty(Row row) + { + if (row == null) + { + return true; + } + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) + { + Cell cell = row.getCell(i); + if (cell != null && cell.getCellType() != CellType.BLANK) + { + return false; + } + } + return true; + } + + /** + * 获取Excel2003图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictures03(HSSFSheet sheet, HSSFWorkbook workbook) + { + Map sheetIndexPicMap = new HashMap(); + List pictures = workbook.getAllPictures(); + if (!pictures.isEmpty()) + { + for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) + { + HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor(); + if (shape instanceof HSSFPicture) + { + HSSFPicture pic = (HSSFPicture) shape; + int pictureIndex = pic.getPictureIndex() - 1; + HSSFPictureData picData = pictures.get(pictureIndex); + String picIndex = anchor.getRow1() + "_" + anchor.getCol1(); + sheetIndexPicMap.put(picIndex, picData); + } + } + return sheetIndexPicMap; + } + else + { + return sheetIndexPicMap; + } + } + + /** + * 获取Excel2007图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictures07(XSSFSheet sheet, XSSFWorkbook workbook) + { + Map sheetIndexPicMap = new HashMap(); + for (POIXMLDocumentPart dr : sheet.getRelations()) + { + if (dr instanceof XSSFDrawing) + { + XSSFDrawing drawing = (XSSFDrawing) dr; + List shapes = drawing.getShapes(); + for (XSSFShape shape : shapes) + { + if (shape instanceof XSSFPicture) + { + XSSFPicture pic = (XSSFPicture) shape; + XSSFClientAnchor anchor = pic.getPreferredSize(); + CTMarker ctMarker = anchor.getFrom(); + String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol(); + sheetIndexPicMap.put(picIndex, pic.getPictureData()); + } + } + } + } + return sheetIndexPicMap; + } + + /** + * 格式化不同类型的日期对象 + * + * @param dateFormat 日期格式 + * @param val 被格式化的日期对象 + * @return 格式化后的日期字符 + */ + public String parseDateToStr(String dateFormat, Object val) + { + if (val == null) + { + return ""; + } + String str; + if (val instanceof Date) + { + str = DateUtils.parseDateToStr(dateFormat, (Date) val); + } + else if (val instanceof LocalDateTime) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val)); + } + else if (val instanceof LocalDate) + { + str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val)); + } + else + { + str = val.toString(); + } + return str; + } + + /** + * 是否有对象的子列表 + */ + public boolean isSubList() + { + return Collections.isNotEmpty(subFields) && subFields.size() > 0; + } + + /** + * 是否有对象的子列表,集合不为空 + */ + public boolean isSubListValue(T vo) + { + return Collections.isNotEmpty(subFields) && subFields.size() > 0 && Collections.isNotEmpty(getListCellValue(vo)) && getListCellValue(vo).size() > 0; + } + + /** + * 获取集合的值 + */ + public Collection getListCellValue(Object obj) + { + Object value; + try + { + value = subMethod.invoke(obj, new Object[] {}); + } + catch (Exception e) + { + return new ArrayList(); + } + return (Collection) value; + } + + /** + * 获取对象的子列表方法 + * + * @param name 名称 + * @param pojoClass 类对象 + * @return 子列表方法 + */ + public Method getSubMethod(String name, Class pojoClass) + { + StringBuffer getMethodName = new StringBuffer("get"); + getMethodName.append(name.substring(0, 1).toUpperCase()); + getMethodName.append(name.substring(1)); + Method method = null; + try + { + method = pojoClass.getMethod(getMethodName.toString(), new Class[] {}); + } + catch (Exception e) + { + log.error("获取对象异常{}", e.getMessage()); + } + return method; + } +} diff --git a/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/YTConfig.java b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/YTConfig.java new file mode 100644 index 0000000..023b107 --- /dev/null +++ b/cloud-manage-server/src/main/java/com/evotech/hd/cloud/utils/YTConfig.java @@ -0,0 +1,38 @@ +package com.evotech.hd.cloud.utils; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * 类 + * + * @ClassName:YTConfig + * @date: 2025年07月29日 10:32 + * @author: andy.shi + * @contact: 17330188597 + * @remark: 开发人员联系方式 1042025947@qq.com/微信同步 + */ +@Component +@ConfigurationProperties(prefix = "yt") +public class YTConfig { + + private static String profile; + + public static String getProfile() + { + return profile; + } + + public void setProfile(String profile) + { + YTConfig.profile = profile; + } + + /** + * 获取下载路径 + */ + public static String getDownloadPath() + { + return getProfile() + "/download/"; + } +} diff --git a/cloud-manage-server/src/main/resources/mapper/BatteryStationDcMapper.xml b/cloud-manage-server/src/main/resources/mapper/BatteryStationDcMapper.xml index e318832..427edae 100644 --- a/cloud-manage-server/src/main/resources/mapper/BatteryStationDcMapper.xml +++ b/cloud-manage-server/src/main/resources/mapper/BatteryStationDcMapper.xml @@ -13,7 +13,7 @@ - + @@ -30,9 +30,9 @@ diff --git a/cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml b/cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml index 4016891..a7038be 100644 --- a/cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml +++ b/cloud-manage-server/src/main/resources/mapper/BatteryStationMapper.xml @@ -33,6 +33,8 @@ + + @@ -53,7 +55,7 @@ - pk_id, proxy_id, name, code, status, type, address, address_province, address_city, address_area, register_date, contacts, phone, del_flag, active_date, location_point, open_all_day, td_quantity, jqr_quantity, cdj_quantity, dcc_quantity, dc_quantity, ctime, creater, uptime, updater + pk_id, proxy_id, name, code, status, type, address, address_province, address_city, address_area, register_date, contacts, phone, del_flag, active_date, location_point, open_all_day, td_quantity, jqr_quantity, cdj_quantity, dcc_quantity, dc_quantity, ctime, creater, uptime, updater, division_no diff --git a/cloud-manage-server/src/main/resources/mapper/OrderMapper.xml b/cloud-manage-server/src/main/resources/mapper/OrderMapper.xml index b745e50..b355f80 100644 --- a/cloud-manage-server/src/main/resources/mapper/OrderMapper.xml +++ b/cloud-manage-server/src/main/resources/mapper/OrderMapper.xml @@ -47,7 +47,7 @@ from hd_cloud_manage.yt_t_order osb where del_Flag = 0 - and status !=#{status} + and status =#{status} order by order_time desc @@ -151,6 +151,23 @@ + + + + diff --git a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java index 59d2082..ad3f93d 100644 --- a/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java +++ b/gateway-server/src/main/java/com/evotech/hd/gateway/oauth2/AuthorizationManager.java @@ -187,11 +187,20 @@ public class AuthorizationManager implements ReactiveAuthorizationManager delete(Integer rid) { - return roleService.delete(rid); + public Result delete(Integer rid, String rcode) { + return roleService.delete(rid, rcode); } @Operation(summary = "修改") diff --git a/resource-server/src/main/java/com/evotech/hd/resource/controller/UtilController.java b/resource-server/src/main/java/com/evotech/hd/resource/controller/UtilController.java index f885e1c..3726908 100644 --- a/resource-server/src/main/java/com/evotech/hd/resource/controller/UtilController.java +++ b/resource-server/src/main/java/com/evotech/hd/resource/controller/UtilController.java @@ -3,11 +3,14 @@ package com.evotech.hd.resource.controller; import cn.hutool.http.HttpUtil; import com.evotech.hd.common.core.Dto.Result; import com.evotech.hd.common.core.utils.SnowflakeUtil; +import com.evotech.hd.common.permission.util.SpringUtil; +import com.evotech.hd.resource.utils.IpUtils; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import com.github.xiaoymin.knife4j.annotations.ApiSupport; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -24,6 +27,8 @@ public class UtilController { @Value("${yt.util.ip-url1}") private String ipUrl; + @Value("${yt.util.ip-url2}") + private String ipUrl1; @Operation(description = "获取id") @@ -42,7 +47,20 @@ public class UtilController { @GetMapping("/ip") @ApiOperationSupport(order = 2) public Result getIp() { - String res = HttpUtil.get(ipUrl); + String res = null; + try { + res = HttpUtil.get(ipUrl); + } catch (Exception e) { + e.printStackTrace(); + try { + res = HttpUtil.get(ipUrl1); + } catch (Exception e1) { + e1.printStackTrace(); + if(StringUtils.isEmpty(res)){ + res = IpUtils.getIpAddr(SpringUtil.getRequest()); + } + } + } return new Result().success(res.trim()); } diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/RoleService.java b/resource-server/src/main/java/com/evotech/hd/resource/service/RoleService.java index f285d34..1299557 100644 --- a/resource-server/src/main/java/com/evotech/hd/resource/service/RoleService.java +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/RoleService.java @@ -11,7 +11,7 @@ public interface RoleService { public Result add(AuthRole r); - public Result delete(Integer rid); + public Result delete(Integer rid, String rcode); public Result update(AuthRole r); diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/AuthUserServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/AuthUserServiceImpl.java index 9fde18f..93d399a 100644 --- a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/AuthUserServiceImpl.java +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/AuthUserServiceImpl.java @@ -95,7 +95,7 @@ public class AuthUserServiceImpl implements AuthUserService { @Transactional public Result delete(String uid) { AuthUser u = new AuthUser(); - u.setUid(uid); + u.setPkId(Integer.valueOf(uid)); int n = userDao.deleteById(u); if (n == 1) { // 删除账号关联角色信息 diff --git a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/RoleServiceImpl.java b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/RoleServiceImpl.java index 0964205..d0dec1e 100644 --- a/resource-server/src/main/java/com/evotech/hd/resource/service/impl/RoleServiceImpl.java +++ b/resource-server/src/main/java/com/evotech/hd/resource/service/impl/RoleServiceImpl.java @@ -101,13 +101,13 @@ public class RoleServiceImpl implements RoleService { @Override @Transactional - public Result delete(Integer rid) { + public Result delete(Integer rid, String rcode) { int n = authRoleDao.deleteById(rid); if (n == 1) { // 删除角色和用户的关系 - authUserRoleDao.delete(new QueryWrapper().eq("rid", rid)); + authUserRoleDao.delete(new QueryWrapper().eq("rcode", rcode)); // 删除角色权限 - authRoleResourceDao.delete(new QueryWrapper().eq("rid", rid)); + authRoleResourceDao.delete(new QueryWrapper().eq("rcode", rcode)); return new Result().success(n); } return new Result().error("删除角色出错!"); diff --git a/resource-server/src/main/java/com/evotech/hd/resource/utils/IpUtils.java b/resource-server/src/main/java/com/evotech/hd/resource/utils/IpUtils.java new file mode 100644 index 0000000..39e9a07 --- /dev/null +++ b/resource-server/src/main/java/com/evotech/hd/resource/utils/IpUtils.java @@ -0,0 +1,379 @@ +package com.evotech.hd.resource.utils; + + +import jakarta.servlet.http.HttpServletRequest; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * 获取IP方法 + * + * @author evo + */ +public class IpUtils +{ + public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"; + // 匹配 ip + public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")"; + public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))"; + // 匹配网段 + public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")"; + + + /** + * 获取客户端IP + * + * @param request 请求对象 + * @return IP地址 + */ + public static String getIpAddr(HttpServletRequest request) + { + if (request == null) + { + return "unknown"; + } + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Forwarded-For"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getHeader("X-Real-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) + { + ip = request.getRemoteAddr(); + } + + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param ip IP地址 + * @return 结果 + */ + public static boolean internalIp(String ip) + { + byte[] addr = textToNumericFormatV4(ip); + return internalIp(addr) || "127.0.0.1".equals(ip); + } + + /** + * 检查是否为内部IP地址 + * + * @param addr byte地址 + * @return 结果 + */ + private static boolean internalIp(byte[] addr) + { + if (ObjectUtils.isEmpty(addr) || addr.length < 2) + { + return true; + } + final byte b0 = addr[0]; + final byte b1 = addr[1]; + // 10.x.x.x/8 + final byte SECTION_1 = 0x0A; + // 172.16.x.x/12 + final byte SECTION_2 = (byte) 0xAC; + final byte SECTION_3 = (byte) 0x10; + final byte SECTION_4 = (byte) 0x1F; + // 192.168.x.x/16 + final byte SECTION_5 = (byte) 0xC0; + final byte SECTION_6 = (byte) 0xA8; + switch (b0) + { + case SECTION_1: + return true; + case SECTION_2: + if (b1 >= SECTION_3 && b1 <= SECTION_4) + { + return true; + } + case SECTION_5: + switch (b1) + { + case SECTION_6: + return true; + } + default: + return false; + } + } + + /** + * 将IPv4地址转换成字节 + * + * @param text IPv4地址 + * @return byte 字节 + */ + public static byte[] textToNumericFormatV4(String text) + { + if (text.length() == 0) + { + return null; + } + + byte[] bytes = new byte[4]; + String[] elements = text.split("\\.", -1); + try + { + long l; + int i; + switch (elements.length) + { + case 1: + l = Long.parseLong(elements[0]); + if ((l < 0L) || (l > 4294967295L)) + { + return null; + } + bytes[0] = (byte) (int) (l >> 24 & 0xFF); + bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 2: + l = Integer.parseInt(elements[0]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[0] = (byte) (int) (l & 0xFF); + l = Integer.parseInt(elements[1]); + if ((l < 0L) || (l > 16777215L)) + { + return null; + } + bytes[1] = (byte) (int) (l >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 3: + for (i = 0; i < 2; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + l = Integer.parseInt(elements[2]); + if ((l < 0L) || (l > 65535L)) + { + return null; + } + bytes[2] = (byte) (int) (l >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 4: + for (i = 0; i < 4; ++i) + { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) + { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + break; + default: + return null; + } + } + catch (NumberFormatException e) + { + return null; + } + return bytes; + } + + /** + * 获取IP地址 + * + * @return 本地IP地址 + */ + public static String getHostIp() + { + try + { + return InetAddress.getLocalHost().getHostAddress(); + } + catch (UnknownHostException e) + { + } + return "127.0.0.1"; + } + + + /** + * 获取主机名 + * + * @return 本地主机名 + */ + public static String getHostName() + { + try + { + return InetAddress.getLocalHost().getHostName(); + } + catch (UnknownHostException e) + { + } + return "未知"; + } + + /** + * 从多级反向代理中获得第一个非unknown IP地址 + * + * @param ip 获得的IP地址 + * @return 第一个非unknown IP地址 + */ + public static String getMultistageReverseProxyIp(String ip) + { + // 多级反向代理检测 + if (ip != null && ip.indexOf(",") > 0) + { + final String[] ips = ip.trim().split(","); + for (String subIp : ips) + { + if (false == isUnknown(subIp)) + { + ip = subIp; + break; + } + } + } + return StringUtils.substring(ip, 0, 255); + } + + /** + * 检测给定字符串是否为未知,多用于检测HTTP请求相关 + * + * @param checkString 被检测的字符串 + * @return 是否未知 + */ + public static boolean isUnknown(String checkString) + { + return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString); + } + + /** + * 是否为IP + */ + public static boolean isIP(String ip) + { + return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP); + } + + /** + * 是否为IP,或 *为间隔的通配符地址 + */ + public static boolean isIpWildCard(String ip) + { + return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD); + } + + /** + * 检测参数是否在ip通配符里 + */ + public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip) + { + String[] s1 = ipWildCard.split("\\."); + String[] s2 = ip.split("\\."); + boolean isMatchedSeg = true; + for (int i = 0; i < s1.length && !s1[i].equals("*"); i++) + { + if (!s1[i].equals(s2[i])) + { + isMatchedSeg = false; + break; + } + } + return isMatchedSeg; + } + + /** + * 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串 + */ + public static boolean isIPSegment(String ipSeg) + { + return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG); + } + + /** + * 判断ip是否在指定网段中 + */ + public static boolean ipIsInNetNoCheck(String iparea, String ip) + { + int idx = iparea.indexOf('-'); + String[] sips = iparea.substring(0, idx).split("\\."); + String[] sipe = iparea.substring(idx + 1).split("\\."); + String[] sipt = ip.split("\\."); + long ips = 0L, ipe = 0L, ipt = 0L; + for (int i = 0; i < 4; ++i) + { + ips = ips << 8 | Integer.parseInt(sips[i]); + ipe = ipe << 8 | Integer.parseInt(sipe[i]); + ipt = ipt << 8 | Integer.parseInt(sipt[i]); + } + if (ips > ipe) + { + long t = ips; + ips = ipe; + ipe = t; + } + return ips <= ipt && ipt <= ipe; + } + + /** + * 校验ip是否符合过滤串规则 + * + * @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99` + * @param ip 校验IP地址 + * @return boolean 结果 + */ + public static boolean isMatchedIp(String filter, String ip) + { + if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip)) + { + return false; + } + String[] ips = filter.split(";"); + for (String iStr : ips) + { + if (isIP(iStr) && iStr.equals(ip)) + { + return true; + } + else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip)) + { + return true; + } + else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip)) + { + return true; + } + } + return false; + } +} diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/controller/PayController.java b/wechat-server/src/main/java/com/evotech/hd/wechat/controller/PayController.java index 70717c4..7d857b3 100644 --- a/wechat-server/src/main/java/com/evotech/hd/wechat/controller/PayController.java +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/controller/PayController.java @@ -77,5 +77,4 @@ public class PayController { return wechatPayService.refundsBack(request); } - } diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/LoginServiceImpl.java b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/LoginServiceImpl.java index 7c54200..3538f8a 100644 --- a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/LoginServiceImpl.java +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/LoginServiceImpl.java @@ -1,7 +1,5 @@ package com.evotech.hd.wechat.service.impl; -import cn.hutool.core.date.DatePattern; -import cn.hutool.core.date.DateUtil; import cn.hutool.crypto.digest.DigestUtil; import cn.hutool.crypto.digest.HMac; import cn.hutool.crypto.digest.HmacAlgorithm; @@ -24,7 +22,6 @@ import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import java.util.Date; @@ -98,6 +95,7 @@ public class LoginServiceImpl implements LoginService { String sessionKey = redisUtil.get(HDConstant.sessionKeyPrefix + wuid).toString(); HMac hmac = DigestUtil.hmac(HmacAlgorithm.HmacSHA256, sessionKey.getBytes()); String res = LoginUtil.checkSessionKey(accessTokenService.getAccessToken(), openid, hmac.digestHex("")); +// String res = LoginUtil.code2Session(xcxProperties.getAppid(), openid, hmac.digestHex("")); JSONObject jo = JSONUtil.parseObj(res); if (jo.getInt("errcode") == 0) { Map m = tokenBuilder(wuid); @@ -134,18 +132,18 @@ public class LoginServiceImpl implements LoginService { @Override public Map tokenBuilder(String wuid) { //获取redis中的token - String wxToken = ((redisUtil.hasKey(HDConstant.wxToken + wuid) && !ObjectUtils.isEmpty(redisUtil.get(HDConstant.wxToken + wuid))) ? String.valueOf(redisUtil.get(HDConstant.wxToken + wuid)) : null); - if(StringUtils.isEmpty(wxToken)) { - String randomStr = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER); - wxToken = XCXUtil.wechatToken(wuid, randomStr); - redisUtil.set(HDConstant.tokenRandomStr + wuid, randomStr, 0); - // 缓存数据 - } - //刷新token - redisUtil.set(HDConstant.wxToken + wuid, wxToken, 0); +// String wxToken = ((redisUtil.hasKey(HDConstant.wxToken + wuid) && !ObjectUtils.isEmpty(redisUtil.get(HDConstant.wxToken + wuid))) ? String.valueOf(redisUtil.get(HDConstant.wxToken + wuid)) : null); +// if(StringUtils.isEmpty(wxToken)) { +// String randomStr = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMATTER); +// wxToken = XCXUtil.wechatToken(wuid, randomStr); +// redisUtil.set(HDConstant.tokenRandomStr + wuid, randomStr, 0); +// // 缓存数据 +// } +// //刷新token +// redisUtil.set(HDConstant.wxToken + wuid, wxToken, 0); Map m = new HashMap(); m.put("wuid", wuid); - m.put("wxToken", wxToken); +// m.put("wxToken", wxToken); return m; } diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatNativePayServiceImpl.java b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatNativePayServiceImpl.java index 7e010b4..f0fe2b0 100644 --- a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatNativePayServiceImpl.java +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatNativePayServiceImpl.java @@ -6,12 +6,12 @@ import cn.hutool.extra.qrcode.QrCodeUtil; import cn.hutool.extra.qrcode.QrConfig; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; import com.evotech.hd.common.core.Dto.Result; import com.evotech.hd.common.core.dao.cloud.PreOrderRelationSwapOrderDao; import com.evotech.hd.common.core.dao.wechat.WechatUserDao; -import com.evotech.hd.common.core.entity.cloud.PreOrderRelationSwapOrder; import com.evotech.hd.common.core.entity.wechat.WechatPayPreOrder; -import com.evotech.hd.common.core.utils.XCXUtil; +import com.evotech.hd.common.core.utils.Collections; import com.evotech.hd.wechat.config.XcxProperties; import com.evotech.hd.wechat.entity.NativePayVO; import com.evotech.hd.wechat.service.WechatNativePayService; @@ -31,7 +31,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; -import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -59,23 +58,23 @@ public class WechatNativePayServiceImpl implements WechatNativePayService { // return new Result().error("用户信息错误"); // } // 处理附加数据 - String outTradeNo = XCXUtil.payOutTradeNo(22); - JSONObject jo = JSONUtil.parseObj(prePay.getAttach()); - String[] orderNoArr = jo.getStr("orderNo").split(","); - List list = new ArrayList(); - for (int i = 0; i < orderNoArr.length; i++) { - PreOrderRelationSwapOrder relationOrder = new PreOrderRelationSwapOrder(); - relationOrder.setOrderNo(orderNoArr[i]); - relationOrder.setCtime(new Date()); - relationOrder.setDescription(prePay.getDescription()); - relationOrder.setOutTradeNo(outTradeNo); - list.add(relationOrder); - } - preOrderRelationSwapOrderDao.insert(list); - - jo.remove("orderNo"); - prePay.setAttach(jo.toJSONString(0)); + String outTradeNo = com.evotech.hd.common.core.utils.CommonUtil.payTradeNo(2); +// JSONObject jo = JSONUtil.parseObj(prePay.getAttach()); +// String[] orderNoArr = jo.getStr("orderNo").split(","); +// List list = new ArrayList(); +// for (int i = 0; i < orderNoArr.length; i++) { +// PreOrderRelationSwapOrder relationOrder = new PreOrderRelationSwapOrder(); +// relationOrder.setOrderNo(orderNoArr[i]); +// relationOrder.setCtime(new Date()); +// relationOrder.setDescription(prePay.getDescription()); +// relationOrder.setOutTradeNo(outTradeNo); +// list.add(relationOrder); +// } +// preOrderRelationSwapOrderDao.insert(list); +// jo.remove("orderNo"); + prePay.setAttach(JSON.toJSONString(Collections.asMap("type","2", "outTradeNo", outTradeNo))); + WechatPayPreOrder preOrder = new WechatPayPreOrder(); // 组装数据 @@ -88,12 +87,12 @@ public class WechatNativePayServiceImpl implements WechatNativePayService { request.setAppid(xcxProperties.getAppid()); request.setMchid(xcxProperties.getMchid()); request.setDescription(prePay.getDescription()); - request.setNotifyUrl(xcxProperties.getNativeNotifyUrl()); + //request.setNotifyUrl(xcxProperties.getNativeNotifyUrl()); + request.setNotifyUrl(xcxProperties.getNotifyUrl()); request.setOutTradeNo(outTradeNo); // 金额 Amount amount = new Amount(); -// amount.setTotal(prePay.getMoney()); - amount.setTotal(1); + amount.setTotal(prePay.getTotal()); request.setAmount(amount); preOrder.setTotal(amount.getTotal()); // 付款人 不需要 diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatPayServiceImpl.java b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatPayServiceImpl.java index 046f1c1..37a5354 100644 --- a/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatPayServiceImpl.java +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/service/impl/WechatPayServiceImpl.java @@ -70,13 +70,13 @@ public class WechatPayServiceImpl implements WechatPayService { private ApplicationContext applicationContext; @Override - public com.evotech.hd.common.core.Dto.Result xcxPrepay(PrePayVO prePay) { + public Result xcxPrepay(PrePayVO prePay) { //首选检查支付类型 JSONObject entries = JSONUtil.parseObj(prePay.getAttach()); //判断是充值订单还是订单支付 String payType = entries.getStr("type"); if (StringUtils.isEmpty(payType)){ - return new com.evotech.hd.common.core.Dto.Result().error("请在正确途径支付"); + return new Result().error("请在正确途径支付"); } Map mqttRequestExchangeProcessorMap = applicationContext.getBeansOfType(PayExchangeProcessor.class); @@ -85,7 +85,7 @@ public class WechatPayServiceImpl implements WechatPayService { return processor.exchange(prePay); } } - return new com.evotech.hd.common.core.Dto.Result().error("请在正确途径支付"); + return new Result().error("请在正确途径支付"); } /** diff --git a/wechat-server/src/main/java/com/evotech/hd/wechat/service/processor/PayExchangeProcessor.java b/wechat-server/src/main/java/com/evotech/hd/wechat/service/processor/PayExchangeProcessor.java index 925fb87..a47d16a 100644 --- a/wechat-server/src/main/java/com/evotech/hd/wechat/service/processor/PayExchangeProcessor.java +++ b/wechat-server/src/main/java/com/evotech/hd/wechat/service/processor/PayExchangeProcessor.java @@ -147,7 +147,8 @@ public interface PayExchangeProcessor { //交易类型 tradeDetail.setTradeType(getAttach().getInt("type")); tradeDetail.setOrderNo(getAttach().getStr("orderNo")); - tradeDetail.setOrderCount(tradeDetail.getOrderNo().split(",").length); + tradeDetail.setOutTradeNo(getAttach().getStr("outTradeNo")); + tradeDetail.setOrderCount(StringUtils.isNotEmpty(tradeDetail.getOrderNo()) ? tradeDetail.getOrderNo().split(",").length : 0); tradeDetail.setTradeAmount(transaction.getAmount().getPayerTotal()); tradeDetail.setPayType(PayTypeEnums.WECHAT.getCode()); tradeDetail.setWechatPayApiType(transaction.getTradeType().name()); diff --git a/wechat-server/src/main/resources/application.yml b/wechat-server/src/main/resources/application.yml index 1943f52..d9b6287 100644 --- a/wechat-server/src/main/resources/application.yml +++ b/wechat-server/src/main/resources/application.yml @@ -106,6 +106,7 @@ hbyt: -----END PUBLIC KEY----- # 支付回调地址 notify_url: http://api.evo-techina.com/wechat/pay/wechatpay/notify + #notify_url: http://y865f68d.natappfree.cc/wechat/pay/wechatpay/notify # Native支付回调地址 native_notify_url: https://api.evo-techina.com/wechat/wechatpay/native/nativeback/msg # 退款回调地址