Merge branch 'refs/heads/test' into dev

This commit is contained in:
张松 2024-12-26 14:51:18 +08:00
commit 5f7c225582
9 changed files with 229 additions and 71 deletions

View File

@ -1,15 +1,21 @@
package com.sqx.common.utils; package com.sqx.common.utils;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date; import java.util.Date;
import java.util.UUID;
import java.util.function.Supplier;
/** /**
* 接口访问次数 月为单位 * 接口访问次数 月为单位
*/ */
@Component @Component
@Slf4j
public class ApiAccessLimitUtil { public class ApiAccessLimitUtil {
private static final String ACCESS_COUNT_KEY_PREFIX = "sys:limit:"; private static final String ACCESS_COUNT_KEY_PREFIX = "sys:limit:";
@ -122,6 +128,48 @@ public class ApiAccessLimitUtil {
} }
public static<T> T runFunAndCheckKey(Supplier<T> supplier, String lockKey, Integer seconds) {
try{
// 创建线程id, 用作判断
String clientId = UUID.randomUUID().toString();
// 设置分布式锁
boolean lock = Boolean.TRUE.equals(redisUtils.setIfAbsent(lockKey, clientId, seconds));
int count = 0;
while (!lock) {
if (count++ > 100) {
throw new RuntimeException("系统繁忙, 稍后再试");
}
Thread.sleep(20);
lock = Boolean.TRUE.equals(redisUtils.setIfAbsent(lockKey, clientId, seconds));
}
return supplier.get();
} catch (RuntimeException e){
log.info("执行出错:{}", e.getMessage());
throw e;
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally{
redisUtils.delete(lockKey);
}
}
public static boolean isAccessAllowed(String id, String key, Integer count, Integer seconds) {
String redisKey = generateRedisKey(key, id);
Object countObj = redisUtils.get(redisKey);
if (countObj == null) {
// 根据不同时间周期设置过期时间并初始化访问次数为1
redisUtils.set(redisKey, 1, seconds);
return true;
}
if (Integer.parseInt(countObj.toString()) < count) {
// 访问次数未达上限次数加1
redisUtils.incr(redisKey);
return true;
}
return false;
}
private static String generateRedisKey(String key, String id) { private static String generateRedisKey(String key, String id) {
return ACCESS_COUNT_KEY_PREFIX + key + ":" + id; return ACCESS_COUNT_KEY_PREFIX + key + ":" + id;
} }
@ -142,4 +190,4 @@ public class ApiAccessLimitUtil {
long currentTimeStamp = DateUtil.currentSeconds(); long currentTimeStamp = DateUtil.currentSeconds();
return endTimeStamp - currentTimeStamp; return endTimeStamp - currentTimeStamp;
} }
} }

View File

