📣文章目录
1.预警需求1. 预警需求分析2.数据库表
2.后端代码实现:1. 定时器任务2.优化加入队列3.注意:关于Mq4.测试是否成功
3.前端提一嘴前端展示:
1.预警需求
为了更好的管理商品日期,需要对仓库的商品进行预警管理,对商品的保质期控制在一个范围内提示出来,也可以通过该功能间接的展示出一个商品的的销量程度和对下次进货做个考量!
1. 预警需求分析
前端界面需要设置商品的预警天数后端保存预警天数数据库有字段存放商品需要预警的天数通过定时器运行指点方法算出对应那些商品的批次存低于设置的预警天数查询出来在wms首页展出
2.数据库表
对于前端界面的开发不做过多的代码分析,本次重点展示商品预警实现思路!! 数据库用到到字段会截取出来,便于理解! 商品表数据: 预警表数据: 商品批次表: 商品批次表中添加预警字段:后续查询对应的预警信息作为标志 ![在这里插入图片描述](https://img-blog.csdnimg.cn/cf2da4891bbb4f749678afea881581b2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGnmooU=,size_20,color_FFFFFF,t_70,g_se,x_16)
Mysql使用到的函数
//查询当前时间
select now();
//获取时间相减 获取到天数 参数是前面-后面
select DATEDIFF("2022-9-10", now()) as day
如: 由此我们就可以通过函数算出商品距离过期的天数 查询语句:
SELECT bb.id as batchId, bb.product_id as productId, DATEDIFF(bb.ed, now()) as warnDate
FROM `商品批次表` bb
需要注意: 查询或者修改表数据我们如果只要使用某个字段去修改,尽量查询下该表更新的字段数据是否有重复的数据并且其他字段可能跟我们预想不一致,必须要修改的,我们就应该使用多字段去查询修改
查询重复数据
select * from 表 GROUP BY 字段 HAVING count(*)>1
查询预警批次数量: 因为需要展示出来在前端可以给用户点击查看货物存放的地方,所以查询出来的数据库存数量要大于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.后端代码实现:
1. 定时器任务
使用Scheduled作为定时器,通过cron语法指定运行时间,每3小时运行一次表达式如下
代码详情注释写的也比较清楚
/**
* 每3小时运行一次
*/
@Scheduled(cron = "0 0 0/3 * * ?")
public void goodsWarn(){
BasicProductGpExample basicProductGpExample = new BasicProductGpExample();
List warnBatchIds=new ArrayList();
//查询商品预警表信息 商品的货号是唯一的 (所以现在是全表查询出来)
// 这里把商品预警信息都查询出来为了以后扩展做库存预警设置
List basicProductGps = productGpMapper.selectByExample(basicProductGpExample);
//查询商品批次表:商品批次和天数 商品的批次是唯一的,存在多个商品货号(所以现在是全表查询出来)
// 以后扩展商品库存预警只要在这个查询里面添加关联库存数量查询出来,然后在过滤里面添加预警数量判断
List warnGoodsDay = basicBatchMapper.selectWarnGoodsDay();
Long start=System.currentTimeMillis();
for (BasicProductGp basicProductGp : basicProductGps) {
//商品预警日期
Integer warnDate = basicProductGp.getWarnDate();
//商品货号编码
Integer productId = basicProductGp.getProductId();
//查询出符合预警的商品批次
List warnBatchId = warnGoodsDay.stream().filter(warnGood -> warnGood.getProductId().equals(productId) && warnGood.getWarnDate() "warnGoodsQueue"}))
public class WarnGoodsQueue {
@RabbitHandler
public void process(List ids) {
if (ids == null) {
System.out.println("空");
}
System.out.println(ids);
}
}
3.注意:关于Mq
生产者,生产的数据类型一定要要和消费者获取的类型要一致,否则会无限循环报错
Listener threw exception
No method found for class [B
![在这里插入图片描述](https://img-blog.csdnimg.cn/64ed025cb6e7495e9f35b6370db6a671.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGnmooU=,size_20,color_FFFFFF,t_70,g_se,x_16)
4.测试是否成功
生产者存入队列: ![在这里插入图片描述](https://img-blog.csdnimg.cn/3d04062b24dd41cf8a5cd9d82f183f4f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGnmooU=,size_20,color_FFFFFF,t_70,g_se,x_16)
消费者获取数据: 如果消费方法报错不try/catch的话,队列就会一直重试该条数据
可以看出已经获取到修改预警商品的商品编号,这个时候我们只要写方法做相应的处理就行了 我们也可以去RabbitMq管理界面查看队列信息 消费方法代码:
public void updateWarnGoods(List ids){
if (CollectionUtils.isEmpty(ids)){
return;
}
BasicProductGpExample example = new BasicProductGpExample();
example.createCriteria().andProductIdIn(ids);
//查询商品信息 商品的货号是唯一的 (查询变动的商品货号)
List basicProductGps = productGpMapper.selectByExample(example);
//商品批次和天数 商品的批次是唯一的,存在多个商品货号(查询变动的商品货号)
List warnGoodsDay = basicBatchMapper.selectWarnGoodsDayList(ids);
//需要预警的集合
List warnBatchIds=new ArrayList();
//不需要预警的集合
List notWarnBatchIds=new ArrayList();
Long start=System.currentTimeMillis();
for (BasicProductGp basicProductGp : basicProductGps) {
//商品预警日期
Integer warnDate = basicProductGp.getWarnDate();
//商品货号编码
Integer productId = basicProductGp.getProductId();
//查询出符合预警的商品批次
List warnBatchId = warnGoodsDay.stream().filter(warnGood -> {
if (warnGood.getProductId().equals(productId)){
//匹配到的商品数据
//2种情况:一种要预警另外一种不要预警
if (warnGood.getWarnDate()
int count = basicBatchMapper.updateByBatchWarn(notWarnBatchIds, false);
log.info("更新预警数量:{}",count);
}
//更新预警商品
if (!CollectionUtils.isEmpty(warnBatchIds)){
int count = basicBatchMapper.updateByBatchWarn(warnBatchIds, true);
log.info("更新预警数量:{}",count);
}
}
关于一些代码存在冗余我们可以提取成一个公共方法进行调用,后续也对全局修改预警Mq队列走波运算预警的商品 重载方法:
/***
* 重载方法
* 用于运算全局商品类型
* 用于更新商品预警时间
*/
public void updateWarnGoods(){
BasicProductGpExample example = new BasicProductGpExample();
//查询商品信息 商品的货号是唯一的 (查询变动的商品货号)
List basicProductGps = productGpMapper.selectByExample(example);
//商品批次和天数 商品的批次是唯一的,存在多个商品货号(查询变动的商品货号)
List warnGoodsDay = basicBatchMapper.selectWarnGoodsDay();
//需要预警的集合
List warnBatchIds=new ArrayList();
//不需要预警的集合
List notWarnBatchIds=new ArrayList();
Long start=System.currentTimeMillis();
for (BasicProductGp basicProductGp : basicProductGps) {
//商品预警日期
Integer warnDate = basicProductGp.getWarnDate();
//商品货号编码
Integer productId = basicProductGp.getProductId();
//查询出符合预警的商品批次
List warnBatchId = warnGoodsDay.stream().filter(warnGood -> {
if (warnGood.getProductId().equals(productId)){
//匹配到的商品数据
//2种情况:一种要预警另外一种不要预警
if (warnGood.getWarnDate()
int count = basicBatchMapper.updateByBatchWarn(notWarnBatchIds, false);
log.info("更新预警数量:{}",count);
}
//更新预警商品
if (!CollectionUtils.isEmpty(warnBatchIds)){
int count = basicBatchMapper.updateByBatchWarn(warnBatchIds, true);
log.info("更新预警数量:{}",count);
}
}
3.前端提一嘴
给商品添加预警日期,需要用户提些数据,为了避免出现英文空格等我们需要,对输入的数据进行正则,只能输入数字 ![在这里插入图片描述](https://img-blog.csdnimg.cn/894c6470cd45428fa4ab42072cd779aa.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGnmooU=,size_20,color_FFFFFF,t_70,g_se,x_16)
效果: 英文: 但是可以输入0,如果预警日期设置成了0你们就意味着废弃该商品预警提示功能
前端展示:
首页: 预警商品列表: ![在这里插入图片描述](https://img-blog.csdnimg.cn/ef7071dbe2b745589e51bcfdb80e97c4.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASGnmooU=,size_20,color_FFFFFF,t_70,g_se,x_16)
|