欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java開發(fā)WMS倉(cāng)庫(kù)商品預(yù)警需求示例解析

 更新時(shí)間:2022年04月27日 17:12:00   作者:Hi梅  
這篇文章主要為大家介紹了java開發(fā)WMS倉(cāng)庫(kù)商品預(yù)警需求示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1.預(yù)警需求

為了更好的管理商品日期,需要對(duì)倉(cāng)庫(kù)的商品進(jìn)行預(yù)警管理,對(duì)商品的保質(zhì)期控制在一個(gè)范圍內(nèi)提示出來(lái),也可以通過(guò)該功能間接的展示出一個(gè)商品的的銷量程度和對(duì)下次進(jìn)貨做個(gè)考量!

1. 預(yù)警需求分析

  • 前端界面需要設(shè)置商品的預(yù)警天數(shù)
  • 后端保存預(yù)警天數(shù)
  • 數(shù)據(jù)庫(kù)有字段存放商品需要預(yù)警的天數(shù)
  • 通過(guò)定時(shí)器運(yùn)行指點(diǎn)方法算出對(duì)應(yīng)那些商品的批次存低于設(shè)置的預(yù)警天數(shù)
  • 查詢出來(lái)在wms首頁(yè)展出

2.數(shù)據(jù)庫(kù)表

對(duì)于前端界面的開發(fā)不做過(guò)多的代碼分析,本次重點(diǎn)展示商品預(yù)警實(shí)現(xiàn)思路!!
數(shù)據(jù)庫(kù)用到到字段會(huì)截取出來(lái),便于理解!

商品表數(shù)據(jù):

預(yù)警表數(shù)據(jù):

商品批次表:

商品批次表中添加預(yù)警字段:后續(xù)查詢對(duì)應(yīng)的預(yù)警信息作為標(biāo)志

Mysql使用到的函數(shù)

//查詢當(dāng)前時(shí)間
select now();
//獲取時(shí)間相減 獲取到天數(shù) 參數(shù)是前面-后面
select DATEDIFF("2022-9-10", now()) as day

如:

由此我們就可以通過(guò)函數(shù)算出商品距離過(guò)期的天數(shù)

查詢語(yǔ)句:

    SELECT bb.id as batchId, bb.product_id as productId, DATEDIFF(bb.ed, now()) as warnDate
    FROM `商品批次表` bb

需要注意: 查詢或者修改表數(shù)據(jù)我們?nèi)绻灰褂媚硞€(gè)字段去修改,盡量查詢下該表更新的字段數(shù)據(jù)是否有重復(fù)的數(shù)據(jù)并且其他字段可能跟我們預(yù)想不一致,必須要修改的,我們就應(yīng)該使用多字段去查詢修改

查詢重復(fù)數(shù)據(jù)

select * from 表 GROUP BY 字段 HAVING count(*)>1

查詢預(yù)警批次數(shù)量: 因?yàn)樾枰故境鰜?lái)在前端可以給用戶點(diǎn)擊查看貨物存放的地方,所以查詢出來(lái)的數(shù)據(jù)庫(kù)存數(shù)量要大于0

select IFNULL(count(*),0) from  basic_batch bb  LEFT JOIN handle_stock hs on  bb.id=hs.batch_id where bb.is_warn_date=1 and hs.reality_number>0

2.后端代碼實(shí)現(xiàn):

1. 定時(shí)器任務(wù)

使用Scheduled作為定時(shí)器,通過(guò)cron語(yǔ)法指定運(yùn)行時(shí)間,每3小時(shí)運(yùn)行一次表達(dá)式如下