@ -9,6 +9,8 @@ import cn.hutool.core.date.DateUtil;
public class RedisKeys { public class RedisKeys {
public static final String FREE_WATCH_KEY = "free:watch:"; public static final String FREE_WATCH_KEY = "free:watch:";
public static final String LOCK_KEY = "SYS:LOCK:";
public static String getSysConfigKey(String key){ public static String getSysConfigKey(String key){
return "sys:config:" + key; return "sys:config:" + key;
@ -28,4 +30,15 @@ public class RedisKeys {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println(DateUtil.today()); System.out.println(DateUtil.today());
} }
public static String getLockKey(String sign, Object... args) {
StringBuilder key = new StringBuilder(LOCK_KEY + ":" + sign + ":");
for (Object arg : args) {
if (arg != null) {
key.append(":").append(arg);
}
}
return key.toString();
}
} }

View File

@ -1,6 +1,5 @@
package com.sqx.modules.discSpinning.controller; package com.sqx.modules.discSpinning.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -28,7 +27,6 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import reactor.util.annotation.Nullable;
import springfox.documentation.annotations.ApiIgnore; import springfox.documentation.annotations.ApiIgnore;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -49,7 +47,6 @@ public class DiscSpinningController {
private final TaskCenterRecordService taskRecordService; private final TaskCenterRecordService taskRecordService;
private final UserService userService; private final UserService userService;
private final RedisUtils redisUtils; private final RedisUtils redisUtils;
@Autowired @Autowired
public DiscSpinningController(CommonInfoService commonRepository, DiscSpinningService discSpinningService, public DiscSpinningController(CommonInfoService commonRepository, DiscSpinningService discSpinningService,
OrdersService ordersService, DiscSpinningRecordService recordService, OrdersService ordersService, DiscSpinningRecordService recordService,

View File

@ -124,28 +124,38 @@ public class DiscSpinningServiceImpl extends ServiceImpl<DiscSpinningDao, DiscSp
//最高提现金额 //最高提现金额
CommonInfo one2 = commonRepository.findOne(910); CommonInfo one2 = commonRepository.findOne(910);
if (one2 == null || money <= Double.parseDouble(one2.getValue())) { if (one2 == null || money <= Double.parseDouble(one2.getValue())) {
String outOrderNo = AliPayOrderUtil.createOrderId(); if (WuyouPay.checkCanCash(userInfo.getUserId())) {
cashOut.setOrderNumber(outOrderNo); String outOrderNo = AliPayOrderUtil.createOrderId();
BaseResp baseResp = WuyouPay.extractOrder(userInfo.getUserId(), outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName()); cashOut.setOrderNumber(outOrderNo);
if (baseResp.getStatus() != null && (baseResp.getStatus().equals(2) || baseResp.getStatus().equals(10000))) { BaseResp baseResp = WuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName());
if (baseResp.getStatus() != null && (baseResp.getStatus().equals(2) || baseResp.getStatus().equals(10000))) {
UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
userInfo.getUserId(), null, null, title, 4, 2, 1,
new BigDecimal(money), "现金红包自动提现" + money + "", 1);
userMoneyDetailsService.save(userMoneyDetails);
//减去余额
userMoneyService.updateAmount(2, userInfo.getUserId(), money);
cashOut.setState(1);
} else if (StringUtils.isNotBlank(baseResp.getErrorMsg())) {
cashOut.setState(2);
if (baseResp.getErrorMsg().contains("收款人账户号出款属性不匹配")) {
cashOut.setRefund("提现失败,请检查支付宝账号与收款人姓名后,重试。");
} else {
cashOut.setRefund(baseResp.getErrorMsg());
}
} else if (StringUtils.isNotBlank(baseResp.getMsg())) {
cashOut.setState(2);
cashOut.setRefund("提现失败,请检查支付宝账号与收款人姓名后,重试。");
}
}else {
UserMoneyDetails userMoneyDetails = new UserMoneyDetails( UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
userInfo.getUserId(), null, null, title, 4, 2, 1, userInfo.getUserId(), null, null, title, 4, 2, 1,
new BigDecimal(money), "现金红包自动提现" + money + "", 1); new BigDecimal(money), "现金红包自动提现" + money + "", 1);
userMoneyDetailsService.save(userMoneyDetails); userMoneyDetailsService.save(userMoneyDetails);
//减去余额 //减去余额
userMoneyService.updateAmount(2, userInfo.getUserId(), money); userMoneyService.updateAmount(2, userInfo.getUserId(), money);
cashOut.setState(3);
cashOut.setState(1);
} else if (StringUtils.isNotBlank(baseResp.getErrorMsg())) {
cashOut.setState(2);
if (baseResp.getErrorMsg().contains("收款人账户号出款属性不匹配")) {
cashOut.setRefund("提现失败,请检查支付宝账号与收款人姓名后,重试。");
} else {
cashOut.setRefund(baseResp.getErrorMsg());
}
} else if (StringUtils.isNotBlank(baseResp.getMsg())) {
cashOut.setState(2);
cashOut.setRefund("提现失败,请检查支付宝账号与收款人姓名后,重试。");
} }
} else { } else {
UserMoneyDetails userMoneyDetails = new UserMoneyDetails( UserMoneyDetails userMoneyDetails = new UserMoneyDetails(

View File

@ -11,13 +11,10 @@ import com.sqx.modules.utils.AliPayOrderUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List; import java.util.List;
@Component("CashOutTask") @Component("CashOutTask")
@ -37,26 +34,31 @@ public class CashOutTask implements ITask {
logger.info("提现开始"); logger.info("提现开始");
List<CashOut> cashOuts = cashOutDao.selectYesterday(); List<CashOut> cashOuts = cashOutDao.selectYesterday();
for (CashOut cashOut : cashOuts) { for (CashOut cashOut : cashOuts) {
String outOrderNo = AliPayOrderUtil.createOrderId(); if (WuyouPay.checkCanCash(cashOut.getUserId())) {
cashOut.setOrderNumber(outOrderNo); String outOrderNo = AliPayOrderUtil.createOrderId();
BaseResp baseResp = WuyouPay.extractOrder(cashOut.getUserId(), outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName()); cashOut.setOrderNumber(outOrderNo);
if (baseResp.getStatus() != null && baseResp.getStatus().equals(2)) {
cashOut.setState(1);
} else {
cashOut.setState(2);
cashOut.setRefund(StringUtils.isNotBlank(baseResp.getMsg()) ? baseResp.getMsg() : baseResp.getErrorMsg());
if (cashOut.getRefund().contains("收款人账户号出款属性不匹配")||cashOut.getRefund().contains("已驳回")) {
cashOut.setRefund("提现失败,请检查支付宝账号与收款人姓名后,重试。");
}else {
cashOut.setRefund(baseResp.getErrorMsg());
}
UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
cashOut.getUserId(),null,null,"提现失败",4,1,1,
new BigDecimal(cashOut.getMoney()),"提现失败存入余额" + cashOut.getMoney() + "", 1);
//存入余额 BaseResp baseResp = WuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName());
userMoneyService.updateAmount(1, cashOut.getUserId(), Double.parseDouble(cashOut.getMoney())); if (baseResp.getStatus() != null && baseResp.getStatus().equals(2)) {
userMoneyDetailsService.save(userMoneyDetails); cashOut.setState(1);
} else {
cashOut.setState(2);
cashOut.setRefund(StringUtils.isNotBlank(baseResp.getMsg()) ? baseResp.getMsg() : baseResp.getErrorMsg());
if (cashOut.getRefund().contains("收款人账户号出款属性不匹配") || cashOut.getRefund().contains("已驳回")) {
cashOut.setRefund("提现失败,请检查支付宝账号与收款人姓名后,重试。");
} else {
cashOut.setRefund(baseResp.getErrorMsg());
}
UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
cashOut.getUserId(), null, null, "提现失败", 4, 1, 1,
new BigDecimal(cashOut.getMoney()), "提现失败存入余额" + cashOut.getMoney() + "", 1);
//存入余额
userMoneyService.updateAmount(1, cashOut.getUserId(), Double.parseDouble(cashOut.getMoney()));
userMoneyDetailsService.save(userMoneyDetails);
}
}else {
cashOut.setState(3);
} }
cashOutDao.updateById(cashOut); cashOutDao.updateById(cashOut);
} }

View File

@ -0,0 +1,74 @@
package com.sqx.modules.job.task;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.service.UserMoneyDetailsService;
import com.sqx.modules.app.service.UserMoneyService;
import com.sqx.modules.banner.entity.Activity;
import com.sqx.modules.pay.dao.CashOutDao;
import com.sqx.modules.pay.entity.CashOut;
import com.sqx.modules.pay.wuyou.BaseResp;
import com.sqx.modules.pay.wuyou.WuyouPay;
import com.sqx.modules.utils.AliPayOrderUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
@Component("CashOutTask2")
public class CashOutTask2 implements ITask {
@Resource
private CashOutDao cashOutDao;
@Resource
private UserMoneyService userMoneyService;
@Resource
private UserMoneyDetailsService userMoneyDetailsService;
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void run(String params) {
logger.info("提现开始");
List<CashOut> cashOuts = cashOutDao.selectList(new QueryWrapper<CashOut>()
.eq("state", 0)
.gt("create_at", DateUtil.today()+" 00:00:00")
.lt("create_at",DateUtil.today()+" 23:59:59"));
System.out.println(cashOuts.size());
for (CashOut cashOut : cashOuts) {
if (WuyouPay.checkCanCash(cashOut.getUserId())) {
String outOrderNo = AliPayOrderUtil.createOrderId();
cashOut.setOrderNumber(outOrderNo);
BaseResp baseResp = WuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName());
if (baseResp.getStatus() != null && baseResp.getStatus().equals(2)) {
cashOut.setState(1);
} else {
cashOut.setState(2);
cashOut.setRefund(StringUtils.isNotBlank(baseResp.getMsg()) ? baseResp.getMsg() : baseResp.getErrorMsg());
if (cashOut.getRefund().contains("收款人账户号出款属性不匹配")||cashOut.getRefund().contains("已驳回")) {
cashOut.setRefund("提现失败,请检查支付宝账号与收款人姓名后,重试。");
}else {
cashOut.setRefund(baseResp.getErrorMsg());
}
UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
cashOut.getUserId(),null,null,"提现失败",4,1,1,
new BigDecimal(cashOut.getMoney()),"提现失败存入余额" + cashOut.getMoney() + "", 1);
//存入余额
userMoneyService.updateAmount(1, cashOut.getUserId(), Double.parseDouble(cashOut.getMoney()));
userMoneyDetailsService.save(userMoneyDetails);
}
}else {
cashOut.setState(3);
}
cashOutDao.updateById(cashOut);
}
logger.info("提现结束");
}
}

View File

@ -4,7 +4,9 @@ import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sqx.common.annotation.Debounce; import com.sqx.common.annotation.Debounce;
import com.sqx.common.utils.ApiAccessLimitUtil;
import com.sqx.common.utils.DateUtils; import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.RedisKeys;
import com.sqx.common.utils.Result; import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.UserEntity; import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoneyDetails; import com.sqx.modules.app.entity.UserMoneyDetails;
@ -34,6 +36,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -68,12 +71,13 @@ public class WuyouController {
private final CashOutDao cashOutDao; private final CashOutDao cashOutDao;
private final CompletAwardService completAwardService; private final CompletAwardService completAwardService;
private final SysUserService sysUserService; private final SysUserService sysUserService;
private final ApplicationContext applicationContext;
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5); ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
WuyouController(OrdersService ordersService, PayDetailsDao payDetailsDao, UserService userService, InviteService inviteService, CashOutDao cashOutDao, WuyouController(OrdersService ordersService, PayDetailsDao payDetailsDao, UserService userService, InviteService inviteService, CashOutDao cashOutDao,
UserMoneyService userMoneyService, UserMoneyDetailsService userMoneyDetailsService, CommonInfoService commonRepository, UserMoneyService userMoneyService, UserMoneyDetailsService userMoneyDetailsService, CommonInfoService commonRepository,
InviteDao inviteDao,CompletAwardService completAwardService, SysUserService sysUserService) { InviteDao inviteDao, CompletAwardService completAwardService, SysUserService sysUserService, ApplicationContext applicationContext) {
this.ordersService = ordersService; this.ordersService = ordersService;
this.payDetailsDao = payDetailsDao; this.payDetailsDao = payDetailsDao;
this.userService = userService; this.userService = userService;
@ -85,6 +89,7 @@ public class WuyouController {
this.inviteDao = inviteDao; this.inviteDao = inviteDao;
this.completAwardService = completAwardService; this.completAwardService = completAwardService;
this.sysUserService = sysUserService; this.sysUserService = sysUserService;
this.applicationContext = applicationContext;
} }
@Debounce(interval = 1000, value = "#orderId") @Debounce(interval = 1000, value = "#orderId")
@ -335,7 +340,11 @@ public class WuyouController {
ordersService.updateById(order); ordersService.updateById(order);
ordersService.insertOrders(order); ordersService.insertOrders(order);
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() -> {
activities(user, byUser); ApiAccessLimitUtil.runFunAndCheckKey(() -> {
WuyouController proxy = applicationContext.getBean(WuyouController.class);
proxy.activities(user, byUser);
return null;
}, RedisKeys.getLockKey("activaties", user.getUserId(), byUser.getUserId()), 15);
}); });
} }

