pom.xml
@@ -45,18 +45,18 @@ <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- 使用本地 JAR 解决缺失的 cn.cool:framework:jar:3.2.0 --> <!-- <dependency>--> <!-- <groupId>cn.cool</groupId>--> <!-- <artifactId>framework</artifactId>--> <!-- <version>3.2.0</version>--> <!-- <scope>system</scope>--> <!-- <systemPath>${project.basedir}/version/lib/framework-3.2.0.jar</systemPath>--> <!-- </dependency>--> <dependency> <groupId>cn.cool</groupId> <artifactId>framework</artifactId> <version>3.2.0</version> <scope>system</scope> <systemPath>${project.basedir}/version/lib/framework-3.2.0.jar</systemPath> </dependency> <!-- <dependency>--> <!-- <groupId>cn.cool</groupId>--> <!-- <artifactId>framework</artifactId>--> <!-- <version>3.2.0</version>--> <!-- </dependency>--> <dependency> <groupId>org.apache.tika</groupId> <artifactId>tika-core</artifactId> src/main/java/com/zy/api/enums/OrderWkType.java
@@ -14,9 +14,9 @@ ORDER_WK_PRO_LIXIANG_IN("8", "逆向上架入库"), ORDER_WK_MEGER_IN("K", "组合拆零入库"), ORDER_WK_MOVE_IN("Y", "移库位入库"), ORDER_WK_ORDER_OUT_EO("11", "备货指示派工单(EO)"), ORDER_WK_ORDER_OUT_SO("12", "备货指示派工单(SO)"), ORDER_WK_ORDER_OUT("13", "备货单"); ORDER_WK_ORDER_OUT_EO("12", "EO"), ORDER_WK_ORDER_OUT_SO("11", "SO"), ORDER_WK_ORDER_OUT("13", "MD"); OrderWkType(String val, String desc) { this.val = val; src/main/java/com/zy/api/service/impl/KopenApiServiceImpl.java
@@ -461,7 +461,8 @@ } newOrder.setPakinPakoutStatus(2); } //单据类型 newOrder.setShipName(type); newOrder.setUuid(generateUUID(params)); // 流水号(唯一) newOrder.setDefNumber(params.getKopen_id()); src/main/java/com/zy/asrs/controller/MobileController.java
@@ -389,6 +389,16 @@ return mobileService.getAllBindInfo(params); } @ManagerAuth(memo = "确认台车出库") @RequestMapping("/confirm/all/out") public R confirmAllOut(@RequestBody AgvCallParams params) { if (Objects.isNull(params) || Objects.isNull(params.getCarBarcode())) { return R.error("参数不能为空!!"); } return mobileService.outStockByTc(params); } @ApiOperation("确认捆包出库") @ManagerAuth(memo = "确认捆包出库") @RequestMapping("/agv/out/confirm") src/main/java/com/zy/asrs/controller/OrderPakoutController.java
@@ -46,11 +46,14 @@ @RequestMapping(value = "/order/nav/list/auth") @ManagerAuth public R navList(@RequestParam(required = false) String orderNo){ public R navList(@RequestParam(required = false) String orderNo, @RequestParam(required = false) String shipName){ EntityWrapper<OrderPakout> wrapper = new EntityWrapper<>(); if (!Cools.isEmpty(orderNo)) { wrapper.like("order_no", orderNo); } if (!Cools.isEmpty(shipName)) { wrapper.like("ship_name", shipName); } wrapper.le("settle", 2).eq("status", 1); // 筛选出库单,不为OrderTypeEnum.STOCK wrapper.ne("doc_type", OrderTypeEnum.STOCK.type); src/main/java/com/zy/asrs/controller/OutController.java
@@ -334,6 +334,8 @@ if (Cools.isEmpty(locDtos)) { return R.parse(BaseRes.PARAM); } List<LocDto> locDtoArrayList = new ArrayList<>(); for (LocDto locDto : locDtos){ if (locDto.getFrozen()!=1 && locDto.getFrozenLoc()!=1){ src/main/java/com/zy/asrs/controller/WrkMastController.java
@@ -10,19 +10,27 @@ import com.core.common.Cools; import com.core.common.DateUtils; import com.core.common.R; import com.core.exception.CoolException; import com.zy.asrs.entity.WrkDetl; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.service.WrkDetlService; import com.zy.asrs.service.WrkMastService; import com.zy.asrs.service.impl.WrkDetlServiceImpl; 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 java.util.*; import java.util.stream.Collectors; @RestController public class WrkMastController extends BaseController { @Autowired private WrkMastService wrkMastService; @Autowired private WrkDetlService wrkDetlService; @RequestMapping(value = "/wrkMast/{id}/auth") @ManagerAuth @@ -36,12 +44,23 @@ @RequestParam(defaultValue = "10")Integer limit, @RequestParam(required = false)String orderByField, @RequestParam(required = false)String orderByType, @RequestParam(required = false)String barcode, @RequestParam(required = false)String orderNo, @RequestParam(required = false)String condition, @RequestParam Map<String, Object> param){ excludeTrash(param); EntityWrapper<WrkMast> wrapper = new EntityWrapper<>(); convert(param, wrapper); allLike(WrkMast.class, param.keySet(), wrapper, condition); if (!Cools.isEmpty(orderNo)) { List<WrkDetl> detls = wrkDetlService.selectList(new EntityWrapper<WrkDetl>().eq("order_no", orderNo)); if (!Cools.isEmpty(detls)) { List<Integer> wrkNos = detls.stream().map(WrkDetl::getWrkNo).collect(Collectors.toList()); wrapper.in("wrk_no", wrkNos); } } if (!Cools.isEmpty(orderByField)){ if (orderByField.endsWith("$")){ orderByField = orderByField.substring(0, orderByField.length()-1); @@ -61,6 +80,9 @@ wrapper.ge(entry.getKey(), DateUtils.convert(dates[0])); wrapper.le(entry.getKey(), DateUtils.convert(dates[1])); } else { if (entry.getKey().equals("orderNo")){ continue; } wrapper.eq(entry.getKey(), val); } } @@ -141,14 +163,18 @@ @RequestMapping(value = "/wrkMast/add/pri/auth") @ManagerAuth(memo = "工作档增加优先级") @Transactional(rollbackFor = Exception.class) public R addPri(@RequestBody List<WrkMast> list) { if (list.isEmpty()) { return R.error("请至少选择一行数据"); } for (WrkMast entity : list){ entity.setIoPri(entity.getIoPri() + 1); if (!wrkMastService.update(entity, new EntityWrapper<WrkMast>().eq("wrk_no", entity.getWrkNo()))) { throw new CoolException("优先级更新失败!"); } } wrkMastService.updateBatchById(list); // wrkMastService.updateBatchById(list); return R.ok(); } src/main/java/com/zy/asrs/entity/Mat.java
@@ -342,8 +342,8 @@ /** * 出库优先级 */ @TableField("group_proty") private Integer groupProty; @TableField("rank") private String rank; public Mat() {} src/main/java/com/zy/asrs/entity/Order.java
@@ -209,7 +209,7 @@ /** * 物流名称 */ @ApiModelProperty(value= "物流名称") @ApiModelProperty(value= "单据类型") @TableField("ship_name") private String shipName; src/main/java/com/zy/asrs/entity/OrderPakout.java
@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.enums.IdType; import com.core.common.Cools; import com.core.common.SpringUtils; import com.zy.api.enums.OrderWkType; import com.zy.asrs.entity.BasAreas; import com.zy.asrs.service.BasAreasService; import com.zy.asrs.service.DocTypeService; @@ -380,15 +381,14 @@ return null; } public String getPayType$(){ if (null == this.payType){ return null; } switch (this.payType){ case 1: return "现金"; case 2: return "记账"; default: return String.valueOf(this.payType); public String getShipName$(){ if (null == this.shipName){ return OrderWkType.ORDER_WK_ORDER_OUT_SO.desc; } if (this.shipName.equals(OrderWkType.ORDER_WK_ORDER_OUT_EO.val)){ return OrderWkType.ORDER_WK_ORDER_OUT_EO.desc; } else if (this.shipName.equals(OrderWkType.ORDER_WK_ORDER_OUT_SO.val)){ return OrderWkType.ORDER_WK_ORDER_OUT_SO.desc; } else { return OrderWkType.ORDER_WK_ORDER_OUT.desc; } } src/main/java/com/zy/asrs/entity/param/AgvCallParams.java
@@ -42,5 +42,7 @@ @ApiModelProperty("任务类型") private String taskType; @ApiModelProperty("确认单号") private String shipCode; } src/main/java/com/zy/asrs/service/MobileService.java
@@ -213,4 +213,13 @@ * @return */ R getEmptyOutStock(AgvCallParams params); /** * 按台车出库 * @author Ryan * @date 2026/3/28 8:40 * @param params * @return com.core.common.R */ R outStockByTc(AgvCallParams params); } src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java
@@ -22,10 +22,7 @@ import com.zy.common.constant.HIKApiConstant; import com.zy.common.constant.MesConstant; import com.zy.common.entity.Parameter; import com.zy.common.model.DetlDto; import com.zy.common.model.LocTypeDto; import com.zy.common.model.MesCombParam; import com.zy.common.model.StartupDto; import com.zy.common.model.*; import com.zy.common.model.enums.WorkNoType; import com.zy.common.properties.SlaveProperties; import com.zy.common.service.CommonService; @@ -2397,12 +2394,12 @@ locMast = locMastService.selectById(locMast.getLocNo()); // if (locMast.getLocSts().equals(LocStsType.LOC_STS_TYPE_F.type) // || locMast.getLocSts().equals(LocStsType.LOC_STS_TYPE_D.type)) { locMast.setLocSts(ioType == 101 ? "R" : "P"); locMast.setModiUser(userId); locMast.setModiTime(now); if (!locMastService.updateById(locMast)) { throw new CoolException("预约库位状态失败,库位号:" + locMast.getLocNo()); } locMast.setLocSts(ioType == 101 ? "R" : "P"); locMast.setModiUser(userId); locMast.setModiTime(now); if (!locMastService.updateById(locMast)) { throw new CoolException("预约库位状态失败,库位号:" + locMast.getLocNo()); } // } else { // throw new CoolException(locMast.getLocNo() + "库位不是在库状态"); // } @@ -2883,6 +2880,130 @@ } /** * 按台车出库 * * @param params * @return com.core.common.R * @author Ryan * @date 2026/3/28 8:41 */ @Override @Transactional(rollbackFor = Exception.class) public R outStockByTc(AgvCallParams params) { if (Objects.isNull(params.getCarBarcode())) { return R.error("台车码不能为空!!"); } LocCache locCache = locCacheService.selectOne(new EntityWrapper<LocCache>().eq("barcode", params.getCarBarcode())); if (Objects.isNull(locCache)) { return R.error("当前台车不在缓冲库区!!"); } if (Objects.isNull(params.getTarSite())) { return R.error("目标站点不能为空!!"); } List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no", locCache.getLocNo())); if (Objects.isNull(locDetls) || locDetls.isEmpty()) { return R.error("台车上没有对应明细信息!!"); } List<LocDto> locDtos = new ArrayList<>(); locDetls.forEach(locDetl -> { OrderPakout orderPakout = orderPakoutService.selectOne(new EntityWrapper<OrderPakout>() .eq("doc_type", 5) .eq("number", locDetl.getOrderNo())); if (!Objects.isNull(orderPakout)) { locDetl.setMemo(orderPakout.getShipCode()); locDetl.setOrderNo(orderPakout.getOrderNo()); } OrderDetlPakout orderDetl = orderDetlPakoutService.selectOne(new EntityWrapper<OrderDetlPakout>() .eq("matnr", locDetl.getMatnr()) .eq("supp_code", locDetl.getSuppCode()) .eq("order_no", orderPakout.getOrderNo())); if (Objects.isNull(orderDetl)) { throw new CoolException("订单明细不存在!!"); } LocDto locDto = new LocDto(locDetl.getLocNo(), locDetl.getMatnr(), locDetl.getMaktx(), locDetl.getBatch(), orderDetl.getOrderNo(), locDetl.getAnfme()); locDto.setFrozen(locDetl.getFrozen()); locDto.setFrozenLoc(locCache.getFrozen()); // List<BasStation> basStations = basStationService.selectList(new EntityWrapper<BasStation>().in("area_id", areaIds)); // List<String> collect = basStations.stream().map(BasStation::getDevNo).collect(Collectors.toList()); // locDto.setAgvStaNos(collect); locDto.setAgvStaNo(params.getTarSite()); locDto.setBrand(orderDetl.getBrand()); locDto.setSuppCode(orderDetl.getSuppCode()); locDto.setStandby1(orderDetl.getStandby1()); locDto.setStandby2(orderDetl.getStandby2()); locDto.setStandby3(orderDetl.getStandby3()); locDto.setBoxType1(orderDetl.getBoxType1()); locDto.setBoxType2(orderDetl.getBoxType2()); locDto.setBoxType3(orderDetl.getBoxType3()); locDtos.add(locDto); // exist.add(locDetl.getLocNo()); }); generateAgvTaskByTc(locDtos); return R.ok(); } @Transactional(rollbackFor = Exception.class) public void generateAgvTaskByTc(List<LocDto> locDtos) { List<LocDto> locDtoArrayList = new ArrayList<>(); for (LocDto locDto : locDtos){ if (locDto.getFrozen()!=1 && locDto.getFrozenLoc()!=1){ locDtoArrayList.add(locDto); } } locDtos = locDtoArrayList; if (Cools.isEmpty(locDtos)) { throw new CoolException("库存/库位被冻结,请处理后出库!!!"); } boolean lack = true; for (LocDto locDto : locDtos) { if (!locDto.isLack()) { lack = false; break; } } if (lack) { throw new CoolException("库存不足"); } try { Thread.sleep(300L); } catch (InterruptedException e) { throw new RuntimeException(e); } List<TaskDto> taskDtos = new ArrayList<>(); // 根据 (库位 & 出库站) 分组; 理想状态:一组为一次出库任务 for (LocDto locDto : locDtos) { if (locDto.isLack()) { continue; } TaskDto taskDto = new TaskDto(locDto.getLocNo(), locDto.getAgvStaNo(), locDto); if (TaskDto.hasAgv(taskDtos, taskDto)) { TaskDto dto = TaskDto.findAgv(taskDtos, taskDto); assert dto != null; dto.getLocDtos().addAll(taskDto.getLocDtos()); } else { taskDtos.add(taskDto); } } // ----------------------------------------------------------------------------------------------- Map<String, List<TaskDto>> listMap = taskDtos.stream().collect(Collectors.groupingBy(TaskDto::getLocNo)); listMap.keySet().forEach(locNo -> { listMap.get(locNo).forEach(taskDto -> { BasStation station = basStationService.selectOne(new EntityWrapper<BasStation>() .in("loc_sts", Arrays.asList(LocStsType.LOC_STS_TYPE_O.type, LocStsType.LOC_STS_TYPE_O.type)) .eq("dev_no", taskDto.getAgvStaNo())); if (Objects.isNull(station)) { throw new CoolException("数据错误,站点不存在或已使用!!"); } workService.agvStockOut(station, taskDto, 9527L); }); }); } /** * 确认捆包出库 * * @param combParam @@ -3007,6 +3128,7 @@ return R.ok().add(wrkMast); } /** * 生成移库任务 * src/main/resources/application-dev.yml
@@ -12,8 +12,8 @@ driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver username: sa password: sa@123 url: jdbc:sqlserver://192.168.238.32:1433;databasename=jsxsasrs # url: jdbc:sqlserver://192.168.4.34:1433;databasename=jsxsasrs # url: jdbc:sqlserver://192.168.238.32:1433;databasename=jsxsasrs url: jdbc:sqlserver://192.168.4.15:1433;databasename=jsxsasrs mvc: static-path-pattern: /** redis: @@ -31,7 +31,7 @@ # global-config: # field-strategy: 0 configuration: # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true cache-enabled: true call-setters-on-nulls: true src/main/webapp/static/js/orderTablePakout.js
@@ -42,7 +42,7 @@ // {type: 'numbers', title: '#'}, {field: 'orderTime', title: '日期', width: 160}, {field: 'orderNo', title: '单据编号', align: 'center', width: 155}, {field: 'docType$', title: '单据类型', align: 'center'} {field: 'shipName$', title: '单据类型', align: 'center'} ]], done: function (res, curr, count) { $('#dictTable+.layui-table-view .layui-table-body tbody>tr:first').trigger('click'); src/main/webapp/views/orderPakout/out.html
@@ -66,13 +66,23 @@ <div class="layui-fluid" style="padding-bottom: 0;"> <div class="layui-row layui-col-space15"> <!-- 左 --> <div class="layui-col-md3" id="left-table"> <div class="layui-col-md4" id="left-table"> <div class="layui-card"> <div class="layui-card-body" style="padding: 10px;"> <form class="layui-form toolbar"> <div class="layui-form-item"> <div class="layui-inline" style="max-width: 300px;"> <div class="layui-inline" style="max-width: 220px;"> <input name="orderNo" class="layui-input" placeholder="输入单据编号" autocomplete="off"/> </div> <div class="layui-inline" style="max-width: 120px;"> <div class="layui-input-inline"> <select name="shipName"> <option value="">单据类型</option> <option value="11">SO</option> <option value="12">EO</option> <option value="13">MD</option> </select> </div> </div> <div class="layui-inline"> <button class="layui-btn icon-btn" lay-filter="originTableSearch" lay-submit> @@ -89,7 +99,7 @@ </div> </div> <!-- 右 --> <div class="layui-col-md9"> <div class="layui-col-md8"> <div class="layui-card"> <div class="layui-card-body" style="padding: 10px;"> <form class="layui-form toolbar"> src/main/webapp/views/wrkMast/wrkMast.html
@@ -73,17 +73,23 @@ <input class="layui-input" type="text" name="crn_no" placeholder="堆垛机号" autocomplete="off"> </div> </div> <!-- 日期范围 --> <div class="layui-inline" style="width: 300px"> <div class="layui-inline"> <div class="layui-input-inline"> <input class="layui-input layui-laydate-range" name="io_time" type="text" placeholder="起始时间 - 终止时间" autocomplete="off" style="width: 300px"> <input class="layui-input" type="text" name="barcode" placeholder="托盘码" autocomplete="off"> </div> </div> <div class="layui-inline"> <div class="layui-input-inline"> <input class="layui-input" type="text" name="condition" placeholder="请输入" autocomplete="off"> <input class="layui-input" type="text" name="orderNo" 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="io_time" type="text" placeholder="起始时间 - 终止时间" autocomplete="off" style="width: 300px">--> <!-- </div>--> <!-- </div>--> <!--s--> <!-- 待添加 --> <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>