最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

1.預警需求

為了更好的管理商品日期,需要對倉庫的商品進行預警管理,對商品的保質期控制在一個范圍內提示出來,也可以通過該功能間接的展示出一個商品的的銷量程度和對下次進貨做個考量!

1. 預警需求分析

  • 前端界面需要設置商品的預警天數(shù)
  • 后端保存預警天數(shù)
  • 數(shù)據(jù)庫有字段存放商品需要預警的天數(shù)
  • 通過定時器運行指點方法算出對應那些商品的批次存低于設置的預警天數(shù)
  • 查詢出來在wms首頁展出

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

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

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

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

商品批次表:

商品批次表中添加預警字段:后續(xù)查詢對應的預警信息作為標志

Mysql使用到的函數(shù)

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

如:

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

查詢語句:

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

需要注意: 查詢或者修改表數(shù)據(jù)我們如果只要使用某個字段去修改,盡量查詢下該表更新的字段數(shù)據(jù)是否有重復的數(shù)據(jù)并且其他字段可能跟我們預想不一致,必須要修改的,我們就應該使用多字段去查詢修改

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

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

查詢預警批次數(shù)量: 因為需要展示出來在前端可以給用戶點擊查看貨物存放的地方,所以查詢出來的數(shù)據(jù)庫存數(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.后端代碼實現(xiàn):

1. 定時器任務

使用Scheduled作為定時器,通過cron語法指定運行時間,每3小時運行一次表達式如下

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

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

這里面還存在一個問題,如果批次被打上預警標識,此時客戶更改了商品的預警日期,那么商品的預警可能就沒有到達,但是頁面查詢預警也能被查詢出來,解決方案,使用mq來做處理,當客戶更改了商品編碼預警信息,那么程序就把更改的商品編碼存到mq中我們在寫個消費方法來消費更改后的商品編碼單獨走波預警方法

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

先不考慮全局預警設置,只對勾選多個商品進行添加隊列

使用了springBoot的rabbitMq模板類RabbitTemplate

pom.xml引入:

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

生產者添加消息到隊列中

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

消費者:

/**
 * 消費預警隊列信息
 */
@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.注意:關于Mq

生產者,生產的數(shù)據(jù)類型一定要要和消費者獲取的類型要一致,否則會無限循環(huán)報錯

Listener threw exception
No method found for class [B

4.測試是否成功

生產者存入隊列:

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

如果消費方法報錯不try/catch的話,隊列就會一直重試該條數(shù)據(jù)

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

消費方法代碼:

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

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

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

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

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

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

重載方法:

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

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

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

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

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

3.前端提一嘴

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

效果:

英文:

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

前端展示:

首頁:

預警商品列表:

以上就是java開發(fā)WMS倉庫商品預警需求示例解析的詳細內容,更多關于java開發(fā)WMS倉庫商品預警的資料請關注腳本之家其它相關文章!

相關文章

  • IDEA搭建SpringBoot多模塊聚合工程過程詳解(多模塊聚合工程)

    IDEA搭建SpringBoot多模塊聚合工程過程詳解(多模塊聚合工程)

    這篇文章主要是介紹一下,如何在IDEA開發(fā)工具下,搭建一個基于SpringBoot的多模塊聚合工程項目,本篇文章,將項目模塊細分為幾個子工程模塊,在文中給大家詳細介紹過,對IDEA搭建SpringBoot多模塊聚合工程感興趣的朋友一起看看吧
    2022-04-04
  • 使用Feign消費服務時POST/GET請求方式詳解

    使用Feign消費服務時POST/GET請求方式詳解

    這篇文章主要介紹了使用Feign消費服務時POST/GET請求方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java進階:Struts多模塊的技巧

    Java進階:Struts多模塊的技巧

    Java進階:Struts多模塊的技巧...
    2006-12-12
  • mybatis中xml之trim屬性說明

    mybatis中xml之trim屬性說明

    這篇文章主要介紹了mybatis中xml之trim屬性說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java中的@Repeatable注解使用詳解

    Java中的@Repeatable注解使用詳解

    這篇文章主要介紹了Java中的@Repeatable注解使用詳解,@Repeatable注解是java8為了解決同一個注解不能重復在同一類/方法/屬性上使用的問題,本文提供了解決思路和部分實現(xiàn)代碼,需要的朋友可以參考下
    2024-02-02
  • Java使用OpenCV進行圖像處理的示例代碼

    Java使用OpenCV進行圖像處理的示例代碼

    OpenCV是一個開源的計算機視覺庫,廣泛應用于圖像處理、機器學習和計算機視覺等領域,盡管OpenCV主要使用C/C++進行開發(fā),但它也為Java提供了綁定,使得Java開發(fā)者能夠利用其強大的圖像處理功能,在本篇文章中,我們將詳細介紹如何在Java中使用OpenCV,需要的朋友可以參考下
    2025-03-03
  • Zuul 實現(xiàn)網(wǎng)關轉發(fā)的五種方式小結

    Zuul 實現(xiàn)網(wǎng)關轉發(fā)的五種方式小結

    這篇文章主要介紹了Zuul 實現(xiàn)網(wǎng)關轉發(fā)的五種方式小結,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot2.1.3配置sftp自定義sftp連接池的詳細過程

    springboot2.1.3配置sftp自定義sftp連接池的詳細過程

    這篇文章主要介紹了springboot2.1.3配置sftp自定義sftp連接池的詳細過程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • Springboot Redis設置key前綴的方法步驟

    Springboot Redis設置key前綴的方法步驟

    這篇文章主要介紹了Springboot Redis設置key前綴的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • 基于Spring AMQP實現(xiàn)消息隊列的示例代碼

    基于Spring AMQP實現(xiàn)消息隊列的示例代碼

    Spring AMQP作為Spring框架的一部分,是一套用于支持高級消息隊列協(xié)議(AMQP)的工具,AMQP是一種強大的消息協(xié)議,旨在支持可靠的消息傳遞,本文給大家介紹了如何基于Spring AMQP實現(xiàn)消息隊列,需要的朋友可以參考下
    2024-03-03

最新評論

邮箱| 得荣县| 平顶山市| 河曲县| 邓州市| 旌德县| 突泉县| 凤庆县| 高要市| 景谷| 陆丰市| 汾阳市| 青海省| 荔浦县| 舒兰市| 资源县| 甘肃省| 济南市| 从化市| 广河县| 马边| 三明市| 湘潭县| 福泉市| 台北县| 虎林市| 宁德市| 邵东县| 鱼台县| 黄陵县| 尖扎县| 嘉峪关市| 巍山| 罗平县| 南华县| 西吉县| 大新县| 南平市| 平谷区| 五指山市| 衡南县|