From f6125b320b78b36c439e85d926cb2b11cd71fc6c Mon Sep 17 00:00:00 2001
From: zhibing.pu <393733352@qq.com>
Date: 星期六, 31 八月 2024 17:45:52 +0800
Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/mx_charging_pile

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java |  227 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 207 insertions(+), 20 deletions(-)

diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
index dbb8223..0fd7b60 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -11,10 +11,12 @@
 import com.ruoyi.account.api.model.TAppUserCar;
 import com.ruoyi.account.api.model.TAppUserVipDetail;
 import com.ruoyi.account.api.vo.GetAppUserVipDetail;
+import com.ruoyi.chargingPile.api.feignClient.AccountingStrategyDetailClient;
 import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient;
 import com.ruoyi.chargingPile.api.feignClient.ChargingPileClient;
 import com.ruoyi.chargingPile.api.feignClient.SiteClient;
 import com.ruoyi.chargingPile.api.model.Site;
+import com.ruoyi.chargingPile.api.model.TAccountingStrategyDetail;
 import com.ruoyi.chargingPile.api.model.TChargingGun;
 import com.ruoyi.chargingPile.api.model.TChargingPile;
 import com.ruoyi.common.core.domain.R;
@@ -26,16 +28,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;
@@ -43,10 +45,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;
@@ -63,6 +71,7 @@
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
+import java.util.concurrent.*;
 import java.util.stream.Collectors;
 
 /**
@@ -124,6 +133,19 @@
 	@Resource
 	private TOrderEvaluateService orderEvaluateService;
 
+	
+	@Resource
+	private AccountingStrategyDetailClient accountingStrategyDetailClient;
+	
+	@Resource
+	private PlatformStartChargingReplyClient platformStartChargingReplyClient;
+	
+	@Resource
+	private TChargingOrderRefundService chargingOrderRefundService;
+	
+	//计数器
+	private Map<String, Integer> counter_map = new HashMap<>();
+	
 	
 	
 
@@ -425,6 +447,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){
@@ -432,35 +455,189 @@
 		}
 		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);
 		
 		//根据当前充值的金额和计费模板算出充电的金额
 		BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
 		//计算充电金额,会员需要将折扣金额加入到充电总金额中
-
-//		TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
-//		if(){
-//			appUser.getVipId()
-//		}
-//
-//
-//		//调用远程启动充电消息
-//		PlatformStartCharging platformStartCharging = new PlatformStartCharging();
-//		platformStartCharging.setTransaction_serial_number(chargingOrder.getCode());
-//		platformStartCharging.setCharging_pile_code();
-//		platformStartCharging.setCharging_gun_code();
-//		platformStartCharging.setCard_number();
-//		platformStartCharging.setAccount_balance()
-//		sendMessageClient.platformStartCharging(platformStartCharging);
+		TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
+		TAccountingStrategyDetail strategyDetail = accountingStrategyDetailClient.getNowData(chargingGun.getAccountingStrategyId()).getData();
+		//总单价
+		BigDecimal totalUnitPrice = strategyDetail.getServiceCharge().add(strategyDetail.getElectrovalence());
+		//计算能充电的度数
+		BigDecimal degrees = rechargeAmount.divide(totalUnitPrice);
+		//计算电费金额和服务费
+		BigDecimal serviceCharge = strategyDetail.getServiceCharge().multiply(degrees);
+		BigDecimal electrovalence = strategyDetail.getElectrovalence().multiply(degrees);
+		
+		//再处理会员折扣
+		BigDecimal discount = BigDecimal.ZERO;
+		TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
+		if(null != appUser.getVipId()){
+			GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
+			getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
+			getAppUserVipDetail.setVipId(appUser.getVipId());
+			TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
+			if(data.getChargeNum() > 0){
+				discount = serviceCharge.multiply(data.getDiscount().divide(new BigDecimal(10)));
+				data.setChargeNum(data.getChargeNum() - 1);
+				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(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();
+	}
+	
+	
 	
 	
 	/**
@@ -484,6 +661,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());
@@ -494,7 +672,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()){
@@ -865,4 +1042,14 @@
 		chargingOrderTimeVO.setList(pageInfo);
 		return chargingOrderTimeVO;
 	}
+	
+	
+	/**
+	 * 处理充电订单实时监控数据相关的业务逻辑
+	 * @param query
+	 */
+	@Override
+	public void chargeMonitoring(UploadRealTimeMonitoringDataQuery query) {
+		// todo 需完善
+	}
 }

--
Gitblit v1.7.1