From f27f3a1da27ff11e3c12dc1841094a0419a4279a Mon Sep 17 00:00:00 2001
From: 无关风月 <443237572@qq.com>
Date: 星期五, 27 九月 2024 10:36:44 +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 |  213 +++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 165 insertions(+), 48 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 7fabc18..486a730 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
@@ -33,6 +33,7 @@
 import com.ruoyi.integration.api.vo.GetPlatformStopChargingReply;
 import com.ruoyi.order.api.dto.SettlementConfirmAdd;
 import com.ruoyi.order.api.feignClient.AccountingStrategyDetailOrderClient;
+import com.ruoyi.order.api.feignClient.AccountingStrategyOrderClient;
 import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient;
 import com.ruoyi.order.api.model.*;
 import com.ruoyi.order.api.query.ChargingOrderQuery;
@@ -47,11 +48,8 @@
 import com.ruoyi.order.service.TChargingOrderService;
 import com.ruoyi.order.service.TOrderEvaluateService;
 import com.ruoyi.order.service.*;
-import com.ruoyi.other.api.domain.TCoupon;
-import com.ruoyi.other.api.domain.TGoods;
+import com.ruoyi.other.api.domain.*;
 import com.ruoyi.order.vo.ChargingOrderListInfoVO;
-import com.ruoyi.other.api.domain.TIntegralRule;
-import com.ruoyi.other.api.domain.TVip;
 import com.ruoyi.other.api.feignClient.*;
 import com.ruoyi.payment.api.feignClient.AliPaymentClient;
 import com.ruoyi.payment.api.feignClient.WxPaymentClient;
@@ -153,6 +151,9 @@
 
 	@Resource
 	private AccountingStrategyDetailOrderClient accountingStrategyDetailOrderClient;
+	
+	@Resource
+	private AccountingStrategyOrderClient accountingStrategyOrderClient;
 
 	@Resource
 	private AccountingStrategyClient accountingStrategyClient;
@@ -183,6 +184,12 @@
 	
 	@Resource
 	private VipClient vipClient;
+	
+	@Resource
+	private UserTagClient userTagClient;
+	
+	@Resource
+	private AppUserTagClient appUserTagClient;
 
 	//计数器
 	private Map<String, Integer> counter_map = new HashMap<>();
@@ -433,7 +440,28 @@
 		chargingOrder.setRechargePaymentStatus(1);
 		chargingOrder.setRechargeAmount(addChargingOrder.getPaymentAmount());
 		chargingOrder.setAppCouponId(addChargingOrder.getAppUserCouponId());
