Files
jsowell-charger-web/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java
2024-08-28 09:47:24 +08:00

1447 lines
65 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.jsowell.service;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.huifu.adapay.core.AdapayCore;
import com.huifu.adapay.core.util.AdapaySign;
import com.jsowell.adapay.vo.PaymentInfo;
import com.jsowell.common.constant.CacheConstants;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.domain.vo.AuthorizedDeptVO;
import com.jsowell.common.core.domain.ykc.RealTimeMonitorData;
import com.jsowell.common.core.domain.ykc.TransactionRecordsData;
import com.jsowell.common.core.page.PageResponse;
import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.enums.AcquirerEnum;
import com.jsowell.common.enums.DelFlagEnum;
import com.jsowell.common.enums.InvoiceRecordEnum;
import com.jsowell.common.enums.MemberWalletEnum;
import com.jsowell.common.enums.adapay.AdapayEventEnum;
import com.jsowell.common.enums.adapay.AdapayPayChannelEnum;
import com.jsowell.common.enums.uniapp.OccupyOrderPayStatusEnum;
import com.jsowell.common.enums.uniapp.OccupyOrderStatusEnum;
import com.jsowell.common.enums.ykc.*;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.SecurityUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.common.util.bean.BeanUtils;
import com.jsowell.pile.domain.*;
import com.jsowell.pile.dto.*;
import com.jsowell.pile.service.*;
import com.jsowell.pile.service.programlogic.AbstractProgramLogic;
import com.jsowell.pile.service.programlogic.ProgramLogicFactory;
import com.jsowell.pile.util.MerchantUtils;
import com.jsowell.pile.util.UserUtils;
import com.jsowell.pile.vo.OrderPayRecordVO;
import com.jsowell.pile.vo.base.*;
import com.jsowell.pile.vo.base.PileInfoVO;
import com.jsowell.pile.vo.uniapp.customer.*;
import com.jsowell.pile.vo.uniapp.customer.InvoiceRecordVO;
import com.jsowell.pile.vo.web.*;
import com.jsowell.thirdparty.common.CommonService;
import com.jsowell.wxpay.response.WechatPayNotifyParameter;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Service
public class OrderService {
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private OrderBasicInfoService orderBasicInfoService;
@Autowired
private PileRemoteService pileRemoteService;
@Autowired
private PileService pileService;
@Autowired
private MemberService memberService;
@Autowired
private MemberBasicInfoService memberBasicInfoService;
@Autowired
private OrderPayRecordService orderPayRecordService;
@Autowired
private WechatPayService wechatPayService;
@Autowired
private MemberTransactionRecordService memberTransactionRecordService;
@Autowired
private PileStationInfoService pileStationInfoService;
@Autowired
private OrderInvoiceRecordService orderInvoiceRecordService;
@Autowired
private PileStationWhitelistService pileStationWhitelistService;
@Autowired
private AdapayCallbackRecordService adapayCallbackRecordService;
@Autowired
private MemberInvoiceTitleService memberInvoiceTitleService;
@Autowired
private AdapayRefundRecordService adapayRefundRecordService;
@Autowired
private AdapayMemberAccountService adapayMemberAccountService;
@Autowired
private ClearingWithdrawInfoService clearingWithdrawInfoService;
@Autowired
private MemberAdapayRecordService memberAdapayRecordService;
@Resource
private OrderPileOccupyService orderPileOccupyService;
@Resource
private PileMerchantInfoService pileMerchantInfoService;
@Resource
private MemberWalletLogService memberWalletLogService;
@Resource
private ClearingBillInfoService clearingBillInfoService;
@Autowired
private ThirdPartyStationRelationService thirdPartyStationRelationService;
@Autowired
private IThirdpartySnRelationService snRelationService;
@Autowired
private CommonService commonService;
@Resource
private RedisCache redisCache;
/**
* 生成订单
*
* @param dto
* @return
*/
// @Deprecated
// public String generateOrder(GenerateOrderDTO dto) throws ParseException {
// OrderBasicInfo basicInfo = orderBasicInfoService.generateOrder(dto);
// if (basicInfo != null) {
// return basicInfo.getOrderCode();
// }
// return null;
// }
/**
* 生成订单
*
* @param dto
* @return
*/
public String generateOrderV2(GenerateOrderDTO dto) throws ParseException {
String delayMode = null;
if (StringUtils.equals(dto.getRequestSource(), AdapayPayChannelEnum.WX_LITE.getValue())) {
delayMode = pileMerchantInfoService.getDelayModeByWechatAppId(dto.getAppId());
} else if (StringUtils.equals(dto.getRequestSource(), AdapayPayChannelEnum.ALIPAY_LITE.getValue())) {
delayMode = pileMerchantInfoService.getDelayModeByAlipayAppId(dto.getAppId());
}
// 新逻辑
AbstractProgramLogic orderLogic = ProgramLogicFactory.getProgramLogic(delayMode);
OrderBasicInfo orderBasicInfo = orderLogic.generateOrder(dto);
if (orderBasicInfo != null) {
return orderBasicInfo.getOrderCode();
}
return null;
}
/**
* 订单支付
*
* @param dto
*/
// @Deprecated
// public Map<String, Object> payOrder(PayOrderDTO dto) throws Exception {
// return orderBasicInfoService.payOrder(dto);
// }
/**
* 订单支付
*
* @param dto
*/
public Map<String, Object> payOrderV2(PayOrderDTO dto) {
// String mode = pileMerchantInfoService.getDelayModeByWechatAppId(dto.getWechatAppId());
String delayMode = null;
if (StringUtils.equals(dto.getRequestSource(), AdapayPayChannelEnum.WX_LITE.getValue())) {
delayMode = pileMerchantInfoService.getDelayModeByWechatAppId(dto.getWechatAppId());
} else if (StringUtils.equals(dto.getRequestSource(), AdapayPayChannelEnum.ALIPAY_LITE.getValue())) {
delayMode = pileMerchantInfoService.getDelayModeByAlipayAppId(dto.getAlipayAppId());
}
dto.setDelayMode(delayMode);
// 获取处理逻辑
AbstractProgramLogic orderLogic = ProgramLogicFactory.getProgramLogic(delayMode);
Map<String, Object> map = orderLogic.payOrder(dto);
return map;
}
/**
* 结算订单
* endCharging
*
* @param dto 结算订单参数
*/
public void settleOrderForWeb(SettleOrderDTO dto) {
orderBasicInfoService.analysisPileParameter(dto);
// 查询订单详情,验证订单中的桩编号是否正确
OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getOrderCode());
if (orderBasicInfo == null) {
throw new BusinessException(ReturnCodeEnum.CODE_QUERY_ORDER_INFO_IS_NULL);
}
if (!(StringUtils.equals(orderBasicInfo.getPileSn(), dto.getPileSn())
&& StringUtils.equals(orderBasicInfo.getConnectorCode(), dto.getConnectorCode()))) {
throw new BusinessException(ReturnCodeEnum.CODE_ORDER_PILE_MAPPING_ERROR);
}
// push远程停机指令
pileRemoteService.remoteStopCharging(dto.getPileSn(), dto.getConnectorCode(), orderBasicInfo.getTransactionCode());
}
/**
* 通过会员Id查询订单列表
*
* @param memberId 会员Id
* @return 订单信息集合
*/
public PageResponse getListByMemberIdAndOrderStatus(String memberId, UniAppQueryOrderDTO dto) throws ParseException {
String orderStatus = dto.getOrderStatus();
if (StringUtils.isBlank(orderStatus)) {
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
}
ArrayList<String> orderStatusList = Lists.newArrayList();
if (StringUtils.equals("2", orderStatus)) {
// 查未完成订单
CollectionUtils.addAll(orderStatusList, "0", "1", "2", "3", "4", "5");
} else if (StringUtils.equals("3", orderStatus)) {
// 查已完成订单
orderStatusList.add("6");
} else if (StringUtils.equals("4", orderStatus)) {
// 查询正在进行中的订单
orderStatusList.add("1");
}
// 分页
PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
List<OrderVO> list = orderBasicInfoService.getListByMemberIdAndOrderStatus(memberId, orderStatusList);
PageInfo<OrderVO> pageInfo = new PageInfo<>(list);
for (OrderVO orderVO : pageInfo.getList()) {
orderVO.setPileConnectorCode(orderVO.getPileSn() + orderVO.getConnectorCode());
// 从缓存中获取充电时长
List<RealTimeMonitorData> chargingRealTimeData = orderBasicInfoService.getChargingRealTimeData(orderVO.getTransactionCode());
// 默认时间倒序排列,因此只取第一条就可以
if (CollectionUtils.isEmpty(chargingRealTimeData)) {
orderVO.setChargingTime("-");
continue;
}
RealTimeMonitorData realTimeMonitorData = chargingRealTimeData.get(0);
String sumChargingTime = realTimeMonitorData.getSumChargingTime(); // xx分钟
String chargingTime = "-";
try {
// 分钟转成 x时x分
chargingTime = DateUtils.convertMinutesToTime(Integer.parseInt(sumChargingTime));
} catch (Exception e) {
orderVO.setChargingTime(sumChargingTime);
continue;
}
// String chargingTime = "0分钟";
// if (orderVO.getStartTime() != null) {
// Date startTimeDate = DateUtils.parseDate(orderVO.getStartTime());
// Date endTimeDate;
// if (orderVO.getEndTime() != null) {
// endTimeDate = DateUtils.parseDate(orderVO.getEndTime());
// // 计算出两个时间差
// chargingTime = DateUtils.getDatePoor(endTimeDate, startTimeDate);
// } else {
// endTimeDate = new Date();
// }
//
// }
orderVO.setChargingTime(chargingTime);
}
// 返回结果集
PageResponse pageResponse = PageResponse.builder()
.pageNum(dto.getPageNum())
.pageSize(dto.getPageSize())
.list(pageInfo.getList())
.pages(pageInfo.getPages())
.total(pageInfo.getTotal())
.build();
return pageResponse;
}
/**
* 微信支付v3
*
* @param dto
* @return
* @throws Exception
*/
// public Map<String, Object> weixinPayV3(WeixinPayDTO dto) throws Exception {
// return wechatPayService.weixinPayV3(dto);
// }
/**
* 用户停止充电
*
* @param dto
*/
public void stopCharging(StopChargingDTO dto) {
// 查订单
OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getOrderCode());
if (orderInfo == null) {
throw new BusinessException(ReturnCodeEnum.CODE_QUERY_ORDER_INFO_IS_NULL);
}
// 判断订单状态是不是已经结算了
if (StringUtils.equals(orderInfo.getOrderStatus(), OrderStatusEnum.ORDER_COMPLETE.getValue())) {
throw new BusinessException(ReturnCodeEnum.CODE_ORDER_COMPLETE_ERROR);
}
// 校验订单中的会员与操作会员是否一致
if (!StringUtils.equals(orderInfo.getMemberId(), dto.getMemberId())) {
throw new BusinessException(ReturnCodeEnum.CODE_ORDER_MEMBER_NOT_MATCH_ERROR);
}
// 判断该桩是否推送了第三方站点(需要我方平台发送启动指令的,如:华为平台)
List<ThirdPartySnRelationVO> list = snRelationService.selectSnRelationListByParams(orderInfo.getStationId(), orderInfo.getPileSn(), null);
if (CollectionUtils.isNotEmpty(list)) {
for (ThirdPartySnRelationVO vo : list) {
ThirdPartyCommonStopChargeDTO commonStopChargeDTO = new ThirdPartyCommonStopChargeDTO();
commonStopChargeDTO.setThirdPartyType(vo.getThirdPartyType());
commonStopChargeDTO.setOrderBasicInfo(orderInfo);
// 调用统一停止充电接口
String result = commonService.commonStopCharge(commonStopChargeDTO);
log.info("订单:{} 调用统一停止充电接口, result:{}", orderInfo, result);
}
}else {
// 发送停止指令
pileRemoteService.remoteStopCharging(orderInfo.getPileSn(), orderInfo.getConnectorCode(), orderInfo.getTransactionCode());
}
// List<ThirdPartyStationRelationVO> relationInfoList = thirdPartyStationRelationService.getRelationInfoList(orderInfo.getStationId());
//
// if (CollectionUtils.isNotEmpty(relationInfoList)) {
// for (ThirdPartyStationRelationVO vo : relationInfoList) {
// String startMode = vo.getStartMode();
// if (StringUtils.equals(Constants.ONE, startMode)) {
// // 启动类型为 1 的即为对接了类似华为平台,需要调用第三方平台的统一停止充电接口
// ThirdPartyCommonStopChargeDTO commonStopChargeDTO = new ThirdPartyCommonStopChargeDTO();
// commonStopChargeDTO.setThirdPartyType(vo.getThirdPartyType());
// commonStopChargeDTO.setOrderBasicInfo(orderInfo);
// // 调用统一停止充电接口
// String result = commonService.commonStopCharge(commonStopChargeDTO);
// log.info("订单:{}调用第三方平台统一停止充电接口,调用结果 SuccStat:{}", orderInfo.getOrderCode(), result);
// }else {
// // 发送停止指令
// pileRemoteService.remoteStopCharging(orderInfo.getPileSn(), orderInfo.getConnectorCode(), orderInfo.getTransactionCode());
// }
// }
// }else {
// // 发送停止指令
// pileRemoteService.remoteStopCharging(orderInfo.getPileSn(), orderInfo.getConnectorCode(), orderInfo.getTransactionCode());
// }
// 发送停止指令
// pileRemoteService.remoteStopCharging(orderInfo.getPileSn(), orderInfo.getConnectorCode(), orderInfo.getTransactionCode());
log.info("用户停止充电, orderCode:{}, transactionCode:{}, 发送停机指令成功", dto.getOrderCode(), orderInfo.getTransactionCode());
}
/**
* 微信退款
*
* @param dto
*/
// public void weChatRefund(ApplyRefundDTO dto) {
// log.info("微信退款接口 param:{}", JSON.toJSONString(dto));
// orderBasicInfoService.weChatRefund(dto);
// }
/**
* 汇付退款
*
* @param dto
*/
public void adapayRefund(ApplyRefundDTO dto) {
log.info("汇付退款 param:{}", JSON.toJSONString(dto));
// 退款有两种情况 1-订单结算退款 2-用户余额退款
String refundType = dto.getRefundType();
if (StringUtils.equals(refundType, "1")) {
orderBasicInfoService.refundOrderWithAdapay(dto);
} else if (StringUtils.equals(refundType, "2")) {
orderBasicInfoService.refundBalanceWithAdapay(dto);
} else {
log.warn("没有找到退款处理逻辑");
}
}
/**
* 查询订单详情信息
*
* @param orderCode 订单编号
* @return
*/
public OrderDetailInfoVO queryOrderDetailInfo(String orderCode) {
OrderDetailInfoVO vo = new OrderDetailInfoVO();
// 订单信息
OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
if (orderBasicInfo == null) {
return vo;
}
OrderDetailInfoVO.OrderInfo order = new OrderDetailInfoVO.OrderInfo();
order.setOrderCode(orderBasicInfo.getOrderCode());
order.setTransactionCode(orderBasicInfo.getTransactionCode());
order.setOrderStatus(orderBasicInfo.getOrderStatus());
order.setLogicCard(orderBasicInfo.getLogicCard());
if (orderBasicInfo.getVinCode() != null) {
order.setVinCode(orderBasicInfo.getVinCode());
}
String describe = orderBasicInfoService.transformOrderStatusDescribe(orderBasicInfo.getOrderStatus(), orderBasicInfo.getPayStatus());
order.setOrderStatusDescribe(describe);
order.setStartTime(DateUtils.formatDateTime(orderBasicInfo.getChargeStartTime()));
order.setEndTime(DateUtils.formatDateTime(orderBasicInfo.getChargeEndTime()));
order.setCreateTime(DateUtils.formatDateTime(orderBasicInfo.getCreateTime()));
order.setStopReasonMsg(orderBasicInfo.getReason());
order.setStartSOC(orderBasicInfo.getStartSoc());
order.setEndSOC(orderBasicInfo.getEndSoc());
order.setDiscountAmount(String.valueOf(orderBasicInfo.getDiscountAmount()));
order.setSettleAmount(String.valueOf(orderBasicInfo.getSettleAmount()));
order.setSettlementTime(DateUtils.formatDateTime(orderBasicInfo.getSettlementTime()));
vo.setOrderInfo(order);
// 设备信息
PileInfoVO pileInfoVO = pileService.selectPileInfoBySn(orderBasicInfo.getPileSn());
vo.setPileInfo(pileInfoVO);
// 枪口实时数据信息
String pileConnectorCode = orderBasicInfo.getPileSn() + orderBasicInfo.getConnectorCode();
QueryConnectorListDTO dto = new QueryConnectorListDTO();
dto.setConnectorCodeList(Lists.newArrayList(pileConnectorCode));
List<RealTimeMonitorData> chargingRealTimeDataList = orderBasicInfoService.getChargingRealTimeData(orderBasicInfo.getTransactionCode());
if (CollectionUtils.isNotEmpty(chargingRealTimeDataList)) {
List<OrderDetailInfoVO.PileMonitorData> infoList = Lists.newArrayList();
for (RealTimeMonitorData realTimeMonitorData : chargingRealTimeDataList) {
OrderDetailInfoVO.PileMonitorData info = new OrderDetailInfoVO.PileMonitorData();
info.setInstantCurrent(realTimeMonitorData.getOutputCurrent()); // 电流
info.setInstantVoltage(realTimeMonitorData.getOutputVoltage()); // 电压
info.setInstantPower(realTimeMonitorData.getOutputPower()); // 功率
info.setSOC(realTimeMonitorData.getSOC());
info.setTime(realTimeMonitorData.getDateTime()); // 时间
infoList.add(info);
}
// 监控信息
OrderDetailInfoVO.OrderRealTimeInfo realTimeInfo = new OrderDetailInfoVO.OrderRealTimeInfo();
RealTimeMonitorData realTimeMonitorData = chargingRealTimeDataList.get(0); // 最后一次实时数据
realTimeInfo.setOrderAmount(realTimeMonitorData.getChargingAmount());
realTimeInfo.setChargedDegree(realTimeMonitorData.getChargingDegree());
realTimeInfo.setChargingTime(realTimeMonitorData.getSumChargingTime());
realTimeInfo.setTime(realTimeMonitorData.getDateTime());
vo.setOrderRealTimeInfo(realTimeInfo);
// 根据时间进行正序排序
infoList = infoList.stream()
.sorted(Comparator.comparing(OrderDetailInfoVO.PileMonitorData::getTime))
.collect(Collectors.toList());
vo.setRealTimeMonitorDataList(infoList);
// 最后一次实时数据
vo.setLastMonitorData(realTimeMonitorData);
}
// 支付流水对应页面支付信息
List<OrderDetailInfoVO.PayRecord> payRecords = orderPayRecordService.selectOrderPayInfoList(orderCode);
List<OrderPayRecordVO> payRecordList = orderPayRecordService.selectOrderPayRecordList(orderCode);
vo.setPayRecordList(payRecordList);
// 查询退款明细
List<OrderDetailInfoVO.OrderRefundInfo> orderRefundInfoList = orderBasicInfoService.getOrderRefundInfoList(orderBasicInfo);
vo.setOrderRefundInfoList(orderRefundInfoList);
// 查订单明细
OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderCode);
if (orderDetail != null) {
OrderAmountDetailVO billingDetails = new OrderAmountDetailVO();
BeanUtils.copyBeanProp(billingDetails, orderDetail);
vo.setBillingDetails(billingDetails);
List<OrderPeriodAmountVO> orderPeriodAmountVOS = orderBasicInfoService.transformPeriodAmountByOrderDetail(orderDetail);
vo.setChargeDetails(orderPeriodAmountVOS);
}
// 用户信息
MemberVO memberVO = memberService.getMemberInfoByMemberId(orderBasicInfo.getMemberId());
vo.setMemberInfo(memberVO);
try {
// 因为原来的数据在redis中是永久保存所以这里做下查询详情的时候发现已经是完成的订单redis数据存到表中
if (StringUtils.equals(orderBasicInfo.getOrderStatus(), OrderStatusEnum.ORDER_COMPLETE.getValue())) {
// 如果是已完成的订单把redis中的实时数据存到表中
orderBasicInfoService.realTimeMonitorDataRedis2DB(orderBasicInfo.getTransactionCode(), orderBasicInfo.getOrderCode());
}
} catch (Exception e) {
log.error("后管查询订单详情时把redis中的实时数据存到表发生异常", e);
}
try {
if (StringUtils.equals(orderBasicInfo.getOrderStatus(), OrderStatusEnum.IN_THE_CHARGING.getValue())) {
RealTimeMonitorData lastMonitorData = vo.getLastMonitorData();
if (lastMonitorData == null || DateUtils.intervalTime(lastMonitorData.getDateTime(), DateUtils.getDateTime()) > 2L) {
// 没有实时数据 或者 间隔时间超过2分钟, 订单状态修改为异常
orderBasicInfo.setOrderStatus(OrderStatusEnum.ABNORMAL.getValue());
orderBasicInfo.setReason("充电桩长时间没有上传实时数据");
orderBasicInfoService.updateOrderBasicInfo(orderBasicInfo);
}
}
} catch (Exception e) {
log.error("后管查询订单详情时校验订单状态", e);
}
return vo;
}
/**
* 微信支付退款回调
*
* @param request
* @param body
* @throws Exception
*/
public void wechatPayRefundCallback(HttpServletRequest request, WechatPayNotifyParameter body) throws Exception {
// 获取微信退款成功返回的信息
// Map<String, Object> map = wechatPayService.wechatPayRefundCallbackInfo(request, body);
}
/**
* 获取小程序订单详情
*
* @param orderCode
* @return
*/
public UniAppOrderVO getUniAppOrderDetail(String orderCode) {
OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderCode);
UniAppOrderVO vo = new UniAppOrderVO();
if (orderBasicInfo == null) {
throw new BusinessException(ReturnCodeEnum.CODE_QUERY_ORDER_INFO_IS_NULL);
}
String pileSn = orderBasicInfo.getPileSn();
String connectorCode = orderBasicInfo.getConnectorCode();
// 异步发送获取实时数据指令
if (StringUtils.equals(orderBasicInfo.getOrderStatus(), OrderStatusEnum.IN_THE_CHARGING.getValue())) {
CompletableFuture.runAsync(() -> {
try {
pileRemoteService.getRealTimeMonitorData(pileSn, connectorCode);
} catch (Exception e) {
log.error("异步发送获取实时数据指令error", e);
}
});
}
vo.setOrderCode(orderBasicInfo.getOrderCode());
vo.setPileSn(pileSn);
vo.setConnectorCode(connectorCode);
vo.setPileConnectorCode(pileSn + connectorCode);
String orderStatus = orderBasicInfo.getOrderStatus();
vo.setOrderStatus(orderStatus);
// 订单状态描述
String orderStatusDescribe = orderBasicInfoService.transformOrderStatusDescribe(orderStatus, orderBasicInfo.getPayStatus());
vo.setOrderStatusDescribe(orderStatusDescribe);
if (Objects.nonNull(orderBasicInfo.getChargeStartTime())) {
vo.setStartChargingTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, orderBasicInfo.getChargeStartTime()));
}
Date chargeEndTime = orderBasicInfo.getChargeEndTime();
if (Objects.nonNull(chargeEndTime)) {
vo.setEndChargingTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, chargeEndTime));
}
PileStationVO stationInfo = pileStationInfoService.getStationInfo(orderBasicInfo.getStationId());
vo.setStationName(stationInfo.getStationName());
vo.setReason(orderBasicInfo.getReason());
vo.setOrderAmount(String.valueOf(orderBasicInfo.getOrderAmount()));
vo.setPayAmount(String.valueOf(orderBasicInfo.getPayAmount()));
vo.setPayMode(orderBasicInfo.getPayMode());
vo.setRemedialAmount(String.valueOf(orderBasicInfo.getRemedialAmount()));
if (StringUtils.isNotBlank(String.valueOf(stationInfo.getFreeTime()))) {
vo.setFreeTime(stationInfo.getFreeTime());
}
if (StringUtils.isNotBlank(String.valueOf(stationInfo.getOccupyFee()))) {
vo.setOccupyFee(stationInfo.getOccupyFee());
}
// 获取充电桩枪口信息
PileConnectorDetailVO pileConnectorDetailVO = pileService.queryPileConnectorDetail(vo.getPileConnectorCode());
if (pileConnectorDetailVO != null) {
vo.setPileConnectorStatus(pileConnectorDetailVO.getConnectorStatus());
}
// 优惠金额
vo.setDiscountAmount(String.valueOf(orderBasicInfo.getDiscountAmount()));
// 实付金额
vo.setActualAmount(String.valueOf(orderBasicInfo.getOrderAmount().subtract(orderBasicInfo.getDiscountAmount())));
// 获取订单充电数据
List<RealTimeMonitorData> monitorDataList = orderBasicInfoService.getChargingRealTimeData(orderBasicInfo.getTransactionCode());
if (CollectionUtils.isNotEmpty(monitorDataList)) {
List<UniAppOrderVO.ChargingData> chargingDataList = Lists.newArrayList();
UniAppOrderVO.ChargingData data = null;
for (int i = 0; i < monitorDataList.size(); i++) {
RealTimeMonitorData monitorData = monitorDataList.get(i);
data = new UniAppOrderVO.ChargingData();
data.setDateTime(monitorData.getDateTime());
String outputVoltage = monitorData.getOutputVoltage();
data.setOutputVoltage(outputVoltage);
String outputCurrent = monitorData.getOutputCurrent();
data.setOutputCurrent(outputCurrent);
BigDecimal power = new BigDecimal(outputCurrent).multiply(new BigDecimal(outputVoltage))
.divide(new BigDecimal("1000"), 2, RoundingMode.HALF_UP);
data.setPower(power.toString());
data.setSOC(monitorData.getSOC());
data.setBatteryMaxTemperature(monitorData.getBatteryMaxTemperature());
chargingDataList.add(data);
// vo中的实时数据最新一条就取monitorDataList第一个
if (i == 0) {
vo.setBatteryMaxTemperature(data.getBatteryMaxTemperature());
vo.setOutputPower(data.getPower());
vo.setOutputCurrent(data.getOutputCurrent());
vo.setOutputVoltage(data.getOutputVoltage());
vo.setSOC(data.getSOC());
BigDecimal chargingAmount = new BigDecimal(monitorData.getChargingAmount()).setScale(4, RoundingMode.HALF_UP); // 充电金额
vo.setChargingAmount(chargingAmount.toString());
BigDecimal chargingDegree = new BigDecimal(monitorData.getChargingDegree()).setScale(4, RoundingMode.HALF_UP); // 充电度数
vo.setChargingDegree(chargingDegree.toString());
vo.setSumChargingTime(monitorData.getSumChargingTime());
vo.setTimeRemaining(monitorData.getTimeRemaining());
}
}
// monitorDataList是按照时间倒序的chargingDataList需要按照时间正序
Collections.reverse(chargingDataList);
vo.setChargingDataList(chargingDataList);
}
if (orderDetail != null) {
OrderAmountDetailVO billingDetails = new OrderAmountDetailVO();
BeanUtils.copyBeanProp(billingDetails, orderDetail);
vo.setBillingDetails(billingDetails);
if (StringUtils.equals(OrderStatusEnum.ORDER_COMPLETE.getValue(), orderStatus)) {
BigDecimal totalUsedElectricity = orderDetail.getTotalUsedElectricity();
if (totalUsedElectricity != null && StringUtils.isNotBlank(vo.getChargingAmount())
&& totalUsedElectricity.compareTo(new BigDecimal(vo.getChargingAmount())) > 0) {
vo.setChargingDegree(String.valueOf(totalUsedElectricity));
}
}
}
// 因为原来的数据在redis中是永久保存所以这里做下查询详情的时候发现已经是完成的订单redis数据存到表中
CompletableFuture.runAsync(() -> {
try {
if (StringUtils.equals(orderBasicInfo.getOrderStatus(), OrderStatusEnum.ORDER_COMPLETE.getValue())) {
// 如果是已完成的订单把redis中的实时数据存到表中
orderBasicInfoService.realTimeMonitorDataRedis2DB(orderBasicInfo.getTransactionCode(), orderBasicInfo.getOrderCode());
}
} catch (Exception e) {
log.error("后管查询订单详情时把redis中的实时数据存到表发生异常", e);
}
});
return vo;
}
/**
* 根据订单号查询充电桩启动状态
*
* @param orderCode 订单编号
* @return 0: 未启动1: 启动成功2: 启动失败
*/
public Map<String, String> selectPileStarterStatus(String orderCode) {
OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
if (orderInfo == null) {
throw new BusinessException(ReturnCodeEnum.CODE_QUERY_ORDER_INFO_IS_NULL);
}
String status = Constants.ZERO;
String reason = null;
// 如果是订单完成状态
if (StringUtils.equals(orderInfo.getOrderStatus(), OrderStatusEnum.ORDER_COMPLETE.getValue())) {
status = Constants.TWO;
reason = orderInfo.getReason();
} else {
// 查询订单的实时监测数据
List<RealTimeMonitorData> chargingRealTimeData = orderBasicInfoService.getChargingRealTimeData(orderInfo.getTransactionCode());
if (CollectionUtils.isNotEmpty(chargingRealTimeData)) {
// 实时监测数据不为空说明已经在充电中了
status = Constants.ONE;
}
}
Map<String, String> resultMap = Maps.newHashMap();
resultMap.put("status", status);
resultMap.put("reason", reason);
resultMap.put("orderCode", orderInfo.getOrderCode());
resultMap.put("pileConnectorCode", orderInfo.getPileConnectorCode());
return resultMap;
}
/**
* 关闭支付未启动的订单
*
* @param dto
*/
public void closeStartFailedOrder(QueryOrderDTO dto) {
orderBasicInfoService.closeStartFailedOrder(dto.getStartTime(), dto.getEndTime());
}
/**
* 人工结算订单
*
* @param dto
*/
public boolean manualSettlementOrder(ManualSettlementDTO dto) {
log.info("人工结算订单-begin orderCode:{}", dto.getOrderCode());
// 查询订单
OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getOrderCode());
if (orderBasicInfo == null) {
log.info("人工结算订单-根据订单号:{}, 查询为null", dto.getOrderCode());
return false;
}
// 当前登录用户,是否可以结算该订单
AuthorizedDeptVO authorizedMap = UserUtils.getAuthorizedMap();
if (authorizedMap == null) {
log.info("人工结算订单-当前登录管理员无权限");
return false;
}
List<String> stationDeptIds = authorizedMap.getStationDeptIds();
if (CollectionUtils.isEmpty(stationDeptIds)) {
// 运营商管理员
List<String> merchantDeptIds = authorizedMap.getMerchantDeptIds();
}
// 充电金额
String chargingAmount = dto.getChargingAmount();
// 充电度数
String chargingDegree = dto.getChargingDegree();
if (StringUtils.equals(chargingAmount, Constants.ZERO) || StringUtils.equals(chargingDegree, Constants.ZERO)) {
// 获取最后一次实时数据
List<RealTimeMonitorData> chargingRealTimeData = orderBasicInfoService.getChargingRealTimeData(orderBasicInfo.getTransactionCode());
if (CollectionUtils.isNotEmpty(chargingRealTimeData)) {
RealTimeMonitorData realTimeMonitorData = chargingRealTimeData.get(0);
chargingAmount = realTimeMonitorData.getChargingAmount();
chargingDegree = realTimeMonitorData.getChargingDegree();
}
}
// 查询订单退款记录,如存在退款说明已经结算过,不能再次结算
List<OrderDetailInfoVO.OrderRefundInfo> orderRefundInfoList = orderBasicInfoService.getOrderRefundInfoList(orderBasicInfo);
if (CollectionUtils.isNotEmpty(orderRefundInfoList)) {
// 已退款金额
BigDecimal refunded = orderRefundInfoList.stream()
.map(x -> Objects.nonNull(x.getReverseAmt()) ? new BigDecimal(x.getReverseAmt()) : BigDecimal.ZERO)
.reduce(BigDecimal.ZERO,BigDecimal::add);
if (Objects.nonNull(orderBasicInfo.getPayAmount())) {
chargingAmount = orderBasicInfo.getPayAmount().subtract(refunded).toString();
log.info("订单:{}, 已经存在退款记录:{}, 支付金额{}, 退款金额:{}, 重新计算消费金额为:{}",
orderBasicInfo.getOrderCode(), JSON.toJSONString(orderRefundInfoList), orderBasicInfo.getPayAmount(), refunded, chargingAmount);
}
}
// 组装交易记录数据
TransactionRecordsData data = new TransactionRecordsData();
data.setConsumptionAmount(chargingAmount); // 总消费金额
data.setTotalElectricity(chargingDegree); // 总用电量
data.setStopReasonMsg("人工结算订单,操作人:" + SecurityUtils.getUsername()); // 停止原因
// 结算订单 新逻辑
String mode = pileMerchantInfoService.getDelayModeByMerchantId(orderBasicInfo.getMerchantId());
AbstractProgramLogic orderLogic = ProgramLogicFactory.getProgramLogic(mode);
orderLogic.settleOrder(data, orderBasicInfo);
// 发送停止充电指令
pileRemoteService.remoteStopCharging(orderBasicInfo.getPileSn(), orderBasicInfo.getConnectorCode(), orderBasicInfo.getTransactionCode());
log.info("人工结算订单-end orderCode:{}", dto.getOrderCode());
// 异步推送第三方平台订单信息
CompletableFuture.runAsync(() -> {
try {
commonService.commonPushOrderInfo(orderBasicInfo);
} catch (Exception e) {
log.error("人工结算订单 推送第三方平台订单信息error, orderCode:{}", orderBasicInfo.getOrderCode(), e);
}
});
return true;
}
/**
* 当前登录会员 获取支付方式
*
* @param dto
*/
public List<PayModeVO> getPayMode(GetPayModeDTO dto) {
log.info("当前登录会员 获取支付方式, param:{}, 请求来源:{}", JSON.toJSONString(dto), dto.getRequestSource());
List<PayModeVO> result = Lists.newArrayList();
// 查询会员在站点是否是白名单用户
PileStationWhitelist whitelist = pileStationWhitelistService.queryWhitelistByMemberId(dto.getStationId(), dto.getMemberId());
// 查询是否为平台测试员
PlatformTesterVO platformTesterVO = memberBasicInfoService.selectPlatformTesterStatus(dto.getMemberId());
// 根据memberId查询该用户是否是希晓的会员
MemberBasicInfo memberBasicInfo = memberBasicInfoService.selectInfoByMemberId(dto.getMemberId());
boolean flag = whitelist != null || StringUtils.equals(platformTesterVO.getStatus(), Constants.ONE);
if (flag) {
result.add(
PayModeVO.builder()
.payModeCode(OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue())
.payModeName(OrderPayModeEnum.PAYMENT_OF_WHITELIST.getLabel())
.build()
);
} else {
// 微信支付
if (StringUtils.equals(dto.getRequestSource(), AdapayPayChannelEnum.WX_LITE.getValue())) {
result.add(
PayModeVO.builder()
.payModeCode(OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())
.payModeName(OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getLabel())
.build()
);
}
// 支付宝支付
if (StringUtils.equals(dto.getRequestSource(), AdapayPayChannelEnum.ALIPAY_LITE.getValue())) {
result.add(
PayModeVO.builder()
.payModeCode(OrderPayModeEnum.PAYMENT_OF_ALIPAY.getValue())
.payModeName(OrderPayModeEnum.PAYMENT_OF_ALIPAY.getLabel())
.build()
);
}
// 如果是希晓的会员,将余额支付添加进去
if (MerchantUtils.isXiXiaoMerchant(String.valueOf(memberBasicInfo.getMerchantId()))) { // 35-希晓
// 余额支付
result.add(
PayModeVO.builder()
.payModeCode(OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue())
.payModeName(OrderPayModeEnum.PAYMENT_OF_BALANCE.getLabel())
.build()
);
}
}
return result;
}
/**
* 查询未开发票订单
* 时间限制15天内
*
* @param dto
* @return
*/
public List<OrderVO> queryUninvoicedOrderList(QueryOrderDTO dto) {
int i = 15;
// 查询最近15天完成的订单
LocalDateTime dateTime = LocalDateTime.now().plusDays(-i);
List<OrderVO> orderList = orderBasicInfoService.getListByMemberIdAndOrderStatus(dto.getMemberId(), Lists.newArrayList("6"), dateTime);
// 过滤掉订单金额为0的
orderList = orderList.stream()
.filter(x -> x.getSettleAmount().compareTo(BigDecimal.ZERO) > 0)
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(orderList)) {
return orderList;
}
// 查询最近60天申请开票记录
QueryInvoiceRecordDTO build = QueryInvoiceRecordDTO.builder()
.memberId(dto.getMemberId())
.startTime(dateTime)
.build();
List<OrderInvoiceRecord> orderInvoiceRecords = orderInvoiceRecordService.selectInvoiceRecordList(build);
if (CollectionUtils.isEmpty(orderInvoiceRecords)) {
return orderList;
}
// 排除掉已经申请过的订单
List<String> orderCodeList = orderInvoiceRecords.stream() // 转化为 Stream
.map(OrderInvoiceRecord::getOrderCodes) // 获取 OrderInvoiceRecord 中的 orderCodes 字符串
.flatMap(str -> Arrays.stream(str.split(Constants.DEFAULT_DELIMITER))) // 分隔逗号并转化为 Stream
.collect(Collectors.toList()); // 收集为 List<String>
orderList = orderList.stream()
.filter(x -> !orderCodeList.contains(x.getOrderCode()))
.collect(Collectors.toList());
return orderList;
}
public List<StationInfoVO> queryUninvoicedStationList(QueryOrderDTO dto) {
return Lists.newArrayList();
}
/**
* 申请开票
*
* @param dto
*/
public void applyOrderInvoice(ApplyOrderInvoiceDTO dto) {
int i = 15;
// 查询最近15天完成的订单
LocalDateTime dateTime = LocalDateTime.now().plusDays(-i);
// 查询最近15天 会员的开票记录
List<OrderInvoiceRecord> orderInvoiceRecords = orderInvoiceRecordService.selectInvoiceRecordList(dto.getMemberId(), dateTime, LocalDateTime.now());
List<String> orderCodeList = orderInvoiceRecords.stream() // 转化为 Stream
.map(OrderInvoiceRecord::getOrderCodes) // 获取 OrderInvoiceRecord 中的 orderCodes 字符串
.flatMap(str -> Arrays.stream(str.split(Constants.DEFAULT_DELIMITER))) // 分隔逗号并转化为 Stream
.collect(Collectors.toList()); // 收集为 List<String>
// 取交集 校验订单是否已经开票
Set<String> intersection = Sets.intersection(Sets.newHashSet(orderCodeList), Sets.newHashSet(dto.getOrderCodes()));
if (CollectionUtils.isNotEmpty(intersection)) {
log.info("申请开票前端传的:{}订单号list, 包含已经申请的订单:{}", dto.getOrderCodes(), intersection);
return;
}
// 查抬头信息
MemberInvoiceTitle invoiceTitle = memberInvoiceTitleService.selectMemberInvoiceTitleById(Long.parseLong(dto.getTitleId()));
if (StringUtils.isNotEmpty(dto.getReception())) {
boolean b = false;
if (StringUtils.isEmail(dto.getReception()) && !StringUtils.equals(dto.getReception(), invoiceTitle.getEmail())) {
invoiceTitle.setEmail(dto.getReception());
b = true;
}
if (StringUtils.isPhoneNumber(dto.getReception()) && !StringUtils.equals(dto.getReception(), invoiceTitle.getPhoneNumber())) {
invoiceTitle.setPhoneNumber(dto.getReception());
b = true;
}
if (b) {
memberInvoiceTitleService.updateMemberInvoiceTitle(invoiceTitle);
}
}
// 整理数据
List<OrderVO> orderVOList = orderBasicInfoService.getListByOrderCodes(dto.getOrderCodes());
// 根据运营商分组
Map<String, List<OrderVO>> map = orderVOList.stream().collect(Collectors.groupingBy(OrderVO::getMerchantId));
BigDecimal totalAmount = null;
BigDecimal totalElecAmount = null;
BigDecimal totalServiceAmount = null;
// 根据运营商创建多笔开票记录
for (Map.Entry<String, List<OrderVO>> entry : map.entrySet()) {
totalAmount = BigDecimal.ZERO;
totalElecAmount = BigDecimal.ZERO;
totalServiceAmount = BigDecimal.ZERO;
List<OrderVO> orders = entry.getValue();
for (OrderVO orderVO : orders) {
totalAmount = totalAmount.add(orderVO.getOrderAmount());
totalElecAmount = totalElecAmount.add(orderVO.getTotalElectricityAmount());
totalServiceAmount = totalServiceAmount.add(orderVO.getTotalServiceAmount());
}
// 入库
OrderInvoiceRecord orderInvoiceRecord = new OrderInvoiceRecord();
orderInvoiceRecord.setStatus(Constants.ZERO);
orderInvoiceRecord.setMemberId(dto.getMemberId());
orderInvoiceRecord.setMerchantId(entry.getKey());
orderInvoiceRecord.setTitleId(dto.getTitleId());
orderInvoiceRecord.setOrderCodes(String.join(Constants.DEFAULT_DELIMITER, dto.getOrderCodes()));
orderInvoiceRecord.setTotalAmount(totalAmount);
orderInvoiceRecord.setTotalElecAmount(totalElecAmount);
orderInvoiceRecord.setTotalServiceAmount(totalServiceAmount);
orderInvoiceRecordService.insertOrderInvoiceRecord(orderInvoiceRecord);
}
}
/**
* 查询开票记录
*
* @param dto
* @return
*/
public PageResponse queryInvoiceRecord(QueryInvoiceRecordDTO dto) {
QueryInvoiceRecordDTO build = QueryInvoiceRecordDTO.builder()
.memberId(dto.getMemberId())
.build();
int pageNo = dto.getPageNo() == null ? 1 : dto.getPageNo();
int pageSize = dto.getPageSize() == null ? 10 : dto.getPageSize();
PageHelper.startPage(pageNo, pageSize);
// List<OrderInvoiceRecord> orderInvoiceRecords = orderInvoiceRecordService.selectInvoiceRecordList(build);
List<OrderInvoiceRecordVO> orderInvoiceRecords = orderInvoiceRecordService.selectInvoiceVOList(build);
PageInfo<OrderInvoiceRecordVO> pageInfo = new PageInfo<>(orderInvoiceRecords);
List<InvoiceRecordVO> volist = Lists.newArrayList();
for (OrderInvoiceRecordVO vo : orderInvoiceRecords) {
volist.add(
InvoiceRecordVO.builder()
.status(InvoiceRecordEnum.getLabel(vo.getStatus()))
.totalAmount(vo.getTotalAmount())
.totalElecAmount(vo.getTotalElecAmount())
.totalServiceAmount(vo.getTotalServiceAmount())
.merchantName(vo.getMerchantName())
.merchantTel(vo.getMerchantTel())
.createTime(vo.getCreateTime())
.build()
);
}
return PageResponse.builder()
.total(pageInfo.getTotal())
.pages(pageInfo.getPages())
.pageNum(pageInfo.getPageNum())
.pageSize(pageInfo.getPageSize())
.list(volist)
.build();
}
/**
* 汇付支付 支付回调
*
* @param request
* @throws Exception
*/
public void adapayCallback(HttpServletRequest request) throws Exception {
// 验签请参data
String data = request.getParameter("data");
// 验签请参sign
String sign = request.getParameter("sign");
// 验签请参publicKey
String publicKey = AdapayCore.PUBLIC_KEY;
log.info("汇付支付回调验签请参data={}, sign={}", data, sign);
// 验签标记
boolean checkSign = AdapaySign.verifySign(data, sign, publicKey);
if (!checkSign) {
log.info("汇付支付回调验签失败:{}", data);
return;
}
// type
String type = request.getParameter("type");
// 根据type执行不同逻辑
if (AdapayEventEnum.payment_succeeded.getValue().equals(type)) {
// 支付成功
paymentSucceeded(data);
} else if (AdapayEventEnum.refund_succeeded.getValue().equals(type)) {
// 退款成功
refundSucceeded(data);
} else if (AdapayEventEnum.refund_failed.getValue().equals(type)) {
// 退款失败
refundFailed(data);
} else if (AdapayEventEnum.corp_member_failed.getValue().equals(type)) {
// 开户失败 删除
corpMemberFailed(data);
} else if (AdapayEventEnum.corp_member_succeeded.getValue().equals(type)) {
// 开户成功
corpMemberSucceeded(data);
} else if (AdapayEventEnum.payment_reverse_succeeded.getValue().equals(type)) {
// 支付撤销成功
paymentReverseSucceeded(data);
} else if (AdapayEventEnum.payment_reverse_failed.getValue().equals(type)) {
// 支付撤销失败
paymentReverseFailed(data);
} else if (AdapayEventEnum.cash_succeeded.getValue().equals(type)) {
// 取现成功
cashSucceeded(data);
} else if (AdapayEventEnum.cash_failed.getValue().equals(type)) {
// 取现失败
cashFailed(data);
}
}
/**
* adapay支付成功回调
*
* @param data
* @throws JsonProcessingException
*/
private void paymentSucceeded(String data) throws JsonProcessingException {
// 验签成功 保存到回调记录表中
JSONObject jsonObject = JSON.parseObject(data);
log.info("adapay支付成功回调:{}", jsonObject.toJSONString());
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
AdapayCallbackRecord adapayCallbackRecord = mapper.readValue(jsonObject.toJSONString(), AdapayCallbackRecord.class);
// 支付扩展域
adapayCallbackRecord.setExpend(jsonObject.getString("expend"));
// 支付id
String paymentId = jsonObject.getString("id");
adapayCallbackRecord.setPaymentId(paymentId);
// 订单附加说明
JSONObject descJson = JSON.parseObject(adapayCallbackRecord.getDescription());
// 支付回调中包含的场景类型
String scenarioType = descJson.getString("type");
adapayCallbackRecord.setPayScenario(scenarioType);
// 支付回调中包含的会员id
String memberId = descJson.getString("memberId");
adapayCallbackRecord.setMemberId(memberId);
// 支付回调中包含的订单编号
String orderCode = descJson.getString("orderCode");
adapayCallbackRecord.setOrderCode(orderCode);
// 支付金额
BigDecimal amount = adapayCallbackRecord.getPayAmt();
// 保存到数据库
adapayCallbackRecordService.saveAdapayCallbackRecord(adapayCallbackRecord);
// 保存MemberAdapayRecord
MemberAdapayRecord memberAdapayRecord = new MemberAdapayRecord();
memberAdapayRecord.setMemberId(memberId);
memberAdapayRecord.setPaymentId(paymentId);
memberAdapayRecord.setPaymentOrderNo(adapayCallbackRecord.getOutTransId());
memberAdapayRecord.setScenarioType(scenarioType);
memberAdapayRecord.setPayAmt(amount);
memberAdapayRecord.setRefundAmt(BigDecimal.ZERO);
memberAdapayRecord.setSpendAmt(BigDecimal.ZERO);
memberAdapayRecord.setFreezeAmt(BigDecimal.ZERO);
memberAdapayRecord.setBalanceAmt(amount);
memberAdapayRecordService.insertSelective(memberAdapayRecord);
// 微信支付订单 记录会员交易流水
MemberTransactionRecord record = MemberTransactionRecord.builder()
.orderCode(orderCode)
.scenarioType(scenarioType)
.memberId(memberId)
.actionType(ActionTypeEnum.FORWARD.getValue())
.payMode(PayModeEnum.PAYMENT_OF_WECHATPAY.getValue())
.paymentInstitutions(PaymentInstitutionsEnum.ADAPAY.getValue())
.amount(amount) // 单位元
.outTradeNo(adapayCallbackRecord.getPartyOrderId())
.transactionId(adapayCallbackRecord.getOutTransId())
.build();
memberTransactionRecordService.insertSelective(record);
if (StringUtils.equals(scenarioType, ScenarioEnum.ORDER.getValue())) { // 1-订单支付
PaymentInfo paymentInfo = new PaymentInfo();
paymentInfo.setPaymentId(paymentId);
paymentInfo.setAmount(amount.toString());
// 记录订单支付流水
OrderPayRecord orderPayRecord = OrderPayRecord.builder()
.orderCode(orderCode)
.payMode(OrderPayRecordEnum.WECHATPAY_PAYMENT.getValue())
.paymentId(paymentId)
.payAmount(amount)
.acquirer(AcquirerEnum.ADAPAY.getValue())
.deductionRecord(JSON.toJSONString(paymentInfo))
.createBy(memberId)
.delFlag(DelFlagEnum.NORMAL.getValue())
.build();
orderPayRecordService.batchInsert(Lists.newArrayList(orderPayRecord));
// 更新冻结金额 支付成功后全部冻结
CompletableFuture.runAsync(() -> {
try {
memberAdapayRecordService.updateFreezeAmount(paymentId, amount);
} catch (Exception e) {
log.error("更新冻结金额 支付成功后全部冻结error", e);
}
});
// 支付订单成功
PayOrderSuccessCallbackDTO callbackDTO = PayOrderSuccessCallbackDTO.builder()
.orderCode(orderCode)
.payAmount(amount)
.payMode(OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())
.acquirer(AcquirerEnum.ADAPAY.getValue())
.build();
// 订单支付成功 支付回调
orderBasicInfoService.payOrderSuccessCallback(callbackDTO); // 订单在线支付成功回调
// 异步判断是否对接了类似华为平台,如果是,走通用第三方平台启动充电逻辑
CompletableFuture.runAsync(() -> {
try {
checkThirdPartyQueryStartCharge(orderCode);
} catch (Exception e) {
log.error("异步推送第三方平台启动充电逻辑 error", e);
}
});
} else if (StringUtils.equals(scenarioType, ScenarioEnum.BALANCE.getValue())) { // 2-充值余额
// 充值余额成功
UpdateMemberBalanceDTO dto = new UpdateMemberBalanceDTO();
dto.setMemberId(memberId);
dto.setType(MemberWalletEnum.TYPE_IN.getValue());
dto.setSubType(MemberWalletEnum.SUBTYPE_TOP_UP.getValue());
dto.setUpdatePrincipalBalance(amount);
memberBasicInfoService.updateMemberBalance(dto);
} else if (StringUtils.equals(scenarioType, ScenarioEnum.OCCUPY.getValue())) { // 占桩订单
// 通过订单号查询出占桩订单信息
OrderPileOccupy orderPileOccupy = orderPileOccupyService.queryByOccupyCode(orderCode);
// 订单状态改为 1-订单完成
orderPileOccupy.setStatus(OccupyOrderStatusEnum.ORDER_COMPLETE.getCode());
// 支付状态改为 1-支付完成
orderPileOccupy.setPayStatus(OccupyOrderPayStatusEnum.PAYMENT_COMPLETION.getCode());
orderPileOccupyService.updateByPrimaryKey(orderPileOccupy);
}
}
/**
* 汇付退款成功
*/
private void refundSucceeded(String data) {
log.info("退款成功 data:{}", JSON.toJSONString(data));
// 保存退款回调记录
adapayRefundRecordService.saveAdapayRefundRecord(data);
JSONObject jsonObject = JSON.parseObject(data);
JSONObject reason = jsonObject.getJSONObject("reason");
if (ScenarioEnum.BALANCE.getValue().equals(reason.getString("scenarioType"))) {
// 这笔支付订单原来是充值余额的,退款成功了,需要扣掉会员的本金金额
UpdateMemberBalanceDTO dto = new UpdateMemberBalanceDTO();
String memberId = reason.getString("memberId");
dto.setMemberId(memberId);
dto.setUpdatePrincipalBalance(new BigDecimal(jsonObject.getString("refund_amt"))); // 更新会员本金金额,单位元
dto.setType(MemberWalletEnum.TYPE_OUT.getValue());
dto.setSubType(MemberWalletEnum.SUBTYPE_USER_REFUND.getValue());
memberBasicInfoService.updateMemberBalance(dto);
// 收到回调,删除缓存
String redisKey = CacheConstants.MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS + memberId;
redisCache.deleteObject(redisKey);
}
}
/**
* 退款失败
*
* @param data
*/
private void refundFailed(String data) {
log.info("退款失败 data:{}", JSON.toJSONString(data));
JSONObject jsonObject = JSON.parseObject(data);
JSONObject reason = jsonObject.getJSONObject("reason");
if (ScenarioEnum.BALANCE.getValue().equals(reason.getString("scenarioType"))) {
String memberId = reason.getString("memberId");
// 收到回调,删除缓存
String redisKey = CacheConstants.MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS + memberId;
redisCache.deleteObject(redisKey);
}
}
/**
* 对公账户创建失败
*/
private void corpMemberFailed(String data) {
log.info("对公账户创建失败 data:{}", JSON.toJSONString(data));
// 删除表中的记录
JSONObject jsonObject = JSON.parseObject(data);
String memberId = jsonObject.getString("member_id");
if (StringUtils.isBlank(memberId)) {
return;
}
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMemberId(memberId);
if (adapayMemberAccount == null) {
return;
}
adapayMemberAccount.setStatus(Constants.TWO);
if (Objects.nonNull(jsonObject.getString("audit_desc"))) {
adapayMemberAccount.setRemark(jsonObject.getString("audit_desc"));
}
// 逻辑删除记录,并删除缓存
adapayMemberAccountService.updateAdapayMemberAccount(adapayMemberAccount);
}
/**
* 对公账户创建成功
*/
private void corpMemberSucceeded(String data) {
log.info("对公账户创建成功 data:{}", JSON.toJSONString(data));
JSONObject jsonObject = JSON.parseObject(data);
String memberId = jsonObject.getString("member_id");
if (StringUtils.isBlank(memberId)) {
return;
}
AdapayMemberAccount adapayMemberAccount = new AdapayMemberAccount();
adapayMemberAccount.setAdapayMemberId(memberId);
adapayMemberAccount.setStatus(Constants.ONE);
adapayMemberAccount.setDelFlag(DelFlagEnum.NORMAL.getValue());
adapayMemberAccountService.updateAdapayMemberAccountByMemberId(adapayMemberAccount);
}
/**
* 取现成功
*/
private void cashSucceeded(String data) {
log.info("取现成功 data:{}", JSON.toJSONString(data));
JSONObject jsonObject = JSON.parseObject(data);
String withdrawCode = jsonObject.getString("id");
// 通过取现id查询取现数据
ClearingWithdrawInfo clearingWithdrawInfo = clearingWithdrawInfoService.selectByWithdrawCode(withdrawCode);
if (clearingWithdrawInfo != null) {
clearingWithdrawInfo.setWithdrawStatus(Constants.ONE);
clearingWithdrawInfo.setUpdateTime(DateUtils.getNowDate());
clearingWithdrawInfoService.updateByPrimaryKeySelective(clearingWithdrawInfo);
}
// 清分账单数据更新
List<ClearingBillInfo> clearingBillInfos = clearingBillInfoService.selectByWithdrawCode(withdrawCode);
if (CollectionUtils.isNotEmpty(clearingBillInfos)) {
for (ClearingBillInfo clearingBillInfo : clearingBillInfos) {
clearingBillInfo.setBillStatus("4");
}
clearingBillInfoService.updateBatchSelective(clearingBillInfos);
}
}
/**
* 取现失败
*
* @param data
*/
private void cashFailed(String data) {
log.info("取现失败 data:{}", JSON.toJSONString(data));
JSONObject jsonObject = JSON.parseObject(data);
String withdrawCode = jsonObject.getString("id");
// 通过取现id查询取现数据
ClearingWithdrawInfo clearingWithdrawInfo = clearingWithdrawInfoService.selectByWithdrawCode(withdrawCode);
clearingWithdrawInfo.setWithdrawStatus(Constants.TWO);
clearingWithdrawInfo.setUpdateTime(DateUtils.getNowDate());
clearingWithdrawInfoService.updateByPrimaryKeySelective(clearingWithdrawInfo);
}
/**
* 支付撤销成功
*/
private void paymentReverseSucceeded(String data) {
log.info("支付撤销成功 data:{}", JSON.toJSONString(data));
JSONObject jsonObject = JSON.parseObject(data);
JSONObject reason = jsonObject.getJSONObject("reason");
if (ScenarioEnum.BALANCE.getValue().equals(reason.getString("scenarioType"))) {
// 这笔支付订单原来是充值余额的,退款成功了,需要扣掉会员的本金金额
UpdateMemberBalanceDTO dto = new UpdateMemberBalanceDTO();
String memberId = reason.getString("memberId");
dto.setMemberId(memberId);
dto.setUpdatePrincipalBalance(new BigDecimal(jsonObject.getString("reverse_amt"))); // 更新会员本金金额,单位元
dto.setType(MemberWalletEnum.TYPE_OUT.getValue());
dto.setSubType(MemberWalletEnum.SUBTYPE_USER_REFUND.getValue());
memberBasicInfoService.updateMemberBalance(dto);
// 收到回调,删除缓存
String redisKey = CacheConstants.MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS + memberId;
redisCache.deleteObject(redisKey);
}
}
/**
* 支付撤销失败
*/
private void paymentReverseFailed(String data) {
log.info("支付撤销失败 data:{}", JSON.toJSONString(data));
JSONObject jsonObject = JSON.parseObject(data);
JSONObject reason = jsonObject.getJSONObject("reason");
if (ScenarioEnum.BALANCE.getValue().equals(reason.getString("scenarioType"))) {
String memberId = reason.getString("memberId");
// 收到回调,删除缓存
String redisKey = CacheConstants.MEMBER_BALANCE_REFUNDS_ARE_IN_PROGRESS + memberId;
redisCache.deleteObject(redisKey);
}
}
public Map<String, Object> payOccupyPileOrder(PayOrderDTO dto) {
return orderPileOccupyService.payOccupyPileOrder(dto);
}
/**
* 判断是否对接了类似华为平台的第三方平台,并启动充电
* @param orderCode
*/
private boolean checkThirdPartyQueryStartCharge(String orderCode) {
// 根据订单号查询订单信息
OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
String stationId = orderInfo.getStationId();
String pileSn = orderInfo.getPileSn();
// 根据 stationId 查询 pile_sn_relation 表
List<ThirdPartySnRelationVO> snRelations = snRelationService.selectSnRelationListByParams(stationId, pileSn, null);
if (CollectionUtils.isEmpty(snRelations)) {
return false;
}
for (ThirdPartySnRelationVO snRelation : snRelations) {
String startMode = snRelation.getStartMode();
String thirdPartyType = snRelation.getThirdPartyType();
if (StringUtils.equals(Constants.ONE, startMode)) {
// 如果 startMode 为 1则调用第三方平台启动充电接口
ThirdPartyCommonStartChargeDTO dto = new ThirdPartyCommonStartChargeDTO();
dto.setPayMode(orderInfo.getPayMode());
dto.setStationIds(Lists.newArrayList(stationId));
dto.setPileConnectorCode(orderInfo.getPileConnectorCode());
dto.setThirdPartyType(thirdPartyType);
dto.setOrderCode(orderCode);
String result = commonService.commonQueryStartCharge(dto);
log.info("异步判断是否对接第三方平台 stationId:{}, thirdPartyType:{}, result:{}", stationId, thirdPartyType, result);
}
}
// 判断是否对接了类似华为平台
// List<ThirdPartyStationRelationVO> relationInfoList = thirdPartyStationRelationService.getRelationInfoList(stationId);
// if (CollectionUtils.isEmpty(relationInfoList)) {
// return false;
// }
// for (ThirdPartyStationRelationVO vo : relationInfoList) {
// String startMode = vo.getStartMode();
// if (StringUtils.equals(Constants.TWO, startMode)) {
// continue;
// }
// ThirdPartyCommonStartChargeDTO dto = new ThirdPartyCommonStartChargeDTO();
// dto.setPayMode(orderInfo.getPayMode());
// dto.setStationIds(Lists.newArrayList(stationId));
// dto.setPileConnectorCode(orderInfo.getPileConnectorCode());
// dto.setThirdPartyType(vo.getThirdPartyType());
//
// String result = commonService.commonQueryStartCharge(dto);
// log.info("异步判断是否对接第三方平台 result:{}", result);
// }
return true;
}
}