mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-04-20 19:15:35 +08:00
update
This commit is contained in:
@@ -17,6 +17,7 @@ import com.jsowell.pile.vo.web.OrderListVO;
|
||||
import com.jsowell.pile.vo.web.OrderTotalDataVO;
|
||||
import com.jsowell.wxpay.dto.WeChatRefundDTO;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -277,4 +278,15 @@ public interface IOrderBasicInfoService {
|
||||
* @return
|
||||
*/
|
||||
List<MerchantOrderInfoVO> getMerchantOrderInfoList(QueryOrderDTO dto);
|
||||
|
||||
/**
|
||||
* 生成订单逻辑
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
String generateOrder(GenerateOrderDTO dto) throws ParseException;
|
||||
|
||||
void analysisPileParameter(BasicPileDTO dto);
|
||||
|
||||
Map<String, Object> payOrder(PayOrderDTO dto) throws Exception;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
package com.jsowell.pile.service;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
|
||||
import com.jsowell.common.exception.BusinessException;
|
||||
import com.jsowell.common.util.StringUtils;
|
||||
import com.jsowell.pile.domain.PileBillingRelation;
|
||||
import com.jsowell.pile.domain.PileBillingTemplate;
|
||||
import com.jsowell.pile.domain.PileFirmwareInfo;
|
||||
import com.jsowell.pile.domain.ykcCommond.*;
|
||||
import com.jsowell.pile.dto.PublishBillingTemplateDTO;
|
||||
import com.jsowell.pile.dto.RemoteAccountBalanceUpdateDTO;
|
||||
import com.jsowell.pile.dto.UpdateFirmwareDTO;
|
||||
import com.jsowell.pile.vo.web.BillingTemplateVO;
|
||||
import com.jsowell.pile.vo.web.PileDetailVO;
|
||||
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 java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class PileRemoteService {
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
private IPileBillingTemplateService pileBillingTemplateService;
|
||||
|
||||
@Autowired
|
||||
private IPileBasicInfoService pileBasicInfoService;
|
||||
|
||||
@Autowired
|
||||
private YKCPushCommandService ykcPushCommandService;
|
||||
|
||||
@Autowired
|
||||
private IPileFirmwareInfoService pileFirmwareInfoService;
|
||||
|
||||
|
||||
/**
|
||||
* 获取充电桩实时数据信息
|
||||
*
|
||||
* @param pileSn 充电桩sn
|
||||
* @param connectorCode 枪口号
|
||||
*/
|
||||
public void getRealTimeMonitorData(String pileSn, String connectorCode) {
|
||||
if (StringUtils.isNotEmpty(pileSn) || StringUtils.isNotEmpty(connectorCode)) {
|
||||
GetRealTimeMonitorDataCommand command = GetRealTimeMonitorDataCommand.builder()
|
||||
.pileSn(pileSn)
|
||||
.connectorCode(connectorCode)
|
||||
.build();
|
||||
ykcPushCommandService.pushGetRealTimeMonitorDataCommand(command);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 重启指令
|
||||
*
|
||||
* @param pileSn 充电桩sn
|
||||
*/
|
||||
public void reboot(String pileSn) {
|
||||
RebootCommand command = RebootCommand.builder().pileSn(pileSn).build();
|
||||
ykcPushCommandService.pushRebootCommand(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程启动充电 0x34
|
||||
*
|
||||
* @param pileSn 充电桩sn
|
||||
*/
|
||||
public void remoteStartCharging(String pileSn, String connectorCode, String transactionCode, BigDecimal accountBalance) {
|
||||
// String s = "550314127823050120180619144446808800000000000101000000100000057300000000D14B0A54A0860100";
|
||||
if (StringUtils.isEmpty(pileSn) || StringUtils.isEmpty(connectorCode)) {
|
||||
log.warn("远程启动充电, 充电桩编号和枪口号不能为空");
|
||||
return;
|
||||
}
|
||||
log.info("=====平台下发指令=====: 远程启动充电, 桩号:{}, 枪口号:{}", pileSn, connectorCode);
|
||||
StartChargingCommand startChargingCommand = StartChargingCommand.builder()
|
||||
.pileSn(pileSn)
|
||||
.connectorCode(connectorCode)
|
||||
.transactionCode(transactionCode)
|
||||
.chargeAmount(accountBalance)
|
||||
.build();
|
||||
ykcPushCommandService.pushStartChargingCommand(startChargingCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程停止充电
|
||||
*/
|
||||
public void remoteStopCharging(String pileSn, String connectorCode) {
|
||||
StopChargingCommand command = StopChargingCommand.builder()
|
||||
.pileSn(pileSn)
|
||||
.connectorCode(connectorCode)
|
||||
.build();
|
||||
ykcPushCommandService.pushStopChargingCommand(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下发充电桩二维码
|
||||
*
|
||||
* @param pileSn 充电桩sn
|
||||
*/
|
||||
public void issueQRCode(String pileSn) {
|
||||
issueQRCode(pileSn, null);
|
||||
}
|
||||
|
||||
public void issueQRCode(String pileSn, String qrcodePrefix) {
|
||||
IssueQRCodeCommand command = IssueQRCodeCommand.builder().pileSn(pileSn).build();
|
||||
if (StringUtils.isNotBlank(qrcodePrefix)) {
|
||||
command.setQrcodePrefix(qrcodePrefix);
|
||||
}
|
||||
ykcPushCommandService.pushIssueQRCodeCommand(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 充电桩对时
|
||||
*
|
||||
* @param pileSn 充电桩sn
|
||||
*/
|
||||
public void proofreadTime(String pileSn) {
|
||||
|
||||
ProofreadTimeCommand command = ProofreadTimeCommand.builder().pileSn(pileSn).build();
|
||||
ykcPushCommandService.pushProofreadTimeCommand(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下发充电桩计费模型
|
||||
*/
|
||||
public void publishPileBillingTemplate(String pileSn, BillingTemplateVO billingTemplateVO) {
|
||||
|
||||
PublishPileBillingTemplateCommand command = PublishPileBillingTemplateCommand.builder()
|
||||
.billingTemplateVO(billingTemplateVO)
|
||||
.pileSn(pileSn)
|
||||
.build();
|
||||
ykcPushCommandService.pushPublishPileBillingTemplate(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下发计费模板
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
public boolean publishBillingTemplate(PublishBillingTemplateDTO dto) {
|
||||
|
||||
// 获取计费模板信息
|
||||
BillingTemplateVO billingTemplateVO = pileBillingTemplateService.selectBillingTemplateByTemplateId(dto.getTemplateId());
|
||||
if (billingTemplateVO == null) {
|
||||
log.warn("获取计费模板信息, 通过模板id:{}查询计费模板为null", dto.getTemplateId());
|
||||
return false;
|
||||
}
|
||||
// 更新计费模板的发布时间
|
||||
PileBillingTemplate pileBillingTemplate = new PileBillingTemplate();
|
||||
pileBillingTemplate.setId(Long.valueOf(billingTemplateVO.getTemplateId()));
|
||||
pileBillingTemplate.setPublishTime(new Date());
|
||||
pileBillingTemplateService.updatePileBillingTemplate(pileBillingTemplate);
|
||||
|
||||
// 获取到站点下所有的桩
|
||||
List<PileDetailVO> pileList = pileBasicInfoService.selectPileListByStationIds(Lists.newArrayList(Long.valueOf(dto.getStationId())));
|
||||
if (CollectionUtils.isEmpty(pileList)) {
|
||||
log.warn("获取到站点下所有的桩, 通过站点id:{}查询充电桩列表为空", dto.getStationId());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 保存计费模板和桩的关系
|
||||
List<PileBillingRelation> relationList = Lists.newArrayList();
|
||||
for (PileDetailVO pileInfoVO : pileList) {
|
||||
// push
|
||||
publishPileBillingTemplate(pileInfoVO.getPileSn(), billingTemplateVO);
|
||||
|
||||
// 入库
|
||||
relationList.add(PileBillingRelation.builder()
|
||||
.pileSn(pileInfoVO.getPileSn())
|
||||
.billingTemplateCode(billingTemplateVO.getTemplateCode())
|
||||
.stationId(dto.getStationId())
|
||||
.build());
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(relationList)) {
|
||||
pileBillingTemplateService.insertPileBillingRelation(relationList);
|
||||
}
|
||||
|
||||
// 修改计费模板状态
|
||||
pileBillingTemplateService.changeStationTemplate(dto.getStationId(), dto.getTemplateId());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程更新
|
||||
*/
|
||||
public void updateFirmware(UpdateFirmwareDTO dto) {
|
||||
if (StringUtils.isBlank(dto.getFirmwareId())) {
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
|
||||
}
|
||||
PileFirmwareInfo pileFirmwareInfo = pileFirmwareInfoService.selectPileFirmwareInfoById(Long.valueOf(dto.getFirmwareId()));
|
||||
if (pileFirmwareInfo == null) {
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_FIRMWARE_NOT_FOUND_ERROR);
|
||||
}
|
||||
UpdateFirmwareCommand command = UpdateFirmwareCommand.builder()
|
||||
.pileSnList(dto.getPileSns())
|
||||
.filePath(pileFirmwareInfo.getFilePath())
|
||||
.build();
|
||||
ykcPushCommandService.pushUpdateFileCommand(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程账户余额更新
|
||||
*/
|
||||
public void remoteAccountBalanceUpdate(RemoteAccountBalanceUpdateDTO dto) {
|
||||
RemoteAccountBalanceUpdateCommand command = RemoteAccountBalanceUpdateCommand.builder()
|
||||
.pileSn(dto.getPileSn())
|
||||
.connectorCode(dto.getConnectorCode())
|
||||
.accountBalance(dto.getAccountBalance())
|
||||
|
||||
.build();
|
||||
if (StringUtils.isNotBlank(dto.getLogicCard())) {
|
||||
command.setLogicCard(dto.getLogicCard());
|
||||
}
|
||||
ykcPushCommandService.pushAccountBalanceUpdateCommand(command);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,16 +2,21 @@ package com.jsowell.pile.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.alibaba.fastjson2.TypeReference;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.huifu.adapay.core.exception.BaseAdaPayException;
|
||||
import com.huifu.adapay.model.Payment;
|
||||
import com.huifu.adapay.model.Refund;
|
||||
import com.jsowell.adapay.common.CreateAdaPaymentParam;
|
||||
import com.jsowell.common.constant.CacheConstants;
|
||||
import com.jsowell.common.constant.Constants;
|
||||
import com.jsowell.common.core.domain.entity.SysDictData;
|
||||
import com.jsowell.common.core.domain.vo.AuthorizedDeptVO;
|
||||
import com.jsowell.common.core.domain.ykc.RealTimeMonitorData;
|
||||
import com.jsowell.common.core.domain.ykc.TransactionRecordsData;
|
||||
@@ -34,10 +39,7 @@ import com.jsowell.pile.vo.base.OrderAmountDetailVO;
|
||||
import com.jsowell.pile.vo.base.OrderPeriodAmountVO;
|
||||
import com.jsowell.pile.vo.base.PileInfoVO;
|
||||
import com.jsowell.pile.vo.lianlian.AccumulativeInfoVO;
|
||||
import com.jsowell.pile.vo.uniapp.MemberVO;
|
||||
import com.jsowell.pile.vo.uniapp.OrderVO;
|
||||
import com.jsowell.pile.vo.uniapp.PersonPileConnectorSumInfoVO;
|
||||
import com.jsowell.pile.vo.uniapp.SendMessageVO;
|
||||
import com.jsowell.pile.vo.uniapp.*;
|
||||
import com.jsowell.pile.vo.web.*;
|
||||
import com.jsowell.wxpay.common.WeChatPayParameter;
|
||||
import com.jsowell.wxpay.dto.WeChatRefundDTO;
|
||||
@@ -50,11 +52,13 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cglib.beans.BeanMap;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.ParseException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
@@ -84,6 +88,15 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
@Value("${adapay.appId}")
|
||||
private String ADAPAY_APP_ID;
|
||||
|
||||
@Value("${adapay.callback}")
|
||||
private String ADAPAY_CALLBACK_URL;
|
||||
|
||||
@Autowired
|
||||
private WxAppletRemoteService wxAppletRemoteService;
|
||||
|
||||
@Autowired
|
||||
private IOrderPayRecordService orderPayRecordService;
|
||||
|
||||
@@ -105,9 +118,6 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
|
||||
@Autowired
|
||||
private TransactionService pileTransactionService;
|
||||
|
||||
@Autowired
|
||||
private WxAppletRemoteService wxAppletRemoteService;
|
||||
|
||||
@Autowired
|
||||
private IPileBasicInfoService pileBasicInfoService;
|
||||
|
||||
@@ -146,6 +156,9 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
|
||||
|
||||
@Autowired
|
||||
private IAdapayMemberAccountService adapayMemberAccountService;
|
||||
|
||||
@Autowired
|
||||
private PileRemoteService pileRemoteService;
|
||||
/**
|
||||
* 条件查询订单基本信息
|
||||
*
|
||||
@@ -1996,4 +2009,467 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService {
|
||||
PageUtils.startPage(pageNum, pageSize);
|
||||
return orderBasicInfoMapper.getMerchantOrderInfoList(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateOrder(GenerateOrderDTO dto) throws ParseException {
|
||||
logger.info("generateOrder param:{}", JSONObject.toJSONString(dto));
|
||||
// 处理前端传的参数
|
||||
analysisPileParameter(dto);
|
||||
|
||||
// 校验充电桩相关的信息
|
||||
checkPileInfo(dto);
|
||||
|
||||
// 保存订单到数据库 saveOrder2Database
|
||||
String orderCode = saveOrder2Database(dto);
|
||||
|
||||
return orderCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理前端传的参数
|
||||
* pileConnectorCode = pileSn + connectorCode
|
||||
*
|
||||
* @param dto
|
||||
*/
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付订单
|
||||
* @param dto
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> payOrder(PayOrderDTO dto) throws Exception {
|
||||
OrderBasicInfo orderInfo = this.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);
|
||||
}
|
||||
Map<String, Object> resultMap = Maps.newHashMap();
|
||||
if (StringUtils.equals(dto.getPayMode(), OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue())) {
|
||||
// 余额支付
|
||||
balancePayOrder(dto);
|
||||
} else if (StringUtils.equals(dto.getPayMode(), OrderPayModeEnum.PAYMENT_OF_WECHATPAY.getValue())) {
|
||||
// 微信支付
|
||||
dto.setOrderBasicInfo(orderInfo);
|
||||
|
||||
// 从字典中获取使用汇付支付的站点
|
||||
List<SysDictData> adapay_station = DictUtils.getDictCache("adapay_station");
|
||||
List<String> stationIdList = Lists.newArrayList();
|
||||
if (CollectionUtils.isNotEmpty(adapay_station)) {
|
||||
for (SysDictData sysDictData : adapay_station) {
|
||||
stationIdList.add(sysDictData.getDictValue());
|
||||
}
|
||||
}
|
||||
Map<String, Object> weixinMap;
|
||||
if (stationIdList.contains(orderInfo.getStationId())) {
|
||||
logger.info("该站点:{}在字典中配置了使用汇付支付", orderInfo.getStationId());
|
||||
weixinMap = adapayPayOrder(dto);
|
||||
} else {
|
||||
logger.info("该站点:{}使用微信支付", orderInfo.getStationId());
|
||||
weixinMap = wechatPayOrder(dto);
|
||||
}
|
||||
|
||||
// 返回微信支付参数
|
||||
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())) { // 白名单支付
|
||||
// 白名单支付可以直接调支付回调方法
|
||||
dto.setPayAmount(new BigDecimal("500"));
|
||||
whiteListPayOrder(dto);
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 白名单支付订单逻辑
|
||||
* @param dto
|
||||
*/
|
||||
private void whiteListPayOrder(PayOrderDTO dto) {
|
||||
String orderCode = dto.getOrderCode();
|
||||
BigDecimal payAmount = dto.getPayAmount();
|
||||
String payMode = dto.getPayMode();
|
||||
PayOrderSuccessCallbackDTO callbackDTO = PayOrderSuccessCallbackDTO.builder()
|
||||
.orderCode(orderCode)
|
||||
.payAmount(payAmount)
|
||||
.payMode(payMode)
|
||||
.build();
|
||||
payOrderSuccessCallback(callbackDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单支付成功 支付回调
|
||||
* 支付成功后掉用这个方法
|
||||
* 1. 修改订单支付状态
|
||||
* 2. 发送启动充电指令
|
||||
*/
|
||||
private void payOrderSuccessCallback(PayOrderSuccessCallbackDTO dto) {
|
||||
OrderBasicInfo orderInfo = this.getOrderInfoByOrderCode(dto.getOrderCode());
|
||||
BigDecimal payAmount = dto.getPayAmount();
|
||||
|
||||
// 修改订单
|
||||
orderInfo.setPayMode(dto.getPayMode());
|
||||
orderInfo.setPayStatus(Constants.ONE);
|
||||
orderInfo.setPayAmount(payAmount);
|
||||
orderInfo.setPayTime(new Date());
|
||||
this.updateOrderBasicInfo(orderInfo);
|
||||
|
||||
if (StringUtils.equals(orderInfo.getStartType(), StartTypeEnum.NOW.getValue())) { // 立即启动充电
|
||||
String pileSn = orderInfo.getPileSn();
|
||||
// 发送启动充电指令前,再次下发计费模板
|
||||
BillingTemplateVO billingTemplateVO = pileBillingTemplateService.selectBillingTemplateDetailByPileSn(pileSn);
|
||||
if (billingTemplateVO != null) {
|
||||
pileRemoteService.publishPileBillingTemplate(pileSn, billingTemplateVO);
|
||||
}
|
||||
// 发送启动指令
|
||||
pileRemoteService.remoteStartCharging(pileSn, orderInfo.getConnectorCode(), orderInfo.getTransactionCode(), orderInfo.getPayAmount());
|
||||
} else { // 预约充电
|
||||
// 修改枪口状态为 占用预约
|
||||
|
||||
// 下发修改充电桩设置指令
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付订单逻辑 获取支付参数
|
||||
* @param dto
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private Map<String, Object> wechatPayOrder(PayOrderDTO dto) throws Exception {
|
||||
// 相同参数重复请求,返回同一个支付对象
|
||||
String redisKey = CacheConstants.WECHAT_PAY_ORDER_PARAM + dto.getOrderCode();
|
||||
Map<String, Object> cacheObject = redisCache.getCacheObject(redisKey);
|
||||
if (cacheObject != null) {
|
||||
return cacheObject;
|
||||
}
|
||||
|
||||
OrderBasicInfo orderInfo = dto.getOrderBasicInfo();
|
||||
if (orderInfo == null) {
|
||||
orderInfo = this.getOrderInfoByOrderCode(dto.getOrderCode());
|
||||
}
|
||||
String openId = wxAppletRemoteService.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> payV3 = wechatPayService.weixinPayV3(weixinPayDTO);
|
||||
if (payV3 != null) {
|
||||
// 表示已经获取到支付参数了,后续再有支付请求就拒绝
|
||||
redisCache.setCacheObject(redisKey, payV3, 15, TimeUnit.MINUTES);
|
||||
}
|
||||
return payV3;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用汇付支付
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
private Map<String, Object> adapayPayOrder(PayOrderDTO dto) {
|
||||
logger.info("===============使用汇付支付");
|
||||
// 相同参数重复请求,返回同一个支付对象
|
||||
String redisKey = CacheConstants.ADAPAY_ORDER_PARAM + dto.getOrderCode();
|
||||
Map<String, Object> cacheObject = redisCache.getCacheObject(redisKey);
|
||||
if (cacheObject != null) {
|
||||
return cacheObject;
|
||||
}
|
||||
|
||||
OrderBasicInfo orderInfo = dto.getOrderBasicInfo();
|
||||
if (orderInfo == null) {
|
||||
// 订单为空重新查询
|
||||
orderInfo = this.getOrderInfoByOrderCode(dto.getOrderCode());
|
||||
}
|
||||
// 获取openId
|
||||
String openId = wxAppletRemoteService.getOpenIdByCode(dto.getCode());
|
||||
if (StringUtils.isBlank(openId)) {
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_GET_OPEN_ID_BY_CODE_ERROR);
|
||||
}
|
||||
|
||||
// 封装对象
|
||||
String amount = AdapayUtil.formatAmount(dto.getPayAmount()); // 用户支付金额
|
||||
CreateAdaPaymentParam createAdaPaymentParam = new CreateAdaPaymentParam();
|
||||
createAdaPaymentParam.setOrder_no(orderInfo.getOrderCode());
|
||||
createAdaPaymentParam.setPay_amt(amount);
|
||||
createAdaPaymentParam.setApp_id(ADAPAY_APP_ID);
|
||||
createAdaPaymentParam.setPay_channel("wx_lite"); // todo 如果以后有支付宝等别的渠道,这里需要做修改,判断是什么渠道的请求
|
||||
createAdaPaymentParam.setGoods_title("充电费用");
|
||||
createAdaPaymentParam.setGoods_desc("充电桩预付款金额"); // 这个字段是微信支付凭证的商品名
|
||||
Map<String, String> map = Maps.newHashMap();
|
||||
map.put("type", ScenarioEnum.ORDER.getValue());
|
||||
map.put("orderCode", dto.getOrderCode());
|
||||
createAdaPaymentParam.setDescription(JSON.toJSONString(map));
|
||||
//异步通知地址,url为http/https路径,服务器POST回调,URL 上请勿附带参数
|
||||
createAdaPaymentParam.setNotify_url(ADAPAY_CALLBACK_URL);
|
||||
createAdaPaymentParam.setExpend(JSONObject.toJSONString( ImmutableMap.of("open_id", openId)));
|
||||
|
||||
// 分账对象信息
|
||||
// String adapayMemberId = adapayMemberAccountService.selectAdapayMemberIdByStationId(orderInfo.getStationId());
|
||||
// if (StringUtils.isNotBlank(adapayMemberId)) {
|
||||
// JSONObject jsonObject = new JSONObject();
|
||||
// jsonObject.put("member_id", adapayMemberId);
|
||||
// jsonObject.put("amount", amount);
|
||||
// jsonObject.put("fee_flag", Constants.Y);
|
||||
//
|
||||
// // 分账对象信息列表,最多仅支持7个分账方,json 数组形式
|
||||
// JSONArray jsonArray = new JSONArray();
|
||||
// jsonArray.add(jsonObject);
|
||||
// createAdaPaymentParam.setDiv_members(jsonArray.toString());
|
||||
// }
|
||||
|
||||
// 延时分账
|
||||
createAdaPaymentParam.setPay_mode("delay");
|
||||
try {
|
||||
logger.info("创建汇付支付参数:{}", JSONObject.toJSONString(createAdaPaymentParam));
|
||||
Map<String, Object> response = Payment.create(BeanMap.create(createAdaPaymentParam));
|
||||
if (response != null && !response.isEmpty()) {
|
||||
JSONObject expend = JSONObject.parseObject(response.get("expend").toString());
|
||||
JSONObject pay_info = expend.getJSONObject("pay_info");
|
||||
Map<String, Object> resultMap = JSONObject.parseObject(pay_info.toJSONString(), new TypeReference<Map<String, Object>>() {
|
||||
});
|
||||
if (resultMap != null) {
|
||||
// 表示已经获取到支付参数了,后续再有支付请求就拒绝
|
||||
redisCache.setCacheObject(redisKey, resultMap, 15, TimeUnit.MINUTES);
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
} catch (BaseAdaPayException e) {
|
||||
logger.error("汇付-获取支付对象发生异常", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额支付订单逻辑
|
||||
* @param dto
|
||||
*/
|
||||
private void balancePayOrder(PayOrderDTO dto) {
|
||||
// 记录支付流水
|
||||
List<OrderPayRecord> payRecordList = Lists.newArrayList();
|
||||
String orderCode = dto.getOrderCode();
|
||||
BigDecimal chargeAmount = dto.getPayAmount();
|
||||
// 查询该会员的余额
|
||||
MemberVO memberVO = memberBasicInfoService.queryMemberInfoByMemberId(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(orderCode)
|
||||
.payMode(OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue())
|
||||
.payAmount(principalPay)
|
||||
.createBy(dto.getMemberId())
|
||||
.build());
|
||||
}
|
||||
if (giftPay != null) {
|
||||
payRecordList.add(OrderPayRecord.builder()
|
||||
.orderCode(orderCode)
|
||||
.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())
|
||||
.paymentInstitutions(PaymentInstitutionsEnum.LOCAL_ACCOUNTS.getValue())
|
||||
.amount(dto.getPayAmount()) // 单位元
|
||||
.build();
|
||||
memberTransactionRecordService.insertSelective(record);
|
||||
|
||||
// 订单支付流水入库
|
||||
if (CollectionUtils.isNotEmpty(payRecordList)) {
|
||||
orderPayRecordService.batchInsert(payRecordList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验充电桩相关的信息
|
||||
*
|
||||
* @param dto
|
||||
*/
|
||||
private void checkPileInfo(GenerateOrderDTO dto) {
|
||||
// 查询充电桩状态 是否空闲 枪口是否占用
|
||||
PileConnectorDetailVO pileConnector = pileBasicInfoService.queryPileConnectorDetail(dto.getPileSn() + dto.getConnectorCode());
|
||||
if (pileConnector == null) {
|
||||
logger.error("checkPileInfo充电枪口为空 pileSn:{}, connectorCode:{}", dto.getPileSn(), dto.getConnectorCode());
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_CONNECTOR_INFO_NULL_ERROR);
|
||||
}
|
||||
|
||||
// 查询站点状态
|
||||
PileStationVO stationInfo = pileStationInfoService.getStationInfo(pileConnector.getStationId());
|
||||
if (stationInfo == null || StringUtils.equals(stationInfo.getOpenFlag(), Constants.ZERO)) {
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_STATION_IS_NOT_OPEN);
|
||||
}
|
||||
|
||||
// 判断枪口状态
|
||||
if (!(StringUtils.equals(pileConnector.getConnectorStatus(), PileConnectorDataBaseStatusEnum.FREE.getValue())
|
||||
|| StringUtils.equals(pileConnector.getConnectorStatus(), PileConnectorDataBaseStatusEnum.OCCUPIED_NOT_CHARGED.getValue()))) {
|
||||
logger.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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存订单信息到数据库
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
private String saveOrder2Database(GenerateOrderDTO dto) throws ParseException {
|
||||
String orderCode = IdUtils.getOrderCode();
|
||||
String transactionCode = IdUtils.generateTransactionCode(dto.getPileSn(), dto.getConnectorCode());
|
||||
|
||||
if (StringUtils.isBlank(dto.getStartType())) {
|
||||
dto.setStartType(StartTypeEnum.NOW.getValue());
|
||||
}
|
||||
|
||||
String stationId = dto.getPileConnector().getStationId();
|
||||
// 查询站点信息
|
||||
PileStationInfo pileStationInfo = pileStationInfoService.selectPileStationInfoById(Long.valueOf(stationId));
|
||||
String merchantId = pileStationInfo != null ? String.valueOf(pileStationInfo.getMerchantId()) : "";
|
||||
|
||||
// 订单基本信息
|
||||
OrderBasicInfo orderBasicInfo = OrderBasicInfo.builder()
|
||||
.orderCode(orderCode)
|
||||
.transactionCode(transactionCode)
|
||||
.orderStatus(OrderStatusEnum.NOT_START.getValue())
|
||||
.memberId(dto.getMemberId())
|
||||
.stationId(stationId)
|
||||
.merchantId(merchantId)
|
||||
.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)
|
||||
.virtualAmount(BigDecimal.ZERO)
|
||||
.settleAmount(BigDecimal.ZERO)
|
||||
.startType(dto.getStartType())
|
||||
.build();
|
||||
if (StringUtils.equals(dto.getStartType(), StartTypeEnum.APPOINTMENT.getValue())) {
|
||||
orderBasicInfo.setAppointmentTime(DateUtils.parseDate(dto.getAppointmentTime(), DateUtils.YYYY_MM_DD_HH_MM_SS));
|
||||
}
|
||||
|
||||
// 订单详情
|
||||
BillingTemplateVO billingTemplate = dto.getBillingTemplate();
|
||||
logger.info("订单使用的计费模板-orderCode:{}, billingTemplate:{}", orderCode, JSONObject.toJSONString(billingTemplate));
|
||||
BigDecimal sharpElectricityPrice = billingTemplate.getSharpElectricityPrice() != null ? billingTemplate.getSharpElectricityPrice() : BigDecimal.ZERO;
|
||||
BigDecimal sharpServicePrice = billingTemplate.getSharpServicePrice() != null ? billingTemplate.getSharpServicePrice() : BigDecimal.ZERO;
|
||||
BigDecimal peakElectricityPrice = billingTemplate.getPeakElectricityPrice() != null ? billingTemplate.getPeakElectricityPrice() : BigDecimal.ZERO;
|
||||
BigDecimal peakServicePrice = billingTemplate.getPeakServicePrice() != null ? billingTemplate.getPeakServicePrice() : BigDecimal.ZERO;
|
||||
BigDecimal flatElectricityPrice = billingTemplate.getFlatElectricityPrice() != null ? billingTemplate.getFlatElectricityPrice() : BigDecimal.ZERO;
|
||||
BigDecimal flatServicePrice = billingTemplate.getFlatServicePrice() != null ? billingTemplate.getFlatServicePrice() : BigDecimal.ZERO;
|
||||
BigDecimal valleyElectricityPrice = billingTemplate.getValleyElectricityPrice() != null ? billingTemplate.getValleyElectricityPrice() : BigDecimal.ZERO;
|
||||
BigDecimal valleyServicePrice = billingTemplate.getValleyServicePrice() != null ? billingTemplate.getValleyServicePrice() : BigDecimal.ZERO;
|
||||
|
||||
OrderDetail orderDetail = OrderDetail.builder()
|
||||
.orderCode(orderCode)
|
||||
.sharpPrice(sharpElectricityPrice.add(sharpServicePrice))
|
||||
.sharpElectricityPrice(sharpElectricityPrice)
|
||||
.sharpServicePrice(sharpServicePrice)
|
||||
.peakPrice(peakElectricityPrice.add(peakServicePrice))
|
||||
.peakElectricityPrice(peakElectricityPrice)
|
||||
.peakServicePrice(peakServicePrice)
|
||||
.flatPrice(flatElectricityPrice.add(flatServicePrice))
|
||||
.flatElectricityPrice(flatElectricityPrice)
|
||||
.flatServicePrice(flatServicePrice)
|
||||
.valleyPrice(valleyElectricityPrice.add(valleyServicePrice))
|
||||
.valleyElectricityPrice(valleyElectricityPrice)
|
||||
.valleyServicePrice(valleyServicePrice)
|
||||
.build();
|
||||
|
||||
OrderTransactionDTO createOrderTransactionDTO = OrderTransactionDTO.builder()
|
||||
.orderBasicInfo(orderBasicInfo)
|
||||
.orderDetail(orderDetail)
|
||||
.build();
|
||||
pileTransactionService.doCreateOrder(createOrderTransactionDTO);
|
||||
return orderCode;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user