首页 > 其他分享 >砍价功能实现

砍价功能实现

时间:2023-07-12 09:55:08浏览次数:31  
标签:count 功能 return 实现 money bargainEntity int 砍价

在开发中,有这么个需求:做一个砍价的功能,要求可以设置砍价人数、商品最低价、也就是砍完后最低的价格、可以砍小数(比如: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

相关文章

  • 分布式多协议接入网关FluxMQ-2.0功能说明
    FluxMQ—2.0版本更新内容前言FLuxMQ是一款基于java开发,支持无限设备连接的云原生分布式物联网接入平台。FluxMQ基于Netty开发,底层采用Reactor3反应堆模型,具备低延迟,高吞吐量,千万、亿级别设备连接;方便企业快速构建其物联网平台与应用。FluxMQ官网:https://www.fluxmq.comFluxMQ......
  • linux shell脚本实现删除连续的空行为一行
     001、awk实现[root@PC1test02]#lsa.txt[root@PC1test02]#cata.txt##测试数据010203040506070809101112131415161718192021222324252627282930##将多个连续的空行压缩为一个空行[root@PC1tes......
  • Unix C的Http服务器技术实现原理
    基于tiny-httpd的一个httpserver,可处理GET和POST请求。知识范围:POSIX接口pipe(intarr[2])pipe(intarr[2]);使用pipe会创建通道,arr[0]为读,arr[1]为写。dup2-复制文件描述符这个fd我目前理解是用来读数据的,使用dup2相当于直接复制了oldfd对应的数据dup2(oldfd,newfd)......
  • 使用LabVIEW实现 DeepLabv3+ 语义分割含源码
    (文章目录)前言图像分割可以分为两类:语义分割(SemanticSegmentation)和实例分割(InstanceSegmentation),前面已经给大家介绍过两者的区别,并就如何在labview上实现相关模型的部署也给大家做了讲解,今天和大家分享如何使用labview实现deeplabv3+的语义分割,并就PascalVOC2012(DeepL......
  • linux 中sed命令的标签和跳转功能
     001、[root@PC1test02]#lsa.txt[root@PC1test02]#cata.txt##测试数据01020304050607080910[root@PC1test02]#sed':a;N;s/\n//;ta'a.txt##将多行数据转换为一行数据01020304050607080910 命令解释: sed默认只按行......
  • Burp Suite证书安装流程和主要模块功能介绍
    BurpSuite证书添加流程和模块功能介绍1. 打开Google浏览器,右上角打开设置2. 打开后是这样的3. 然后打开隐私和安全4. 打开右边菜单栏的安全5. 点击管理设备证书6. 点击中间证书颁发机构按照上面的顺序点击点击浏览,导入刚刚导出的der文件,下一步点......
  • 通达信金融终端解锁Level-2功能 续二 (非法调试 I say NO)
    图一:1. 破解后的逐笔分析可以不受条件正常运行。2. 打开调试,被防止非法调试代码阻拦。3. 只好关闭调试。4.立马spell符文"ShipSheep,CheapChips,ShiftShit,BullRed"5. 再次打开调试,受到符文回路解放,调试白给。    图二:1. 白给调试后,重新刷新页面2.......
  • 注解开发实现为第三方bean注入资源
     简单类型直接注入,使用Value注解 引用类型使用形参注入,只要在包下存在这个bean,容器就会自动装配注入,而且使用的是按类型装配......
  • 【857】R语言实现字符串操作、补零操作
    ref:AddLeadingZerostotheElementsofaVectorinR 参考代码:#数组>seq(12)[1]123456789101112#格式化打印,自动补零>sprintf("%02d",seq(12))[1]"01""02""03""04""05&......
  • 【.NET源码解读】深入剖析中间件的设计与实现
    合集-.NET源码解读系列(4) 1..NET通过源码深究依赖注入原理05-172.【.NET源码解读】Configuration组件及自动更新05-303..NET源码解读kestrel服务器及创建HttpContext对象流程06-164.【.NET源码解读】深入剖析中间件的设计与实现06-29收起 .NET本身就是一个基于......