View File

@ -486,15 +486,20 @@ public class CashOutServiceImpl extends ServiceImpl<CashOutDao, CashOut> impleme
return Result.success("可提现余额不足!"); return Result.success("可提现余额不足!");
} }
// BaseResp baseResp = WuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName()); if (WuyouPay.checkCanCash(userId)) {
// if (baseResp.getStatus() != null && (baseResp.getStatus().equals(2) || baseResp.getStatus().equals(10000))){ BaseResp baseResp = WuyouPay.extractOrder(outOrderNo, cashOut.getMoney(), cashOut.getZhifubao(), cashOut.getZhifubaoName());
// userMoneyDetails.setContent("成功提现:" + money); if (baseResp.getStatus() != null && (baseResp.getStatus().equals(2) || baseResp.getStatus().equals(10000))){
// cashOut.setState(1); userMoneyDetails.setContent("成功提现:" + money);
// } cashOut.setState(1);
// }
// if (baseResp.getErrorMsg() != null) {
// return Result.error(baseResp.getErrorMsg()); if (baseResp.getErrorMsg() != null) {
// } return Result.error(baseResp.getErrorMsg());
}
}else {
userMoneyDetails.setContent("成功提现:" + money);
cashOut.setState(3);
}
userMoneyDetailsService.save(userMoneyDetails); userMoneyDetailsService.save(userMoneyDetails);
baseMapper.insert(cashOut); baseMapper.insert(cashOut);

