在开发中,有这么个需求:做一个砍价的功能,要求可以设置砍价人数、商品最低价、也就是砍完后最低的价格、可以砍小数(比如:56.35元)
以下是功能实现代码:
一、实现思路:
首先有一个后台管理系统、还有一个小程序。
在后台管理系统中:开发【砍价活动】功能,新增一个砍价活动,设置砍价人数、商品、商品价格、商品最低价等,新增活动的时候,在【新增砍价活动】接口中,根据砍价人数和商品价格、商品的最低价计算出对应的一个砍价随机数(有小数)的list集合,
该集合中的所有随机数加起来==能砍价的总金额数(商品价格-最低价)。集合中的个数和活动设置的参与人数是一致的(活动设置砍价人数为3人,该集合中就有三个随机数,三个随机数的总和=能砍价的总金额数)。最后存在数据库中
活动新增完后,在小程序中,可以看到该活动,用户先参与该砍价活动,参与之后,有一个【砍一刀】的功能,点击砍一刀,系统根据上一步中存的活动对应的随机数集合,随机取集合里面的一个id,根据id查询出对应的随机数、这个随机数就是用户砍了的钱数,代码进行整合一下,最后,再根据这个id把这条数据的状态修改成【删除】状态,等下一个用户也参与该砍价活动的时候,砍一刀时的随机数集合,就没有这条数据了,然后在剩余的随机数中随机获取一条。依次类推
二、砍价工具类--ReducePriceUtils:用来生成随机数集合
package com.astronaut.auction.common.utils;
import java.util.ArrayList;
import java.util.List;
/**
* @Classname ReducePriceUtils
* @Description:砍价工具类
* @Date: 2023-07-11 11:15
* @AUTHOR: 无泪之城
* @Version 1.0
*/
public class ReducePriceUtils {
/**
* 1.总金额不超过总共可砍的价格*100 单位是分
* 2.每次砍价都能砍到金额,最低不能低于1分,最大金额不能超过(总共可砍的价)*100
*/
private static final int MINMONEY = 1;
private static final int MAXMONEY = 200 * 100;
/**
* 这里为了避免某一次砍价占用大量资金,我们需要设定非最后一次砍价的最大金额,
* 我们把他设置为砍价金额平均值的N倍
*/
private static final double TIMES = 3.1;
/**
* 砍价合法性校验
*
* @param money
* @param count
* @return
*/
private static boolean isRight(int money, int count) {
double avg = money / count;
//小于最小金额
if (avg < MINMONEY) {
return false;
} else if (avg > MAXMONEY) {
return false;
}
return true;
}
/**
* 随机分配一个金额
*
* @param money
* @param minS:最小金额
* @param maxS:最大金额
* @param count
* @return
*/
private static int randomReducePrice(int money, int minS, int maxS, int count) {
//若只有一个,直接返回
if (count == 1) {
return money;
}
//如果最大金额和最小金额相等,直接返回金额
if (minS == maxS) {
return minS;
}
int max = maxS > money ? money : maxS;
//分配砍价正确情况,允许砍价的最大值
int maxY = money - (count - 1) * minS;
//分配砍价正确情况,允许砍价最小值
int minY = money - (count - 1) * maxS;
//随机产生砍价的最小值
int min = minS > minY ? minS : minY;
//随机产生砍价的最大值
max = max > maxY ? maxY : max;
//随机产生一个砍价
return (int) Math.rint(Math.random() * (max - min) + min);
}
/**
* 砍价
*
* @param money 可砍总价,*100去进行计算,后续方便除法运算
* @param count 个数
* @return
*/
public static List<Double> splitReducePrice(int money, int count) {
//红包合法性分析
if (!isRight(money, count)) {
return new ArrayList<>();
}
//红包列表
List<Double> list = new ArrayList<>();
//每个红包的最大的金额为平均金额的TIMES倍
int max = (int) (money * TIMES / count);
max = max > MAXMONEY ? MAXMONEY : max;
//分配红包
int sum = 0;
for (int i = 0; i < count; i++) {
int one = randomReducePrice(money, MINMONEY, max, count - i);
list.add(one / 100.0);
money -= one;
sum += one;
}
System.out.println("sum:" + sum);
return list;
}
public static void main(String[] args) {
List<Double> list = splitReducePrice(100, 30);
System.out.println(list);
}
}
三、砍一刀代码:
1.controller
@PostMapping("/user_kyd")
@ApiOperation("【砍一刀】-【小程序】")
public Result<Map<String,Object>> userBargainYd(@RequestBody UserBargainYdDTO dto){
Map<String,Object> map=bargainService.userBargainYd(dto);
return new Result<Map<String,Object>>().ok(map);
}
2.ServiceImpl
@Override
@Transactional(rollbackFor = Exception.class)
public Map<String,Object> userBargainYd(UserBargainYdDTO dto) {
Map<String,Object> map=new HashMap<>();
if (dto == null) {
throw new RenException("前端传入参数有误!");
}
BargainEntity bargainEntity = bargainDao.selectById(dto.getBargainId());
BargainUserEntity bargainUserEntity = bargainDao.getBargainUserAll(dto.getBargainId(),dto.getUserId());
if (bargainEntity == null) {
throw new RenException("该砍价活动不存在!");
}
if (bargainEntity.getBargainStatus()==2){
throw new RenException("该砍价活动已结束!");
}
if (bargainUserEntity.getUserBargainAmount()>0){
throw new RenException("该用户已经砍过一刀了,不能再次砍价哦!");
}
//当前砍后价
Double nowBargainAmount = bargainEntity.getNowBargainAmount();
//最低价
Double price = bargainEntity.getPrice();
//进入随机砍价的金额
Double randomAmount = nowBargainAmount - price;
//最新砍后价
Double newBargainAmount=0.00;
//判断用户是否可以砍一刀
int count = bargainDao.getBargainUserCount(dto.getBargainId());
if (count < bargainEntity.getBargainNumber()) {
if (bargainEntity.getBargainNumber() - count > 1) {
//获取用户随机砍的金额
List<Long> ids=bargainDao.getRandomIds(dto.getBargainId());
if (ids==null){
throw new RenException("该砍价活动-随机砍价金额表数据异常!");
}
Random rand = new Random();
Long id = ids.get(rand.nextInt(ids.size()));
BargainRandomEntity bargainRandomEntity=bargainRandomDao.selectById(id);
double rd = bargainRandomEntity.getAmount();
//最新砍后价
newBargainAmount = nowBargainAmount - rd;
bargainUserEntity.setUserBargainAmount(rd);
bargainUserDao.updateById(bargainUserEntity);
log.info("添加用户砍价记录-成功!" + "用户砍价金额为" + rd);
map.put("bargainAmount",rd);
//修改当前砍后价
bargainEntity.setNowBargainAmount(newBargainAmount);
bargainDao.updateById(bargainEntity);
log.info("修改当前砍后价为:" + newBargainAmount);
bargainRandomEntity.setStatus(Constant.DataStatus.DELETE.getValue());
bargainRandomDao.updateById(bargainRandomEntity);
} else if (bargainEntity.getBargainNumber() - count == 1) {
//最新砍后价
newBargainAmount = price;
bargainUserEntity.setUserBargainAmount(randomAmount);
bargainUserDao.updateById(bargainUserEntity);
log.info("添加用户砍价记录-成功!" + "用户砍价金额为" + randomAmount);
map.put("bargainAmount",randomAmount);
//修改当前砍后价、砍价表状态改为 砍价结束
bargainEntity.setNowBargainAmount(newBargainAmount);
bargainEntity.setBargainStatus(2);
bargainDao.updateById(bargainEntity);
log.info("修改当前砍后价为:" + newBargainAmount);
//遍历所有砍价用户,状态改为砍价成功!
List<Long> ids=bargainDao.getIds(dto.getBargainId());
for (Long id:ids) {
BargainUserEntity bar=bargainUserDao.selectById(id);
bar.setUserBargainStatus(1);
bargainUserDao.updateById(bar);
}
}
}
String msg = "用户砍一刀-成功!";
log.info(msg);
map.put("msg",msg);
return map;
}
标签:count,功能,return,实现,money,bargainEntity,int,砍价
From: https://www.cnblogs.com/xiaoguo-java/p/17546706.html