-		if(null != appUser.getVipId()){
+		chargingOrder.setVipDiscount(new BigDecimal(10));
+		chargingOrder.setVipDiscountAmount(BigDecimal.ZERO);
+		
+		Site site = siteClient.getSiteByIds(Arrays.asList(tChargingGun.getSiteId())).getData().get(0);
+		Integer accountingStrategyId = tChargingGun.getAccountingStrategyId();
+		if(null == accountingStrategyId){
+			//查询站点上面的计费策略
+			accountingStrategyId = site.getAccountingStrategyId();
+		}
+		TAccountingStrategy accountingStrategy = accountingStrategyClient.getAccountingStrategyById(accountingStrategyId).getData();
+		
+		//直营站点才可以享受会员折扣
+		if(null != appUser.getVipId() && 1 == site.getBusinessCategory()){
+			TVip vip = vipClient.getInfo(appUser.getVipId()).getData();
+			BigDecimal discount = null;
+			if(1 == vip.getType()){
+				//普通会员折扣使用积分策略上的折扣,且有最高优惠金额
+				discount = accountingStrategy.getDiscount();
+			}else{
+				//内部会员使用会员信息设置的折扣,没有最高优惠金额
+				discount = vip.getDiscount();
+			}
 			GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
 			getAppUserVipDetail.setAppUserId(appUser.getId());
 			getAppUserVipDetail.setVipId(appUser.getVipId());
@@ -441,24 +469,13 @@
 			if(null != vipDetail){
 				Integer chargeNum = vipDetail.getChargeNum();
 				if(0 > chargeNum){
-					chargingOrder.setVipDiscount(vipDetail.getDiscount());
-					BigDecimal discountAmount = addChargingOrder.getPaymentAmount().multiply((new BigDecimal(10)
-							.subtract(vipDetail.getDiscount())).divide(new BigDecimal(10))).setScale(4, BigDecimal.ROUND_HALF_EVEN);
-					chargingOrder.setVipDiscountAmount(discountAmount);
+					chargingOrder.setVipDiscount(discount);
 				}
 			}
-
 		}
 		this.save(chargingOrder);
 
 		//添加订单的计费策略
-		Integer accountingStrategyId = tChargingGun.getAccountingStrategyId();
-		if(null == accountingStrategyId){
-			//查询站点上面的计费策略
-			Site site = siteClient.getSiteByIds(Arrays.asList(tChargingGun.getSiteId())).getData().get(0);
-			accountingStrategyId = site.getAccountingStrategyId();
-		}
-		TAccountingStrategy accountingStrategy = accountingStrategyClient.getAccountingStrategyById(accountingStrategyId).getData();
 		List<TAccountingStrategyDetail> strategyDetailList = accountingStrategyDetailClient.getListByAccountingStrategyId(accountingStrategyId).getData();
 		AccountingStrategyOrder accountingStrategyOrder = new AccountingStrategyOrder();
 		BeanUtils.copyProperties(accountingStrategy, accountingStrategyOrder);
@@ -532,42 +549,84 @@
 		
 		//根据当前充值的金额和计费模板算出充电的金额
 		BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
-		//计算充电金额,会员需要将折扣金额加入到充电总金额中
-		TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
-		AccountingStrategyDetailOrder strategyDetail = accountingStrategyDetailOrderClient.getNowAccountingStrategyDetailOrder(chargingOrder.getId()).getData();
-		//总单价
-		BigDecimal totalUnitPrice = strategyDetail.getServiceCharge().add(strategyDetail.getElectrovalence());
-		//计算能充电的度数
-		BigDecimal degrees = rechargeAmount.divide(totalUnitPrice);
+		BigDecimal rechargeAmount1 = new BigDecimal(rechargeAmount.toString());
+		Long now = System.currentTimeMillis();
+		//根据支付金额,获取出使用的计费策略明细
 		//计算电费金额和服务费
-		BigDecimal serviceCharge = strategyDetail.getServiceCharge().multiply(degrees);
-		BigDecimal electrovalence = strategyDetail.getElectrovalence().multiply(degrees);
-
-		//再处理会员折扣
-		BigDecimal discount = BigDecimal.ZERO;
+		BigDecimal serviceCharge = BigDecimal.ZERO;
+		BigDecimal electrovalence = BigDecimal.ZERO;
+		BigDecimal discountAmount = BigDecimal.ZERO;
+		BigDecimal discount = chargingOrder.getVipDiscount();
+		//先根据额定功率计算出每秒充电度数,然后计算出支付金额能充多少度电
+		TChargingGun tChargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
+		BigDecimal s_degrees = tChargingGun.getRatedPower().divide(new BigDecimal(3600));
+		
+		
 		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);
+		List<AccountingStrategyDetailOrder> list = accountingStrategyDetailOrderClient.getAllAccountingStrategyDetailOrder(chargingOrder.getId()).getData();
+		for (AccountingStrategyDetailOrder accountingStrategyDetailOrder : list) {
+			AccountingStrategyOrder accountingStrategyOrder = accountingStrategyOrderClient.getAccountingStrategyOrderById(accountingStrategyDetailOrder.getAccountingStrategyOrderId()).getData();
+			Integer start = Integer.valueOf(accountingStrategyDetailOrder.getStartTime().replaceAll(":", ""));
+			String[] split = accountingStrategyDetailOrder.getEndTime().split(":");
+			if(now >= start){
+				Calendar calendar = Calendar.getInstance();
+				calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
+				calendar.set(Calendar.MINUTE, Integer.valueOf(split[1]));
+				//到此策略结束的秒数
+				long m = (calendar.getTimeInMillis() - now) / 1000;
+				//每度电的单价
+				BigDecimal total_unit = accountingStrategyDetailOrder.getElectrovalence().add(accountingStrategyDetailOrder.getServiceCharge());
+				//每秒需要支付的金额
+				BigDecimal multiply = s_degrees.multiply(total_unit);
+				//计算充值金额能充多长时间的电
+				long times = rechargeAmount1.divide(multiply, 0, RoundingMode.DOWN).longValue();
+				if(times > m){
+					//充电时间跨度两个计费策略,需要继续对下一个策略进行计算
+					electrovalence = accountingStrategyDetailOrder.getElectrovalence().multiply(s_degrees).multiply(new BigDecimal(m));
+					serviceCharge = accountingStrategyDetailOrder.getServiceCharge().multiply(s_degrees).multiply(new BigDecimal(m));
+					discountAmount = discountAmount.add(serviceCharge.multiply((new BigDecimal(10).subtract(discount)).divide(new BigDecimal(10))));
+					rechargeAmount1 = rechargeAmount1.subtract(multiply.multiply(new BigDecimal(m)));
+				}else{
+					electrovalence = accountingStrategyDetailOrder.getElectrovalence().multiply(s_degrees).multiply(new BigDecimal(times));
+					serviceCharge = accountingStrategyDetailOrder.getServiceCharge().multiply(s_degrees).multiply(new BigDecimal(times));
+					discountAmount = discountAmount.add(serviceCharge.multiply((new BigDecimal(10).subtract(discount)).divide(new BigDecimal(10))));
+					break;
+				}
 			}
 		}
