ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppCouponFallbackFactory.java
@@ -3,6 +3,7 @@ import com.ruoyi.account.api.dto.GrantCouponDto; import com.ruoyi.account.api.feignClient.AppCouponClient; import com.ruoyi.account.api.feignClient.AppUserClient; import com.ruoyi.account.api.model.TAppCoupon; import com.ruoyi.account.api.query.ExchangeRecordGoodsQuery; import com.ruoyi.account.api.vo.ExchangeRecordVO; import com.ruoyi.common.core.domain.R; @@ -53,6 +54,11 @@ public R refund(String id) { return R.fail("后台退款 退回优惠券失败:"+throwable.getMessage()); } @Override public R<TAppCoupon> getAppCouponById(Long id) { return R.fail("根据id获取优惠券领取记录失败:" + throwable.getMessage()); } }; } } ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppCouponClient.java
@@ -3,6 +3,7 @@ import com.ruoyi.account.api.dto.GrantCouponDto; import com.ruoyi.account.api.factory.AppCouponFallbackFactory; import com.ruoyi.account.api.factory.AppUserFallbackFactory; import com.ruoyi.account.api.model.TAppCoupon; import com.ruoyi.account.api.query.ExchangeRecordGoodsQuery; import com.ruoyi.account.api.vo.ExchangeRecordVO; import com.ruoyi.common.core.constant.ServiceNameConstants; @@ -12,6 +13,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import java.util.List; @@ -47,6 +49,17 @@ */ @PostMapping("/t-app-coupon/grantCoupon") R grantCoupon(@RequestBody GrantCouponDto dto); @PostMapping(value = "/t-app-coupon/refund/{id}") R refund(@PathVariable("id") String id); /** * 根据id获取优惠券领取记录 * @param id * @return */ @PostMapping(value = "/t-app-coupon/getAppCouponById") R<TAppCoupon> getAppCouponById(@RequestParam("id") Long id); } ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/model/TAppCoupon.java
@@ -76,9 +76,6 @@ @ApiModelProperty(value = "状态(1=未使用,2=已使用)") @TableField("status") private Integer status; @ApiModelProperty(value = "订单id 后台发放的优惠券没有订单id") @TableField("orderId") private Long orderId; @ApiModelProperty(value = "当前领取优惠卷的json记录") @TableField("coupon_json") ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/PlatformStopChargingReplyFallbackFactory.java
New file @@ -0,0 +1,35 @@ package com.ruoyi.integration.api.factory; import com.ruoyi.common.core.domain.R; import com.ruoyi.integration.api.feignClient.PlatformStopChargingReplyClient; import com.ruoyi.integration.api.feignClient.SendMessageClient; import com.ruoyi.integration.api.model.PlatformStartCharging; import com.ruoyi.integration.api.model.PlatformStopCharging; import com.ruoyi.integration.api.model.PlatformStopChargingReply; import com.ruoyi.integration.api.vo.GetPlatformStopChargingReply; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 充电桩服务降级处理 * * @author ruoyi */ @Component public class PlatformStopChargingReplyFallbackFactory implements org.springframework.cloud.openfeign.FallbackFactory<PlatformStopChargingReplyClient> { private static final Logger log = LoggerFactory.getLogger(PlatformStopChargingReplyFallbackFactory.class); @Override public PlatformStopChargingReplyClient create(Throwable throwable) { log.error("远程停机命令应答失败:{}", throwable.getMessage()); return new PlatformStopChargingReplyClient() { @Override public R<PlatformStopChargingReply> getPlatformStopChargingReply(GetPlatformStopChargingReply query) { return R.fail("获取远程停机命令应答失败:" + throwable.getMessage()); } }; } } ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/SendMessageFallbackFactory.java
@@ -5,6 +5,7 @@ import com.ruoyi.integration.api.feignClient.SendMessageClient; import com.ruoyi.integration.api.model.ChargingHandshake; import com.ruoyi.integration.api.model.PlatformStartCharging; import com.ruoyi.integration.api.model.PlatformStopCharging; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.openfeign.FallbackFactory; @@ -27,9 +28,14 @@ @Override public void platformStartCharging(PlatformStartCharging platformStartCharging) { public String platformStartCharging(PlatformStartCharging platformStartCharging) { throw new RuntimeException("远程启机失败" + throwable.getMessage()); } @Override public String platformStopCharging(PlatformStopCharging platformStopCharging) { throw new RuntimeException("远程停机失败" + throwable.getMessage()); } }; } } ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/PlatformStopChargingReplyClient.java
New file @@ -0,0 +1,27 @@ package com.ruoyi.integration.api.feignClient; import com.ruoyi.common.core.constant.ServiceNameConstants; import com.ruoyi.common.core.domain.R; import com.ruoyi.integration.api.factory.PlatformStopChargingReplyFallbackFactory; import com.ruoyi.integration.api.model.PlatformStopChargingReply; import com.ruoyi.integration.api.vo.GetPlatformStopChargingReply; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; /** * @author zhibing.pu * @Date 2024/9/2 17:05 */ @FeignClient(contextId = "PlatformStopChargingReplyClient", value = ServiceNameConstants.INTEGRATION_SERVICE, fallbackFactory = PlatformStopChargingReplyFallbackFactory.class) public interface PlatformStopChargingReplyClient { /** * 获取远程停机命令应答 * @param query * @return */ @PostMapping("/platformStopChargingReply/getPlatformStopChargingReply") R<PlatformStopChargingReply> getPlatformStopChargingReply(@RequestBody GetPlatformStopChargingReply query); } ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/SendMessageClient.java
@@ -3,6 +3,7 @@ import com.ruoyi.common.core.constant.ServiceNameConstants; import com.ruoyi.integration.api.factory.SendMessageFallbackFactory; import com.ruoyi.integration.api.model.PlatformStartCharging; import com.ruoyi.integration.api.model.PlatformStopCharging; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -21,5 +22,14 @@ * @return */ @PostMapping("/sendMessage/platformStartCharging") void platformStartCharging(@RequestBody PlatformStartCharging platformStartCharging); String platformStartCharging(@RequestBody PlatformStartCharging platformStartCharging); /** * 远程控制停机 * @param platformStopCharging * @return */ @PostMapping("/sendMessage/platformStopCharging") String platformStopCharging(@RequestBody PlatformStopCharging platformStopCharging); } ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/vo/GetPlatformStopChargingReply.java
New file @@ -0,0 +1,19 @@ package com.ruoyi.integration.api.vo; import lombok.Data; /** * @author zhibing.pu * @Date 2024/9/2 17:00 */ @Data public class GetPlatformStopChargingReply { /** * 充电桩编号 */ private String charging_pile_code; /** * 充电枪编号 */ private String charging_gun_code; } ruoyi-api/ruoyi-api-integration/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -3,3 +3,4 @@ com.ruoyi.integration.api.factory.ChargingHandshakeFallbackFactory com.ruoyi.integration.api.factory.SendMessageFallbackFactory com.ruoyi.integration.api.factory.PlatformStartChargingReplyFallbackFactory com.ruoyi.integration.api.factory.PlatformStopChargingReplyFallbackFactory ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyDetailOrder.java
New file @@ -0,0 +1,53 @@ package com.ruoyi.order.api.model; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; /** * @author zhibing.pu * @Date 2024/9/3 14:00 */ @Data @TableName("t_accounting_strategy_detail_order") public class AccountingStrategyDetailOrder { /** * 主键 */ @TableField(value = "id") private Integer id; @ApiModelProperty(value = "策略id") @TableField("accounting_strategy_id") private Integer accountingStrategyId; @ApiModelProperty(value = "阶段(1=尖阶段,2=峰阶段,3=平阶段,4=谷阶段)") @TableField("type") private Integer type; @ApiModelProperty(value = "开始时间") @TableField("start_time") private String startTime; @ApiModelProperty(value = "结束时间") @TableField("end_time") private String endTime; @ApiModelProperty(value = "电价") @TableField("electrovalence") private BigDecimal electrovalence; @ApiModelProperty(value = "服务费") @TableField("service_charge") private BigDecimal serviceCharge; @ApiModelProperty(value = "原价服务费") @TableField("cost_service_charge") private BigDecimal costServiceCharge; @ApiModelProperty(value = "充电订单id") @TableField("charging_order_id") private Long chargingOrderId; } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AccountingStrategyOrder.java
New file @@ -0,0 +1,81 @@ package com.ruoyi.order.api.model; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.core.web.domain.BasePojo; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.math.BigDecimal; import java.time.LocalDateTime; /** * @author zhibing.pu * @Date 2024/9/3 14:13 */ @Data @TableName("t_accounting_strategy_order") public class AccountingStrategyOrder extends BasePojo { @ApiModelProperty(value = "主键") @TableField(value = "id") private Integer id; @ApiModelProperty(value = "站点id") @TableField("site_id") private Integer siteId; @ApiModelProperty(value = "申请人id") @TableField("user_id") private Long userId; @ApiModelProperty(value = "策略名称") @TableField("name") private String name; @ApiModelProperty(value = "策略说明") @TableField("description") private String description; @ApiModelProperty(value = "会员折扣") @TableField("discount") private BigDecimal discount; @ApiModelProperty(value = "一级审核用户id") @TableField("first_user_id") private Long firstUserId; @ApiModelProperty(value = "二级审核用户id") @TableField("two_user_id") private Long twoUserId; @ApiModelProperty(value = "一级审核备注") @TableField("first_remark") private String firstRemark; @ApiModelProperty(value = "二级审核备注") @TableField("two_remark") private String twoRemark; @ApiModelProperty(value = "审核状态(1=待审核一级,2=待审核二级,3=审核通过,4=驳回)") @TableField("audit_status") private Integer auditStatus; @ApiModelProperty(value = "一级审核时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField("first_audit_time") private LocalDateTime firstAuditTime; @ApiModelProperty(value = "二级审核时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField("two_audit_time") private LocalDateTime twoAuditTime; @ApiModelProperty(value = "充电订单id") @TableField("charging_order_id") private Long chargingOrderId; } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrder.java
@@ -123,6 +123,10 @@ @TableField("recharge_serial_number") private String rechargeSerialNumber; @ApiModelProperty(value = "充电金额(传给硬件方的金额)") @TableField("charge_amount") private BigDecimal chargeAmount; @ApiModelProperty(value = "剩余金额(用于前端展示)") @TableField("residual_amount") private BigDecimal residualAmount; @@ -158,14 +162,6 @@ @ApiModelProperty(value = "退款金额") @TableField("refund_amount") private BigDecimal refundAmount; @ApiModelProperty(value = "累计服务费") @TableField("service_charge") private BigDecimal serviceCharge; @ApiModelProperty(value = "累计电费") @TableField("electrovalence") private BigDecimal electrovalence; @ApiModelProperty(value = "退款状态(1=退款中,2=退款成功)") @TableField("refund_status") ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrderAccountingStrategy.java
@@ -11,6 +11,7 @@ import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; /** * <p> @@ -35,6 +36,10 @@ @ApiModelProperty(value = "充电订单id") @TableField("charging_order_id") private Long chargingOrderId; @ApiModelProperty(value = "计费策略明细id") @TableField("accounting_strategy_detail_id") private Integer accountingStrategyDetailId; @ApiModelProperty(value = "阶段(1=尖阶段,2=峰阶段,3=平阶段,4=谷阶段)") @TableField("type") @@ -72,6 +77,14 @@ @TableField("period_service_price") private BigDecimal periodServicePrice; @ApiModelProperty(value = "时段原服务费(不含折扣)") @TableField("period_original_service_price") private BigDecimal periodOriginalServicePrice; @ApiModelProperty(value = "首次添加时间") @TableField("create_time") private LocalDateTime createTime; @ApiModelProperty(value = "会员抵扣") @TableField(exist = false) private BigDecimal vipDiscount; ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppCouponController.java
@@ -65,13 +65,18 @@ private TAppUserCarService appUserCarService; @Autowired private TokenService tokenService; @Autowired @Resource private ChargingPileClient chargingPileClient; @Autowired @Resource private ChargingOrderClient chargingOrderClient; @Resource private ChargingGunClient chargingGunClient; @Autowired private TAppUserTagService appUserTagService; @Autowired private TAppUserService appUserService; /** * 后台退款 回退优惠券使用状态 @@ -208,10 +213,7 @@ return R.ok(tAppCouponService.lambdaQuery().le(TAppCoupon::getStartTime, now).ge(TAppCoupon::getEndTime, now).eq(TAppCoupon::getStatus, 1).count()); } @Autowired private TAppUserTagService appUserTagService; @Autowired private TAppUserService appUserService; /** * 后台远程调用 给用户发放优惠券 @@ -275,5 +277,17 @@ return R.ok(); } /** * 根据id获取优惠券领取记录 * @param id * @return */ @PostMapping("/getAppCouponById") public R<TAppCoupon> getAppCouponById(@RequestParam("id") Long id){ TAppCoupon appCoupon = tAppCouponService.getById(id); return R.ok(appCoupon); } } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/controller/PlatformStopChargingReplyController.java
New file @@ -0,0 +1,34 @@ package com.ruoyi.integration.controller; import com.ruoyi.common.core.domain.R; import com.ruoyi.integration.api.model.PlatformStopChargingReply; import com.ruoyi.integration.api.vo.GetPlatformStopChargingReply; import com.ruoyi.integration.mongodb.service.PlatformStopChargingReplyService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; /** * @author zhibing.pu * @Date 2024/9/2 16:52 */ @RestController @RequestMapping("/platformStopChargingReply") public class PlatformStopChargingReplyController { @Resource private PlatformStopChargingReplyService platformStopChargingReplyService; /** * 获取远程停机命令应答 * @param query * @return */ @PostMapping("/getPlatformStopChargingReply") public R<PlatformStopChargingReply> getPlatformStopChargingReply(@RequestBody GetPlatformStopChargingReply query){ PlatformStopChargingReply platformStopChargingReply = platformStopChargingReplyService.getPlatformStopChargingReply(query); return R.ok(platformStopChargingReply); } } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/PlatformStopChargingReplyService.java
@@ -1,7 +1,15 @@ package com.ruoyi.integration.mongodb.service; import com.ruoyi.integration.api.model.PlatformStopChargingReply; import com.ruoyi.integration.api.vo.GetPlatformStopChargingReply; import com.ruoyi.integration.mongodb.base.BaseService; public interface PlatformStopChargingReplyService extends BaseService<PlatformStopChargingReply> { /** * 根据枪编号获取停机应答 * @return */ PlatformStopChargingReply getPlatformStopChargingReply(GetPlatformStopChargingReply query); } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/impl/PlatformStopChargingReplyServiceImpl.java
@@ -1,10 +1,13 @@ package com.ruoyi.integration.mongodb.service.impl; import com.ruoyi.integration.api.vo.GetPlatformStopChargingReply; import com.ruoyi.integration.iotda.constant.IotConstant; import com.ruoyi.integration.api.model.PlatformStopChargingReply; import com.ruoyi.integration.mongodb.service.PlatformStopChargingReplyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.stereotype.Service; import java.util.List; @@ -28,4 +31,16 @@ public List<PlatformStopChargingReply> findAll() { return mongoTemplate.findAll(PlatformStopChargingReply.class); } /** * 根据枪编号获取 * @return */ @Override public PlatformStopChargingReply getPlatformStopChargingReply(GetPlatformStopChargingReply query) { List<PlatformStopChargingReply> platformStopChargingReplies = mongoTemplate.find(new Query().addCriteria(Criteria.where("charging_pile_code").is(query.getCharging_pile_code()) .and("charging_gun_code").is(query.getCharging_gun_code())), PlatformStopChargingReply.class); return platformStopChargingReplies.size() > 0 ? platformStopChargingReplies.get(0) : null; } } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
@@ -456,7 +456,7 @@ * @param request */ @ResponseBody @PostMapping(value = "/chargingOrderALICallback") @PostMapping(value = "/chargingOrderStartupFailureWxRefund") public void chargingOrderStartupFailureWxRefund(HttpServletRequest request){ WxRefundNotifyResp data = wxPaymentClient.refundNotify(request).getData(); if(null != data){ ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -1,12 +1,15 @@ package com.ruoyi.order.service.impl; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.account.api.feignClient.AppCouponClient; import com.ruoyi.account.api.feignClient.AppUserCarClient; import com.ruoyi.account.api.feignClient.AppUserClient; import com.ruoyi.account.api.feignClient.AppUserVipDetailClient; import com.ruoyi.account.api.model.TAppCoupon; import com.ruoyi.account.api.model.TAppUser; import com.ruoyi.account.api.model.TAppUserCar; import com.ruoyi.account.api.model.TAppUserVipDetail; @@ -27,14 +30,10 @@ import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.common.redis.service.RedisService; import com.ruoyi.common.security.service.TokenService; import com.ruoyi.integration.api.feignClient.ChargingHandshakeClient; import com.ruoyi.integration.api.feignClient.PlatformStartChargingReplyClient; import com.ruoyi.integration.api.feignClient.SendMessageClient; import com.ruoyi.integration.api.feignClient.UploadRealTimeMonitoringDataClient; import com.ruoyi.integration.api.model.ChargingHandshake; import com.ruoyi.integration.api.model.PlatformStartCharging; import com.ruoyi.integration.api.model.PlatformStartChargingReply; import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData; import com.ruoyi.integration.api.feignClient.*; import com.ruoyi.integration.api.model.*; import com.ruoyi.integration.api.vo.GetPlatformStopChargingReply; import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient; import com.ruoyi.order.api.model.*; import com.ruoyi.order.api.query.ChargingOrderQuery; import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery; @@ -58,12 +57,15 @@ import com.ruoyi.payment.api.vo.*; import io.seata.spring.annotation.GlobalTransactional; import io.swagger.annotations.ApiModelProperty; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; @@ -113,7 +115,8 @@ private AliPaymentClient aliPaymentClient; @Resource private AppCouponClient appCouponClient; @Resource private AppUserVipDetailClient appUserVipDetailClient; @@ -142,6 +145,9 @@ @Resource private TChargingOrderRefundService chargingOrderRefundService; @Resource private PlatformStopChargingReplyClient platformStopChargingReplyClient; //计数器 private Map<String, Integer> counter_map = new HashMap<>(); @@ -456,7 +462,6 @@ chargingOrder.setRechargePaymentStatus(2); chargingOrder.setRechargeSerialNumber(transaction_id); chargingOrder.setStatus(2); this.updateById(chargingOrder); //添加安全检测数据到缓存中,每步安全检测完成后需要更新缓存数据 PreChargeCheck preChargeCheck = new PreChargeCheck(); @@ -495,6 +500,8 @@ } } electrovalence = electrovalence.add(discount); chargingOrder.setChargeAmount(electrovalence); this.updateById(chargingOrder); TChargingPile chargingPile = chargingPileClient.getChargingPileById(chargingGun.getChargingPileId()).getData(); @@ -702,13 +709,176 @@ chargingOrder.setEndMode(1); this.updateById(chargingOrder); //调用硬件停止充电,停止成功后开始计算费用退款 // todo 待完善 TChargingPile chargingPile = chargingPileClient.getChargingPileById(chargingOrder.getChargingPileId()).getData(); TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData(); PlatformStopCharging platformStopCharging = new PlatformStopCharging(); platformStopCharging.setCharging_pile_code(chargingPile.getCode()); platformStopCharging.setCharging_gun_code(chargingGun.getCode()); sendMessageClient.platformStopCharging(platformStopCharging); //开始查询停机应答,成功后开始计费费用 for (int i = 0; i < 60; i++) { GetPlatformStopChargingReply query = new GetPlatformStopChargingReply(); query.setCharging_gun_code(chargingGun.getCode()); query.setCharging_pile_code(chargingPile.getCode()); PlatformStopChargingReply reply = platformStopChargingReplyClient.getPlatformStopChargingReply(query).getData(); if(null == reply){ try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } continue; } if(0 == reply.getStop_result()){ String failure_cause = ""; switch (reply.getFailure_cause()){ case 0: failure_cause = "无"; break; case 1: failure_cause = "设备编号不匹配"; break; case 2: failure_cause = "枪未处于充电状态"; break; case 3: failure_cause = "其他"; break; } throw new RuntimeException(failure_cause); } //计算费用,处理退款 endCharge(chargingOrder); break; } return AjaxResult.success(); } /** * 手动结束后的费用计算和退款逻辑 */ @GlobalTransactional(rollbackFor = Exception.class) public void endCharge(TChargingOrder chargingOrder){ //如果使用优惠券需要判断优惠券是否满足使用条件 //根据实际的充电金额计算退款金额 退回费用=(原金额/总金额)*(总金额-实际充电金额) //退款金额=优惠券金额+剩余充电金额 List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>().eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId())); BigDecimal total = BigDecimal.ZERO; for (TChargingOrderAccountingStrategy chargingOrderAccountingStrategy : list) { BigDecimal periodElectricPrice = chargingOrderAccountingStrategy.getPeriodElectricPrice(); BigDecimal periodServicePrice = chargingOrderAccountingStrategy.getPeriodOriginalServicePrice(); total = total.add(periodElectricPrice).add(periodServicePrice); } BigDecimal rechargeAmount = chargingOrder.getRechargeAmount(); BigDecimal vipDiscountAmount = chargingOrder.getVipDiscountAmount(); BigDecimal decimal = rechargeAmount.add(vipDiscountAmount); //退款金额(已经计算了折扣优惠部分) BigDecimal refundAmount = rechargeAmount.divide(decimal, new MathContext(4, RoundingMode.HALF_EVEN)).multiply(decimal.subtract(total)); BigDecimal payAmount = BigDecimal.valueOf(total.doubleValue()); BigDecimal orderAmount = BigDecimal.valueOf(total.doubleValue()); if(null != chargingOrder.getVipDiscount()){ orderAmount = orderAmount.divide(chargingOrder.getVipDiscount().divide(new BigDecimal(10))); chargingOrder.setOrderAmount(total); } public void endCharge(){ if(null != chargingOrder.getAppCouponId()){ //判断实际充电金额是否满足优惠券使用条件,如果不满足则不适用优惠券。 TAppCoupon appCoupon = appCouponClient.getAppCouponById(chargingOrder.getAppCouponId()).getData(); String couponJson = appCoupon.getCouponJson(); TCoupon tCoupon = JSON.parseObject(couponJson, TCoupon.class); Integer preferentialMode = tCoupon.getPreferentialMode(); if(1 == preferentialMode){ //满减 if(total.compareTo(tCoupon.getMeetTheConditions()) >= 0){ refundAmount = refundAmount.add(tCoupon.getDiscountAmount()); chargingOrder.setCouponDiscountAmount(tCoupon.getDiscountAmount()); payAmount = payAmount.subtract(tCoupon.getDiscountAmount()); }else{ chargingOrder.setAppCouponId(null); chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO); appCouponClient.refund(chargingOrder.getAppCouponId().toString()); } } if(2 == preferentialMode){ //抵扣 if(total.compareTo(tCoupon.getMeetTheConditions()) >= 0){ //折扣金额 BigDecimal divide = total.multiply(new BigDecimal(10).subtract(tCoupon.getDiscount())).divide(new BigDecimal(10)); divide = divide.compareTo(tCoupon.getMaximumDiscountAmount()) > 0 ? tCoupon.getMaximumDiscountAmount() : divide; refundAmount = refundAmount.add(divide); chargingOrder.setCouponDiscountAmount(divide); payAmount = payAmount.subtract(divide); }else{ chargingOrder.setAppCouponId(null); chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO); appCouponClient.refund(chargingOrder.getAppCouponId().toString()); } } } if(null != chargingOrder.getVipDiscount()){ BigDecimal subtract = orderAmount.subtract(total); chargingOrder.setVipDiscountAmount(subtract); payAmount = payAmount.subtract(subtract); } chargingOrder.setPaymentAmount(payAmount); this.updateById(chargingOrder); //开始构建退款费用 if(refundAmount.compareTo(BigDecimal.ZERO) > 0){ Integer rechargePaymentType = chargingOrder.getRechargePaymentType(); //构建退款明细 TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund(); chargingOrderRefund.setChargingOrderId(chargingOrder.getId()); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); chargingOrderRefund.setRefundCode("CDF" + sdf.format(new Date()) + (Math.random() * 1000)); chargingOrderRefund.setRefundAmount(refundAmount); chargingOrderRefund.setRefundStatus(1); chargingOrderRefund.setPayType(rechargePaymentType); chargingOrderRefund.setRefundStatus(1); chargingOrderRefund.setCode(chargingOrder.getCode()); chargingOrderRefund.setRefundTitle("充电完成退款"); chargingOrderRefund.setRefundContent("充电完成退款"); chargingOrderRefund.setRefundReason("充电完成退款"); chargingOrderRefund.setRefundRemark("充电完成退款"); chargingOrderRefund.setRefundTotalAmount(refundAmount); chargingOrderRefund.setPayAmount(rechargeAmount); if(1 == rechargePaymentType){ WxPaymentRefundModel model = new WxPaymentRefundModel(); model.setOut_trade_no(chargingOrder.getCode()); model.setOut_refund_no(chargingOrderRefund.getRefundCode()); model.setReason("充电完成退款"); model.setNotify_url("http://127.0.0.1:9000/order/t-charging-order/chargingOrderStartupFailureWxRefund"); WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount(); amount.setRefund(refundAmount.multiply(new BigDecimal(100)).intValue()); amount.setTotal(rechargeAmount.multiply(new BigDecimal(100)).intValue()); amount.setCurrency("CNY"); model.setAmount(amount); R<String> orderR = wxPaymentClient.refundOrderR(model); if(200 == orderR.getCode()){ chargingOrderRefundService.save(chargingOrderRefund); } } if(2 == rechargePaymentType){ RefundReq dto = new RefundReq(); dto.setOutTradeNo(chargingOrder.getCode()); dto.setOutRequestNo(chargingOrderRefund.getCode()); dto.setRefundAmount(rechargeAmount.toString()); dto.setRefundReason("充电完成退款"); RefundResp resp = aliPaymentClient.refund(dto).getData(); if(null != resp){ SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-DDTHH:mm:ss+TIMEZONE"); AjaxResult success = chargingOrderStartupFailureWxRefund(resp.getOutTradeNo(), resp.getTradeNo(), "SUCCESS", sdf1.format(new Date())); if(success.isSuccess()){ chargingOrderRefundService.save(chargingOrderRefund); } } } } } @@ -1050,6 +1220,97 @@ */ @Override public void chargeMonitoring(UploadRealTimeMonitoringDataQuery query) { // todo 需完善 if(com.ruoyi.common.core.utils.StringUtils.isNotEmpty(query.getCharging_gun_code())){ //获取当前的计费策略 TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, query.getCharging_gun_code())); TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData(); TAccountingStrategyDetail strategyDetail = accountingStrategyDetailClient.getNowData(chargingGun.getAccountingStrategyId()).getData(); TChargingOrderAccountingStrategy chargingOrderAccountingStrategy = chargingOrderAccountingStrategyService.getOne(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>() .eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId()).orderByDesc(TChargingOrderAccountingStrategy::getCreateTime).last(" limit 0, 1")); SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); if(null == chargingOrderAccountingStrategy){ chargingOrderAccountingStrategy = new TChargingOrderAccountingStrategy(); chargingOrderAccountingStrategy.setChargingOrderId(chargingOrder.getId()); chargingOrderAccountingStrategy.setAccountingStrategyDetailId(strategyDetail.getId()); chargingOrderAccountingStrategy.setType(strategyDetail.getType()); chargingOrderAccountingStrategy.setStartTime(sdf.format(chargingOrder.getStartTime())); chargingOrderAccountingStrategy.setEndTime(sdf.format(new Date())); chargingOrderAccountingStrategy.setElectrovalence(strategyDetail.getElectrovalence()); chargingOrderAccountingStrategy.setServiceCharge(strategyDetail.getServiceCharge()); chargingOrderAccountingStrategy.setCostServiceCharge(strategyDetail.getCostServiceCharge()); BigDecimal charging_degree = query.getCharging_degree(); BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(charging_degree); BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(charging_degree); BigDecimal serviceCharge = originalServicePrice; //计算优惠金额 if(null != chargingOrder.getVipDiscount()){ serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount().divide(new BigDecimal(10))); } chargingOrderAccountingStrategy.setChargingCapacity(charging_degree); chargingOrderAccountingStrategy.setPeriodElectricPrice(electrovalenc); chargingOrderAccountingStrategy.setPeriodServicePrice(serviceCharge); chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(originalServicePrice); chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now()); chargingOrderAccountingStrategyService.save(chargingOrderAccountingStrategy); }else{ if(chargingOrderAccountingStrategy.getAccountingStrategyDetailId().equals(strategyDetail.getId())){ BigDecimal periodServicePrice = chargingOrderAccountingStrategy.getPeriodServicePrice(); BigDecimal periodElectricPrice = chargingOrderAccountingStrategy.getPeriodElectricPrice(); BigDecimal periodOriginalServicePrice = chargingOrderAccountingStrategy.getPeriodOriginalServicePrice(); BigDecimal charging_degree = query.getCharging_degree(); BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(charging_degree); BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(charging_degree); BigDecimal serviceCharge = originalServicePrice; //计算优惠金额 if(null != chargingOrder.getVipDiscount()){ serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount().divide(new BigDecimal(10))); } periodServicePrice = periodServicePrice.add(serviceCharge); periodOriginalServicePrice = periodOriginalServicePrice.add(originalServicePrice); periodElectricPrice = periodElectricPrice.add(electrovalenc); chargingOrderAccountingStrategy.setPeriodServicePrice(periodServicePrice); chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(periodOriginalServicePrice); chargingOrderAccountingStrategy.setPeriodElectricPrice(periodElectricPrice); chargingOrderAccountingStrategy.setEndTime(sdf.format(new Date())); chargingOrderAccountingStrategyService.updateById(chargingOrderAccountingStrategy); }else{ TChargingOrderAccountingStrategy chargingOrderAccountingStrategy1 = new TChargingOrderAccountingStrategy(); chargingOrderAccountingStrategy1.setChargingOrderId(chargingOrder.getId()); chargingOrderAccountingStrategy1.setAccountingStrategyDetailId(strategyDetail.getId()); chargingOrderAccountingStrategy1.setType(strategyDetail.getType()); chargingOrderAccountingStrategy1.setStartTime(sdf.format(chargingOrderAccountingStrategy.getEndTime())); chargingOrderAccountingStrategy1.setEndTime(sdf.format(new Date())); chargingOrderAccountingStrategy1.setElectrovalence(strategyDetail.getElectrovalence()); chargingOrderAccountingStrategy1.setServiceCharge(strategyDetail.getServiceCharge()); chargingOrderAccountingStrategy1.setCostServiceCharge(strategyDetail.getCostServiceCharge()); BigDecimal charging_degree = query.getCharging_degree(); BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(charging_degree); BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(charging_degree); BigDecimal serviceCharge = originalServicePrice; //计算优惠金额 if(null != chargingOrder.getVipDiscount()){ serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount().divide(new BigDecimal(10))); } chargingOrderAccountingStrategy1.setChargingCapacity(charging_degree); chargingOrderAccountingStrategy1.setPeriodElectricPrice(electrovalenc); chargingOrderAccountingStrategy1.setPeriodOriginalServicePrice(originalServicePrice); chargingOrderAccountingStrategy1.setPeriodServicePrice(serviceCharge); chargingOrderAccountingStrategy1.setCreateTime(LocalDateTime.now()); chargingOrderAccountingStrategyService.save(chargingOrderAccountingStrategy1); } } List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>() .eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId())); BigDecimal t = BigDecimal.ZERO; for (TChargingOrderAccountingStrategy coas : list) { t = t.add(coas.getPeriodServicePrice()).add(coas.getPeriodElectricPrice()); } BigDecimal residualAmount = chargingOrder.getRechargeAmount().subtract(t).setScale(2, RoundingMode.HALF_EVEN); chargingOrder.setResidualAmount(residualAmount); BigDecimal divide = query.getOutput_current().multiply(query.getOutput_voltage()).divide(new BigDecimal(1000)); chargingOrder.setChargingPower(divide); this.updateById(chargingOrder); } } } ruoyi-service/ruoyi-order/src/main/resources/bootstrap.yml
@@ -24,6 +24,7 @@ namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb username: nacos password: nacos ip: 192.168.110.85 config: # 配置中心地址 server-addr: 192.168.110.169:8848