package com.ruoyi.order.service.impl;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.api.dto.SendMessageDTO;
import com.ruoyi.account.api.feignClient.*;
import com.ruoyi.account.api.model.*;
import com.ruoyi.account.api.vo.AppUserWhitelistMatchVO;
import com.ruoyi.account.api.vo.GetAppUserVipDetail;
import com.ruoyi.account.api.vo.GetInviteUser;
import com.ruoyi.chargingPile.api.dto.GetSiteListDTO;
import com.ruoyi.chargingPile.api.feignClient.*;
import com.ruoyi.chargingPile.api.model.*;
import com.ruoyi.chargingPile.api.vo.GetChargingGunByCode;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.dto.ChargingOrderGroup;
import com.ruoyi.common.core.dto.ChargingPercentProvinceDto;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.domain.BasePojo;
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.common.security.utils.SecurityUtils;
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.ChargingOrderVo;
import com.ruoyi.integration.api.vo.GetPlatformStopChargingReply;
import com.ruoyi.integration.api.vo.NotificationConnectorChargeStatusVo;
import com.ruoyi.integration.api.vo.StartChargeResult;
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.model.*;
import com.ruoyi.order.api.query.ChargingOrderQuery;
import com.ruoyi.order.api.query.SettlementListQuery;
import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery;
import com.ruoyi.order.api.vo.*;
import com.ruoyi.order.api.vo.PlatformStopChargingReplyVO;
import com.ruoyi.order.dto.*;
import com.ruoyi.order.mapper.TChargingOrderMapper;
import com.ruoyi.order.mapper.TChargingOrderShareRecordMapper;
import com.ruoyi.order.mapper.TSettlementConfirmMapper;
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.order.service.*;
import com.ruoyi.order.util.mongodb.service.PlatformStartChargingReplyService;
import com.ruoyi.order.util.mongodb.service.TransactionRecordService;
import com.ruoyi.order.util.mongodb.service.UploadRealTimeMonitoringDataService;
import com.ruoyi.order.vo.EndOfChargePageInfo;
import com.ruoyi.order.vo.ChargingSimulationVO;
import com.ruoyi.order.vo.IcbcAdminSubOrderVO;
import com.ruoyi.order.vo.OrderCountByDate;
import com.ruoyi.order.vo.StatisticsOfBatteryVO;
import com.ruoyi.other.api.domain.*;
import com.ruoyi.order.vo.ChargingOrderListInfoVO;
import com.ruoyi.other.api.domain.TVip;
import com.ruoyi.other.api.dto.ExchangeCodeConsumeDTO;
import com.ruoyi.other.api.feignClient.*;
import com.ruoyi.other.api.vo.ExchangeCodeConsumeResultVO;
import com.ruoyi.payment.api.feignClient.AliPaymentClient;
import com.ruoyi.payment.api.feignClient.H5AliPaymentClient;
import com.ruoyi.payment.api.feignClient.IcbcPaymentClient;
import com.ruoyi.payment.api.feignClient.WxPaymentClient;
import com.ruoyi.payment.api.model.*;
import com.ruoyi.payment.api.vo.*;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.feignClient.SysUserClient;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import javax.crypto.MacSpi;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.time.temporal.ChronoUnit;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
/**
*
* 服务实现类
*
*
* @author xiaochen
* @since 2024-08-07
*/
@Service
public class TChargingOrderServiceImpl extends ServiceImpl implements TChargingOrderService {
private Logger log = LoggerFactory.getLogger(TChargingOrderServiceImpl.class);
private static final int WHITELIST_BENEFIT_ALL_FREE = 1;
private static final int WHITELIST_BENEFIT_ELECTRIC_FREE = 2;
private static final int WHITELIST_BENEFIT_SERVICE_FREE = 3;
private static final String SHARE_AFTER_COMMIT_RESOURCE_PREFIX = "chargingOrderShareAfterCommit:";
private static final String SPECIAL_REFUND_TITLE = "特殊退款处理";
@Resource
private ChargingGunClient chargingGunClient;
@Resource
private TSettlementConfirmMapper tSettlementConfirmMapper;
@Resource
private PartnerClient partnerClient;
@Resource
private SiteClient siteClient;
@Resource
private AppUserCarClient appUserCarClient;
@Resource
private AppUserClient appUserClient;
@Resource
private ChargingPileClient chargingPileClient;
@Resource
private TChargingOrderAccountingStrategyService chargingOrderAccountingStrategyService;
@Resource
private TokenService tokenService;
@Resource
private WxPaymentClient wxPaymentClient;
@Resource
private AliPaymentClient aliPaymentClient;
@Resource
private H5AliPaymentClient h5AliPaymentClient;
@Resource
private IcbcPaymentClient icbcPaymentClient;
@Resource
private TChargingOrderShareRecordMapper chargingOrderShareRecordMapper;
@Resource
private ChargingOrderSettlementExecutor chargingOrderSettlementExecutor;
@Resource
private PlatformTransactionManager transactionManager;
@Resource
private AppCouponClient appCouponClient;
@Resource
private AppUserWhitelistClient appUserWhitelistClient;
@Resource
private AppUserVipDetailClient appUserVipDetailClient;
@Resource
private RedisService redisService;
@Resource
private UploadRealTimeMonitoringDataService uploadRealTimeMonitoringDataService;
@Resource
private TCECClient tcecClient;
@Resource
private SendMessageClient sendMessageClient;
@Resource
private WxSubscribeMessageService wxSubscribeMessageService;
@Resource
private TOrderEvaluateService orderEvaluateService;
@Resource
private AccountingStrategyDetailClient accountingStrategyDetailClient;
@Resource
private AccountingStrategyDetailOrderClient accountingStrategyDetailOrderClient;
@Resource
private AccountingStrategyClient accountingStrategyClient;
@Resource
private PlatformStartChargingReplyService platformStartChargingReplyService;
@Resource
private TChargingOrderRefundService chargingOrderRefundService;
@Resource
private PlatformStopChargingReplyClient platformStopChargingReplyClient;
@Resource
private AccountingStrategyOrderService accountingStrategyOrderService;
@Resource
private AccountingStrategyDetailOrderService accountingStrategyDetailOrderService;
@Resource
private InviteUserClient inviteUserClient;
@Resource
private AppUserIntegralChangeClient appUserIntegralChangeClient;
@Resource
private IntegralRuleClient integralRuleClient;
@Resource
private VipClient vipClient;
@Resource
private OtherClient otherClient;
@Resource
private UserTagClient userTagClient;
@Resource
private AppUserTagClient appUserTagClient;
@Resource
private SecurityDetectionClient securityDetectionClient;
//计数器
private Map counter_map = new HashMap<>();
//计数器
private Map boot_failed_map = new HashMap<>();
@Resource
private OperatorClient operatorClient;
@Resource
private TransactionRecordService transactionRecordService;
@Resource
private ITChargingOrderSummaryDataService chargingOrderSummaryDataService;
@Resource
private TOrderAppealService orderAppealService;
@Autowired
private RedissonClient redissonClient;
@Resource
private ChargingMessageClient chargingMessageClient;
@Resource
private ChengDuJianGuanClient chengDuJianGuanClient;
/**
* 获取小程序充电记录列表数据
*
* @param query
* @return
*/
@Override
public Map getMyChargingOrderList(GetMyChargingOrderList query) {
Long appUserId = tokenService.getLoginUserApplet().getUserId();
Map map = new HashMap<>();
int size = this.baseMapper.getMyChargingOrderList(appUserId, 1, null, null).size();
map.put("number", size);
Integer pageCurr = query.getPageCurr() == null || query.getPageCurr() < 1 ? 1 : query.getPageCurr();
Integer pageSize = query.getPageSize() == null || query.getPageSize() < 1 ? 10 : query.getPageSize();
query.setPageCurr((pageCurr - 1) * pageSize);
query.setPageSize(pageSize);
List list = this.baseMapper.getMyChargingOrderList(appUserId, query.getType(), query.getPageCurr(), query.getPageSize());
List orderLists = new ArrayList<>();
for (TChargingOrder tChargingOrder : list) {
MyChargingOrderList myChargingOrderList = new MyChargingOrderList();
myChargingOrderList.setId(tChargingOrder.getId().toString());
myChargingOrderList.setSiteId(tChargingOrder.getSiteId());
myChargingOrderList.setStatus(tChargingOrder.getStatus());
Site site = getOrderSite(tChargingOrder.getSiteId());
myChargingOrderList.setTitle(site == null ? "未知电站" : site.getName());
myChargingOrderList.setChargingDegree(tChargingOrder.getChargingCapacity());
String name = getChargingGunName(tChargingOrder.getChargingGunId());
myChargingOrderList.setChargingGunId(tChargingOrder.getChargingGunId());
myChargingOrderList.setName(name);
myChargingOrderList.setEndMode(tChargingOrder.getEndMode());
Integer status = tChargingOrder.getStatus();
BigDecimal payMoney = status != null && status < 4 ? tChargingOrder.getRechargeAmount() : tChargingOrder.getPaymentAmount();
myChargingOrderList.setPayMoney(payMoney);
if (tChargingOrder.getCreateTime() != null) {
myChargingOrderList.setCreateTime(tChargingOrder.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
long count = orderEvaluateService.count(new LambdaQueryWrapper().eq(TOrderEvaluate::getOrderType, 1)
.eq(TOrderEvaluate::getOrderId, tChargingOrder.getId()).eq(TOrderEvaluate::getDelFlag, 0));
myChargingOrderList.setEvaluate(count + 1L);
orderLists.add(myChargingOrderList);
}
list = this.baseMapper.getMyChargingOrderList(appUserId, query.getType(), null, null);
map.put("list", orderLists);
map.put("totle", list.size());
return map;
}
private Site getOrderSite(Integer siteId) {
if (siteId == null) {
return null;
}
R> result = siteClient.getSiteByIds(Collections.singletonList(siteId));
List sites = result == null ? Collections.emptyList() : result.getData();
return sites == null || sites.isEmpty() ? null : sites.get(0);
}
private String getChargingGunName(Integer chargingGunId) {
if (chargingGunId == null) {
return "";
}
R result = chargingGunClient.getAllName(chargingGunId);
return result == null || result.getData() == null ? "" : result.getData();
}
/**
* 获取充电订单明细
*
* @param id 订单id
* @return
*/
@Override
public MyChargingOrderInfo getMyChargingOrderInfo(String id) {
TChargingOrder chargingOrder = this.getById(id);
MyChargingOrderInfo myChargingOrderInfo = new MyChargingOrderInfo();
myChargingOrderInfo.setId(id);
myChargingOrderInfo.setChargingGunId(chargingOrder.getChargingGunId());
myChargingOrderInfo.setCode(chargingOrder.getCode());
myChargingOrderInfo.setCreateTime(chargingOrder.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
myChargingOrderInfo.setStatus(chargingOrder.getStatus());
Site site = siteClient.getSiteByIds(Arrays.asList(chargingOrder.getSiteId())).getData().get(0);
myChargingOrderInfo.setTitle(site.getName());
TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
myChargingOrderInfo.setChargeMode(chargingGun.getChargeMode());
String name = chargingGunClient.getAllName(chargingOrder.getChargingGunId()).getData();
myChargingOrderInfo.setName(name);
if (Objects.nonNull(chargingOrder.getAppUserCarId())) {
TAppUserCar tAppUserCar = appUserCarClient.getCarById(chargingOrder.getAppUserCarId().toString()).getData();
if (null != tAppUserCar) {
myChargingOrderInfo.setLicensePlate(tAppUserCar.getLicensePlate());
} else {
myChargingOrderInfo.setLicensePlate("无");
}
} else {
myChargingOrderInfo.setLicensePlate(chargingOrder.getPlateNum());
}
if (null != chargingOrder.getStartTime()) {
myChargingOrderInfo.setStartTime(chargingOrder.getStartTime().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() * 1000);
}
if (null != chargingOrder.getEndTime()) {
myChargingOrderInfo.setEndTime(chargingOrder.getEndTime().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() * 1000);
}
myChargingOrderInfo.setOrderAmount(chargingOrder.getOrderAmount());
myChargingOrderInfo.setPaymentAmount(chargingOrder.getPaymentAmount());
myChargingOrderInfo.setRechargeAmount(chargingOrder.getRechargeAmount());
myChargingOrderInfo.setCouponDiscountAmount(chargingOrder.getCouponDiscountAmount());
myChargingOrderInfo.setVipDiscountAmount(chargingOrder.getVipDiscountAmount());
myChargingOrderInfo.setRefundAmount(chargingOrder.getRefundAmount());
List stageCost = chargingOrderAccountingStrategyService.list(
new LambdaQueryWrapper().eq(TChargingOrderAccountingStrategy::getChargingOrderId, id)
.orderByAsc(TChargingOrderAccountingStrategy::getStartTime)
);
myChargingOrderInfo.setStageCost(stageCost);
List dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode());
if (null != dataList) {
//在MongoDB中获取数据
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
List dataLists = new ArrayList<>();
String t = "";
for (UploadRealTimeMonitoringData uploadRealTimeMonitoringData : dataList) {
if (!sdf.format(uploadRealTimeMonitoringData.getCreate_time()).equals(t)) {
dataLists.add(uploadRealTimeMonitoringData);
t = sdf.format(uploadRealTimeMonitoringData.getCreate_time());
}
}
List time = dataLists.stream().map(s -> sdf.format(s.getCreate_time())).collect(Collectors.toList());
List outputVoltage = dataLists.stream().map(UploadRealTimeMonitoringData::getOutput_voltage).collect(Collectors.toList());
List outputCurrent = dataLists.stream().map(UploadRealTimeMonitoringData::getOutput_current).collect(Collectors.toList());
List