-		electrovalence = electrovalence.add(discount);
+		if(discountAmount.compareTo(BigDecimal.ZERO) >= 0){
+			//计算会员最大优惠金额
+			if(null != appUser.getVipId()){
+				TVip vip = vipClient.getInfo(appUser.getVipId()).getData();
+				BigDecimal maximumDeduction = vip.getMaximumDeduction();
+				//普通会员有最高优惠限制
+				if(vip.getType() == 1 && discountAmount.compareTo(maximumDeduction) > 0){
+					discountAmount = maximumDeduction;
+				}
+				
+				//判断会员是否还有充电优惠次数
+				GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
+				getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
+				getAppUserVipDetail.setVipId(appUser.getVipId());
+				TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
+				if(data.getChargeNum() > 0){
+					data.setChargeNum(data.getChargeNum() - 1);
+					appUserVipDetailClient.updateAppUserVipDetail(data);
+					//会员有充电优惠次数,直接将优惠金额加入到充电费用中增加充电时长
+					electrovalence = electrovalence.add(discountAmount);
+				}
+			}
+		}
 		chargingOrder.setChargeAmount(electrovalence);
+		chargingOrder.setVipDiscountAmount(discountAmount);
 		this.updateById(chargingOrder);
-
-
-		TChargingPile chargingPile = chargingPileClient.getChargingPileById(chargingGun.getChargingPileId()).getData();
+		
+		TChargingPile chargingPile = chargingPileClient.getChargingPileById(tChargingGun.getChargingPileId()).getData();
 		//调用远程启动充电消息
 		PlatformStartCharging platformStartCharging = new PlatformStartCharging();
 		platformStartCharging.setTransaction_serial_number(chargingOrder.getCode());
 		platformStartCharging.setCharging_pile_code(chargingPile.getCode());
-		platformStartCharging.setCharging_gun_code(chargingGun.getCode());
+		platformStartCharging.setCharging_gun_code(tChargingGun.getCode());
 		//使用订单id作为逻辑卡号
 		platformStartCharging.setCard_number(chargingOrder.getId().toString());
 		platformStartCharging.setAccount_balance(electrovalence);
@@ -586,7 +645,7 @@
 				PreChargeCheck preChargeCheck1 = redisService.getCacheObject(key);
 				//状态为5的时候,硬件会间隔60秒后再次检测,依然未插枪,则不启动充电
 				//因这里是间隔5秒执行检测,所以累计次数在30次以上