View File

@ -82,30 +82,30 @@ public class WuyouPay {
return JSONObject.parseObject(body, BaseResp.class); return JSONObject.parseObject(body, BaseResp.class);
} }
public static boolean checkCanCash(long userId) {
// 查询当日体现次数
Integer successCashCount = cashOutDao.selectTodayCashCount(userId, 1);
CommonInfo cashLimit = commonInfoService.findOne(922);
if (cashLimit == null || StrUtil.isBlank(cashLimit.getValue())) {
logger.warn("提现必要参数未配置,请联系管理员");
return false;
}
if (successCashCount >= Integer.parseInt(cashLimit.getValue())) {
logger.warn("提现必要参数未配置,请联系管理员");
return false;
}
return true;
}
/** /**
* 提现 * 提现
* @param account 支付宝账号 * @param account 支付宝账号
* @param userName 支付宝名称 * @param userName 支付宝名称
* @return * @return
*/ */
public static BaseResp extractOrder(long userId, String outOrderNo, String amount, String account, String userName) { public static BaseResp extractOrder(String outOrderNo, String amount, String account, String userName) {
// 查询当日体现次数
Integer successCashCount = cashOutDao.selectTodayCashCount(userId, 1);
CommonInfo cashLimit = commonInfoService.findOne(922);
if (cashLimit == null || StrUtil.isBlank(cashLimit.getValue())) {
BaseResp baseResp = new BaseResp();
baseResp.setStatus(0);
baseResp.setErrorMsg("提现必要参数未配置,请联系管理员");
return baseResp;
}
if (successCashCount >= Integer.parseInt(cashLimit.getValue())) {
BaseResp baseResp = new BaseResp();
baseResp.setStatus(0);
baseResp.setErrorMsg("每日提现次数限制" + cashLimit.getValue() + "次, 您已超过上限");
return baseResp;
}
Map<String, Object> params = getBaseParams(); Map<String, Object> params = getBaseParams();