砍价功能实现

在开发中,有这么个需求:做一个砍价的功能,要求可以设置砍价人数、商品最低价、也就是砍完后最低的价格、可以砍小数(比如: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;
    }
posted @ 2023-07-12 09:48  青喺半掩眉砂  阅读(117)  评论(0编辑  收藏  举报