-				if(failure_cause == 5 && null == counter || counter < 35){
+				if(failure_cause == 5 && (null == counter || counter < 35)){
 					counter++;
 					counter_map.put(code, counter);
 					//启动失败
@@ -767,7 +826,65 @@
 		chargingOrder.setStatus(4);
 		chargingOrder.setEndMode(1);
 		this.updateById(chargingOrder);
-
+		
+		//处理用户标签数据
+		List<TUserTag> data = userTagClient.getAllUserTag().getData();
+		//累计充电次数
+		long count1 = this.count(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, chargingOrder.getAppUserId())
+				.eq(TChargingOrder::getRechargePaymentStatus, 2).isNotNull(TChargingOrder::getPaymentAmount).eq(TChargingOrder::getDelFlag, 0));
+		List<TUserTag> userTagList1 = data.stream().filter(s -> s.getStandardCondition() == 1).collect(Collectors.toList());
+		int old_times = 0;
+		Integer userTagId = null;
+		for (TUserTag tUserTag : userTagList1) {
+			Integer times = JSON.parseObject(tUserTag.getConditions()).getInteger("times");
+			//加上本次充电
+			//获取最大值标签
+			if((count1 + 1) >= times && old_times < times){
+				userTagId = tUserTag.getId();
+				old_times = times;
+			}
+		}
+		if(null != userTagId){
+			TAppUserTag appUserTag = new TAppUserTag();
+			appUserTag.setAppUserId(chargingOrder.getAppUserId());
+			appUserTag.setUserTagId(userTagId);
+			TAppUserTag data1 = appUserTagClient.getUserTag(appUserTag).getData();
+			if(null == data1){
+				data1 = new TAppUserTag();
+				data1.setAppUserId(chargingOrder.getAppUserId());
+				data1.setUserTagId(userTagId);
+				data1.setCreateTime(LocalDateTime.now());
+				appUserTagClient.addUserTag(data1);
+			}
+		}
+		//充电评率
+		List<TUserTag> userTagList2 = data.stream().filter(s -> s.getStandardCondition() == 2).collect(Collectors.toList());
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		for (TUserTag tUserTag : userTagList2) {
+			TAppUserTag appUserTag = new TAppUserTag();
+			appUserTag.setAppUserId(chargingOrder.getAppUserId());
+			appUserTag.setUserTagId(tUserTag.getId());
+			TAppUserTag data1 = appUserTagClient.getUserTag(appUserTag).getData();
+			if(null == data1){
+				Integer day = JSON.parseObject(tUserTag.getConditions()).getInteger("day");
+				Integer times = JSON.parseObject(tUserTag.getConditions()).getInteger("times");
+				Calendar start = Calendar.getInstance();
+				start.set(Calendar.DAY_OF_YEAR, start.get(Calendar.DAY_OF_YEAR) + day);
+				count1 = this.count(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, chargingOrder.getAppUserId())
+						.eq(TChargingOrder::getRechargePaymentStatus, 2).isNotNull(TChargingOrder::getPaymentAmount)
+						.between(TChargingOrder::getStartTime, sdf.format(start.getTime()), sdf.format(new Date())).eq(TChargingOrder::getDelFlag, 0));
+				//加上本次充电
+				if(count1 >= times){
+					data1 = new TAppUserTag();
+					data1.setAppUserId(chargingOrder.getAppUserId());
+					data1.setUserTagId(tUserTag.getId());
+					data1.setCreateTime(LocalDateTime.now());
+					appUserTagClient.addUserTag(data1);
+				}
+			}
+		}
+		
+		
 		//异步线程处理停机
 		ExecutorService cachedThreadPool = Executors.newFixedThreadPool(1);
 		cachedThreadPool.execute(()->{
@@ -998,7 +1115,7 @@
 				model.setOut_trade_no(chargingOrder.getCode());
 				model.setOut_refund_no(chargingOrderRefund.getRefundCode());
 				model.setReason("充电完成退款");
-				model.setNotify_url("http://221.182.45.100:9000/order/t-charging-order/chargingOrderStartupFailureWxRefund");
+				model.setNotify_url("/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());
@@ -1783,7 +1900,7 @@
 					model.setOut_refund_no(chargingOrderRefund.getRefundCode());
 					model.setTransaction_id(tChargingOrder.getRechargeSerialNumber());
 					model.setReason("取消订单");
-					model.setNotify_url("http://221.182.45.100:9000/order/t-shopping-order/cancelShoppingOrderWxRefund");
+					model.setNotify_url("/order/t-shopping-order/cancelShoppingOrderWxRefund");
 					WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
 					amount.setRefund(payOrderQueryDto.getRefundAmount().multiply(new BigDecimal(100)).intValue());
 					amount.setTotal(tChargingOrder.getPaymentAmount().multiply(new BigDecimal(100)).intValue());
@@ -1838,7 +1955,7 @@
 					model.setOut_refund_no(chargingOrderRefund.getRefundCode());
 					model.setTransaction_id(tChargingOrder.getSerialNumber());
 					model.setReason("取消订单");
-					model.setNotify_url("http://221.182.45.100:9000/order/t-shopping-order/cancelShoppingOrderWxRefund");
+					model.setNotify_url("/order/t-shopping-order/cancelShoppingOrderWxRefund");
 					WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
 					amount.setRefund(payOrderQueryDto.getRefundAmount().multiply(new BigDecimal(100)).intValue());
 					amount.setTotal(tChargingOrder.getPaymentAmount().multiply(new BigDecimal(100)).intValue());

--
Gitblit v1.7.1