Files
jsowell-charger-web/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java

831 lines
33 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.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.domain.ykc.RealTimeMonitorData;
import com.jsowell.common.core.page.PageResponse;
import com.jsowell.common.enums.MemberWalletEnum;
import com.jsowell.common.enums.ykc.ActionTypeEnum;
import com.jsowell.common.enums.ykc.OrderPayModeEnum;
import com.jsowell.common.enums.ykc.OrderPayRecordEnum;
import com.jsowell.common.enums.ykc.OrderPayStatusEnum;
import com.jsowell.common.enums.ykc.OrderStatusEnum;
import com.jsowell.common.enums.ykc.PayModeEnum;
import com.jsowell.common.enums.ykc.PileConnectorDataBaseStatusEnum;
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
import com.jsowell.common.enums.ykc.ScenarioEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.common.util.bean.BeanUtils;
import com.jsowell.common.util.id.IdUtils;
import com.jsowell.netty.command.ykc.PublishPileBillingTemplateCommand;
import com.jsowell.netty.command.ykc.StartChargingCommand;
import com.jsowell.netty.service.yunkuaichong.YKCPushCommandService;
import com.jsowell.pile.domain.MemberTransactionRecord;
import com.jsowell.pile.domain.OrderBasicInfo;
import com.jsowell.pile.domain.OrderDetail;
import com.jsowell.pile.domain.OrderPayRecord;
import com.jsowell.pile.domain.WxpayCallbackRecord;
import com.jsowell.pile.dto.BasicPileDTO;
import com.jsowell.pile.dto.GenerateOrderDTO;
import com.jsowell.pile.dto.PayOrderDTO;
import com.jsowell.pile.dto.PayOrderSuccessCallbackDTO;
import com.jsowell.pile.dto.PaymentScenarioDTO;
import com.jsowell.pile.dto.QueryConnectorListDTO;
import com.jsowell.pile.dto.QueryOrderDTO;
import com.jsowell.pile.dto.SettleOrderDTO;
import com.jsowell.pile.dto.StopChargingDTO;
import com.jsowell.pile.dto.UniAppQueryOrderDTO;
import com.jsowell.pile.dto.WeixinPayDTO;
import com.jsowell.pile.service.IMemberBasicInfoService;
import com.jsowell.pile.service.IMemberTransactionRecordService;
import com.jsowell.pile.service.IOrderBasicInfoService;
import com.jsowell.pile.service.IOrderPayRecordService;
import com.jsowell.pile.service.IPileBillingTemplateService;
import com.jsowell.pile.service.IPileStationInfoService;
import com.jsowell.pile.service.WechatPayService;
import com.jsowell.pile.service.WxpayCallbackRecordService;
import com.jsowell.pile.transaction.dto.OrderTransactionDTO;
import com.jsowell.pile.transaction.service.TransactionService;
import com.jsowell.pile.vo.base.PileInfoVO;
import com.jsowell.pile.vo.uniapp.MemberVO;
import com.jsowell.pile.vo.uniapp.OrderVO;
import com.jsowell.pile.vo.uniapp.PileConnectorDetailVO;
import com.jsowell.pile.vo.uniapp.UniAppOrderVO;
import com.jsowell.pile.vo.web.BillingTemplateVO;
import com.jsowell.pile.vo.web.OrderDetailInfoVO;
import com.jsowell.pile.vo.web.PileStationVO;
import com.jsowell.pile.vo.web.UpdateMemberBalanceDTO;
import com.jsowell.wxpay.dto.WeChatRefundDTO;
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.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
public class OrderService {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Autowired
private TransactionService pileTransactionService;
@Autowired
private IPileBillingTemplateService pileBillingTemplateService;
@Autowired
private IOrderBasicInfoService orderBasicInfoService;
@Autowired
private PileRemoteService pileRemoteService;
@Autowired
private YKCPushCommandService ykcPushCommandService;
@Autowired
private PileService pileService;
@Autowired
private MemberService memberService;
@Autowired
private IMemberBasicInfoService memberBasicInfoService;
@Autowired
private IOrderPayRecordService orderPayRecordService;
@Autowired
private WechatPayService wechatPayService;
@Autowired
private WxpayCallbackRecordService wxpayCallbackRecordService;
@Autowired
private IMemberTransactionRecordService memberTransactionRecordService;
@Autowired
private IPileStationInfoService pileStationInfoService;
/**
* 生成订单
*
* @param dto
* @return
*/
public String generateOrder(GenerateOrderDTO dto) {
log.info("generateOrder param:{}", JSONObject.toJSONString(dto));
// 处理前端传的参数
analysisPileParameter(dto);
// 校验充电桩相关的信息
checkPileInfo(dto);
// 保存订单到数据库 saveOrder2Database
String orderCode = saveOrder2Database(dto);
return orderCode;
}
/**
* 订单支付
*
* @param dto
*/
public Map<String, Object> payOrder(PayOrderDTO dto) throws Exception {
Map<String, Object> resultMap = Maps.newHashMap();
OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getOrderCode());
if (orderInfo == null) {
throw new BusinessException(ReturnCodeEnum.CODE_QUERY_ORDER_NULL_ERROR);
}
if (!StringUtils.equals(orderInfo.getPayStatus(), "0")) {
// 订单已支付
throw new BusinessException(ReturnCodeEnum.CODE_ORDER_IS_NOT_TO_BE_PAID_ERROR);
}
String orderCode = orderInfo.getOrderCode();
// 该订单充电金额
BigDecimal chargeAmount = dto.getPayAmount();
// 记录支付流水
List<OrderPayRecord> payRecordList = Lists.newArrayList();
if (StringUtils.equals(dto.getPayMode(), OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue())) { // 余额支付
// 查询该会员的余额
MemberVO memberVO = memberService.getMemberInfoByMemberId(dto.getMemberId());
BigDecimal totalAccountAmount = memberVO.getTotalAccountAmount();
if (totalAccountAmount.compareTo(chargeAmount) < 0) {
// 总余额小于充电金额
throw new BusinessException(ReturnCodeEnum.CODE_BALANCE_IS_INSUFFICIENT);
}
BigDecimal principalAmount = memberVO.getPrincipalBalance(); // 会员剩余本金金额
BigDecimal giftAmount = memberVO.getGiftBalance(); // 会员剩余赠送余额
BigDecimal principalPay = null; // 30
BigDecimal giftPay = null; // 10
// 先扣除本金金额,再扣除赠送金额
BigDecimal subtract = principalAmount.subtract(chargeAmount);
if (subtract.compareTo(BigDecimal.ZERO) >= 0) {
principalPay = chargeAmount;
} else {
if (principalAmount.compareTo(BigDecimal.ZERO) > 0) {
principalPay = principalAmount;
}
giftPay = subtract.negate();
}
// 更新会员钱包
UpdateMemberBalanceDTO updateMemberBalanceDTO = UpdateMemberBalanceDTO.builder()
.memberId(dto.getMemberId())
.type(MemberWalletEnum.TYPE_OUT.getValue())
.subType(MemberWalletEnum.SUBTYPE_PAYMENT_FOR_ORDER.getValue())
.updatePrincipalBalance(principalPay)
.updateGiftBalance(giftPay)
.relatedOrderCode(orderCode)
.build();
memberBasicInfoService.updateMemberBalance(updateMemberBalanceDTO);
// 记录流水
if (principalPay != null) {
payRecordList.add(OrderPayRecord.builder()
.orderCode(dto.getOrderCode())
.payMode(OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue())
.payAmount(principalPay)
.createBy(dto.getMemberId())
.build());
}
if (giftPay != null) {
payRecordList.add(OrderPayRecord.builder()
.orderCode(dto.getOrderCode())
.payMode(OrderPayRecordEnum.GIFT_BALANCE_PAYMENT.getValue())
.payAmount(giftPay)
.createBy(dto.getMemberId())
.build());
}
// 余额支付可以直接调支付回调方法
PayOrderSuccessCallbackDTO callbackDTO = PayOrderSuccessCallbackDTO.builder()
.orderCode(orderCode)
.payAmount(chargeAmount)
.payMode(dto.getPayMode())
.build();
payOrderSuccessCallback(callbackDTO);
// 余额支付订单 记录会员交易流水
MemberTransactionRecord record = MemberTransactionRecord.builder()
.orderCode(orderCode)
.scenarioType(ScenarioEnum.ORDER.getValue())
.memberId(memberVO.getMemberId())
.actionType(ActionTypeEnum.FORWARD.getValue())
.payMode(PayModeEnum.PAYMENT_OF_BALANCE.getValue())
.amount(dto.getPayAmount()) // 单位元
.build();
memberTransactionRecordService.insertSelective(record);
} else if (StringUtils.equals(dto.getPayMode(), OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())) { // 微信支付
String openId = memberService.getOpenIdByCode(dto.getCode());
if (StringUtils.isBlank(openId)) {
throw new BusinessException(ReturnCodeEnum.CODE_GET_OPEN_ID_BY_CODE_ERROR);
}
WeixinPayDTO weixinPayDTO = new WeixinPayDTO();
weixinPayDTO.setOpenId(openId);
weixinPayDTO.setAmount(dto.getPayAmount().toString());
// 支付订单 附加参数
PaymentScenarioDTO paymentScenarioDTO = PaymentScenarioDTO.builder()
.type(ScenarioEnum.ORDER.getValue())
.orderCode(dto.getOrderCode())
.memberId(orderInfo.getMemberId())
.build();
weixinPayDTO.setAttach(JSONObject.toJSONString(paymentScenarioDTO));
weixinPayDTO.setDescription("充电费用");
Map<String, Object> weixinMap = this.weixinPayV3(weixinPayDTO);
// 返回微信支付参数
resultMap.put("weixinMap", weixinMap);
} else if (StringUtils.equals(dto.getPayMode(), OrderPayModeEnum.PAYMENT_OF_ALIPAY.getValue())) { // 支付宝支付
// TODO 返回支付宝支付参数
} else if (StringUtils.equals(dto.getPayMode(), OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue())) { // 白名单支付
// 白名单支付可以直接调支付回调方法
PayOrderSuccessCallbackDTO callbackDTO = PayOrderSuccessCallbackDTO.builder()
.orderCode(orderCode)
.payAmount(dto.getPayAmount())
.payMode(dto.getPayMode())
.build();
payOrderSuccessCallback(callbackDTO);
}
// 订单支付流水入库
if (CollectionUtils.isNotEmpty(payRecordList)) {
orderPayRecordService.batchInsert(payRecordList);
}
return resultMap;
}
/**
* 订单支付成功 支付回调
* 支付成功后掉用这个方法
* 1. 修改订单支付状态
* 2. 发送启动充电指令
*/
public void payOrderSuccessCallback(PayOrderSuccessCallbackDTO dto) {
OrderBasicInfo orderInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getOrderCode());
BigDecimal payAmount = dto.getPayAmount();
// 修改订单
orderInfo.setPayMode(dto.getPayMode());
orderInfo.setPayStatus("1");
orderInfo.setPayAmount(payAmount);
orderInfo.setPayTime(new Date());
orderBasicInfoService.updateOrderBasicInfo(orderInfo);
String pileSn = orderInfo.getPileSn();
// 发送启动充电指令前,再次下发计费模板
BillingTemplateVO billingTemplateVO = pileBillingTemplateService.selectBillingTemplateDetailByPileSn(pileSn);
if (billingTemplateVO != null) {
PublishPileBillingTemplateCommand templateCommand = new PublishPileBillingTemplateCommand();
templateCommand.setBillingTemplateVO(billingTemplateVO);
templateCommand.setPileSn(pileSn);
ykcPushCommandService.pushPublishPileBillingTemplate(templateCommand);
}
// 发送启动指令
StartChargingCommand startChargingCommand = StartChargingCommand.builder()
.pileSn(pileSn)
.connectorCode(orderInfo.getConnectorCode())
.transactionCode(orderInfo.getTransactionCode())
.chargeAmount(payAmount)
.build();
ykcPushCommandService.pushStartChargingCommand(startChargingCommand);
}
/**
* 保存订单信息到数据库
*
* @param dto
* @return
*/
private String saveOrder2Database(GenerateOrderDTO dto) {
String orderCode = IdUtils.getOrderCode();
String transactionCode = IdUtils.generateTransactionCode(dto.getPileSn(), dto.getConnectorCode());
// 订单基本信息
OrderBasicInfo orderBasicInfo = OrderBasicInfo.builder()
.orderCode(orderCode)
.transactionCode(transactionCode)
.orderStatus(OrderStatusEnum.NOT_START.getValue())
.memberId(dto.getMemberId())
.stationId(dto.getPileConnector().getStationId())
.pileSn(dto.getPileSn())
.connectorCode(dto.getConnectorCode())
.pileConnectorCode(dto.getPileSn() + dto.getConnectorCode())
.startMode(dto.getStartMode())
.payStatus(Constants.ZERO)
.payAmount(dto.getChargeAmount())
.payMode(dto.getPayMode())
.orderAmount(BigDecimal.ZERO)
.build();
// 订单详情
OrderDetail orderDetail = OrderDetail.builder()
.orderCode(orderCode)
.sharpElectricityPrice(dto.getBillingTemplate().getSharpElectricityPrice())
.sharpServicePrice(dto.getBillingTemplate().getSharpServicePrice())
.peakElectricityPrice(dto.getBillingTemplate().getPeakElectricityPrice())
.peakServicePrice(dto.getBillingTemplate().getPeakServicePrice())
.flatElectricityPrice(dto.getBillingTemplate().getFlatElectricityPrice())
.flatServicePrice(dto.getBillingTemplate().getFlatServicePrice())
.valleyElectricityPrice(dto.getBillingTemplate().getValleyElectricityPrice())
.valleyServicePrice(dto.getBillingTemplate().getValleyServicePrice())
.build();
OrderTransactionDTO createOrderTransactionDTO = OrderTransactionDTO.builder()
.orderBasicInfo(orderBasicInfo)
.orderDetail(orderDetail)
.build();
pileTransactionService.doCreateOrder(createOrderTransactionDTO);
return orderCode;
}
/**
* 校验充电桩相关的信息
*
* @param dto
*/
private void checkPileInfo(GenerateOrderDTO dto) {
// 查询充电桩状态 是否空闲 枪口是否占用
PileConnectorDetailVO pileConnector = pileService.queryPileConnectorDetail(dto.getPileSn() + dto.getConnectorCode());
if (pileConnector == null) {
log.error("checkPileInfo充电枪口为空 pileSn:{}, connectorCode:{}", dto.getPileSn(), dto.getConnectorCode());
throw new BusinessException(ReturnCodeEnum.CODE_CONNECTOR_INFO_NULL_ERROR);
}
// 判断枪口状态
if (!(StringUtils.equals(pileConnector.getConnectorStatus(), PileConnectorDataBaseStatusEnum.FREE.getValue())
|| StringUtils.equals(pileConnector.getConnectorStatus(), PileConnectorDataBaseStatusEnum.OCCUPIED_NOT_CHARGED.getValue()))) {
log.error("checkPileInfo充电枪口状态不正确当前状态为:{}", pileConnector.getConnectorStatus());
throw new BusinessException(ReturnCodeEnum.CODE_PILE_CONNECTOR_STATUS_ERROR);
}
// 查询充电桩的计费模板
BillingTemplateVO billingTemplateVO = pileBillingTemplateService.selectBillingTemplateDetailByPileSn(dto.getPileSn());
if (billingTemplateVO == null) {
throw new BusinessException(ReturnCodeEnum.CODE_BILLING_TEMPLATE_NULL_ERROR);
}
dto.setPileConnector(pileConnector);
dto.setBillingTemplate(billingTemplateVO);
}
/**
* 处理前端传的参数
* pileConnectorCode = pileSn + connectorCode
*
* @param dto
*/
public void analysisPileParameter(BasicPileDTO dto) {
if (StringUtils.isBlank(dto.getPileSn()) || StringUtils.isBlank(dto.getConnectorCode())) {
// 从pileConnectorCode解析
String pileConnectorCode = dto.getPileConnectorCode();
if (StringUtils.isNotEmpty(pileConnectorCode) && pileConnectorCode.length() == Constants.PILE_CONNECTOR_CODE_LENGTH) {
dto.setPileSn(StringUtils.substring(pileConnectorCode, 0, pileConnectorCode.length() - 2));
dto.setConnectorCode(StringUtils.substring(pileConnectorCode, pileConnectorCode.length() - 2, pileConnectorCode.length()));
} else {
throw new BusinessException(ReturnCodeEnum.CODE_DATA_LENGTH_ERROR);
}
} else {
// 说明pileSn 和 connectorCode前端传了那就校验一下长度
if (dto.getPileSn().length() != Constants.PILE_SN_LENGTH || dto.getConnectorCode().length() != Constants.CONNECTOR_CODE_LENGTH) {
throw new BusinessException(ReturnCodeEnum.CODE_DATA_LENGTH_ERROR);
}
}
}
/**
* 结算订单
* endCharging
*
* @param dto 结算订单参数
*/
public void settleOrderForWeb(SettleOrderDTO dto) {
analysisPileParameter(dto);
// 查询订单详情,验证订单中的桩编号是否正确
OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(dto.getOrderCode());
if (orderBasicInfo == null) {
throw new BusinessException(ReturnCodeEnum.CODE_QUERY_ORDER_NULL_ERROR);
}
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());
// 桩计算的消费金额
// 对比一下,是否需要退款
}
/**
* 通过会员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");
}
// 分页
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());
Date endTimeDate;
Date startTimeDate = sdf.parse(orderVO.getStartTime());
if (StringUtils.isNotBlank(orderVO.getEndTime())) {
endTimeDate = sdf.parse(orderVO.getEndTime());
} else {
endTimeDate = new Date();
}
// 计算出两个时间差
orderVO.setChargingTime(DateUtils.getDatePoor(endTimeDate, startTimeDate));
}
// 返回结果集
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_NULL_ERROR);
}
// 校验订单中的会员与操作会员是否一致
if (!StringUtils.equals(orderInfo.getMemberId(), dto.getMemberId())) {
throw new BusinessException(ReturnCodeEnum.CODE_ORDER_MEMBER_NOT_MATCH_ERROR);
}
// 发送停止指令
pileRemoteService.remoteStopCharging(orderInfo.getPileSn(), orderInfo.getConnectorCode());
log.info("订单号:{}发送停机指令成功", dto.getOrderCode());
}
/**
* 微信支付回调
*
* @param request
* @param body
* @throws Exception
*/
public void wechatPayCallback(HttpServletRequest request, WechatPayNotifyParameter body) throws Exception {
// 获取微信支付成功返回的信息
Map<String, Object> map = wechatPayService.wechatPayCallbackInfo(request, body);
String type = (String) map.get("type");
BigDecimal amount = (BigDecimal) map.get("amount"); // 微信给的amount单位是分
amount = amount.divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP); // 转换为元
String orderCode = (String) map.get("orderCode");
String memberId = (String) map.get("memberId");
if (StringUtils.equals(type, ScenarioEnum.ORDER.getValue())) { // 1-订单支付
// 支付订单成功
// orderCode = (String) map.get("orderCode");
PayOrderSuccessCallbackDTO callbackDTO = PayOrderSuccessCallbackDTO.builder()
.orderCode(orderCode)
.payAmount(amount)
.payMode(OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())
.build();
// 订单支付成功 支付回调
payOrderSuccessCallback(callbackDTO);
// 记录订单支付流水
OrderPayRecord orderPayRecord = OrderPayRecord.builder()
.orderCode(orderCode)
.payMode(OrderPayRecordEnum.WECHATPAY_PAYMENT.getValue())
.payAmount(amount)
.createBy(null)
.build();
orderPayRecordService.batchInsert(Lists.newArrayList(orderPayRecord));
} else if (StringUtils.equals(type, ScenarioEnum.BALANCE.getValue())) { // 2-充值余额
// 充值余额成功
// memberId = (String) map.get("memberId");
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);
}
// 微信支付订单 记录会员交易流水
MemberTransactionRecord record = MemberTransactionRecord.builder()
.orderCode(orderCode)
.scenarioType(type)
.memberId(memberId)
.actionType(ActionTypeEnum.FORWARD.getValue())
.payMode(PayModeEnum.PAYMENT_OF_WECHATPAY.getValue())
.amount(amount) // 单位元
.outTradeNo(String.valueOf(map.get("out_trade_no")))
.transactionId(String.valueOf(map.get("transaction_id")))
.build();
memberTransactionRecordService.insertSelective(record);
}
public void weChatRefund(WeChatRefundDTO dto) {
log.info("微信退款接口 param:{}", JSONObject.toJSONString(dto));
orderBasicInfoService.weChatRefund(dto);
}
/**
* 查询订单详情信息
* @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.setOrderStatus(orderBasicInfo.getOrderStatus());
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());
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.RealTimeMonitorData> infoList = Lists.newArrayList();
for (RealTimeMonitorData realTimeMonitorData : chargingRealTimeDataList) {
OrderDetailInfoVO.RealTimeMonitorData info = new OrderDetailInfoVO.RealTimeMonitorData();
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.setTotalElectricityAmount();
// realTimeInfo.setTotalServiceAmount();
realTimeInfo.setChargedDegree(realTimeMonitorData.getChargingDegree());
// realTimeInfo.setSOC(realTimeMonitorData.getSOC());
realTimeInfo.setChargingTime(realTimeMonitorData.getSumChargingTime());
vo.setOrderRealTimeInfo(realTimeInfo);
// 根据时间进行正序排序
infoList = infoList.stream()
.sorted(Comparator.comparing(OrderDetailInfoVO.RealTimeMonitorData::getTime))
.collect(Collectors.toList());
vo.setRealTimeMonitorDataList(infoList);
}
// 支付流水
List<OrderPayRecord> orderPayRecordList = orderPayRecordService.getOrderPayRecordList(orderCode);
if (CollectionUtils.isNotEmpty(orderPayRecordList)) {
OrderPayRecord orderPayRecord = orderPayRecordList.get(0);
List<OrderDetailInfoVO.PayRecord> payRecordList = Lists.newArrayList();
OrderDetailInfoVO.PayRecord payInfo = new OrderDetailInfoVO.PayRecord();
// 余额支付如果是由本金和赠送一起支付的,合并为一个
BigDecimal bigDecimal = orderPayRecordList.stream()
.map(OrderPayRecord::getPayAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
payInfo.setPayAmount(bigDecimal.toString());
payInfo.setPayStatus(orderBasicInfo.getPayStatus());
payInfo.setPayTime(DateUtils.formatDateTime(orderBasicInfo.getPayTime()));
String payMode = orderPayRecord.getPayMode();
if (StringUtils.equals(payMode, OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue())
|| StringUtils.equals(payMode, OrderPayRecordEnum.GIFT_BALANCE_PAYMENT.getValue())) {
// 使用余额支付
payInfo.setPayMode(OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue());
payInfo.setPayModeDesc(OrderPayModeEnum.PAYMENT_OF_BALANCE.getLabel());
} else if (StringUtils.equals(payMode, OrderPayRecordEnum.WECHATPAY_PAYMENT.getValue())){
// 使用微信支付
payInfo.setPayMode(OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue());
payInfo.setPayModeDesc(OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getLabel());
// 查微信支付回调记录
WxpayCallbackRecord wxpayCallbackRecord = wxpayCallbackRecordService.selectByOrderCode(orderCode);
if (wxpayCallbackRecord != null) {
payInfo.setOutTradeNo(wxpayCallbackRecord.getOutTradeNo());
payInfo.setTransactionId(wxpayCallbackRecord.getTransactionId());
}
} else if (StringUtils.equals(payMode, OrderPayRecordEnum.WHITELIST_PAYMENT.getValue())){
// 使用白名单支付
payInfo.setPayMode(OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue());
payInfo.setPayModeDesc(OrderPayModeEnum.PAYMENT_OF_WHITELIST.getLabel());
}
payRecordList.add(payInfo);
vo.setPayRecordList(payRecordList);
}
// 查订单明细
OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderCode);
if (orderDetail != null) {
OrderDetailInfoVO.BillingDetails billingDetails = new OrderDetailInfoVO.BillingDetails();
BeanUtils.copyBeanProp(billingDetails, orderDetail);
vo.setBillingDetails(billingDetails);
}
// 用户信息
MemberVO memberVO = memberService.getMemberInfoByMemberId(orderBasicInfo.getMemberId());
vo.setMemberInfo(memberVO);
return vo;
}
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);
if (orderBasicInfo == null) {
throw new BusinessException(ReturnCodeEnum.CODE_QUERY_ORDER_NULL_ERROR);
}
UniAppOrderVO vo = new UniAppOrderVO();
vo.setOrderCode(orderBasicInfo.getOrderCode());
vo.setPileSn(orderBasicInfo.getPileSn());
vo.setConnectorCode(orderBasicInfo.getConnectorCode());
vo.setPileConnectorCode(orderBasicInfo.getPileSn() + orderBasicInfo.getConnectorCode());
String orderStatus = orderBasicInfo.getOrderStatus();
vo.setOrderStatus(orderStatus);
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()));
// 订单状态描述
String orderStatusDescribe;
if (StringUtils.equals(orderStatus, OrderStatusEnum.NOT_START.getValue())) {
// 未启动还有两种情况 待支付 / 支付成功
String payStatus = orderBasicInfo.getPayStatus();
if (StringUtils.equals(payStatus, OrderPayStatusEnum.paid.getValue())) {
// 支付成功,未启动
orderStatusDescribe = OrderPayStatusEnum.paid.getLabel() + ", " + OrderStatusEnum.getOrderStatus(orderStatus);
} else {
// 待支付
orderStatusDescribe = OrderPayStatusEnum.unpaid.getLabel();
}
} else {
orderStatusDescribe = OrderStatusEnum.getOrderStatus(orderStatus);
}
vo.setOrderStatusDescribe(orderStatusDescribe);
// 获取充电桩枪口信息
PileConnectorDetailVO pileConnectorDetailVO = pileService.queryPileConnectorDetail(vo.getPileConnectorCode());
if (pileConnectorDetailVO != null) {
vo.setPileConnectorStatus(pileConnectorDetailVO.getConnectorStatus());
}
// 获取订单充电数据
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, BigDecimal.ROUND_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(2, BigDecimal.ROUND_HALF_UP); // 充电金额
vo.setChargingAmount(chargingAmount.toString());
BigDecimal chargingDegree = new BigDecimal(monitorData.getChargingDegree()).setScale(2, BigDecimal.ROUND_HALF_UP); // 充电度数
vo.setChargingDegree(chargingDegree.toString());
vo.setSumChargingTime(monitorData.getSumChargingTime());
vo.setTimeRemaining(monitorData.getTimeRemaining());
}
}
// monitorDataList是按照时间倒序的chargingDataList需要按照时间正序
Collections.reverse(chargingDataList);
vo.setChargingDataList(chargingDataList);
}
OrderDetail orderDetail = orderBasicInfoService.getOrderDetailByOrderCode(orderCode);
if (orderDetail != null) {
UniAppOrderVO.BillingDetails billingDetails = new UniAppOrderVO.BillingDetails();
BeanUtils.copyBeanProp(billingDetails, orderDetail);
vo.setBillingDetails(billingDetails);
}
return vo;
}
/**
* 根据订单号查询充电桩启动状态
* @param orderCode
* @return
*/
public String selectPileStarterStatus(String orderCode) {
OrderBasicInfo orderInfoByOrderCode = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
if (orderInfoByOrderCode == null) {
return Constants.ZERO;
}
List<RealTimeMonitorData> chargingRealTimeData = orderBasicInfoService.getChargingRealTimeData(orderInfoByOrderCode.getTransactionCode());
// 只有充电桩上传的实时数据中的状态为充电,才能查到实时数据列表
return CollectionUtils.isNotEmpty(chargingRealTimeData) ? Constants.ONE : Constants.ZERO;
}
public void closeStartFailedOrder(QueryOrderDTO dto) {
orderBasicInfoService.closeStartFailedOrder(dto.getStartTime(), dto.getEndTime());
}
}