ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserFallbackFactory.java
@@ -35,7 +35,7 @@ @Override public R<TAppUser> getUserById(Long id) { return R.fail("根据id查询用户失败:"+throwable.getMessage()); throw new RuntimeException("根据id查询用户失败:"+throwable.getMessage()); } @Override ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/factory/AppUserVipDetailFallbackFactory.java
@@ -26,7 +26,12 @@ @Override public R<TAppUserVipDetail> getAppUserVipDetail(GetAppUserVipDetail getAppUserVipDetail) { return R.fail("获取用户当前有效的VIP明细调用失败:" + throwable.getMessage()); throw new RuntimeException("获取用户当前有效的VIP明细调用失败:" + throwable.getMessage()); } @Override public void updateAppUserVipDetail(TAppUserVipDetail appUserVipDetail) { throw new RuntimeException(throwable.getMessage()); } }; } ruoyi-api/ruoyi-api-account/src/main/java/com/ruoyi/account/api/feignClient/AppUserVipDetailClient.java
@@ -7,6 +7,7 @@ import com.ruoyi.common.core.domain.R; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; /** * @author zhibing.pu @@ -24,4 +25,10 @@ R<TAppUserVipDetail> getAppUserVipDetail(GetAppUserVipDetail getAppUserVipDetail); /** * 修改会员明细 * @param appUserVipDetail */ @PostMapping("/appUserVipDetail/updateAppUserVipDetail") void updateAppUserVipDetail(@RequestBody TAppUserVipDetail appUserVipDetail); } ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ChargingGunFallbackFactory.java
@@ -35,7 +35,7 @@ @Override public R<TChargingGun> getChargingGunById(Integer id) { return R.fail("根据id获取充电枪失败:" + throwable.getMessage()); throw new RuntimeException("根据id获取充电枪失败:" + throwable.getMessage()); } @Override ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/PlatformStartChargingReplyFallbackFactory.java
New file @@ -0,0 +1,34 @@ package com.ruoyi.integration.api.factory; import com.ruoyi.common.core.domain.R; import com.ruoyi.integration.api.feignClient.PlatformStartChargingReplyClient; import com.ruoyi.integration.api.model.PlatformStartChargingReply; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.stereotype.Component; import java.util.List; /** * @author zhibing.pu * @Date 2024/8/31 15:16 */ @Component public class PlatformStartChargingReplyFallbackFactory implements FallbackFactory<PlatformStartChargingReplyClient> { private static final Logger log = LoggerFactory.getLogger(PlatformStartChargingReplyFallbackFactory.class); @Override public PlatformStartChargingReplyClient create(Throwable throwable) { log.error("远程启机应答调用失败:{}", throwable.getMessage()); return new PlatformStartChargingReplyClient(){ @Override public R<List<PlatformStartChargingReply>> getPlatformStartChargingReply(String code) { return R.fail("根据订单编号查询远程启机应答结果失败:" + throwable.getMessage()); } }; } } ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/SendMessageFallbackFactory.java
@@ -28,6 +28,7 @@ @Override public void platformStartCharging(PlatformStartCharging platformStartCharging) { throw new RuntimeException("远程启机失败" + throwable.getMessage()); } }; } ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/PlatformStartChargingReplyClient.java
New file @@ -0,0 +1,28 @@ 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.PlatformStartChargingReplyFallbackFactory; import com.ruoyi.integration.api.model.PlatformStartChargingReply; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import java.util.List; /** * @author zhibing.pu * @Date 2024/8/31 15:16 */ @FeignClient(contextId = "PlatformStartChargingReplyClient", value = ServiceNameConstants.INTEGRATION_SERVICE, fallbackFactory = PlatformStartChargingReplyFallbackFactory.class) public interface PlatformStartChargingReplyClient { /** * 根据订单编号查询远程启机应答结果 * @param code * @return */ @PostMapping("/platformStartChargingReply/getPlatformStartChargingReply") R<List<PlatformStartChargingReply>> getPlatformStartChargingReply(@RequestParam("code") String code); } ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/model/UploadRealTimeMonitoringData.java
@@ -2,7 +2,6 @@ import lombok.Data; import lombok.experimental.Accessors; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import java.math.BigDecimal; @@ -16,7 +15,6 @@ @Accessors(chain = true) public class UploadRealTimeMonitoringData extends BaseModel { @Id private String transaction_serial_number; // 交易流水号 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
@@ -1,4 +1,5 @@ com.ruoyi.integration.api.factory.IntegrationFallbackFactory com.ruoyi.integration.api.factory.UploadRealTimeMonitoringDataFallbackFactory com.ruoyi.integration.api.factory.ChargingHandshakeFallbackFactory com.ruoyi.integration.api.factory.SendMessageFallbackFactory com.ruoyi.integration.api.factory.SendMessageFallbackFactory com.ruoyi.integration.api.factory.PlatformStartChargingReplyFallbackFactory ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/factory/ChargingOrderFallbackFactory.java
@@ -4,6 +4,7 @@ import com.ruoyi.order.api.feignClient.ChargingOrderClient; import com.ruoyi.order.api.model.TChargingOrder; import com.ruoyi.order.api.query.TChargingCountQuery; import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.openfeign.FallbackFactory; @@ -49,6 +50,10 @@ public R<Long> getCar() { return R.fail("获取用户最近使用车辆充电的车辆id:" + throwable.getMessage()); } @Override public void chargeMonitoring(UploadRealTimeMonitoringDataQuery query) { } }; } } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/feignClient/ChargingOrderClient.java
@@ -5,6 +5,7 @@ import com.ruoyi.order.api.factory.ChargingOrderFallbackFactory; import com.ruoyi.order.api.model.TChargingOrder; import com.ruoyi.order.api.query.TChargingCountQuery; import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -46,4 +47,13 @@ */ @GetMapping(value = "/t-charging-order/getCar") public R<Long> getCar(); /** * 处理充电订单实时监控数据相关的业务逻辑 * @param query * @return */ @PostMapping(value = "/t-charging-order/chargeMonitoring") void chargeMonitoring(@RequestBody UploadRealTimeMonitoringDataQuery query); } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/TChargingOrder.java
@@ -109,6 +109,10 @@ @ApiModelProperty(value = "充值支付第三方流水号") @TableField("recharge_serial_number") private String rechargeSerialNumber; @ApiModelProperty(value = "剩余金额(用于前端展示)") @TableField("residual_amount") private BigDecimal residualAmount; @ApiModelProperty(value = "订单金额(总金额)") @TableField("order_amount") ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/query/UploadRealTimeMonitoringDataQuery.java
New file @@ -0,0 +1,36 @@ package com.ruoyi.order.api.query; import lombok.Data; import java.math.BigDecimal; import java.util.Date; /** * 上传实时监测数据 **/ @Data public class UploadRealTimeMonitoringDataQuery { private String transaction_serial_number; // 交易流水号 private String charging_pile_code; // 桩编码 private String charging_gun_code; // 抢号 private Integer charging_gun_status; // 状态(0:离线,1:故障,2:空闲,3:充电) private Integer homing_status; // 枪是否归位(0:否,1:是,2:未知) private Integer insertion_status; // 是否插枪(0:否,1:是) private BigDecimal output_voltage; // 输出电压,精确到小数点后一位;待机置零 private BigDecimal output_current; // 输出电流,精确到小数点后一位;待机置零 private Integer gun_line_temperature; // 枪线温度,整形,偏移量-50;待机置零 private String gun_line_code; // 枪线编码,没有置零 private Integer soc; // SOC待机置零;交流桩置零 private Integer battery_temperature; // 电池组最高温度,整形,偏移量-50 ºC;待机置零;交流桩置零 private Integer cumulative_charging_time; // 累计充电时间,单位:min;待机置零 private Integer time_remaining; // 剩余时间,单位:min;待机置零、交流桩置零 private BigDecimal charging_degree; // 充电度数,精确到小数点后四位;待机置零 private BigDecimal loss_of_charging_degree; // 计损充电度数,精确到小数点后四位;待机置零,未设置计损比例时等于充电度数 private BigDecimal paid_amount; // 已充金额,精确到小数点后四位;待机置零(电费+服务费)*计损充电度数 private Integer hardware_fault; // 硬件故障(1:急停按钮动作故障;2:无可用整流模块;3:出风口温度过高;4:交流防雷故障;5:交直流模块 DC20 通信中断;6:绝缘检测模块 FC08 通信中断;7:电度表通信中断;8:读卡器通信中断;9:RC10 通信中断;10:风扇调速板故障;11:直流熔断器故障;12:高压接触器故障;13:门打开) private Date create_time; } ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/controller/TAppUserVipDetailController.java
@@ -56,6 +56,15 @@ } return R.ok(list); } /** * 修改会员明细 * @param appUserVipDetail */ @PostMapping("/updateAppUserVipDetail") public void updateAppUserVipDetail(@RequestBody TAppUserVipDetail appUserVipDetail){ appUserVipDetailService.updateById(appUserVipDetail); } } ruoyi-service/ruoyi-integration/pom.xml
@@ -164,8 +164,11 @@ <artifactId>huaweicloud-sdk-bundle</artifactId> <version>3.1.87</version> </dependency> <dependency> <groupId>com.ruoyi</groupId> <artifactId>ruoyi-api-order</artifactId> </dependency> </dependencies> <build> ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/controller/PlatformStartChargingReplyController.java
New file @@ -0,0 +1,35 @@ package com.ruoyi.integration.controller; import com.ruoyi.common.core.domain.R; import com.ruoyi.integration.api.model.PlatformStartChargingReply; import com.ruoyi.integration.mongodb.service.PlatformStartChargingReplyService; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.List; /** * @author zhibing.pu * @Date 2024/8/31 15:09 */ @RestController @RequestMapping("/platformStartChargingReply") public class PlatformStartChargingReplyController { @Resource private PlatformStartChargingReplyService platformStartChargingReplyService; /** * 根据订单编号查询远程启机应答结果 * @param code * @return */ @PostMapping("/getPlatformStartChargingReply") public R<List<PlatformStartChargingReply>> getPlatformStartChargingReply(@RequestParam("code") String code){ List<PlatformStartChargingReply> platformStartChargingReply = platformStartChargingReplyService.getPlatformStartChargingReply(code); return R.ok(platformStartChargingReply); } } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/PlatformStartChargingReplyService.java
@@ -2,6 +2,17 @@ import com.ruoyi.integration.api.model.PlatformStartChargingReply; import com.ruoyi.integration.mongodb.base.BaseService; import org.springframework.web.bind.annotation.RequestParam; import java.util.List; public interface PlatformStartChargingReplyService extends BaseService<PlatformStartChargingReply> { /** * 根据订单编号查询远程启机应答数据 * @param code * @return */ List<PlatformStartChargingReply> getPlatformStartChargingReply(String code); } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/mongodb/service/impl/PlatformStartChargingReplyServiceImpl.java
@@ -5,6 +5,8 @@ import com.ruoyi.integration.mongodb.service.PlatformStartChargingReplyService; 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; @@ -29,4 +31,18 @@ public List<PlatformStartChargingReply> findAll() { return mongoTemplate.findAll(PlatformStartChargingReply.class); } /** * 根据订单编号查询远程启机应答数据 * @param code * @return */ @Override public List<PlatformStartChargingReply> getPlatformStartChargingReply(String code) { Query query = new Query(); query.addCriteria(Criteria.where("transaction_serial_number").is(code)); List<PlatformStartChargingReply> platformStartChargingReplies = mongoTemplate.find(query, PlatformStartChargingReply.class); return platformStartChargingReplies; } } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/rocket/listener/UploadRealTimeMonitoringDataMessageListener.java
@@ -5,12 +5,16 @@ import com.ruoyi.integration.mongodb.service.UploadRealTimeMonitoringDataService; import com.ruoyi.integration.rocket.model.UploadRealTimeMonitoringDataMessage; import com.ruoyi.integration.rocket.util.EnhanceMessageHandler; import com.ruoyi.order.api.feignClient.ChargingOrderClient; import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery; import lombok.extern.slf4j.Slf4j; import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; import org.apache.rocketmq.spring.core.RocketMQListener; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.Resource; @Slf4j @Component @@ -24,6 +28,15 @@ @Autowired private UploadRealTimeMonitoringDataService uploadRealTimeMonitoringDataService; @Resource private ChargingOrderClient chargingOrderClient; @Override protected void handleMessage(UploadRealTimeMonitoringDataMessage message) throws Exception { // 此时这里才是最终的业务处理,代码只需要处理资源类关闭异常,其他的可以交给父类重试 @@ -33,6 +46,9 @@ BeanUtils.copyProperties(message,uploadRealTimeMonitoringData); uploadRealTimeMonitoringDataService.create(uploadRealTimeMonitoringData); // 业务处理 UploadRealTimeMonitoringDataQuery query = new UploadRealTimeMonitoringDataQuery(); BeanUtils.copyProperties(uploadRealTimeMonitoringData, query); chargingOrderClient.chargeMonitoring(query); } @Override ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
@@ -24,9 +24,11 @@ import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.page.BasePage; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.integration.api.model.UploadRealTimeMonitoringData; import com.ruoyi.order.api.model.*; import com.ruoyi.order.api.query.ChargingOrderQuery; import com.ruoyi.order.api.query.TChargingCountQuery; import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery; import com.ruoyi.order.api.vo.ChargingOrderInfoVO; import com.ruoyi.order.api.vo.ChargingOrderVO; import com.ruoyi.order.api.vo.TCharingOrderVO; @@ -40,6 +42,7 @@ import com.ruoyi.payment.api.feignClient.AliPaymentClient; import com.ruoyi.payment.api.feignClient.WxPaymentClient; import com.ruoyi.payment.api.vo.AliQueryOrder; import com.ruoyi.payment.api.vo.WxRefundNotifyResp; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; @@ -85,7 +88,7 @@ @Resource private TShoppingOrderService shoppingOrderService; @Autowired @Resource private AppUserClient appUserClient; @Resource @@ -406,6 +409,27 @@ e.printStackTrace(); } } /** * 远程启动失败后退款回调 * @param request */ @ResponseBody @PostMapping(value = "/chargingOrderALICallback") public void chargingOrderStartupFailureWxRefund(HttpServletRequest request){ WxRefundNotifyResp data = wxPaymentClient.refundNotify(request).getData(); if(null != data){ String out_refund_no = data.getOut_refund_no(); String refund_id = data.getRefund_id(); String tradeState = data.getTradeState(); String success_time = data.getSuccess_time(); chargingOrderService.chargingOrderStartupFailureWxRefund(out_refund_no, refund_id, tradeState, success_time); } } @ResponseBody @@ -442,5 +466,18 @@ public AjaxResult stopCharging(@PathVariable String id) { return chargingOrderService.stopCharging(id); } /** * 处理充电订单实时监控数据相关的业务逻辑 * @param query */ @PostMapping("/chargeMonitoring") public void chargeMonitoring(@RequestBody UploadRealTimeMonitoringDataQuery query){ chargingOrderService.chargeMonitoring(query); } } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/dto/PreChargeCheck.java
@@ -17,4 +17,8 @@ private Boolean insulationTesting; @ApiModelProperty("电子锁锁止") private Boolean electronicLockLock; @ApiModelProperty("启动成功(1=启动中,2=启动成功,3=启动失败,退款)") private Integer startupSuccess; @ApiModelProperty("失败原因(0:无,1:设备编号不匹配,2:枪已在充电,3:设备故障,4:设备离线,5:未插枪桩在收到启充命令后,检测到未插枪则发送 0x33 报文回复充电失败。若在 60 秒(以收到 0x34 时间开始计算)内检测到枪重新连接,则补送 0x33 成功报文;超时或者离线等其他异常,桩不启充、不补发 0x33 报文)") private Integer failureCause; } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TChargingOrderService.java
@@ -8,6 +8,7 @@ import com.ruoyi.order.api.model.TChargingOrder; import com.ruoyi.order.api.model.TChargingOrderRefund; import com.ruoyi.order.api.query.ChargingOrderQuery; import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery; import com.ruoyi.order.api.vo.ChargingOrderTimeVO; import com.ruoyi.order.api.vo.ChargingOrderVO; import com.ruoyi.order.api.vo.TCharingOrderVO; @@ -72,6 +73,18 @@ /** * 充电启动失败后的退款回调处理 * @param out_refund_no * @param refund_id * @param tradeState * @param success_time * @return */ AjaxResult chargingOrderStartupFailureWxRefund(String out_refund_no, String refund_id, String tradeState, String success_time); /** * 获取充电中的详情 * @param id * @return @@ -93,4 +106,11 @@ R<PageInfo<TChargingOrderRefund>> getRefundList(ChargingRefundDto chargingRefundDto); ChargingOrderTimeVO chargingList(ChargingListQuery dto); /** * 处理充电订单实时监控数据相关的业务逻辑 * @param query */ void chargeMonitoring(UploadRealTimeMonitoringDataQuery query); } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -25,16 +25,16 @@ 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.order.api.model.TChargingOrder; import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy; import com.ruoyi.order.api.model.TChargingOrderRefund; import com.ruoyi.order.api.model.TOrderEvaluate; import com.ruoyi.order.api.model.*; import com.ruoyi.order.api.query.ChargingOrderQuery; import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery; import com.ruoyi.order.api.vo.ChargingOrderListVO; import com.ruoyi.order.api.vo.ChargingOrderTimeVO; import com.ruoyi.order.api.vo.ChargingOrderVO; @@ -42,10 +42,16 @@ import com.ruoyi.order.dto.*; import com.ruoyi.order.mapper.TChargingOrderMapper; import com.ruoyi.order.service.TChargingOrderAccountingStrategyService; import com.ruoyi.order.service.TChargingOrderRefundService; import com.ruoyi.order.service.TChargingOrderService; import com.ruoyi.order.service.TOrderEvaluateService; import com.ruoyi.other.api.domain.TCoupon; import com.ruoyi.other.api.domain.TGoods; import com.ruoyi.payment.api.feignClient.AliPaymentClient; import com.ruoyi.payment.api.feignClient.WxPaymentClient; import com.ruoyi.payment.api.model.RefundReq; import com.ruoyi.payment.api.model.RefundResp; import com.ruoyi.payment.api.model.WxPaymentRefundModel; import com.ruoyi.payment.api.vo.*; import io.seata.spring.annotation.GlobalTransactional; import io.swagger.annotations.ApiModelProperty; @@ -61,6 +67,7 @@ import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.concurrent.*; import java.util.stream.Collectors; /** @@ -122,6 +129,15 @@ @Resource private AccountingStrategyDetailClient accountingStrategyDetailClient; @Resource private PlatformStartChargingReplyClient platformStartChargingReplyClient; @Resource private TChargingOrderRefundService chargingOrderRefundService; //计数器 private Map<String, Integer> counter_map = new HashMap<>(); @@ -424,6 +440,7 @@ * @return */ @Override @GlobalTransactional(rollbackFor = Exception.class) public AjaxResult chargingOrderCallback(Integer paymentType, String out_trade_no, String transaction_id, String attach) { TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, out_trade_no)); if(chargingOrder.getRechargePaymentStatus() == 2){ @@ -431,12 +448,15 @@ } chargingOrder.setRechargePaymentStatus(2); chargingOrder.setRechargeSerialNumber(transaction_id); chargingOrder.setStatus(2); this.updateById(chargingOrder); //添加安全检测数据到缓存中,每步安全检测完成后需要更新缓存数据 PreChargeCheck preChargeCheck = new PreChargeCheck(); preChargeCheck.setElectronicLockLock(false); preChargeCheck.setInsulationTesting(false); preChargeCheck.setSecureConnectionDetection(false); preChargeCheck.setStartupSuccess(1); String key = "AQJC_" + chargingOrder.getChargingGunId(); redisService.setCacheObject(key, preChargeCheck); @@ -464,24 +484,153 @@ if(data.getChargeNum() > 0){ discount = serviceCharge.multiply(data.getDiscount().divide(new BigDecimal(10))); data.setChargeNum(data.getChargeNum() - 1); appUserVipDetailClient. appUserVipDetailClient.updateAppUserVipDetail(data); } } electrovalence = electrovalence.add(discount); TChargingPile chargingPile = chargingPileClient.getChargingPileById(chargingGun.getChargingPileId()).getData(); //调用远程启动充电消息 PlatformStartCharging platformStartCharging = new PlatformStartCharging(); platformStartCharging.setTransaction_serial_number(chargingOrder.getCode()); platformStartCharging.setCharging_pile_code(); platformStartCharging.setCharging_gun_code(); platformStartCharging.setCard_number(); platformStartCharging.setCharging_pile_code(chargingPile.getCode()); platformStartCharging.setCharging_gun_code(chargingGun.getCode()); //使用订单id作为逻辑卡号 platformStartCharging.setCard_number(chargingOrder.getId().toString()); platformStartCharging.setAccount_balance(electrovalence); sendMessageClient.platformStartCharging(platformStartCharging); //异步线程检测远程启动的应答结果。如果失败,则需要全额退款 String code = chargingOrder.getCode(); //执行5分钟的定时任务检测 ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); scheduler.scheduleAtFixedRate(()->{ List<PlatformStartChargingReply> data = platformStartChargingReplyClient.getPlatformStartChargingReply(code).getData(); if(data.size() != 0){ PlatformStartChargingReply platformStartChargingReply = data.get(1); Integer startup_result = platformStartChargingReply.getStartup_result(); Integer failure_cause = platformStartChargingReply.getFailure_cause(); Integer counter = counter_map.get(code); PreChargeCheck preChargeCheck1 = redisService.getCacheObject(key); //状态为5的时候,硬件会间隔60秒后再次检测,依然未插枪,则不启动充电 //因这里是间隔5秒执行检测,所以累计次数在30次以上 if(failure_cause == 5 && null == counter || counter < 35){ counter++; counter_map.put(code, counter); //启动失败 preChargeCheck1.setStartupSuccess(3); preChargeCheck1.setFailureCause(failure_cause); redisService.setCacheObject(key, preChargeCheck1); return; } //清除计时器中的无效数据 counter_map.remove(code); //开始处理退款 TChargingOrder order = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, code)); if(0 == startup_result){ //启动失败 preChargeCheck1.setStartupSuccess(3); preChargeCheck1.setFailureCause(failure_cause); //启动失败后取消订单,退款操作 refund(code); order.setStatus(5); order.setEndMode(0); }else{ preChargeCheck1.setStartupSuccess(2); order.setStatus(3); order.setStartTime(LocalDateTime.now()); } this.updateById(order); redisService.setCacheObject(key, preChargeCheck1); //提前结束定时任务 scheduler.shutdown(); } }, 5, 300, TimeUnit.SECONDS); return AjaxResult.success(); } /** * 启动失败后的退款,取消订单 * @param code */ public void refund(String code){ TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, code)); if(chargingOrder.getStatus() == 2){ Integer rechargePaymentType = chargingOrder.getRechargePaymentType(); BigDecimal rechargeAmount = chargingOrder.getRechargeAmount(); //构建退款明细 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(rechargeAmount); chargingOrderRefund.setRefundStatus(1); chargingOrderRefund.setPayType(rechargePaymentType); chargingOrderRefund.setRefundStatus(1); chargingOrderRefund.setCode(code); chargingOrderRefund.setRefundTitle("充电失败"); chargingOrderRefund.setRefundContent("充电失败"); chargingOrderRefund.setRefundReason("充电失败"); chargingOrderRefund.setRefundRemark("全额退款"); chargingOrderRefund.setRefundTotalAmount(rechargeAmount); 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(rechargeAmount.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); } } } } } /** * 启动失败后微信退款的回调处理 * @param out_refund_no * @param refund_id * @param tradeState * @param success_time * @return */ public AjaxResult chargingOrderStartupFailureWxRefund(String out_refund_no, String refund_id, String tradeState, String success_time){ if("SUCCESS".equals(tradeState)){ TChargingOrderRefund one = chargingOrderRefundService.getOne(new LambdaQueryWrapper<TChargingOrderRefund>().eq(TChargingOrderRefund::getRefundCode, out_refund_no)); one.setRefundSerialNumber(refund_id); one.setRefundStatus(2); one.setRefundTime(LocalDateTime.parse(success_time, DateTimeFormatter.ofPattern("yyyy-MM-DDTHH:mm:ss+TIMEZONE"))); chargingOrderRefundService.updateById(one); } return AjaxResult.success(); } /** @@ -505,6 +654,7 @@ chargingDetails.setName(site.getName() + "-" + chargingPile.getName()); chargingDetails.setCode(one.getCode()); chargingDetails.setStatus(one.getStatus()); chargingDetails.setChargingCost(one.getResidualAmount()); UploadRealTimeMonitoringData data = uploadRealTimeMonitoringDataClient.chargingOrderInfo(one.getCode()).getData(); if(null != data){ chargingDetails.setChargeCurrent(data.getOutput_current()); @@ -515,7 +665,6 @@ chargingDetails.setRemainingChargeTime(data.getTime_remaining()); chargingDetails.setChargedDegrees(data.getCharging_degree()); chargingDetails.setChargedTime(data.getCumulative_charging_time()); chargingDetails.setChargingCost(data.getPaid_amount()); } ChargingHandshake chargingHandshake = chargingHandshakeClient.getDataByOrderCode(one.getCode()).getData(); if(null != chargingHandshake && null != data && null != one.getAppUserCarId()){ @@ -843,4 +992,14 @@ chargingOrderTimeVO.setList(pageInfo); return chargingOrderTimeVO; } /** * 处理充电订单实时监控数据相关的业务逻辑 * @param query */ @Override public void chargeMonitoring(UploadRealTimeMonitoringDataQuery query) { // todo 需完善 } } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TShoppingOrderServiceImpl.java
@@ -405,6 +405,7 @@ public AjaxResult cancelShoppingOrderWxRefund(String out_refund_no, String refund_id, String refund_status, String success_time) { if("SUCCESS".equals(refund_status)){ TShoppingOrderRefund one = shoppingOrderRefundService.getOne(new LambdaQueryWrapper<TShoppingOrderRefund>().eq(TShoppingOrderRefund::getRefundCode, out_refund_no)); one.setRefundStatus(2); one.setRefundSerialNumber(refund_id); one.setRefundTime(LocalDateTime.parse(success_time, DateTimeFormatter.ofPattern("yyyy-MM-DDTHH:mm:ss+TIMEZONE"))); shoppingOrderRefundService.updateById(one); ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml
@@ -24,6 +24,7 @@ <result column="recharge_payment_type" property="rechargePaymentType" /> <result column="recharge_payment_status" property="rechargePaymentStatus" /> <result column="recharge_serial_number" property="rechargeSerialNumber" /> <result column="residual_amount" property="residualAmount" /> <result column="order_amount" property="orderAmount" /> <result column="app_coupon_id" property="appCouponId" /> <result column="coupon_discount_amount" property="couponDiscountAmount" />