|
|
@@ -64,6 +64,12 @@ import com.zsElectric.boot.common.util.DateUtils;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.redisson.api.RLock;
|
|
|
+import org.redisson.api.RedissonClient;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+import static com.zsElectric.boot.business.service.WFTOrderService.USER_FUND_LOCK_KEY;
|
|
|
+import static com.zsElectric.boot.business.service.WFTOrderService.USER_FUND_LOCK_EXPIRE;
|
|
|
|
|
|
/**
|
|
|
* 充电订单信息服务实现类
|
|
|
@@ -106,6 +112,7 @@ public class ChargeOrderInfoServiceImpl extends ServiceImpl<ChargeOrderInfoMappe
|
|
|
private final ThirdPartyApiLogMapper thirdPartyApiLogMapper;
|
|
|
private final ObjectMapper objectMapper;
|
|
|
private final DictItemService dictItemService;
|
|
|
+ private final RedissonClient redissonClient;
|
|
|
|
|
|
//充电订单号前缀
|
|
|
private final String ORDER_NO_PREFIX = "CD";
|
|
|
@@ -196,21 +203,55 @@ public class ChargeOrderInfoServiceImpl extends ServiceImpl<ChargeOrderInfoMappe
|
|
|
|
|
|
log.info("启动充电开始,用户ID:{},设备认证流水号:{},充电桩编号:{}", SecurityUtils.getUserId(), formData.getEquipAuthSeq(), formData.getEquipmentId());
|
|
|
|
|
|
- try {
|
|
|
- AppChargeVO appInvokeChargeVO = new AppChargeVO();
|
|
|
-
|
|
|
- //渠道方启动充电
|
|
|
- if (Objects.equals(formData.getOrderType(), SystemConstants.CHARGE_ORDER_TYPE_CHANNEL)) {
|
|
|
-
|
|
|
- log.info("渠道方启动充电开始,用户ID:{},设备认证流水号:{},充电桩编号:{}", SecurityUtils.getUserId(), formData.getEquipAuthSeq(), formData.getEquipmentId());
|
|
|
+ // 渠道方启动充电不需要用户资金锁
|
|
|
+ if (Objects.equals(formData.getOrderType(), SystemConstants.CHARGE_ORDER_TYPE_CHANNEL)) {
|
|
|
+ log.info("渠道方启动充电开始,用户ID:{},设备认证流水号:{},充电桩编号:{}", SecurityUtils.getUserId(), formData.getEquipAuthSeq(), formData.getEquipmentId());
|
|
|
+ try {
|
|
|
+ AppChargeVO appInvokeChargeVO = new AppChargeVO();
|
|
|
String orderNo = channelInvokeCharge(formData);
|
|
|
appInvokeChargeVO.setChargeOrderNo(orderNo);
|
|
|
return appInvokeChargeVO;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("渠道方启动充电失败", e);
|
|
|
+ throw new BusinessException("启动充电失败 !" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 必要校验
|
|
|
+ Long userId = SecurityUtils.getUserId();
|
|
|
+ Assert.isTrue(userId != null, "用户ID不能为空");
|
|
|
+
|
|
|
+ // 获取用户资金操作统一锁,防止充电启动与退款并发
|
|
|
+ String lockKey = USER_FUND_LOCK_KEY + userId;
|
|
|
+ RLock lock = redissonClient.getLock(lockKey);
|
|
|
+
|
|
|
+ boolean locked = false;
|
|
|
+ try {
|
|
|
+ // 尝试获取锁,等待3秒,锁过期时间60秒
|
|
|
+ locked = lock.tryLock(3, USER_FUND_LOCK_EXPIRE, TimeUnit.SECONDS);
|
|
|
+ if (!locked) {
|
|
|
+ log.warn("用户:{}资金操作正在进行中,无法启动充电", userId);
|
|
|
+ throw new BusinessException("操作正在进行中,请稍后重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ return doInvokeCharge(formData, userId);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ throw new BusinessException("启动充电失败,请稍后重试");
|
|
|
+ } finally {
|
|
|
+ // 释放锁
|
|
|
+ if (locked && lock.isHeldByCurrentThread()) {
|
|
|
+ lock.unlock();
|
|
|
}
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- //必要校验
|
|
|
- Long userId = SecurityUtils.getUserId();
|
|
|
- Assert.isTrue(userId != null, "用户ID不能为空");
|
|
|
+ /**
|
|
|
+ * 执行启动充电逻辑(内部方法)
|
|
|
+ */
|
|
|
+ private AppChargeVO doInvokeCharge(AppInvokeChargeForm formData, Long userId) {
|
|
|
+ try {
|
|
|
+ AppChargeVO appInvokeChargeVO = new AppChargeVO();
|
|
|
|
|
|
AppUserInfoVO userInfo = userInfoMapper.getAppletUserInfo(userId);
|
|
|
Assert.isTrue(userInfo != null, "用户信息不存在");
|
|
|
@@ -371,7 +412,10 @@ public class ChargeOrderInfoServiceImpl extends ServiceImpl<ChargeOrderInfoMappe
|
|
|
chargeOrderInfo.setPreAmt(formData.getChannelPreAmt());
|
|
|
//渠道方订单设置运营商ID
|
|
|
chargeOrderInfo.setOperatorId(formData.getOperatorId());
|
|
|
-
|
|
|
+ //车牌号
|
|
|
+ if(ObjectUtil.isNotEmpty(formData.getPlateNum())) {
|
|
|
+ chargeOrderInfo.setPlateNum(formData.getPlateNum());
|
|
|
+ }
|
|
|
//启动充电
|
|
|
StartChargingRequestDTO requestDTO = new StartChargingRequestDTO();
|
|
|
requestDTO
|