@@ -0,0 +1 @@ | |||
7352 |
@@ -2,6 +2,9 @@ package com.qtzl.alterSales.dao.repo.jpa.primary; | |||
import com.qtzl.alterSales.dao.entity.primary.WechatBillPayApply; | |||
import org.springframework.data.jpa.repository.JpaRepository; | |||
import org.springframework.data.jpa.repository.Query; | |||
import java.util.List; | |||
/*** | |||
* <p> |
@@ -2,6 +2,7 @@ package com.qtzl.alterSales.manager.service; | |||
import cn.com.taiji.common.manager.net.http.ServiceHandleException; | |||
import cn.hutool.core.bean.BeanUtil; | |||
import cn.hutool.core.util.ObjectUtil; | |||
import com.google.common.collect.Lists; | |||
import com.qtzl.alterSales.dao.entity.primary.*; | |||
import com.qtzl.alterSales.dao.repo.jpa.primary.*; | |||
@@ -10,10 +11,13 @@ import com.qtzl.alterSales.manager.model.protocol.UcServiceError; | |||
import com.qtzl.alterSales.manager.model.protocol.sales.ChoiceBillsPayRequest; | |||
import com.qtzl.alterSales.manager.model.protocol.wechat.WechatPaymentCorrelationV3Manager; | |||
import com.qtzl.alterSales.manager.model.protocol.wechat.partnerpayments.JsapiV3Manager; | |||
import com.qtzl.alterSales.manager.tools.RedisUtils; | |||
import com.qtzl.alterSales.manager.vo.ChoiceBillsPayVo; | |||
import com.wechat.pay.java.service.partnerpayments.jsapi.model.PrepayWithRequestPaymentResponse; | |||
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.springframework.stereotype.Service; | |||
import org.springframework.util.CollectionUtils; | |||
@@ -34,6 +38,8 @@ import java.util.stream.Collectors; | |||
@Service | |||
public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationService { | |||
private static final Logger log = LoggerFactory.getLogger(ChoiceBillsOperationServiceImpl.class); | |||
@Resource | |||
private WechatPaymentCorrelationV3Manager wechatPaymentConfigManager; | |||
@Resource | |||
@@ -52,7 +58,11 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
private AflVehicleMchRelRepo aflVehicleMchRelRepo; | |||
@Resource | |||
private WechatBillPayApplyRepo wechatBillPayApplyRepo; | |||
@Resource | |||
private RedisUtils redisUtils; | |||
// 请不要改这个key | |||
private static final String REDIS_KEY = "PAY_FAIL_"; | |||
@Override | |||
public ChoiceBillsPayVo choiceBillsPay(ChoiceBillsPayRequest request) throws ServiceHandleException { | |||
if (StringUtils.isEmpty(request.getOpenId())) { | |||
@@ -78,6 +88,19 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
if (vehicleIds.size() > 1) { | |||
throw UcServiceError.BUSINESS_VALIDATE_ERR.toHandleException("暂不支持多车牌同时补缴"); | |||
} | |||
// 下列两个if内容不要合在一起 | |||
for (String payId : request.getPayIds()) { | |||
// 校验是否存在轮扣中 | |||
final Object redisData = redisUtils.get(REDIS_KEY + payId); | |||
if (!ObjectUtil.isEmpty(redisData)) { | |||
log.warn("该笔流水用户正在轮扣中,请10分钟后重试...payId:" + payId); | |||
throw UcServiceError.BUSINESS_VALIDATE_ERR.toHandleException("系统轮扣等待微信结果中,为避免重复扣费,请10分钟稍后重试"); | |||
} | |||
} | |||
for (String payId : request.getPayIds()) { | |||
// 插入不允许轮扣 | |||
redisUtils.set(REDIS_KEY + payId, payId); | |||
} | |||
final String vehicleId = vehicleIds.iterator().next(); | |||
String orderNo = "AFLBQ" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")) + (int) ((Math.random() * 9 + 1) * Math.pow(10, 5)); | |||
final long totalFee = payList.stream().mapToLong(FssPaccountPay::getReceiptAmt).sum(); | |||
@@ -117,6 +140,13 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
jsapiV3Manager.jsApiOrderClose(payOrder.getOrderNo(), MchInfoEnum.find(payOrder.getSubMchId())); | |||
payOrder.setOrderStatus(AflApPayOrderStatus.CLOSE); | |||
payOrderRepo.save(payOrder); | |||
final List<String> payIds = payOrderRelRepo.getPayId((id)); | |||
for (String payId : payIds) { | |||
final Object redisData = redisUtils.get(REDIS_KEY + payId); | |||
if (!ObjectUtil.isEmpty(redisData)) { | |||
redisUtils.del(REDIS_KEY + payId); | |||
} | |||
} | |||
} | |||
@Override | |||
@@ -129,6 +159,13 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
// 支付订单不是待支付的。不查询微信,不处理任何业务 | |||
throw UcServiceError.BUSINESS_VALIDATE_ERR.toHandleException(payOrder.getOrderStatus().getStatus()); | |||
} | |||
final List<String> payIds = payOrderRelRepo.getPayId((id)); | |||
for (String payId : payIds) { | |||
final Object redisData = redisUtils.get(REDIS_KEY + payId); | |||
if (!ObjectUtil.isEmpty(redisData)) { | |||
redisUtils.del(REDIS_KEY + payId); | |||
} | |||
} | |||
final Transaction transaction = jsapiV3Manager.jsApiQueryByOutTradeNo(payOrder.getOrderNo(), MchInfoEnum.find(payOrder.getSubMchId())); | |||
if (Transaction.TradeStateEnum.PAYERROR.equals(transaction.getTradeState())) { | |||
// 支付失败 | |||
@@ -146,9 +183,8 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
payOrder.setPayTime(payTime); | |||
payOrderRepo.save(payOrder); | |||
// 2、流水处理 | |||
final List<String> payId = payOrderRelRepo.getPayId((id)); | |||
final List<FssPaccountPay> accountPayList = accountPayRepo.findAll(((root, query, cb) -> query.where( | |||
root.<String>get("payId").in(payId) | |||
root.<String>get("payId").in(payIds) | |||
).getRestriction())); | |||
if (CollectionUtils.isEmpty(accountPayList)) { | |||
return; | |||
@@ -166,7 +202,7 @@ public class ChoiceBillsOperationServiceImpl implements ChoiceBillsOperationServ | |||
final String agreementNum = accountPayList.get(0).getAgreementNum(); | |||
final List<FssPaccountPay> notDeducted = accountPayRepo.findByAgreementNum(agreementNum); | |||
final List<FssPaccountPay> collected = notDeducted.stream() | |||
.filter(vo -> !payId.contains(vo.getPayId())) | |||
.filter(vo -> !payIds.contains(vo.getPayId())) | |||
.toList(); | |||
if (CollectionUtils.isEmpty(collected)) { | |||
final List<String> orderList = accountPayList.stream().map(FssPaccountPay::getOrderId).toList(); |
@@ -6,6 +6,7 @@ import com.qtzl.alterSales.dao.entity.primary.AflSupplementaryPayOrder; | |||
import com.qtzl.alterSales.dao.entity.primary.FssPaccountPay; | |||
import com.qtzl.alterSales.dao.repo.jpa.primary.AflSupplementaryPayOrderRepo; | |||
import com.qtzl.alterSales.dao.repo.jpa.primary.FssPaccountPayRepo; | |||
import com.qtzl.alterSales.dao.repo.jpa.primary.WechatBillPayApplyRepo; | |||
import com.qtzl.alterSales.manager.enums.VehiclePlateColorEnum; | |||
import com.qtzl.alterSales.manager.model.protocol.UcServiceError; | |||
import com.qtzl.alterSales.manager.vo.VehicleAgreementNumBillsVo; | |||
@@ -30,6 +31,8 @@ public class FssPaccountPayServiceImpl implements FssPaccountPayService { | |||
private FssPaccountPayRepo paccountPayRepo; | |||
@Resource | |||
private AflSupplementaryPayOrderRepo supplementaryPayOrderRepo; | |||
@Resource | |||
private WechatBillPayApplyRepo wechatBillPayApplyRepo; | |||
@Override | |||
public List<VehicleAgreementNumBillsVo> getAgreementBills(String plateNumber, Integer plateColor) throws ServiceHandleException { | |||
@@ -60,13 +63,17 @@ public class FssPaccountPayServiceImpl implements FssPaccountPayService { | |||
return toVo(paccountPayRepo.findByPayIdIn(payIds)); | |||
} | |||
private List<VehicleAgreementNumBillsVo> toVo(List<FssPaccountPay> payList){ | |||
if (CollectionUtils.isEmpty(payList)){ | |||
private List<VehicleAgreementNumBillsVo> toVo(List<FssPaccountPay> payList) { | |||
if (CollectionUtils.isEmpty(payList)) { | |||
return Lists.newArrayList(); | |||
} | |||
List<VehicleAgreementNumBillsVo> billsVos = Lists.newArrayList(); | |||
VehicleAgreementNumBillsVo billsVo; | |||
for (FssPaccountPay bill : payList) { | |||
if (null == wechatBillPayApplyRepo.findFirstByPayIdOrderByInsertTimeDesc(bill.getPayId())) { | |||
// 过滤掉没有// 过滤掉没有轮扣过的流水 | |||
continue; | |||
} | |||
billsVo = new VehicleAgreementNumBillsVo(bill.getPayId(), bill.getSceneTp(), bill.getReceiptAmt(), bill.getChargeTime()); | |||
// 处理车牌号、车牌颜色 | |||
if (!StringUtils.isEmpty(bill.getVehicleId()) && bill.getVehicleId().contains("_")) { |
@@ -0,0 +1,115 @@ | |||
package com.qtzl.alterSales.manager.tools; | |||
import org.springframework.data.redis.core.RedisTemplate; | |||
import org.springframework.stereotype.Component; | |||
import org.springframework.util.CollectionUtils; | |||
import javax.annotation.Resource; | |||
import java.util.Collection; | |||
import java.util.concurrent.TimeUnit; | |||
/*** | |||
* <p> | |||
* redis 工具类 | |||
* </p> | |||
* @author hou yi | |||
* @date 2022/8/19 14:05 | |||
**/ | |||
@Component | |||
public class RedisUtils { | |||
@Resource | |||
private RedisTemplate<String, Object> redisTemplate; | |||
/** | |||
* 根据key 获取过期时间 | |||
* | |||
* @param key 键 不能为null | |||
* @return 时间(秒) 返回0代表为永久有效 | |||
*/ | |||
public long getExpire(String key) { | |||
return redisTemplate.getExpire(key, TimeUnit.SECONDS); | |||
} | |||
/** | |||
* 判断key是否存在 | |||
* | |||
* @param key 键 | |||
* @return true 存在 false不存在 | |||
*/ | |||
public boolean hasKey(String key) { | |||
try { | |||
return Boolean.TRUE.equals(redisTemplate.hasKey(key)); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return false; | |||
} | |||
} | |||
/** | |||
* 删除缓存 | |||
* | |||
* @param key 可以传一个值 或多个 | |||
*/ | |||
@SuppressWarnings("unchecked") | |||
public void del(String... key) { | |||
if (key != null && key.length > 0) { | |||
if (key.length == 1) { | |||
redisTemplate.delete(key[0]); | |||
} else { | |||
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key)); | |||
} | |||
} | |||
} | |||
/** | |||
* 普通缓存获取 | |||
* | |||
* @param key 键 | |||
* @return 值 | |||
*/ | |||
public Object get(String key) { | |||
return key == null ? null : redisTemplate.opsForValue().get(key); | |||
} | |||
/** | |||
* 普通缓存放入 | |||
* | |||
* @param key 键 | |||
* @param value 值 | |||
* @return true成功 false失败 | |||
*/ | |||
public boolean set(String key, Object value) { | |||
try { | |||
redisTemplate.opsForValue().set(key, value); | |||
return true; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return false; | |||
} | |||
} | |||
/** | |||
* 普通缓存放入并设置时间 | |||
* | |||
* @param key 键 | |||
* @param value 值 | |||
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 | |||
* @return true成功 false 失败 | |||
*/ | |||
public boolean set(String key, Object value, long time) { | |||
try { | |||
if (time > 0) { | |||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); | |||
} else { | |||
set(key, value); | |||
} | |||
return true; | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return false; | |||
} | |||
} | |||
} |
@@ -1,4 +1,21 @@ | |||
spring: | |||
redis: | |||
# Redis数据库索引(默认为0) | |||
database: 15 | |||
# Redis服务器地址 | |||
host: 159.75.82.245 | |||
# Redis服务器连接端口 | |||
port: 6379 | |||
# 连接超时时间(毫秒 | |||
timeout: 5000 | |||
# Redis服务器连接密码(默认为空) | |||
password: 'houyi..' | |||
jedis: | |||
pool: | |||
max-active: 100 # 连接池最大连接数(使用负值表示没有限制) | |||
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) | |||
max-idle: 50 # 连接池中的最大空闲连接 | |||
min-idle: 0 | |||
datasource: | |||
primary: | |||
# 使用阿里的Druid连接池 |
@@ -1,4 +1,21 @@ | |||
spring: | |||
redis: | |||
# Redis数据库索引(默认为0) | |||
database: 15 | |||
# Redis服务器地址 | |||
host: 192.168.101.131 | |||
# Redis服务器连接端口 | |||
port: 6381 | |||
# 连接超时时间(毫秒 | |||
timeout: 5000 | |||
# Redis服务器连接密码(默认为空) | |||
password: '7b79834498f444f1b00b1519824b005d' | |||
jedis: | |||
pool: | |||
max-active: 100 # 连接池最大连接数(使用负值表示没有限制) | |||
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) | |||
max-idle: 50 # 连接池中的最大空闲连接 | |||
min-idle: 0 | |||
datasource: | |||
# 使用阿里的Druid连接池 | |||
primary: | |||
@@ -112,7 +129,7 @@ center: | |||
# 比亚迪配置 | |||
byd: | |||
url: https://dilinkappserver-dev-cn.fangchengbaocloud.com | |||
url: https://dilinkappserver-test-cn.fangchengbaocloud.com | |||
identifier: etcDashboard | |||
token: WqRTpaPFz8uK4WoQ7DNGEsqOUjIQN2QDcBqWY7 | |||
# url: |
@@ -11,6 +11,7 @@ import com.qtzl.alterSales.manager.service.AflBydDashboardService; | |||
import com.qtzl.alterSales.manager.service.byd.BydService; | |||
import com.qtzl.alterSales.manager.service.byd.vo.BydDashBoardResponse; | |||
import com.qtzl.alterSales.manager.service.byd.vo.BydPushDataResultRequest; | |||
import com.qtzl.alterSales.manager.tools.RedisUtils; | |||
import com.qtzl.alterSales.manager.vo.BydOrderVehicleInfoVo; | |||
import org.junit.Test; | |||
import org.junit.runner.RunWith; | |||
@@ -44,6 +45,13 @@ public class SaleTest { | |||
private AflBydDashboardService aflBydDashboardService; | |||
@Resource | |||
private AflCancelOrderTask aflCancelOrderTask; | |||
@Resource | |||
private RedisUtils redisUtils; | |||
@Test | |||
public void redisTest(){ | |||
System.out.println(redisUtils.get("ttt")); | |||
} | |||
@Test | |||
public void cancel(){ |