代碼詳情注釋寫的也比較清楚

    /**
     * 每3小時(shí)運(yùn)行一次
     */
    @Scheduled(cron = "0 0 0/3 * * ?")
    public void goodsWarn(){
        BasicProductGpExample basicProductGpExample = new BasicProductGpExample();
        List<String> warnBatchIds=new ArrayList<>();
        //查詢商品預(yù)警表信息 商品的貨號(hào)是唯一的 (所以現(xiàn)在是全表查詢出來(lái))
        // 這里把商品預(yù)警信息都查詢出來(lái)為了以后擴(kuò)展做庫(kù)存預(yù)警設(shè)置
        List<BasicProductGp> basicProductGps = productGpMapper.selectByExample(basicProductGpExample);
        //查詢商品批次表:商品批次和天數(shù) 商品的批次是唯一的,存在多個(gè)商品貨號(hào)(所以現(xiàn)在是全表查詢出來(lái))
        // 以后擴(kuò)展商品庫(kù)存預(yù)警只要在這個(gè)查詢里面添加關(guān)聯(lián)庫(kù)存數(shù)量查詢出來(lái),然后在過(guò)濾里面添加預(yù)警數(shù)量判斷
        List<BasicProductWarn> warnGoodsDay = basicBatchMapper.selectWarnGoodsDay();
        Long start=System.currentTimeMillis();
        for (BasicProductGp basicProductGp : basicProductGps) {
            //商品預(yù)警日期
            Integer warnDate = basicProductGp.getWarnDate();
            //商品貨號(hào)編碼
            Integer productId = basicProductGp.getProductId();
            //查詢出符合預(yù)警的商品批次
            List<String> warnBatchId = warnGoodsDay.stream().filter(warnGood -> warnGood.getProductId().equals(productId) && warnGood.getWarnDate() <= warnDate)
                    .map(BasicProductWarn::getBatchId).collect(Collectors.toList());
            warnBatchIds.addAll(warnBatchId);
        }
        Long end=System.currentTimeMillis();
        log.info("消耗時(shí)長(zhǎng):"+(end-start)/1000+"秒");
        //獲取出所有需要提醒的批次號(hào)
        log.info(Arrays.toString(warnBatchIds.toArray()));
        //數(shù)組為空時(shí)不更新
        if (CollectionUtils.isEmpty(warnBatchIds)){
            log.info("沒(méi)有需要預(yù)警的商品批次!");
            return;
        }
        //修改批次狀態(tài)為1標(biāo)識(shí)預(yù)警日期已經(jīng)到達(dá)
        //使用boolean類型保存數(shù)據(jù)庫(kù)會(huì)自動(dòng)把true轉(zhuǎn)換成1
        int count = basicBatchMapper.updateByBatchWarn(warnBatchIds, true);
        log.info("更新預(yù)警數(shù)量:{}",count);
    }

這里面還存在一個(gè)問(wèn)題,如果批次被打上預(yù)警標(biāo)識(shí),此時(shí)客戶更改了商品的預(yù)警日期,那么商品的預(yù)警可能就沒(méi)有到達(dá),但是頁(yè)面查詢預(yù)警也能被查詢出來(lái),解決方案,使用mq來(lái)做處理,當(dāng)客戶更改了商品編碼預(yù)警信息,那么程序就把更改的商品編碼存到mq中我們?cè)趯憘€(gè)消費(fèi)方法來(lái)消費(fèi)更改后的商品編碼單獨(dú)走波預(yù)警方法

2.優(yōu)化加入隊(duì)列

先不考慮全局預(yù)警設(shè)置,只對(duì)勾選多個(gè)商品進(jìn)行添加隊(duì)列

使用了springBoot的rabbitMq模板類RabbitTemplate

pom.xml引入:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

生產(chǎn)者添加消息到隊(duì)列中

       //存入隊(duì)列                        routingkey名稱  存入的數(shù)據(jù)
       rabbitTemplate.convertAndSend("warnGoodsQueue",ids);

消費(fèi)者:

/**
 * 消費(fèi)預(yù)警隊(duì)列信息
 */
