个人桩启动充电

This commit is contained in:
Guoqs
2024-06-21 11:16:53 +08:00
parent 58710aedf3
commit 1bd051e73f
8 changed files with 152 additions and 207 deletions

View File

@@ -3,7 +3,8 @@ package com.jsowell.pile.dto;
import lombok.Data;
@Data
public class StartPersonPileDTO {
public class StartPersonPileDTO extends BaseDTO {
private String appId;
/**
* 充电桩枪口编号

View File

@@ -133,7 +133,21 @@ public interface PileMerchantInfoService {
*/
List<String> getDeptIdsByAppId(String appId);
/**
// @Override
// public String getDelayModeByWechatAppId(String wechatAppId) {
// PileMerchantInfo merchant = getFirstLevelMerchantByAppId(wechatAppId);
// if (merchant != null) {
// String delayMode = merchant.getDelayMode();
// if (StringUtils.equals(delayMode, Constants.ONE)) {
// return Constants.ADAPAY_PAY_MODE_DELAY;
// }
// }
// return null;
// }
String getDelayModeByAppIdAndRequestSource(String appId, String requestSource);
/**
* 通过wechatAppId查询一级运营商的延时支付模式配置
* @param wechatAppId 微信小程序id
* @return 延时分账模式0-不延时1-延时分账)

View File

@@ -5,6 +5,7 @@ import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.domain.entity.SysDept;
import com.jsowell.common.core.domain.entity.SysUser;
import com.jsowell.common.core.domain.vo.AuthorizedDeptVO;
import com.jsowell.common.enums.adapay.AdapayPayChannelEnum;
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.DateUtils;
@@ -500,6 +501,19 @@ public class PileMerchantInfoServiceImpl implements PileMerchantInfoService {
// return null;
// }
@Override
public String getDelayModeByAppIdAndRequestSource(String appId, String requestSource) {
String delayMode = "";
if (StringUtils.equals(requestSource, AdapayPayChannelEnum.WX_LITE.getValue())) {
delayMode = getDelayModeByWechatAppId(appId);
} else if (StringUtils.equals(requestSource, AdapayPayChannelEnum.ALIPAY_LITE.getValue())) {
delayMode = getDelayModeByAlipayAppId(appId);
} else {
throw new BusinessException("", "未知来源");
}
return delayMode;
}
/**
* 通过wechatAppId查询一级运营商的延时支付模式配置
* @param wechatAppId 微信小程序id

View File

@@ -20,6 +20,8 @@ import com.jsowell.pile.dto.*;
import com.jsowell.pile.service.*;
import com.jsowell.pile.transaction.service.TransactionService;
import com.jsowell.pile.vo.uniapp.MemberVO;
import com.jsowell.pile.vo.uniapp.PersonalPileInfoVO;
import com.jsowell.pile.vo.uniapp.PileConnectorDetailVO;
import com.jsowell.pile.vo.web.*;
import com.jsowell.wxpay.dto.WechatSendMsgDTO;
import com.jsowell.wxpay.service.WxAppletRemoteService;
@@ -37,6 +39,7 @@ import java.text.ParseException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 描述订单逻辑
@@ -110,22 +113,6 @@ public abstract class AbstractProgramLogic implements InitializingBean {
@Autowired
protected RedisCache redisCache;
/**
* 生成订单编号
*
* @return
*/
protected String generateNewOrderCode() {
while (true) {
String orderCode = "C" + IdUtils.getOrderCode();
// 通过orderCode查询是否已经存在
OrderBasicInfo orderBasicInfo = orderBasicInfoService.getOrderInfoByOrderCode(orderCode);
if (orderBasicInfo == null) {
return orderCode;
}
}
}
/**
* 生成订单
*/
@@ -133,11 +120,19 @@ public abstract class AbstractProgramLogic implements InitializingBean {
/**
* 支付订单
*
* @param dto
* @return
*/
public abstract Map<String, Object> payOrder(PayOrderDTO dto);
/**
* 个人桩启动充电
* @param dto
* @return
*/
public abstract String startPersonalPileCharging(StartPersonPileDTO dto);
/**
* 订单结算/结算订单逻辑/订单结算逻辑
*/
@@ -145,6 +140,7 @@ public abstract class AbstractProgramLogic implements InitializingBean {
/**
* 第三方平台结算订单(目前给华为用)
*
* @param data
* @param orderBasicInfo
*/
@@ -162,6 +158,7 @@ public abstract class AbstractProgramLogic implements InitializingBean {
/**
* 余额退款
*
* @param dto
*/
public abstract void refundBalance(ApplyRefundDTO dto);
@@ -171,115 +168,6 @@ public abstract class AbstractProgramLogic implements InitializingBean {
*/
public abstract List<OrderDetailInfoVO.OrderRefundInfo> getOrderRefundInfoList(OrderBasicInfo orderBasicInfo);
/**
* 生成订单 返回交易流水号
*
* @param dto
* @return
*/
// protected Map<String, Object> generateOrderByCard(GenerateOrderDTO dto) throws Exception {
// logger.info("充电桩主动申请启动充电生成订单 param:{}", JSON.toJSONString(dto));
// BigDecimal accountBalance;
// String payMode;
// // 判断当前用户是否为平台测试员
// PlatformTesterVO platformTesterVO = memberBasicInfoService.selectPlatformTesterStatus(dto.getMemberId());
// PileBasicInfo pileBasicInfo = pileBasicInfoService.selectPileBasicInfoBySN(dto.getPileSn());
// PileStationWhitelist pileStationWhitelist = pileStationWhitelistService.queryWhitelistByMemberId(String.valueOf(pileBasicInfo.getStationId()), dto.getMemberId());
//
// // 运营商id
// String merchantId = pileBasicInfo.getMerchantId() + "";
//
// if (platformTesterVO != null && StringUtils.equals(Constants.ONE, platformTesterVO.getStatus())) {
// // 是平台测试员
// accountBalance = Constants.WHITELIST_DEFAULT_AMOUNT;
// payMode = OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue();
// } else if (pileStationWhitelist != null) {
// // 站点白名单
// accountBalance = Constants.WHITELIST_DEFAULT_AMOUNT;
// payMode = OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue();
// } else {
// // 通过memberId获取账户余额
// MemberVO memberVO = memberBasicInfoService.queryMemberInfoByMemberId(dto.getMemberId(), merchantId);
// if (memberVO == null) {
// throw new BusinessException(ReturnCodeEnum.CODE_GET_MEMBER_ACCOUNT_AMOUNT_ERROR);
// }
// accountBalance = memberVO.getTotalAccountAmount();
// if (accountBalance.compareTo(BigDecimal.ZERO) <= 0) {
// logger.info("充电桩主动申请启动充电生成订单 余额不足, memberId:{}, MemberVO:{}", dto.getMemberId(), JSON.toJSONString(memberVO));
// throw new BusinessException(ReturnCodeEnum.CODE_BALANCE_IS_INSUFFICIENT);
// }
// BigDecimal defaultAmount = Constants.BALANCE_PAY_MAX_AMOUNT;
// if (accountBalance.compareTo(defaultAmount) > 0) {
// accountBalance = defaultAmount;
// }
// payMode = OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue();
// // accountBalance = memberVO.getTotalAccountAmount();
// // dto.setChargeAmount(totalAccountAmount); // 充电金额
// // dto.setPayMode(OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue()); // 1-余额支付
// }
// dto.setChargeAmount(accountBalance);
// dto.setPayMode(payMode);
// /*
// 生成订单
// */
// OrderBasicInfo basicInfo = generateOrder(dto);
// if (basicInfo == null) {
// return null;
// }
// if (StringUtils.equals(StartModeEnum.AUTH_CARD.getValue(), dto.getStartMode())) {
// // 将卡状态改为启动锁定
// PileAuthCard pileAuthCard = PileAuthCard.builder()
// .id(dto.getPileAuthCardInfo().getId())
// .logicCard(dto.getPileAuthCardInfo().getLogicCard())
// .status("2")
// .build();
// pileAuthCardService.updatePileAuthCard(pileAuthCard);
// } else if (StringUtils.equals(StartModeEnum.VIN_CODE.getValue(), dto.getStartMode())) {
// // 将vin码改成启动锁定 2023.11.4 站点白名单和测试员不需要锁定
// if (!StringUtils.equals(OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue(), dto.getPayMode())) {
// dto.getMemberPlateNumberRelation().setVinStatus("2");
// }
// // 2024.02.06 不再判断锁定状态
// // memberPlateNumberRelationService.updateMemberPlateNumberRelation(dto.getMemberPlateNumberRelation());
// }
//
// // 组装结果集
// Map<String, Object> map = Maps.newHashMap();
// map.put("orderCode", basicInfo.getOrderCode());
// map.put("transactionCode", basicInfo.getTransactionCode());
// map.put("accountBalance", accountBalance);
//
// logger.info("生成订单 result:{}", JSON.toJSONString(map));
//
// // 支付订单
// PayOrderDTO payOrderDTO = new PayOrderDTO();
// payOrderDTO.setOrderCode(basicInfo.getOrderCode());
// payOrderDTO.setPayAmount(accountBalance);
// payOrderDTO.setPayMode(dto.getPayMode());
// payOrderDTO.setMemberId(dto.getMemberId());
// payOrderDTO.setStartMode(dto.getStartMode());
// // payOrderDTO.setCode();
// // payOrderDTO.setLockValue();
// // payOrderDTO.setOrderBasicInfo(basicInfo);
//
// // payOrder(payOrderDTO);
//
// String mode = pileMerchantInfoService.getDelayModeByMerchantId(merchantId);
// // 获取处理逻辑
// AbstractProgramLogic orderLogic = ProgramLogicFactory.getProgramLogic(mode);
// orderLogic.payOrder(payOrderDTO);
//
// // 推送小程序启动充电消息
// // 通过memberId查询openId
// MemberBasicInfo memberBasicInfo = memberBasicInfoService.selectInfoByMemberId(dto.getMemberId());
// WechatSendMsgDTO sendMsgDTO = new WechatSendMsgDTO();
// sendMsgDTO.setOpenId(memberBasicInfo.getOpenId());
// sendMsgDTO.setOrderCode(basicInfo.getOrderCode());
//
// wxAppletRemoteService.startChargingSendMsg(sendMsgDTO);
//
// return map;
// }
/**
* 订单支付成功 支付回调
@@ -295,76 +183,6 @@ public abstract class AbstractProgramLogic implements InitializingBean {
return orderBasicInfoService.calculateTheBalanceDeductionAmount(memberId, amount);
}
/**
* 处理前端传的参数
* pileConnectorCode = pileSn + connectorCode
* 2024年3月11日14点04分修改使用OrderBasicInfoService中的公共方法
* @param dto
*/
// protected 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);
// }
// }
// }
/**
* 校验充电桩相关的信息
* 2024年3月11日14点04分修改使用OrderBasicInfoService中的公共方法
* @param dto
*/
// protected 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);
// }
//
// // 校验启动桩使用的小程序,和充电桩所属一级运营商是否一致
// String merchantIdByAppId = pileMerchantInfoService.getFirstLevelMerchantIdByAppId(dto.getAppId());
// String merchantIdByMerchantId = pileMerchantInfoService.getFirstLevelMerchantIdByMerchantId(stationInfo.getMerchantId());
// if (!StringUtils.equals(merchantIdByAppId, merchantIdByMerchantId)) {
// throw new BusinessException("", "当前桩运营商与小程序所属运营商不一致");
// }
//
// // 如果是鉴权卡或者vin启动不判断枪口状态
// if (!(StringUtils.equals(dto.getStartMode(), StartModeEnum.AUTH_CARD.getValue())
// || StringUtils.equals(dto.getStartMode(), StartModeEnum.VIN_CODE.getValue()))) {
// // 判断枪口状态
// 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);
// }
/**
* 返回更新后的OrderBasicInfo对象
@@ -389,7 +207,7 @@ public abstract class AbstractProgramLogic implements InitializingBean {
// 虚拟金额 指订单消费中不参与结算的部分
BigDecimal virtualAmount = BigDecimal.ZERO;
if (OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue().equals(orderBasicInfo.getPayMode())
|| OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue().equals(orderBasicInfo.getPayMode())) {
|| OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue().equals(orderBasicInfo.getPayMode())) {
// 白名单支付所消费的金额,都属于虚拟金额,不参与结算对账
virtualAmount = new BigDecimal(orderAmount.toString());
}
@@ -416,6 +234,7 @@ public abstract class AbstractProgramLogic implements InitializingBean {
* 获取更新数据后的orderDetail对象
* 专用方法,其他地方如果要用请仔细检查
* 【公共方法】
*
* @return 查询并更新过数据的orderDetail
*/
protected OrderDetail returnUpdateOrderDetail(OrderBasicInfo orderBasicInfo, TransactionRecordsData data) {
@@ -555,11 +374,12 @@ public abstract class AbstractProgramLogic implements InitializingBean {
/**
* 获取更新数据后的orderDetail对象(给第三方平台结算订单用)
*
* @param orderBasicInfo
* @param data
* @return
*/
protected OrderDetail returnUpdateOrderDetailForThirdParty(OrderBasicInfo orderBasicInfo, TransactionRecordsData data){
protected OrderDetail returnUpdateOrderDetailForThirdParty(OrderBasicInfo orderBasicInfo, TransactionRecordsData data) {
String orderCode = orderBasicInfo.getOrderCode();
BigDecimal orderAmount = orderBasicInfo.getOrderAmount();
// 更新订单详情 查询订单详情 修改订单数据
@@ -579,9 +399,10 @@ public abstract class AbstractProgramLogic implements InitializingBean {
/**
* 余额支付 计算需要退回的金额
* 【公共方法】
*
* @param principalPay 本金支付金额
* @param giftPay 赠送金额支付的金额
* @param orderAmount 订单消费金额
* @param giftPay 赠送金额支付的金额
* @param orderAmount 订单消费金额
* @return
*/
protected Map<String, BigDecimal> calculateReturnAmount(BigDecimal principalPay, BigDecimal giftPay, BigDecimal orderAmount) {
@@ -591,9 +412,10 @@ public abstract class AbstractProgramLogic implements InitializingBean {
/**
* 余额支付 计算需要退回的金额
* 【公共方法】
* @param principalPay 本金支付金额
* @param giftPay 赠送金额支付金额
* @param orderAmount 订单消费金额
*
* @param principalPay 本金支付金额
* @param giftPay 赠送金额支付的金额
* @param orderAmount 订单消费金额
* @param discountAmount 订单折扣金额
* @return
*/
@@ -647,7 +469,8 @@ public abstract class AbstractProgramLogic implements InitializingBean {
/**
* 计算解冻金额
* @param orderAmount 订单消费金额
*
* @param orderAmount 订单消费金额
* @param payRecordList 订单支付记录
*/
public List<Map<String, Object>> calculateUnfreezeAmount(BigDecimal orderAmount, List<OrderPayRecord> payRecordList) {
@@ -758,6 +581,7 @@ public abstract class AbstractProgramLogic implements InitializingBean {
/**
* 解锁vin状态
* 【公共方法】
*
* @param vinCode
*/
protected void vinStatusUnlocked(String vinCode) {
@@ -775,8 +599,9 @@ public abstract class AbstractProgramLogic implements InitializingBean {
/**
* 计算订单折扣V2
* 使用优惠计费模板计算优惠金额
*
* @param orderBasicInfo 订单主表
* @param orderDetail 订单详情
* @param orderDetail 订单详情
*/
protected void calculateOrderDiscountsV2(OrderBasicInfo orderBasicInfo, OrderDetail orderDetail) {
String memberId = orderBasicInfo.getMemberId(); // 会员id
@@ -935,4 +760,37 @@ public abstract class AbstractProgramLogic implements InitializingBean {
return resultMap;
}
/**
* 是否有白名单权限
*/
protected boolean hasWhitelistPermission(String pileConnectorCode, String memberId) {
// 查询桩信息
PileConnectorDetailVO pileConnectorDetailVO = pileBasicInfoService.queryPileConnectorDetail(pileConnectorCode);
// 查询会员在站点是否是白名单用户
PileStationWhitelist whitelist = pileStationWhitelistService.queryWhitelistByMemberId(pileConnectorDetailVO.getStationId(), memberId);
// 查询是否为平台测试员
PlatformTesterVO platformTesterVO = memberBasicInfoService.selectPlatformTesterStatus(memberId);
// 查询个人桩
List<PersonalPileInfoVO> personalPileInfoVOListList = pileBasicInfoService.getPileInfoByMemberId(memberId);
List<String> personalPileSnList = personalPileInfoVOListList.stream()
.map(PersonalPileInfoVO::getPileSn)
.collect(Collectors.toList());
String pileSn = pileConnectorCode.substring(0, pileConnectorCode.length() - 2);
/*
满足一下三种情况任意一种,就可以使用白名单支付
1、该会员是站点白名单
2、该会员是平台测试员
3、该会员的个人桩列表包含目标桩
*/
boolean result = whitelist != null
|| StringUtils.equals(platformTesterVO.getStatus(), Constants.ONE)
|| personalPileSnList.contains(pileSn);
logger.info("会员:{}是否有枪口编号:{}的白名单权限, whitelist:{}, platformTesterVO:{}, personalPileSnList:{}, 校验结果:{}",
memberId, pileConnectorCode, whitelist, platformTesterVO, personalPileSnList, result);
return result;
}
}

View File

@@ -77,6 +77,11 @@ public class DelayMerchantProgramLogic extends AbstractProgramLogic {
return orderBasicInfoService.saveOrder2Database(dto);
}
/**
* 支付订单
* @param dto
* @return
*/
@Override
public Map<String, Object> payOrder(PayOrderDTO dto) {
logger.info("【{}】-支付订单start, param:{}", this.getClass().getSimpleName(), JSON.toJSONString(dto));
@@ -823,4 +828,40 @@ public class DelayMerchantProgramLogic extends AbstractProgramLogic {
}
logger.info("【{}】-汇付支付订单:{}, 执行退款逻辑 param:{}, result:{}", this.getClass().getSimpleName(), dto.getOrderCode(), JSON.toJSONString(dto), JSON.toJSONString(response));
}
/**
* 个人桩启动
*/
@Transactional(rollbackFor = Exception.class)
public String startPersonalPileCharging(StartPersonPileDTO dto) {
// 校验是否有权限启动
String pileConnectorCode = dto.getPileConnectorCode();
String pileSn = pileConnectorCode.substring(0, pileConnectorCode.length() - 2);
String connectorCode = pileConnectorCode.substring(pileConnectorCode.length() - 2);
boolean b = hasWhitelistPermission(pileConnectorCode, dto.getMemberId());
if (!b) {
throw new BusinessException("00600006", "个人桩启动失败,无启动权限");
}
String orderCode = "";
// 生成订单
GenerateOrderDTO generateOrderDTO = new GenerateOrderDTO();
generateOrderDTO.setMemberId(dto.getMemberId());
generateOrderDTO.setRequestSource(dto.getRequestSource());
generateOrderDTO.setStartMode("1");
generateOrderDTO.setStartType(dto.getStartType());
generateOrderDTO.setPileSn(pileSn);
generateOrderDTO.setConnectorCode(connectorCode);
try {
OrderBasicInfo orderBasicInfo = generateOrder(generateOrderDTO);
orderCode = orderBasicInfo.getOrderCode();
} catch (ParseException e) {
throw new RuntimeException(e);
}
// 支付订单
PayOrderDTO payOrderDTO = new PayOrderDTO();
payOrderDTO.setOrderCode(orderCode);
payOrderDTO.setPayMode(OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue());
payOrder(payOrderDTO);
return orderCode;
}
}

View File

@@ -1,6 +1,8 @@
package com.jsowell.pile.vo.web;
import lombok.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@Getter
@Setter
@@ -18,4 +20,12 @@ public class PlatformTesterVO {
* 1-是0-否
*/
private String status;
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
.append("memberId", memberId)
.append("status", status)
.toString();
}
}