| | |
| | | package com.zy.asrs.controller; |
| | | |
| | | import com.alibaba.excel.EasyExcel; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.mapper.Wrapper; |
| | | import com.baomidou.mybatisplus.plugins.Page; |
| | | import com.zy.asrs.entity.BasCrnError; |
| | | import com.zy.asrs.service.BasCrnErrorService; |
| | | import com.zy.common.web.BaseController; |
| | | import com.core.annotations.ManagerAuth; |
| | | import com.core.common.BaseRes; |
| | | import com.core.common.Cools; |
| | | import com.core.common.DateUtils; |
| | | import com.core.common.R; |
| | | import com.zy.asrs.entity.BasCrnError; |
| | | import com.zy.asrs.importexcle.ImportCrnErrDto; |
| | | import com.zy.asrs.importexcle.ImportCrnErrListener; |
| | | import com.zy.asrs.service.BasCrnErrorService; |
| | | import com.zy.common.web.BaseController; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.*; |
| | | |
| | | @RestController |
| | |
| | | return R.ok(basCrnErrorService.selectById(String.valueOf(id))); |
| | | } |
| | | |
| | | @PostMapping("/importCrnErr") |
| | | @ManagerAuth(memo = "导入堆垛机异常表") |
| | | public R importCrnErr(@RequestParam("file") MultipartFile multipartFile) { |
| | | try { |
| | | importCrnErrExec(multipartFile); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return R.error(e.getMessage()); |
| | | } |
| | | return R.ok("导入成功"); |
| | | } |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void importCrnErrExec(MultipartFile multipartFile) throws IOException { |
| | | EasyExcel.read(multipartFile.getInputStream(), ImportCrnErrDto.class, |
| | | new ImportCrnErrListener(basCrnErrorService)).sheet().doReadSync(); |
| | | } |
| | | |
| | | @RequestMapping(value = "/basCrnError/list/auth") |
| | | @ManagerAuth |
| | | public R list(@RequestParam(defaultValue = "1")Integer curr, |
| | |
| | | @ApiModelProperty(value= "生产日期") |
| | | private String manu_date; |
| | | |
| | | private String manuDate; |
| | | |
| | | @ApiModelProperty(value= "品项数") |
| | | private String item_num; |
| | | |
| | |
| | | @ApiModelProperty(value= "长度") |
| | | private Double man_length; |
| | | |
| | | private Double manLength; |
| | | |
| | | @ApiModelProperty(value= "体积") |
| | | private Double volume; |
| | | |
| | |
| | | @ApiModelProperty(value= "生产日期") |
| | | private String manu_date; |
| | | |
| | | private String manuDate; |
| | | |
| | | @ApiModelProperty(value= "品项数") |
| | | private String item_num; |
| | | |
| | |
| | | @ApiModelProperty(value= "长度") |
| | | private Double man_length; |
| | | |
| | | private Double manLength; |
| | | |
| | | @ApiModelProperty(value= "体积") |
| | | private Double volume; |
| | | |
| | |
| | | LocMast locMast = service.selectById(this.locNo); |
| | | if (!Cools.isEmpty(locMast)){ |
| | | return String.valueOf(locMast.getLocNo()); |
| | | } else if(!Cools.isEmpty(this.locNo)) { |
| | | return this.locNo; |
| | | } |
| | | return null; |
| | | } |
| | |
| | | LocMast locMast = service.selectById(this.locNo); |
| | | if (!Cools.isEmpty(locMast)){ |
| | | return String.valueOf(locMast.getLocNo()); |
| | | } else if(!Cools.isEmpty(this.locNo)) { |
| | | return this.locNo; |
| | | } |
| | | return null; |
| | | } |
New file |
| | |
| | | package com.zy.asrs.importexcle; |
| | | |
| | | import com.alibaba.excel.annotation.ExcelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author pang.jiabao |
| | | * @description 导入堆垛机异常代码dto |
| | | * @createDate 2024/9/2 9:55 |
| | | */ |
| | | @Data |
| | | public class ImportCrnErrDto { |
| | | |
| | | @ExcelProperty(value = "序号",index = 0) |
| | | private Long column1; |
| | | |
| | | @ExcelProperty(value = "异常描述",index = 1) |
| | | private String column2; |
| | | |
| | | } |
New file |
| | |
| | | package com.zy.asrs.importexcle; |
| | | |
| | | import com.alibaba.excel.context.AnalysisContext; |
| | | import com.alibaba.excel.event.AnalysisEventListener; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.zy.asrs.entity.BasCrnError; |
| | | import com.zy.asrs.service.BasCrnErrorService; |
| | | import lombok.SneakyThrows; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author pang.jiabao |
| | | * @description 导入垛机异常表监听器 |
| | | * @createDate 2024/9/2 9:56 |
| | | */ |
| | | @Slf4j |
| | | public class ImportCrnErrListener extends AnalysisEventListener<ImportCrnErrDto> { |
| | | /** |
| | | * 每隔1000条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 |
| | | */ |
| | | private static final int BATCH_COUNT = 500; |
| | | |
| | | private int count = 0; |
| | | |
| | | List<ImportCrnErrDto> list = new ArrayList<>(); |
| | | /** |
| | | * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。 |
| | | */ |
| | | private final BasCrnErrorService basCrnErrorService; |
| | | |
| | | /** |
| | | * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来 |
| | | */ |
| | | public ImportCrnErrListener(BasCrnErrorService basCrnErrorService) { |
| | | this.basCrnErrorService = basCrnErrorService; |
| | | } |
| | | |
| | | /** |
| | | * 这个每一条数据解析都会来调用 |
| | | */ |
| | | @SneakyThrows |
| | | @Override |
| | | public void invoke(ImportCrnErrDto data, AnalysisContext context) { |
| | | log.info("解析到第 {} 条数据:{}", ++count, JSON.toJSONString(data)); |
| | | if (!data.getColumn2().equals("<No value>")) { |
| | | list.add(data); |
| | | } |
| | | |
| | | // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM |
| | | if (list.size() >= BATCH_COUNT) { |
| | | saveData(); |
| | | // 存储完成清理 list |
| | | list.clear(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 所有数据解析完成了 都会来调用 |
| | | */ |
| | | @Override |
| | | public void doAfterAllAnalysed(AnalysisContext context) { |
| | | // 这里也要保存数据,确保最后遗留的数据也存储到数据库 |
| | | if (list.size() > 0) { |
| | | saveData(); |
| | | } |
| | | log.info("所有数据解析完成!"); |
| | | } |
| | | |
| | | /** |
| | | * 加上存储数据库 |
| | | */ |
| | | private void saveData() { |
| | | log.info("{}条数据,开始存储数据库!", list.size()); |
| | | List<BasCrnError> basCrnErrors = new ArrayList<>(); |
| | | list.forEach(importCrnErrDto -> { |
| | | BasCrnError basCrnError = new BasCrnError(); |
| | | basCrnError.setErrorCode(importCrnErrDto.getColumn1()); |
| | | basCrnError.setErrName(importCrnErrDto.getColumn2()); |
| | | basCrnErrors.add(basCrnError); |
| | | }); |
| | | basCrnErrorService.insertBatch(basCrnErrors); |
| | | |
| | | log.info("存储数据库成功!"); |
| | | } |
| | | /** |
| | | *解析出现错误会进入该方法 具体看源代码或文档 |
| | | */ |
| | | @Override |
| | | public void onException(Exception exception, AnalysisContext context) throws Exception { |
| | | log.error("处理异常:" + exception.getMessage()); |
| | | throw exception; |
| | | } |
| | | } |
| | |
| | | if (wrkMast.getCtnType() == 0) { |
| | | wrkMast.setCtnType(1); |
| | | this.updateById(wrkMast); |
| | | log.info("自动补尾桶信号成功,任务号:{}",wrkMast.getCrnNo()); |
| | | log.info("自动补尾桶信号成功,任务号:{}",wrkMast.getWrkNo()); |
| | | } |
| | | } |
| | | |
| | |
| | | and a.specs like '%' + #{specs} + '%' |
| | | </if> |
| | | <if test="model!=null and model!='' "> |
| | | and a.specs like '%' + #{model} + '%' |
| | | and a.model like '%' + #{model} + '%' |
| | | </if> |
| | | <if test="volume!=null and volume!='' "> |
| | | and a.volume like '%' + #{volume} + '%' |
| | | </if> |
| | | </sql> |
| | | |
| | |
| | | select * from |
| | | ( |
| | | select |
| | | ROW_NUMBER() over (order by sum(a.anfme) desc) as row |
| | | ROW_NUMBER() over (order by matnr desc) as row |
| | | , a.matnr |
| | | , a.maktx |
| | | , a.model |
| | |
| | | SELECT |
| | | GETDATE() AS today |
| | | , CONVERT(decimal, DATEDIFF(second,asr_loc_detl.appe_time, GETDATE()) / 86400.0, 9) AS stay_time |
| | | , manu_date manuDate,man_length manLength |
| | | , asr_loc_detl.* |
| | | FROM asr_loc_detl |
| | | INNER JOIN asr_loc_mast ON asr_loc_detl.loc_no = asr_loc_mast.loc_no |
| | |
| | | ROW_NUMBER() OVER(Order by t.io_time desc) as row |
| | | , * |
| | | from ( |
| | | select * |
| | | select manu_date manuDate,man_length manLength,* |
| | | from asr_wrkin_view |
| | | where 1=1 |
| | | <include refid="viewWorkInConditionSql"></include> |
| | |
| | | ROW_NUMBER() OVER(Order by t.io_time desc) as row |
| | | , * |
| | | from ( |
| | | select * |
| | | select manu_date manuDate,man_length manLength,* |
| | | from asr_wrkout_view |
| | | where 1=1 |
| | | <include refid="viewWorkInConditionSql"></include> |
| | |
| | | var pageCurr; |
| | | layui.use(['table','laydate', 'form'], function(){ |
| | | layui.use(['table','laydate', 'form','upload','layer'], function(){ |
| | | var table = layui.table; |
| | | var $ = layui.jquery; |
| | | var layer = layui.layer; |
| | | var layDate = layui.laydate; |
| | | var form = layui.form; |
| | | |
| | | var upload = layui.upload; |
| | | // 数据渲染 |
| | | tableIns = table.render({ |
| | | elem: '#basCrnError', |
| | |
| | | }); |
| | | } |
| | | }); |
| | | |
| | | upload.render({ |
| | | elem: '#uploadExcel', // 绑定元素 |
| | | url: baseUrl+'/importCrnErr', // 上传接口,替换为你的后端接口 |
| | | headers:{'token': localStorage.getItem('token')}, |
| | | accept: 'file', // 允许上传的文件类型 |
| | | exts: 'xls|xlsx', // 允许上传的文件后缀 |
| | | done: function(res){ |
| | | // 上传完毕回调 |
| | | if(res.code === 200){ |
| | | layer.msg(res.msg); |
| | | console.log('文件数据:', res.data); |
| | | } else { |
| | | layer.msg(res.msg || '上传失败'); |
| | | } |
| | | }, |
| | | error: function(){ |
| | | // 请求异常回调 |
| | | layer.msg('上传失败,请重试'); |
| | | } |
| | | }); |
| | | // 监听排序事件 |
| | | table.on('sort(basCrnError)', function (obj) { |
| | | var searchData = {}; |
| | |
| | | ] |
| | | |
| | | var detlCols = [ |
| | | {field: 'matnr', align: 'center',title: '商品编号(品号)', sort:true} |
| | | ,{field: 'maktx', align: 'center',title: '商品名称(品名)', sort:true} |
| | | {field: 'matnr', align: 'center',title: '商品编号', sort:true} |
| | | ,{field: 'maktx', align: 'center',title: '商品名称', sort:true} |
| | | ,{field: 'orderNo', align: 'center',title: '单据编号', hide: true} |
| | | ,{field: 'batch', align: 'center',title: '货品特征', sort:true, hide: true} |
| | | ,{field: 'batch', align: 'center',title: '批次', sort:true} |
| | | ,{field: 'anfme', align: 'center',title: '数量', hide: false} |
| | | ,{field: 'zpallet', align: 'center',title: '托盘条码', hide: false} |
| | | |
| | | ,{field: 'specs', align: 'center',title: '规格', hide: true} |
| | | ,{field: 'model', align: 'center',title: '桶型', hide: false} |
| | | ,{field: 'color', align: 'center',title: '颜色', hide: true} |
| | |
| | | ,{field: 'barcode', align: 'center',title: '条码', hide: true} |
| | | ,{field: 'origin', align: 'center',title: '产地', hide: true} |
| | | ,{field: 'manu', align: 'center',title: '厂家', hide: true} |
| | | ,{field: 'manuDate', align: 'center',title: '生产日期', hide: true} |
| | | ,{field: 'manuDate', align: 'center',title: '生产日期'} |
| | | ,{field: 'itemNum', align: 'center',title: '品项数', hide: true} |
| | | ,{field: 'safeQty', align: 'center',title: '安全库存量', hide: true} |
| | | ,{field: 'weight', align: 'center',title: '净重', hide: true} |
| | | ,{field: 'manLength', align: 'center',title: '毛重', hide: true} |
| | | ,{field: 'volume', align: 'center',title: '罐装量', hide: false} |
| | | ,{field: 'weight', align: 'center',title: '净重'} |
| | | ,{field: 'manLength', align: 'center',title: '毛重'} |
| | | ,{field: 'volume', align: 'center',title: '罐装量'} |
| | | ,{field: 'threeCode', align: 'center',title: '箱子尺寸', hide: true} |
| | | ,{field: 'supp', align: 'center',title: '供应商', hide: true} |
| | | ,{field: 'suppCode', align: 'center',title: '供应商编码', hide: true} |
| | |
| | | ,{field: 'locNo$', align: 'center',title: '目标库位'} |
| | | ,{field: 'barcode', align: 'center',title: '条码'} |
| | | // ,{field: 'preHave', align: 'center',title: '先入品', hide: true} |
| | | ,{field: 'rgvNo', align: 'center',title: 'RGV', hide: true} |
| | | ,{field: 'pdcType', align: 'center',title: '空桶类型', hide: true} |
| | | ,{field: 'ctnType', align: 'center',title: '尾托', hide: true} |
| | | ,{field: 'whsType', align: 'center',title: '入罐装线', hide: true} |
| | | ,{field: 'manuType', align: 'center',title: '人工操作', hide: true} |
| | | // ,{field: 'takeNone', align: 'center',title: '空操作', hide: true} |
| | | // ,{field: 'picking', align: 'center',title: '拣料', templet:function(row){ |
| | | // var html = "<input value='picking' type='checkbox' lay-skin='primary' lay-filter='tableCheckbox' table-index='"+row.LAY_TABLE_INDEX+"'"; |
| | |
| | | ,{field: 'staNo$', align: 'center',title: '目标站'} |
| | | ,{field: 'sourceLocNo$', align: 'center',title: '源库位'} |
| | | ,{field: 'locNo$', align: 'center',title: '目标库位'} |
| | | ,{field: 'rgvNo', align: 'center',title: 'RGV', hide: true} |
| | | ,{field: 'pdcType', align: 'center',title: '空桶类型', hide: true} |
| | | ,{field: 'ctnType', align: 'center',title: '尾托', hide: true} |
| | | ,{field: 'whsType', align: 'center',title: '入罐装线', hide: true} |
| | | ,{field: 'manuType', align: 'center',title: '人工操作', hide: true} |
| | | // ,{field: 'picking', align: 'center',title: '拣料', templet:function(row){ |
| | | // var html = "<input value='picking' type='checkbox' lay-skin='primary' lay-filter='tableCheckbox' table-index='"+row.LAY_TABLE_INDEX+"'"; |
| | | // if(row.picking === 'Y'){html += " checked ";} |
| | |
| | | <div class="layui-btn-container"> |
| | | <button class="layui-btn layui-btn-sm" id="btn-add" lay-event="addData">新增</button> |
| | | <button class="layui-btn layui-btn-sm" id="btn-delete" lay-event="deleteData">删除</button> |
| | | <button id="uploadExcel" class="layui-btn layui-btn-primary layui-btn-sm" >导入</button> |
| | | <button class="layui-btn layui-btn-primary layui-btn-sm" id="btn-export" lay-event="exportData">导出</button> |
| | | </div> |
| | | </script> |
| | |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="matnr" placeholder="品号" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="matnr" placeholder="商品编号" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="specs" placeholder="规格" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="layui-inline">--> |
| | | <!-- <div class="layui-input-inline">--> |
| | | <!-- <input class="layui-input" type="text" name="specs" placeholder="规格" autocomplete="off">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="zpallet" placeholder="托盘码" autocomplete="off"> |
| | |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="batch" placeholder="货品特征" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="batch" placeholder="批次" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="anfme" placeholder="数量" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="layui-inline">--> |
| | | <!-- <div class="layui-input-inline">--> |
| | | <!-- <input class="layui-input" type="text" name="anfme" placeholder="数量" autocomplete="off">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <div class="layui-inline" style="width: 300px"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input layui-laydate-range" name="query_date" type="text" placeholder="入库起始时间 - 入库终止时间" autocomplete="off" style="width: 300px"> |
| | |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="matnr" placeholder="品号" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="matnr" placeholder="商品编号" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="specs" placeholder="规格" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="layui-inline">--> |
| | | <!-- <div class="layui-input-inline">--> |
| | | <!-- <input class="layui-input" type="text" name="specs" placeholder="规格" autocomplete="off">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="zpallet" placeholder="托盘码" autocomplete="off"> |
| | |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="batch" placeholder="货品特征" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="batch" placeholder="批次" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="anfme" placeholder="数量" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="layui-inline">--> |
| | | <!-- <div class="layui-input-inline">--> |
| | | <!-- <input class="layui-input" type="text" name="anfme" placeholder="数量" autocomplete="off">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <div class="layui-inline" style="width: 300px"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input layui-laydate-range" name="query_date" type="text" placeholder="起始时间 - 终止时间" autocomplete="off" style="width: 300px"> |
| | |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="order_no" placeholder="订单编号" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="order_no" placeholder="订单号" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="matnr" placeholder="品号" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="matnr" placeholder="商品编号" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="specs" placeholder="规格" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="layui-inline">--> |
| | | <!-- <div class="layui-input-inline">--> |
| | | <!-- <input class="layui-input" type="text" name="specs" placeholder="规格" autocomplete="off">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="zpallet" placeholder="托盘码" autocomplete="off"> |
| | |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="batch" placeholder="货品特征" autocomplete="off"> |
| | | <input class="layui-input" type="text" name="batch" placeholder="批次" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <div class="layui-input-inline"> |
| | | <input class="layui-input" type="text" name="anfme" placeholder="数量" autocomplete="off"> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="layui-inline">--> |
| | | <!-- <div class="layui-input-inline">--> |
| | | <!-- <input class="layui-input" type="text" name="anfme" placeholder="数量" autocomplete="off">--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- 待添加 --> |
| | | <div id="data-search-btn" class="layui-btn-container layui-form-item"> |
| | | <button id="search" class="layui-btn layui-btn-primary layui-btn-radius" lay-submit lay-filter="search">搜索</button> |