@Configuration
@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "warnGoodsQueue", durable = "true"),
        exchange = @Exchange(value = "warnGoodsExchange",
                ignoreDeclarationExceptions = "true",
                type = ExchangeTypes.TOPIC),
        key = {"warnGoodsQueue"}))
public class WarnGoodsQueue {

    @RabbitHandler
    public void process(List<String> ids) {
        if (ids == null) {
            System.out.println("空");
        }
        System.out.println(ids);
    }
}

3.注意:關(guān)于Mq

生產(chǎn)者,生產(chǎn)的數(shù)據(jù)類型一定要要和消費(fèi)者獲取的類型要一致,否則會(huì)無(wú)限循環(huán)報(bào)錯(cuò)

Listener threw exception
No method found for class [B

4.測(cè)試是否成功

生產(chǎn)者存入隊(duì)列:

消費(fèi)者獲取數(shù)據(jù):

如果消費(fèi)方法報(bào)錯(cuò)不try/catch的話,隊(duì)列就會(huì)一直重試該條數(shù)據(jù)

可以看出已經(jīng)獲取到修改預(yù)警商品的商品編號(hào),這個(gè)時(shí)候我們只要寫方法做相應(yīng)的處理就行了
我們也可以去RabbitMq管理界面查看隊(duì)列信息

消費(fèi)方法代碼:

public void updateWarnGoods(List<Integer> ids){
        if (CollectionUtils.isEmpty(ids)){
            return;
        }
        BasicProductGpExample example = new BasicProductGpExample();
        example.createCriteria().andProductIdIn(ids);
        //查詢商品信息 商品的貨號(hào)是唯一的 (查詢變動(dòng)的商品貨號(hào))
        List<BasicProductGp> basicProductGps = productGpMapper.selectByExample(example);

        //商品批次和天數(shù) 商品的批次是唯一的,存在多個(gè)商品貨號(hào)(查詢變動(dòng)的商品貨號(hào))
        List<BasicProductWarn> warnGoodsDay = basicBatchMapper.selectWarnGoodsDayList(ids);
        //需要預(yù)警的集合
        List<String> warnBatchIds=new ArrayList<>();
        //不需要預(yù)警的集合
        List<String> notWarnBatchIds=new ArrayList<>();

        Long start=System.currentTimeMillis();
        for (BasicProductGp basicProductGp : basicProductGps) {
            //商品預(yù)警日期
            Integer warnDate = basicProductGp.getWarnDate();
            //商品貨號(hào)編碼
            Integer productId = basicProductGp.getProductId();
            //查詢出符合預(yù)警的商品批次
            List<String> warnBatchId = warnGoodsDay.stream().filter(warnGood -> {
                if (warnGood.getProductId().equals(productId)){
                    //匹配到的商品數(shù)據(jù)
                    //2種情況:一種要預(yù)警另外一種不要預(yù)警
                    if (warnGood.getWarnDate() <= warnDate){
                        //預(yù)警的返回
                        return true;
                    }
                    //不要預(yù)警的添加到不預(yù)警集合用于更新
                    notWarnBatchIds.add(warnGood.getBatchId());
                }
                return false;
            }).map(BasicProductWarn::getBatchId).collect(Collectors.toList());

            //把預(yù)警集合添加到預(yù)警大集合中
            warnBatchIds.addAll(warnBatchId);
        }
        long end=System.currentTimeMillis();
        log.info("更新預(yù)警商品耗時(shí):{}秒",(end-start)/1000);
        //結(jié)束后會(huì)得到2種集合:不預(yù)警和要預(yù)警集合

        //更新未預(yù)警商品
        if (!CollectionUtils.isEmpty(notWarnBatchIds)){
            int count = basicBatchMapper.updateByBatchWarn(notWarnBatchIds, false);
            log.info("更新預(yù)警數(shù)量:{}",count);
        }
        //更新預(yù)警商品
        if (!CollectionUtils.isEmpty(warnBatchIds)){
            int count = basicBatchMapper.updateByBatchWarn(warnBatchIds, true);
            log.info("更新預(yù)警數(shù)量:{}",count);
        }
    }

關(guān)于一些代碼存在冗余我們可以提取成一個(gè)公共方法進(jìn)行調(diào)用,后續(xù)也對(duì)全局修改預(yù)警Mq隊(duì)列走波運(yùn)算預(yù)警的商品

重載方法:

/***
     * 重載方法
     * 用于運(yùn)算全局商品類型
     * 用于更新商品預(yù)警時(shí)間
     */
    public void updateWarnGoods(){
        BasicProductGpExample example = new BasicProductGpExample();
        //查詢商品信息 商品的貨號(hào)是唯一的 (查詢變動(dòng)的商品貨號(hào))
        List<BasicProductGp> basicProductGps = productGpMapper.selectByExample(example);

        //商品批次和天數(shù) 商品的批次是唯一的,存在多個(gè)商品貨號(hào)(查詢變動(dòng)的商品貨號(hào))
        List<BasicProductWarn> warnGoodsDay = basicBatchMapper.selectWarnGoodsDay();
        //需要預(yù)警的集合
        List<String> warnBatchIds=new ArrayList<>();
        //不需要預(yù)警的集合
        List<String> notWarnBatchIds=new ArrayList<>();

        Long start=System.currentTimeMillis();
        for (BasicProductGp basicProductGp : basicProductGps) {
            //商品預(yù)警日期
            Integer warnDate = basicProductGp.getWarnDate();
            //商品貨號(hào)編碼
            Integer productId = basicProductGp.getProductId();
            //查詢出符合預(yù)警的商品批次
            List<String> warnBatchId = warnGoodsDay.stream().filter(warnGood -> {
                if (warnGood.getProductId().equals(productId)){
                    //匹配到的商品數(shù)據(jù)
                    //2種情況:一種要預(yù)警另外一種不要預(yù)警
                    if (warnGood.getWarnDate() <= warnDate){
                        //預(yù)警的返回
                        return true;
                    }
                    //不要預(yù)警的添加到不預(yù)警集合用于更新
                    notWarnBatchIds.add(warnGood.getBatchId());
                }
                return false;
            }).map(BasicProductWarn::getBatchId).collect(Collectors.toList());

            //把預(yù)警集合添加到預(yù)警大集合中
            warnBatchIds.addAll(warnBatchId);
        }
        long end=System.currentTimeMillis();
        log.info("更新預(yù)警商品耗時(shí):{}秒",(end-start)/1000);
        //結(jié)束后會(huì)得到2種集合:不預(yù)警和要預(yù)警集合

        //更新未預(yù)警商品
        if (!CollectionUtils.isEmpty(notWarnBatchIds)){
            int count = basicBatchMapper.updateByBatchWarn(notWarnBatchIds, false);
            log.info("更新預(yù)警數(shù)量:{}",count);
        }
        //更新預(yù)警商品
        if (!CollectionUtils.isEmpty(warnBatchIds)){
            int count = basicBatchMapper.updateByBatchWarn(warnBatchIds, true);
            log.info("更新預(yù)警數(shù)量:{}",count);
        }
    }

3.前端提一嘴

給商品添加預(yù)警日期,需要用戶提些數(shù)據(jù),為了避免出現(xiàn)英文空格等我們需要,對(duì)輸入的數(shù)據(jù)進(jìn)行正則,只能輸入數(shù)字

效果:

英文:

但是可以輸入0,如果預(yù)警日期設(shè)置成了0你們就意味著廢棄該商品預(yù)警提示功能

前端展示:

首頁(yè):

預(yù)警商品列表:

以上就是java開發(fā)WMS倉(cāng)庫(kù)商品預(yù)警需求示例解析的詳細(xì)內(nèi)容,更多關(guān)于java開發(fā)WMS倉(cāng)庫(kù)商品預(yù)警的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論