redis 方法封装

抽奖金额概率 配置
banner 跳转类型
This commit is contained in:
wangw 2024-12-13 10:53:40 +08:00
parent 4227ece60a
commit 73631f76a7
9 changed files with 334 additions and 153 deletions

View File

@ -9,4 +9,8 @@ public class RedisKeys {
public static String getSysConfigKey(String key){
return "sys:config:" + key;
}
public static String getDateKey(String key){
return "date:" + key;
}
}

View File

@ -1,10 +1,14 @@
package com.sqx.common.utils;
import com.google.gson.Gson;
import com.sqx.modules.redisService.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.concurrent.TimeUnit;
/**
@ -13,6 +17,8 @@ import java.util.concurrent.TimeUnit;
*/
@Component
public class RedisUtils {
@Autowired
private RedisService redisService;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
@ -31,6 +37,37 @@ public class RedisUtils {
public final static long NOT_EXPIRE = -1;
private final static Gson Gson = new Gson();
/**
* 获取缓存里的数据 如果不存在 则插入 并返回
* @param key redis Key
* @param clazz 返回类型
* @param method RedisService调用的方法名 如果数据不存在会执行该调用方法
*/
public <T> T getDate(String key, Class<T> clazz,String method) {
if (!this.hasKey(key)) {
try {
// 获取Lookup对象
MethodHandles.Lookup lookup = MethodHandles.lookup();
// 构建方法类型这里假设方法无参数返回类型为void
MethodType methodType = MethodType.methodType(void.class , String.class);
// 获取方法句柄
MethodHandle methodHandle = lookup.findVirtual(redisService.getClass(), method, methodType);
// 调用方法句柄
methodHandle.invoke(redisService,key);
} catch (Exception e) {
e.printStackTrace();
return null;
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
return this.get(key, clazz);
}
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
public void set(String key, Object value, long expire){
valueOperations.set(key, toJson(value));
if(expire != NOT_EXPIRE){

View File

@ -53,6 +53,10 @@ public class Banner implements Serializable {
* 分类 1 banner图 2 首页分类
*/
private Integer classify;
/**
* 跳转类型 1 内部 2 外部
*/
private Integer jumpType;
/**
* 跳转地址

View File

@ -0,0 +1,65 @@
package com.sqx.modules.discSpinning.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.utils.RedisKeys;
import com.sqx.common.utils.RedisUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.discSpinning.entity.DiscSpinningAmount;
import com.sqx.modules.discSpinning.service.DiscSpinningAmountService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
@Api(value = "现金红包 抽奖配置", tags = {"现金红包 抽奖金额配置"})
@RequestMapping(value = "/discSpinningAmount")
public class DiscSpinningAmountController {
/**
* 服务对象
*/
@Autowired
private DiscSpinningAmountService discSpinningAmountService;
@Autowired
private RedisUtils redisUtils;
@PostMapping("/insertDiscSpinningAmount")
@ApiOperation("添加现金红包 抽奖配置")
public Result insertDiscSpinningAmount(@RequestBody DiscSpinningAmount discSpinningAmount) {
discSpinningAmountService.save(discSpinningAmount);
redisUtils.delete(RedisKeys.getDateKey("spinning:amount"));
return Result.success();
}
@GetMapping("/{id}")
@ApiOperation("通过Id查询详情")
public Result selectOne(@PathVariable Integer id) {
return Result.success().put("data", discSpinningAmountService.getById(id));
}
@PostMapping("/updateDiscSpinningAmount")
@ApiOperation("修改现金红包 抽奖配置")
public Result updateDiscSpinningAmount(@RequestBody DiscSpinningAmount discSpinningAmount) {
discSpinningAmountService.updateById(discSpinningAmount);
redisUtils.delete(RedisKeys.getDateKey("spinning:amount"));
return Result.success();
}
@PostMapping("/deleteDiscSpinningAmount")
@ApiOperation("删除现金红包 抽奖配置")
public Result deleteDiscSpinningAmount(Long id) {
discSpinningAmountService.removeById(id);
redisUtils.delete(RedisKeys.getDateKey("spinning:amount"));
return Result.success();
}
@GetMapping("/selectDiscSpinningAmount")
@ApiOperation("查询现金红包 抽奖配置")
public Result selectDiscSpinningAmount(Integer page, Integer limit) {
return Result.success().put("data", discSpinningAmountService.page(new Page<>(page, limit), new QueryWrapper<DiscSpinningAmount>().orderByDesc("status").orderByAsc("random","max_amount")));
}
}

View File

@ -1,44 +1,27 @@
package com.sqx.modules.discSpinning.controller;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.annotation.Debounce;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.entity.UserEntity;
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.app.service.UserService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.discSpinning.entity.DiscSpinning;
import com.sqx.modules.discSpinning.entity.DiscSpinningAmount;
import com.sqx.modules.discSpinning.entity.DiscSpinningRecord;
import com.sqx.modules.discSpinning.service.DiscSpinningAmountService;
import com.sqx.modules.discSpinning.service.DiscSpinningRecordService;
import com.sqx.modules.discSpinning.service.DiscSpinningService;
import com.sqx.modules.orders.entity.Orders;
import com.sqx.modules.orders.service.OrdersService;
import com.sqx.modules.pay.entity.CashOut;
import com.sqx.modules.pay.service.CashOutService;
import com.sqx.modules.pay.wuyou.BaseResp;
import com.sqx.modules.pay.wuyou.WuyouPay;
import com.sqx.modules.taskCenter.service.TaskCenterService;
import com.sqx.modules.utils.AliPayOrderUtil;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import reactor.util.annotation.Nullable;
import springfox.documentation.annotations.ApiIgnore;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.CompletableFuture;
@ -50,34 +33,20 @@ public class DiscSpinningController {
private final DiscSpinningService discSpinningService;
private final DiscSpinningRecordService recordService;
private final DiscSpinningAmountService amountService;
private final CommonInfoService commonRepository;
private final OrdersService ordersService;
private final UserMoneyService userMoneyService;
private final UserMoneyDetailsService userMoneyDetailsService;
private final UserService userService;
private final CashOutService cashOutService;
private final TaskCenterService taskCenterService;
@Autowired
public DiscSpinningController(CommonInfoService commonRepository, DiscSpinningService discSpinningService,
UserMoneyDetailsService userMoneyDetailsService, CashOutService cashOutService,
OrdersService ordersService, DiscSpinningRecordService recordService,
UserMoneyService userMoneyService, UserService userService,
TaskCenterService taskCenterService, DiscSpinningAmountService amountService
TaskCenterService taskCenterService
) {
this.commonRepository = commonRepository;
this.discSpinningService = discSpinningService;
this.amountService = amountService;
this.ordersService = ordersService;
this.recordService = recordService;
this.userMoneyService = userMoneyService;
this.userMoneyDetailsService = userMoneyDetailsService;
this.userService = userService;
this.cashOutService = cashOutService;
this.taskCenterService = taskCenterService;
}
@PostMapping("/discSpinning/insertDiscSpinning")
@ -193,7 +162,7 @@ public class DiscSpinningController {
}
}
return new Result().put("data",
draws(amount, orderId, userId, maps == null || maps.get("source") == null ? "order" : maps.get("source").toString()));
discSpinningService.draws(amount, orderId, userId, maps == null || maps.get("source") == null ? "order" : maps.get("source").toString()));
}
@ApiOperation("大转盘奖项领取")
@ -202,121 +171,9 @@ public class DiscSpinningController {
public Result receive(@RequestBody DiscSpinningRecord receive) {
DiscSpinningRecord record = recordService.getById(receive.getId());
CompletableFuture.runAsync(() -> {
receiveAsync(record);
discSpinningService.receiveAsync(record);
});
return Result.success();
}
@Transactional
public void receiveAsync(DiscSpinningRecord receive) {
if (receive.getType() != 2) {
return;
}
UserEntity userInfo = userService.queryByUserId(receive.getUserId());
UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
receive.getUserId(), null, null, "[现金大转盘]", 5, 1, 2,
receive.getNumber(), "现金红包奖励" + receive.getNumber() + "", 1);
//上一秒
userMoneyDetails.setCreateTime(DateUtil.format(new Date(System.currentTimeMillis() - 1000), "yyyy-MM-dd HH:mm:ss"));
userMoneyDetailsService.save(userMoneyDetails);
receive.setTarget("2");
receive.setTargetId(userMoneyDetails.getId());
recordService.updateById(receive);
//存入余额
userMoneyService.updateAmount(1, receive.getUserId(), receive.getNumber().doubleValue());
if (receive.getNumber().compareTo(new BigDecimal("0.1")) > 0 && StringUtils.isNotBlank(userInfo.getZhiFuBao()) && StringUtils.isNotBlank(userInfo.getZhiFuBaoName())) {
//提现
withdraw(userInfo, receive.getNumber().doubleValue());
}
}
@Transactional
public void withdraw(UserEntity userInfo, Double money) {
CashOut cashOut = new CashOut();
cashOut.setIsOut(false);
cashOut.setMoney(money.toString());
cashOut.setUserId(userInfo.getUserId());
cashOut.setZhifubao(userInfo.getZhiFuBao());
cashOut.setZhifubaoName(userInfo.getZhiFuBaoName());
cashOut.setState(0);
cashOut.setRate(0.00);
cashOut.setUserType(1);
cashOut.setCreateAt(DateUtil.now());
UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
userInfo.getUserId(), null, null, "[现金大转盘]", 4, 2, 1,
new BigDecimal(money), "现金红包自动提现" + money + "", 1);
userMoneyDetailsService.save(userMoneyDetails);
//减去余额
userMoneyService.updateAmount(2, userInfo.getUserId(), money);
//最高提现金额
CommonInfo one2 = commonRepository.findOne(910);
if (one2 == null || money <= Double.parseDouble(one2.getValue())) {
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 if (StringUtils.isNotBlank(baseResp.getErrorMsg())) {
cashOut.setState(2);
cashOut.setRefund(baseResp.getErrorMsg());
}
}
cashOutService.saveBody(cashOut);
}
@Transactional
public DiscSpinningRecord draws(double orderAmount, Long orderId, Long userId, String source) {
DiscSpinning result = new DiscSpinning("谢谢惠顾", 1, null);
List<DiscSpinning> prizes = discSpinningService.list(new QueryWrapper<DiscSpinning>().eq("disc_type", "order".equals(source) ? 1 : 2).orderByAsc("odds"));
Random random = new Random();
double randomDouble;
do {
randomDouble = random.nextDouble();
} while (randomDouble == 0);
BigDecimal randomNum = new BigDecimal(randomDouble).multiply(new BigDecimal(10000)).divide(new BigDecimal(100));
List<DiscSpinningAmount> amounts = amountService.list(new QueryWrapper<DiscSpinningAmount>().eq("status",1).orderByAsc("max_amount"));
for (DiscSpinning prize : prizes) {
if (randomNum.compareTo(prize.getNumber()) < 0) {
if (prize.getType() == 2) {
int maxAmount = Integer.parseInt(commonRepository.findOne(900).getValue());
double resultAmount = 0;
if (prize.getType() == 2) {
double baseRandom = random.nextDouble();
double baseAmount = 0;
for (DiscSpinningAmount amount : amounts) {
if (baseRandom < amount.getRandom()) {
resultAmount = baseAmount + random.nextDouble() * (amount.getMaxAmount() - baseAmount);
break;
}
baseAmount = amount.getMaxAmount();
}
if (resultAmount < 0.01) {
resultAmount = 0.01;
}
resultAmount = orderAmount + resultAmount;
if (resultAmount > maxAmount) {
resultAmount = maxAmount;
}
}
result = new DiscSpinning(prize.getName(), 2, new BigDecimal(resultAmount).setScale(2, RoundingMode.HALF_UP));
break;
}
// else {
// result = prize;
// }
}
}
DiscSpinningRecord record = new DiscSpinningRecord(result.getName(), orderId, userId, result.getType(),
result.getNumber(), DateUtils.formatYMD(new Date()), DateUtils.format(new Date()), source);
recordService.save(record);
return record;
}
}

View File

@ -1,11 +1,21 @@
package com.sqx.modules.discSpinning.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.discSpinning.entity.DiscSpinning;
import java.util.Map;
import com.sqx.modules.discSpinning.entity.DiscSpinningRecord;
public interface DiscSpinningService extends IService<DiscSpinning> {
//抽奖
DiscSpinningRecord draws(double orderAmount, Long orderId, Long userId, String source);
//领奖
void receiveAsync(DiscSpinningRecord receive);
//提现
void withdraw(UserEntity userInfo, Double money);
}

View File

@ -1,21 +1,188 @@
package com.sqx.modules.discSpinning.service.impl;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.RedisKeys;
import com.sqx.common.utils.RedisUtils;
import com.sqx.modules.app.entity.UserEntity;
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.app.service.UserService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.discSpinning.dao.DiscSpinningDao;
import com.sqx.modules.discSpinning.entity.DiscSpinning;
import com.sqx.modules.discSpinning.entity.DiscSpinningAmount;
import com.sqx.modules.discSpinning.entity.DiscSpinningRecord;
import com.sqx.modules.discSpinning.service.DiscSpinningAmountService;
import com.sqx.modules.discSpinning.service.DiscSpinningRecordService;
import com.sqx.modules.discSpinning.service.DiscSpinningService;
import org.springframework.stereotype.Service;
import com.sqx.modules.orders.service.OrdersService;
import com.sqx.modules.pay.entity.CashOut;
import com.sqx.modules.pay.service.CashOutService;
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 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
@Service
public class DiscSpinningServiceImpl extends ServiceImpl<DiscSpinningDao, DiscSpinning> implements DiscSpinningService {
@Autowired
private DiscSpinningDao discSpinningDao;
private final DiscSpinningRecordService recordService;
private final DiscSpinningAmountService amountService;
private final CommonInfoService commonRepository;
private final OrdersService ordersService;
private final UserMoneyService userMoneyService;
private final UserMoneyDetailsService userMoneyDetailsService;
private final UserService userService;
private final CashOutService cashOutService;
private final RedisUtils redisUtils;
@Autowired
public DiscSpinningServiceImpl(CommonInfoService commonRepository,
UserMoneyDetailsService userMoneyDetailsService, CashOutService cashOutService,
OrdersService ordersService, DiscSpinningRecordService recordService,
UserMoneyService userMoneyService, UserService userService,
DiscSpinningAmountService amountService,RedisUtils redisUtils
) {
this.commonRepository = commonRepository;
this.amountService = amountService;
this.ordersService = ordersService;
this.recordService = recordService;
this.userMoneyService = userMoneyService;
this.userMoneyDetailsService = userMoneyDetailsService;
this.userService = userService;
this.cashOutService = cashOutService;
this.redisUtils = redisUtils;
}
@Override
@Transactional
public void receiveAsync(DiscSpinningRecord receive) {
if (receive.getType() != 2) {
return;
}
UserEntity userInfo = userService.queryByUserId(receive.getUserId());
UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
receive.getUserId(), null, null, "[现金大转盘]", 5, 1, 2,
receive.getNumber(), "现金红包奖励" + receive.getNumber() + "", 1);
//上一秒
userMoneyDetails.setCreateTime(DateUtil.format(new Date(System.currentTimeMillis() - 1000), "yyyy-MM-dd HH:mm:ss"));
userMoneyDetailsService.save(userMoneyDetails);
receive.setTarget("2");
receive.setTargetId(userMoneyDetails.getId());
recordService.updateById(receive);
//存入余额
userMoneyService.updateAmount(1, receive.getUserId(), receive.getNumber().doubleValue());
if (receive.getNumber().compareTo(new BigDecimal("0.1")) > 0 && StringUtils.isNotBlank(userInfo.getZhiFuBao()) && StringUtils.isNotBlank(userInfo.getZhiFuBaoName())) {
//提现
withdraw(userInfo, receive.getNumber().doubleValue());
}
}
@Override
@Transactional
public void withdraw(UserEntity userInfo, Double money) {
CashOut cashOut = new CashOut();
cashOut.setIsOut(false);
cashOut.setMoney(money.toString());
cashOut.setUserId(userInfo.getUserId());
cashOut.setZhifubao(userInfo.getZhiFuBao());
cashOut.setZhifubaoName(userInfo.getZhiFuBaoName());
cashOut.setState(0);
cashOut.setRate(0.00);
cashOut.setUserType(1);
cashOut.setCreateAt(DateUtil.now());
UserMoneyDetails userMoneyDetails = new UserMoneyDetails(
userInfo.getUserId(), null, null, "[现金大转盘]", 4, 2, 1,
new BigDecimal(money), "现金红包自动提现" + money + "", 1);
userMoneyDetailsService.save(userMoneyDetails);
//减去余额
userMoneyService.updateAmount(2, userInfo.getUserId(), money);
//最高提现金额
CommonInfo one2 = commonRepository.findOne(910);
if (one2 == null || money <= Double.parseDouble(one2.getValue())) {
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 if (StringUtils.isNotBlank(baseResp.getErrorMsg())) {
cashOut.setState(2);
cashOut.setRefund(baseResp.getErrorMsg());
}
}
cashOutService.saveBody(cashOut);
}
@Override
@Transactional
public DiscSpinningRecord draws(double orderAmount, Long orderId, Long userId, String source) {
DiscSpinning result = new DiscSpinning("谢谢惠顾", 1, null);
List<DiscSpinning> prizes = baseMapper.selectList(new QueryWrapper<DiscSpinning>().eq("disc_type", "order".equals(source) ? 1 : 2).orderByAsc("odds"));
Random random = new Random();
double randomDouble;
do {
randomDouble = random.nextDouble();
} while (randomDouble == 0);
BigDecimal randomNum = new BigDecimal(randomDouble).multiply(new BigDecimal(10000)).divide(new BigDecimal(100));
List<DiscSpinningAmount> amounts = redisUtils.getDate(RedisKeys.getDateKey("spinning:amount"), ArrayList.class, "setDiscSpinningAmounts");
for (DiscSpinning prize : prizes) {
if (randomNum.compareTo(prize.getNumber()) < 0) {
if (prize.getType() == 2) {
int maxAmount = Integer.parseInt(commonRepository.findOne(900).getValue());
double resultAmount = 0;
if (prize.getType() == 2) {
double baseRandom = random.nextDouble();
double baseAmount = 0;
for (DiscSpinningAmount amount : amounts) {
if (baseRandom < amount.getRandom()) {
resultAmount = baseAmount + random.nextDouble() * (amount.getMaxAmount() - baseAmount);
break;
}
baseAmount = amount.getMaxAmount();
}
if (resultAmount < 0.01) {
resultAmount = 0.01;
}
resultAmount = orderAmount + resultAmount;
if (resultAmount > maxAmount) {
resultAmount = maxAmount;
}
}
result = new DiscSpinning(prize.getName(), 2, new BigDecimal(resultAmount).setScale(2, RoundingMode.HALF_UP));
break;
}
// else {
// result = prize;
// }
}
}
DiscSpinningRecord record = new DiscSpinningRecord(result.getName(), orderId, userId, result.getType(),
result.getNumber(), DateUtils.formatYMD(new Date()), DateUtils.format(new Date()), source);
recordService.save(record);
return record;
}
}

View File

@ -0,0 +1,11 @@
package com.sqx.modules.redisService;
/**
* 进行redis 缓存数据初始化
* 参数key 必须存在
*/
public interface RedisService {
void setDiscSpinningAmounts(String key);
}

View File

@ -0,0 +1,26 @@
package com.sqx.modules.redisService.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sqx.common.utils.RedisUtils;
import com.sqx.modules.discSpinning.entity.DiscSpinningAmount;
import com.sqx.modules.discSpinning.service.DiscSpinningAmountService;
import com.sqx.modules.redisService.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class RedisServiceImpl implements RedisService {
@Lazy
@Autowired
private RedisUtils redisUtils;
@Autowired
private DiscSpinningAmountService amountService;
@Override
public void setDiscSpinningAmounts(String key) {
List<DiscSpinningAmount> amounts = amountService.list(new QueryWrapper<DiscSpinningAmount>().eq("status", 1).orderByAsc("max_amount"));
redisUtils.set(key, amounts);
}
}