From 108885261a81096af9166ba5b9618abe4bec6d42 Mon Sep 17 00:00:00 2001 From: liuxy Date: Mon, 24 Oct 2022 20:36:50 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../callEmpty/GjxCallEmpVehicleTask.java | 333 +++++++++++------- .../wql/QSCH_GjxCallEmpVehicleTask.wql | 79 +---- 2 files changed, 226 insertions(+), 186 deletions(-) diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java index 217556a..0ba30cc 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java @@ -2,8 +2,10 @@ package org.nl.wms.sch.tasks.callEmpty; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; @@ -13,9 +15,11 @@ import org.nl.modules.common.utils.SecurityUtils; import org.nl.modules.system.util.CodeUtil; import org.nl.modules.wql.WQL; import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; import org.nl.wms.sch.manage.AbstractAcsTask; import org.nl.wms.sch.manage.TaskStatusEnum; import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.sch.tasks.RegionTypeEnum; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -42,6 +46,9 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { if (StrUtil.equals(status, "0")) { // 取消删除任务 + if (StrUtil.equals(jsonTask.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } taskTab.delete("task_id = '" + task_id + "'"); } @@ -54,47 +61,65 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { } if (StrUtil.equals(status, TaskStatusEnum.FINISHED.getCode())) { - // 更改任务状态为完成 + /* + * 更改任务状态为完成 + * 1.终点为叠盘架更新叠盘架数量、起点点位状态、等待位状态,更新任务组状态 + * 2.终点为供给线,更新起点载数量 + */ jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); jsonTask.put("update_optid", SecurityUtils.getCurrentUserId()); jsonTask.put("update_optname", SecurityUtils.getCurrentUsername()); jsonTask.put("update_time", DateUtil.now()); taskTab.update(jsonTask); - String end_point_code = jsonTask.getString("point_code2"); - String start_point_code = jsonTask.getString("point_code1"); - JSONObject endPoint = pointTab.query("point_code = '" + end_point_code + "'").uniqueResult(0); - //从空托盘缓存B区或养生A区搬运到叠盘架 - if (StrUtil.equals("DPJQB01", endPoint.getString("region_code"))) { - //解锁起点 - JSONObject startPoint = new JSONObject(); - startPoint.put("lock_type", "1"); - startPoint.put("point_status", "1"); - startPoint.put("update_time", DateUtil.now()); - pointTab.update(startPoint, "point_code = '" + start_point_code + "'"); - //更新终点点位状态 - endPoint.put("point_status", "2"); - endPoint.put("lock_type", "00"); - endPoint.put("vehicle_qty", jsonTask.getString("vehicle_qty")); - endPoint.put("vehicle_type", jsonTask.getString("vehicle_type")); - endPoint.put("update_time", DateUtil.now()); - pointTab.update(endPoint); - } else { - JSONObject startPoint = pointTab.query("point_code = '" + start_point_code + "'").uniqueResult(0); - Integer vehicle_qty = startPoint.getInteger("vehicle_qty"); - int after_qty = vehicle_qty - 1; - startPoint.put("lock_type", "1"); - startPoint.put("vehicle_qty", after_qty); - if (after_qty > 0) { - startPoint.put("point_status", "2"); - } else { - startPoint.put("point_status", "1"); + // 判断终点在哪里 + String point_code1 = jsonTask.getString("point_code1"); + String point_code2 = jsonTask.getString("point_code2"); + + JSONObject jsonEnd = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + // 终点在叠盘架 + if (StrUtil.equals(jsonEnd.getString("region_id"), RegionTypeEnum.DPJQB.getId())) { + // 更新起点点位状态 + JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + // 判断此起点是否是等待点 + if (!StrUtil.equals(jsonStart.getString("row_num"), "9")) { + // 如果不是等待点更新等待点状态 + JSONObject jsonEmpWait = pointTab.query("region_id = '" + jsonStart.getString("region_id") + + "' and block_num = '" + jsonStart.getString("block_num") + + "' and col_num = '" + jsonStart.getString("col_num") + + "' and row_num = '9'").uniqueResult(0); + + jsonEmpWait.put("lock_type", "1"); + pointTab.update(jsonEmpWait); } - startPoint.put("update_time", DateUtil.now()); - pointTab.update(startPoint, "point_code = '" + start_point_code + "'"); + + jsonStart.put("point_status", "1"); + jsonStart.put("lock_type", "1"); + jsonStart.put("vehicle_type", ""); + jsonStart.put("vehicle_code", ""); + jsonStart.put("vehicle_qty", 0); + pointTab.update(jsonStart); + + // 更新终点(叠盘架状态) + jsonEnd.put("vehicle_qty", NumberUtil.add(jsonEnd.getString("vehicle_qty"),jsonTask.getString("vehicle_qty"))); + jsonEnd.put("lock_type", "1"); + pointTab.update(jsonEnd); + + // 更新任务组状态 + JSONObject jsonTask2 = taskTab.query("task_group_id = '" + jsonTask.getString("task_group_id") + "' and task_id <> '" + jsonTask.getString("task_id") + "'").uniqueResult(0); + jsonTask2.put("point_code1", jsonEnd.getString("point_code")); + jsonTask2.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(jsonTask2); + } else { + // 终点在油漆线: 更新起点(叠盘架)数量 + JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + jsonStart.put("vehicle_qty",NumberUtil.sub(jsonStart.getString("vehicle_qty"),"1")); + jsonStart.put("lock_type", "1"); + pointTab.update(jsonStart); } } } + @Override public List addTask() { return null; @@ -102,8 +127,8 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { @Override public void findStartPoint() { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 JSONArray taskArr = taskTab.query("is_delete = '0' and handle_class = '" + this.THIS_CLASS + "' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); for (int i = 0; i < taskArr.size(); i++) { @@ -111,74 +136,119 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { JSONObject jsonTask = taskArr.getJSONObject(i); String vehicle_type = jsonTask.getString("vehicle_type"); - //判断叠盘位是否有另外任务 - JSONObject taskObj = taskTab.query("is_delete='0' and handle_class='" + this.THIS_CLASS + "' and task_status <>'" + TaskStatusEnum.FINISHED.getCode() + "' and task_id <> " + jsonTask.getLong("task_id")).uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) continue; + // 找叠盘架是否与对应的载具类型 + JSONObject jsonDpjStart = pointTab.query("region_id = '" + RegionTypeEnum.DPJQB.getId() + "' and can_vehicle_type = '" + vehicle_type + "' and lock_type = '1' and is_used = '1' and is_delete = '0' and vehicle_qty <> '0'").uniqueResult(0); - //判断叠盘架是否有载具 - JSONObject dpjPoint = pointTab.query("is_used ='1' and lock_type='00' and is_delete='0' and region_code='DPJQB01' and vehicle_qty >0 and can_vehicle_type like '%" + vehicle_type + "%'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(dpjPoint)) { - jsonTask.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - jsonTask.put("point_code1", dpjPoint.getString("point_code")); - jsonTask.put("update_time", DateUtil.now()); + if (ObjectUtil.isNotEmpty(jsonDpjStart)) { + // 判断叠盘架是否有任务 有就下一个任务 + boolean is_point = this.isTask(jsonDpjStart.getString("point_code")); + if (!is_point) continue; + + // 更新任务起点 + jsonTask.put("point_code1", jsonDpjStart.getString("point_code")); + jsonTask.put("task_status", TaskStatusEnum.START_AND_POINT); taskTab.update(jsonTask); - //锁住点位 - dpjPoint.put("lock_type", "2"); - pointTab.update(dpjPoint); } else { - //查找叠盘架编码 - JSONObject dpjPoint1 = pointTab.query("is_delete='0' and region_code='DPJQB01' and can_vehicle_type like '%" + vehicle_type + "%'").uniqueResult(0); + // 判断叠盘架载具数量是否是0 + JSONObject jsonDpjStart2 = pointTab.query("region_id = '" + RegionTypeEnum.DPJQB.getId() + "' and can_vehicle_type = '" + vehicle_type + "' and lock_type = '1' and is_used = '1' and is_delete = '0' and vehicle_qty = '0'").uniqueResult(0); + if (ObjectUtil.isEmpty(jsonDpjStart2)) continue; - //叠盘架无载具:1-判断是否有在执行中的堆叠任务,有则等堆叠任务完成以后再去,否则去去缓存位和养生A区找 - JSONObject ddTask = taskTab.query("is_delete='0' and point_code2 = '" + dpjPoint1.getString("point_code") + "'" + " and task_status <> '7' ").uniqueResult(0); - if (ObjectUtil.isNotEmpty(ddTask)) continue; + // 判断叠盘架是否有任务 + boolean is_point = this.isTask(jsonDpjStart2.getString("point_code")); + if (!is_point) continue; - //去缓存位和养生A区找,生成到叠盘架的任务 - JSONObject whereParam = new JSONObject(); - whereParam.put("flag", "1"); - whereParam.put("vehicle_type", '%' + jsonTask.getString("vehicle_type") + "%"); - JSONObject outJsonObj = WQL.getWO("QSCH_GjxCallEmpVehicleTask").addParamMap(whereParam).process().uniqueResult(0); + // 找叠盘架暂存位是否有空托盘 + JSONObject map = new JSONObject(); + map.put("flag", "1"); + map.put("vehicle_type", vehicle_type); - // 空托盘缓存货架或者养生A区------>叠盘架B区 - JSONObject param = new JSONObject(); - Long task_id = IdUtil.getSnowflake(1, 1).nextId(); - Long task_group_id = IdUtil.getSnowflake(1, 1).nextId(); - param.put("task_id", task_id); - param.put("task_code", CodeUtil.getNewCode("TASK_CODE")); - param.put("vehicle_type", vehicle_type); - param.put("priority", 100); - param.put("handle_class", THIS_CLASS); - param.put("task_type", "kzj"); - param.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - param.put("task_group_id", task_group_id); - param.put("sort_seq", 1); - param.put("point_code1", outJsonObj.getString("point_code")); - param.put("point_code2", dpjPoint1.getString("point_code")); - param.put("create_name", SecurityUtils.getCurrentUsername()); - param.put("create_id", SecurityUtils.getCurrentUserId()); - param.put("create_time", DateUtil.now()); - taskTab.insert(param); + JSONObject jsonZcKtp = WQL.getWO("QSCH_GjxCallEmpVehicleTask").addParamMap(map).process().uniqueResult(0); + if (ObjectUtil.isNotEmpty(jsonZcKtp)) { + // 创建任务:空载具暂存位 --> 叠盘架 + SchTaskDto dto = SchTaskDto.builder() + .task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_status(TaskStatusEnum.START_AND_POINT.getCode()) + .point_code1(jsonZcKtp.getString("point_code")) + .point_code2(jsonDpjStart2.getString("point_code")) + .vehicle_code(jsonZcKtp.getString("vehicle_code")) + .vehicle_type(jsonZcKtp.getString("vehicle_type")) + .vehicle_qty(jsonZcKtp.getIntValue("vehicle_qty")) + .task_group_id(jsonTask.getLong("task_group_id")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + // 锁定起点 + jsonZcKtp.put("lock_type", "2"); + pointTab.update(jsonZcKtp); + } else { + // 空托盘暂存区没有就到养生A区找: 先找到出库等待点 + JSONObject jsonEmpWait = pointTab.query("region_id = '" + RegionTypeEnum.YSAQKTPQ01.getId() + + "' and row_num = '9' and can_vehicle_type = '" + vehicle_type + + "' and is_used = '1' and is_delete = '0'").uniqueResult(0); + if (ObjectUtil.isEmpty(jsonEmpWait)) continue; - //锁住起点 - outJsonObj.put("lock_type", "2"); - pointTab.update(outJsonObj); - this.notifyAcs(String.valueOf(task_id)); + JSONObject jsonStartPoint = pointTab.query("region_id = '" + jsonEmpWait.getString("region_id") + + "' and block_num = '" + jsonEmpWait.getString("block_num") + + "' and col_num = '" + jsonEmpWait.getString("col_num") + + "' and point_status = '2' and lock_type = '1' order by out_empty_seq DESC").uniqueResult(0); + if (ObjectUtil.isEmpty(jsonStartPoint)) continue; - - jsonTask.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - jsonTask.put("point_code1", outJsonObj.getString("point_code")); - jsonTask.put("sort_seq", 2); - jsonTask.put("task_group_id", task_group_id); - jsonTask.put("remark", "叠盘架无载具!"); - taskTab.update(jsonTask); - - //锁住点位 - dpjPoint1.put("lock_type", "2"); - pointTab.update(outJsonObj); + // 判断找到的空载具点位是否是等待点 + if (StrUtil.equals(jsonEmpWait.getString("point_code"),jsonStartPoint.getString("point_code"))) { + // 创建 养生A区空载具等待点 --> 叠盘架 + SchTaskDto dto = SchTaskDto.builder() + .task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_status(TaskStatusEnum.START_AND_POINT.getCode()) + .point_code1(jsonStartPoint.getString("point_code")) + .point_code2(jsonDpjStart2.getString("point_code")) + .vehicle_code(jsonStartPoint.getString("vehicle_code")) + .vehicle_type(jsonStartPoint.getString("vehicle_type")) + .vehicle_qty(jsonStartPoint.getIntValue("vehicle_qty")) + .task_group_id(jsonTask.getLong("task_group_id")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + // 锁起点 + jsonStartPoint.put("lock_type", "2"); + pointTab.update(jsonStartPoint); + } else { + // 判断等待点是否是 未锁定、为空载具 + if (StrUtil.equals(jsonEmpWait.getString("lock_type"), "1") && StrUtil.equals(jsonEmpWait.getString("point_status"), "2")) { + // 创建 养生A区空载具 --> 叠盘架 + SchTaskDto dto = SchTaskDto.builder() + .task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_status(TaskStatusEnum.START_AND_POINT.getCode()) + .point_code1(jsonStartPoint.getString("point_code")) + .point_code2(jsonDpjStart2.getString("point_code")) + .vehicle_code(jsonStartPoint.getString("vehicle_code")) + .vehicle_type(jsonStartPoint.getString("vehicle_type")) + .vehicle_qty(jsonStartPoint.getIntValue("vehicle_qty")) + .task_group_id(jsonTask.getLong("task_group_id")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + // 锁起点 + jsonStartPoint.put("lock_type", "2"); + pointTab.update(jsonStartPoint); + } else { + continue; + } + } + } } - - } } @@ -187,41 +257,40 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { @Override @Transactional(rollbackFor = Exception.class) public String createTask(JSONObject form) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + /* + * 1.先生成确定终点的任务 + * 2.通过findStartPoint()找起点 + * 3.下发给ACS + */ + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); // 生产工单表 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); //点位基础表 - String end_point_code = form.getString("point_code2"); - String vehicle_type = form.getString("vehicle_type"); + String point_code2 = form.getString("point_code1"); - // 终点不能为空 - if (ObjectUtil.isEmpty(end_point_code)) { - throw new BadRequestException("终点不能为空"); - } else { - // 判断终点是否有正在执行的任务 - JSONObject beforTaskObj = taskTab.query("is_delete='0' and point_code2='" + end_point_code + "' and task_status <>'" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(beforTaskObj)) - throw new BadRequestException("存在任务号为'" + beforTaskObj.getString("task_code") + "' 未完成!"); - } - // 创建任务 - JSONObject jsonTask = new JSONObject(); - Long task_id = IdUtil.getSnowflake(1, 1).nextId(); - jsonTask.put("task_id", task_id); - jsonTask.put("task_code", CodeUtil.getNewCode("TASK_CODE")); - jsonTask.put("handle_class", THIS_CLASS); - jsonTask.put("vehicle_type", vehicle_type); + String device_code = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0).getString("device_code"); - jsonTask.put("point_code2", end_point_code); - jsonTask.put("create_name", SecurityUtils.getCurrentUsername()); - jsonTask.put("create_id", SecurityUtils.getCurrentUserId()); - jsonTask.put("create_time", DateUtil.now()); + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); - //见基础分类表的任务分类 - jsonTask.put("task_type", "gjxsqkp"); - jsonTask.put("task_status", TaskStatusEnum.SURE_END.getCode()); - jsonTask.put("point_code1", ""); - taskTab.insert(jsonTask); + SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_status(TaskStatusEnum.SURE_END.getCode()) + .point_code2(point_code2) + .vehicle_code(form.getString("vehicle_code")) + .vehicle_type(workOrderObj.getString("vehicle_type")) + .vehicle_qty(form.getIntValue("qty")) + .task_group_id(org.nl.wms.util.IdUtil.getLongId()) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); this.findStartPoint(); - return String.valueOf(task_id); +// this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); } @Override @@ -236,4 +305,28 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { } + @Transactional(rollbackFor = Exception.class) + public boolean isTask(String point_code) { + /* + * 判断点位是否有任务存在 + */ + WQLObject tab = WQLObject.getWQLObject("SCH_BASE_Task"); + + boolean result; + + JSONObject jsonPointCode1 = tab.query("point_code1 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); + JSONObject jsonPointCode2 = tab.query("point_code2 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); + JSONObject jsonPointCode3 = tab.query("point_code3 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); + JSONObject jsonPointCode4 = tab.query("point_code4 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); + + if (ObjectUtil.isEmpty(jsonPointCode1) && ObjectUtil.isEmpty(jsonPointCode2) && ObjectUtil.isEmpty(jsonPointCode3) && ObjectUtil.isEmpty(jsonPointCode4)) { + result = true; + } else { + result = false; + } + + return result; + } + + } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_GjxCallEmpVehicleTask.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_GjxCallEmpVehicleTask.wql index d8774b0..b76c2fb 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_GjxCallEmpVehicleTask.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_GjxCallEmpVehicleTask.wql @@ -14,9 +14,7 @@ ## 表字段对应输入参数 ################################################# 输入.flag TYPEAS s_string - 输入.vehicle_qty TYPEAS s_string - 输入.vehicle_type TYPEAS s_string - 输入.region_code TYPEAS s_string + 输入.vehicle_type TYPEAS s_string [临时表] --这边列出来的临时表就会在运行期动态创建 @@ -42,72 +40,21 @@ IF 输入.flag = "1" QUERY - SELECT - p.point_id, - p.point_code, - p.point_name - FROM - SCH_BASE_Point p - WHERE - p.is_used = '1' - AND p.is_delete = '0' - AND p.lock_type = '00' - AND p.point_status = '2' - and region_code in ('KTPHCQB01','YSQA01') + SELECT + * + FROM + SCH_BASE_Point + WHERE + is_used = '1' + AND is_delete = '0' + AND lock_type = '1' + AND point_status = '2' + AND region_code = 'KTPHCQB01' OPTION 输入.vehicle_type <> "" - p.vehicle_type like 输入.vehicle_type + can_vehicle_type = 输入.vehicle_type ENDOPTION - order by out_empty_seq,p.vehicle_qty - ENDSELECT ENDQUERY - ENDIF - - IF 输入.flag = "3" - QUERY - SELECT - point.* - FROM - sch_base_point point - LEFT JOIN SCH_BASE_Region region ON point.region_id = region.region_id - WHERE - point.lock_type = '00' - AND point.point_status = '01' - AND IFNULL(point.vehicle_qty,0) == 输入.vehicle_qty - - OPTION 输入.region_code <> "" - region.region_code = 输入.region_code - ENDOPTION - - OPTION 输入.vehicle_type <> "" - point.vehicle_type = 输入.vehicle_type - ENDOPTION - - order by point.point_code DESC - - ENDSELECT - ENDQUERY - ENDIF - - IF 输入.flag = "2" - QUERY - SELECT - point.* - FROM - sch_base_point point - LEFT JOIN SCH_BASE_Region region ON point.region_id = region.region_id - WHERE - point.lock_type = '00' - AND point.point_status = '00' - - OPTION 输入.region_code <> "" - region.region_code = 输入.region_code - ENDOPTION - - order by point.point_code DESC - - ENDSELECT - ENDQUERY - ENDIF + ENDIF \ No newline at end of file From 2eb75f782eae5545ab7452aa39d4aae1980b1d25 Mon Sep 17 00:00:00 2001 From: ldj_willow Date: Tue, 25 Oct 2022 08:39:08 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../acs/service/impl/AcsToWmsServiceImpl.java | 12 +- .../main/java/org/nl/wms/sch/SchTaskDto.java | 2 +- ...Material.java => GjxSendMaterialTask.java} | 9 +- .../sendMaterial/HkxSendMaterialTask.java | 279 ++++++++++++++++++ .../sendMaterial/YqxSendMaterialTask.java | 248 +++++++--------- .../wql/QSCH_hkxSendMaterial_01.wql | 68 +++++ .../wql/QSCH_yqxSendMaterial_01.wql | 62 ++++ .../src/main/java/org/nl/wms/wms.xls | Bin 285184 -> 285184 bytes 8 files changed, 527 insertions(+), 153 deletions(-) rename lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/{GjxSendMaterial.java => GjxSendMaterialTask.java} (98%) create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HkxSendMaterialTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hkxSendMaterial_01.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yqxSendMaterial_01.wql diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java index 7977e59..268dbe9 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java @@ -22,12 +22,12 @@ import org.nl.wms.sch.manage.TaskStatusEnum; import org.nl.wms.sch.service.PointService; import org.nl.wms.sch.service.TaskService; import org.nl.wms.sch.service.dto.TaskDto; -import org.nl.wms.sch.tasks.PointToPointTask; import org.nl.wms.sch.tasks.callEmpty.GjxCallEmpVehicleTask; import org.nl.wms.sch.tasks.callMaterial.CallMaterialTask; import org.nl.wms.sch.tasks.sendEmpty.HtSendEmpVehicleTask; import org.nl.wms.sch.tasks.sendEmpty.YqxSendEmpVehicleTask; -import org.nl.wms.sch.tasks.sendMaterial.GjxSendMaterial; +import org.nl.wms.sch.tasks.sendMaterial.GjxSendMaterialTask; +import org.nl.wms.sch.tasks.sendMaterial.HkxSendMaterialTask; import org.nl.wms.sch.tasks.sendMaterial.YqxSendMaterialTask; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @@ -194,7 +194,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { * 4.油漆线申请物料 * 5.油漆线空盘入库 * 6.一楼空盘入库 (有载具号) - * 7.油漆线->输送线 + * 7.油漆线->输送线(油漆线满料) * 8.豪凯自动线下料入库 */ if (StrUtil.equals(type, "1")) { @@ -220,7 +220,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { param.put("vehicle_type", vehicle_type); param.put("vehicle_code", vehicle_code); - GjxSendMaterial taskBean = SpringContextHolder.getBean(GjxSendMaterial.class); + GjxSendMaterialTask taskBean = SpringContextHolder.getBean(GjxSendMaterialTask.class); String task_id = taskBean.createTask(param); // 创建任务 } else if (StrUtil.equals(type, "3")) { // 3.油漆线申请空盘: 调用空托盘出库处理类创建任务 @@ -297,12 +297,12 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { JSONObject param = new JSONObject(); param.put("point_code1", point_code); // 1.生成起点确定的任务 - SpringContextHolder.getBean(PointToPointTask.class).createTask(param); + SpringContextHolder.getBean(YqxSendMaterialTask.class).createTask(param); } else if (StrUtil.equals(type, "8")) { // 8.豪凯自动线下料入库 JSONObject param = new JSONObject(); param.put("point_code1", point_code); - YqxSendMaterialTask taskBean = SpringContextHolder.getBean(YqxSendMaterialTask.class); + HkxSendMaterialTask taskBean = SpringContextHolder.getBean(HkxSendMaterialTask.class); String task_id = taskBean.createTask(param); } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/SchTaskDto.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/SchTaskDto.java index 38de98a..ba4c9a5 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/SchTaskDto.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/SchTaskDto.java @@ -103,7 +103,7 @@ public class SchTaskDto implements Serializable { */ private Integer sort_seq; //物料数量 - private Integer material_qty; + private String material_qty; /** * 任务完成类型 diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterial.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterialTask.java similarity index 98% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterial.java rename to lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterialTask.java index 59b5829..64cac96 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterial.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterialTask.java @@ -13,11 +13,9 @@ import org.nl.modules.common.utils.SecurityUtils; import org.nl.modules.system.util.CodeUtil; import org.nl.modules.wql.WQL; import org.nl.modules.wql.core.bean.WQLObject; -import org.nl.modules.wql.util.SpringContextHolder; import org.nl.wms.sch.SchTaskDto; import org.nl.wms.sch.manage.AbstractAcsTask; import org.nl.wms.sch.manage.TaskStatusEnum; -import org.nl.wms.sch.service.PointService; import org.nl.wms.sch.tasks.AcsTaskDto; import org.nl.wms.util.IdUtil; import org.springframework.stereotype.Service; @@ -33,8 +31,9 @@ import java.util.List; @Service @RequiredArgsConstructor @Slf4j -public class GjxSendMaterial extends AbstractAcsTask { - private final String THIS_CLASS = GjxSendMaterial.class.getName(); +public class GjxSendMaterialTask extends AbstractAcsTask { + + private final String THIS_CLASS = GjxSendMaterialTask.class.getName(); @Override @@ -274,7 +273,7 @@ public class GjxSendMaterial extends AbstractAcsTask { WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); if (ObjectUtil.isNotEmpty(taskObj)) - this.updateTaskStatus(taskObj,"2"); + this.updateTaskStatus(taskObj, "2"); } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HkxSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HkxSendMaterialTask.java new file mode 100644 index 0000000..44b646a --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HkxSendMaterialTask.java @@ -0,0 +1,279 @@ +package org.nl.wms.sch.tasks.sendMaterial; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.system.util.CodeUtil; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.SchTaskDto; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.util.IdUtil; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + + +/** + * 豪凯自动线线送料任务服务 + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class HkxSendMaterialTask extends AbstractAcsTask { + + private final String THIS_CLASS = HkxSendMaterialTask.class.getName(); + + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateTaskStatus(JSONObject task, String status) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + + String task_id = task.getString("task_id"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); + + //任务取消 + if (StrUtil.equals(status, "0")) { + // 取消删除任务 + if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + String point_code2 = taskObj.getString("point_code2"); + if (ObjectUtil.isEmpty(point_code2)) { + JSONObject endPoint = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + endPoint.put("lock_type", "1"); + pointTab.update(endPoint); + } + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("remark", "已取消"); + taskTab.update(taskObj); + } + + if ("1".equals(status)) { + // 更新任务状态为执行中 + taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskObj.put("car_no", taskObj.getString("car_no")); + taskTab.update(taskObj); + } + + if (StrUtil.equals(status, "2")) { + // 更改任务状态为完成 + taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + + String point_code2 = taskObj.getString("point_code2"); + JSONObject point2Obj = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + JSONObject requestObj = task.getJSONObject("request_param"); + //工单标识 + String workorder_id = requestObj.getString("material_info_id"); + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + JSONObject workorderObj = workOrderTab.query("workorder_id", workorder_id).uniqueResult(0); + + //区域出入表【st_ivt_regionIO】 + WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); + JSONObject regionIoObj = new JSONObject(); + regionIoObj.put("iostorinv_id", IdUtil.getLongId()); + regionIoObj.put("bill_code", CodeUtil.getNewCode("IN_STORE_CODE")); + regionIoObj.put("buss_date", DateUtil.today()); + regionIoObj.put("io_type", "1"); + regionIoObj.put("region_id", point2Obj.getString("region_id")); + regionIoObj.put("region_code", point2Obj.getString("region_code")); + regionIoObj.put("region_name", point2Obj.getString("region_name")); + regionIoObj.put("material_id", taskObj.getString("material_id")); + regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); + regionIoObj.put("qty", requestObj.getString("qty")); + regionIoObj.put("bill_status", "3"); + regionIoObj.put("start_point_code", taskObj.getString("point_code1")); + regionIoObj.put("end_point_code", taskObj.getString("point_code3")); + regionIoObj.put("create_mode", "2"); + regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + regionIoObj.put("create_id", SecurityUtils.getCurrentUserId()); + regionIoObj.put("create_name", SecurityUtils.getCurrentNickName()); + regionIoObj.put("create_time", DateUtil.now()); + regionIoTab.insert(regionIoObj); + + + //完成后入库 + //仓位库存表【ST_IVT_StructIvt】 + WQLObject ivtTab = WQLObject.getWQLObject("ST_IVT_StructIvt"); + JSONObject ivtObj = new JSONObject(); + ivtObj.put("stockrecord_id", IdUtil.getLongId()); + ivtObj.put("point_id", point2Obj.getString("point_id")); + ivtObj.put("point_code", point2Obj.getString("point_code")); + ivtObj.put("point_name", point2Obj.getString("point_name")); + ivtObj.put("region_id", point2Obj.getString("region_id")); + ivtObj.put("region_code", point2Obj.getString("region_code")); + ivtObj.put("region_name", point2Obj.getString("region_name")); + ivtObj.put("instorage_time", DateUtil.now()); + ivtObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); + ivtObj.put("ivt_qty", requestObj.getString("qty")); + ivtObj.put("standing_time", workorderObj.getString("standing_time")); + ivtObj.put("material_id", workorderObj.getString("material_id")); + ivtTab.insert(ivtObj); + } + + } + + @Override + public void findNextPoint() { + /* + * 根据业务找对应的终点 + */ + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); + JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '2'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + JSONObject taskObj = taskArr.getJSONObject(i); + String vehicle_type = taskObj.getString("vehicle_type"); + JSONObject param1 = new JSONObject(); + param1.put("flag", "1"); + param1.put("region_code", "CPQYA01"); + param1.put("vehicle_type", "%" + vehicle_type + "%"); + //1、查找库区类是否有响应的载具类型和对应的物料 + JSONObject endPoint = WQL.getWO("QSCH_hkxSendMaterial_01").addParamMap(param1).process().uniqueResult(0); + if (ObjectUtil.isEmpty(endPoint)) { + taskObj.put("remark", "成品区无可用货位!"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + taskObj.put("update_time", DateUtil.now()); + taskObj.put("point_code2", endPoint.getString("point_code")); + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(taskObj); + + //锁住终点 + endPoint.put("task_id", taskObj.getString("task_id")); + endPoint.put("lock_type", "2"); + pointTab.update(endPoint); + } + + + } + } + + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code3")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; + } + + @Override + public String createTask(JSONObject whereJson) { + String point_code1 = whereJson.getString("point_code1"); + String vehicle_type = whereJson.getString("vehicle_type"); + String vehicle_code = whereJson.getString("vehicle_code"); + String qty = whereJson.getString("qty"); + + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + //点位基础表【SCH_BASE_Point】 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); + String device_code = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0).getString("device_code"); + + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + + SchTaskDto dto = SchTaskDto.builder() + .task_id(IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("task_type") + .task_status(TaskStatusEnum.SURE_START.getCode()) + .point_code1(point_code1) + .vehicle_code(vehicle_code) + .material_info_id(workOrderObj.getLong("workorder_id")) + .material_id(workOrderObj.getLong("material_id")) + .vehicle_type(vehicle_type) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .request_param(whereJson.toJSONString()) + .build(); + //任务表【SCH_BASE_Task】 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + + //创建好立即下发 + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); + } + + @Override + public void forceFinish(String task_id) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject taskObj = taskTab.query("task_id = '" + task_id + "' and is_delete = '0' and task_status <> " + TaskStatusEnum.FINISHED.getCode()).uniqueResult(0); + if (ObjectUtil.isNotEmpty(taskObj)) + this.updateTaskStatus(taskObj, "2"); + } + + + @Override + public void cancel(String task_id) { + + } + + @Transactional(rollbackFor = Exception.class) + @Override + public String againApply(String task_id) { + /* + * 再次下发任务处理方法 + * 涉及业务:入空载具、出空载具、入物料、出物料 + */ + + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); // 点位表 + + JSONObject taskObj = taskTab.query("task_id ='" + task_id + "'").uniqueResult(0); + JSONObject jsonPoint2 = pointTab.query("point_code = '" + taskObj.getString("point_code2") + "'").uniqueResult(0); + + // 根据 区域、块、列找到第一个有物料的货位 + JSONObject jsonOnePoint = pointTab.query("region_id = '" + jsonPoint2.getString("region_id") + + "' and block_num = '" + jsonPoint2.getString("block_num") + + "' and col_num = '" + jsonPoint2.getString("col_num") + + "' and point_status = '1' order by row_num desc").uniqueResult(0); + + if (ObjectUtil.isEmpty(jsonOnePoint)) throw new BadRequestException("该列库存状态有误,请检查!"); + + taskObj.put("point_code3", jsonOnePoint.getString("point_code")); + taskObj.put("remark", "二次申请货位"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + + return jsonOnePoint.getString("point_code"); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java index 6e23a71..4d1c278 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java @@ -1,9 +1,9 @@ package org.nl.wms.sch.tasks.sendMaterial; import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; @@ -14,18 +14,18 @@ import org.nl.modules.system.util.CodeUtil; import org.nl.modules.wql.WQL; import org.nl.modules.wql.core.bean.WQLObject; import org.nl.modules.wql.util.SpringContextHolder; -import org.nl.wms.sch.PointFindUtil; +import org.nl.wms.sch.SchTaskDto; import org.nl.wms.sch.manage.AbstractAcsTask; import org.nl.wms.sch.manage.TaskStatusEnum; import org.nl.wms.sch.service.PointService; import org.nl.wms.sch.service.dto.PointDto; -import org.nl.wms.sch.service.impl.PointServiceImpl; import org.nl.wms.sch.tasks.AcsTaskDto; import org.nl.wms.sch.tasks.RegionTypeEnum; +import org.nl.wms.util.IdUtil; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.HashMap; +import java.util.ArrayList; import java.util.List; @@ -47,11 +47,23 @@ public class YqxSendMaterialTask extends AbstractAcsTask { **/ String task_id = taskObj.getString("task_id"); WQLObject taskTab = WQLObject.getWQLObject("sch_base_task"); + //点位基础表【SCH_BASE_Point】 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); JSONObject jsonTask = taskTab.query("task_id='" + task_id + "'").uniqueResult(0); if (StrUtil.equals(status, "0")) { - // 取消删除任务 - taskTab.delete("task_id = '" + task_id + "'"); + //取消任务,释放相关点位的锁 + String point_code1 = jsonTask.getString("point_code1"); + String point_code2 = jsonTask.getString("point_code1"); + JSONObject param = new JSONObject(); + param.put("lock_type", "1"); + param.put("task_id", ""); + pointTab.update(param, "point_code = '" + point_code1 + "'"); + pointTab.update(param, "point_code = '" + point_code2 + "'"); + + jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); + jsonTask.put("remark", "已取消"); + taskTab.update(jsonTask); } if (TaskStatusEnum.EXECUTING.getCode().equals(status)) { @@ -60,12 +72,6 @@ public class YqxSendMaterialTask extends AbstractAcsTask { jsonTask.put("update_time", DateUtil.now()); jsonTask.put("car_no", taskObj.getString("car_no")); taskTab.update(jsonTask); - HashMap map = new HashMap(); - map.put("update_optid", SecurityUtils.getCurrentUserId()); - map.put("update_optname", SecurityUtils.getCurrentNickName()); - map.put("update_time", DateUtil.now()); - map.put("bill_status", "40"); - WQLObject.getWQLObject("ST_IVT_regionIO").update(map, "task_id='" + jsonTask.getString("task_id") + "'"); } if (TaskStatusEnum.FINISHED.getCode().equals(status)) { @@ -74,49 +80,20 @@ public class YqxSendMaterialTask extends AbstractAcsTask { jsonTask.put("taskfinish_mode", taskObj.getString("taskfinish_mode")); jsonTask.put("update_time", DateUtil.now()); jsonTask.put("remark", "任务执行完成"); - ///审核单据 增加库存 改变出入库表的状态 - WQLObject mstTab = WQLObject.getWQLObject("ST_IVT_regionIO"); - JSONObject mstObj = mstTab.query("task_id='" + task_id + "' and is_delete='0'").uniqueResult(0); - //审核 加库存可和用数量 - mstObj.put("bill_status", "50"); - mstObj.put("confirm_optid", SecurityUtils.getCurrentUserId()); - mstObj.put("confirm_optname", SecurityUtils.getCurrentNickName()); - mstObj.put("confirm_time", DateUtil.now()); - mstTab.update(mstObj); - - String iostorinv_id = mstObj.getString("iostorinv_id"); - String bill_code = mstObj.getString("bill_code"); - String bill_type_scode = mstObj.getString("bill_type"); - String point_code2 = mstObj.getString("end_point_code"); - String point_code1 = mstObj.getString("point_code1"); - - - PointServiceImpl pointService = SpringContextHolder.getBean(PointServiceImpl.class); - PointDto nextPointDto = pointService.findByCode(point_code2); - if (ObjectUtil.isNull(nextPointDto)) { - throw new BadRequestException("未找到可用点位:" + point_code2); - } - PointDto startPointDto = pointService.findByCode(point_code1); - if (ObjectUtil.isNull(startPointDto)) { - throw new BadRequestException("未找到可用点位:" + point_code1); - } - // 解锁点位 - String vehicle_code = jsonTask.getString("vehicle_code"); - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); - JSONObject endpointObj = pointTab.query("point_code='" + jsonTask.getString("point_code2") + "'").uniqueResult(0); - endpointObj.put("lock_type", "1"); - endpointObj.put("point_status", "02"); - endpointObj.put("vehicle_code", vehicle_code); - endpointObj.put("vehicle_type", jsonTask.getString("vehicle_type")); - pointTab.update(endpointObj); taskTab.update(jsonTask); - /* JSONObject startPointObj = pointTab.query("point_code='" + jsonTask.getString("point_code1") + "'").uniqueResult(0); - startPointObj.put("lock_type", "1"); - startPointObj.put("point_status", "00"); - startPointObj.put("vehicle_code", ""); - pointTab.update(startPointObj); - taskTab.update(jsonTask);*/ + + //取消任务,释放相关点位的锁 + String point_code1 = jsonTask.getString("point_code1"); + String point_code2 = jsonTask.getString("point_code1"); + JSONObject param = new JSONObject(); + param.put("lock_type", "1"); + param.put("task_id", ""); + + pointTab.update(param, "point_code = '" + point_code1 + "'"); + + param.put("point_status", "3"); + pointTab.update(param, "point_code = '" + point_code2 + "'"); } } @@ -125,108 +102,76 @@ public class YqxSendMaterialTask extends AbstractAcsTask { public void findNextPoint() { String task_status = TaskStatusEnum.SURE_START.getCode(); WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + //点位基础表【SCH_BASE_Point】 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); JSONArray taskArry = taskTab.query("task_status='" + task_status + "' AND handle_class='" + THIS_CLASS + "' AND is_delete='0' ").getResultJSONArray(0); for (int i = 0; i < taskArry.size(); i++) { JSONObject taskObj = taskArry.getJSONObject(i); String task_id = taskObj.getString("task_id"); - //1 将任务修改为分配 2将终点写入,完成分配,3 加锁点位 - //找一个合适的仓位 - WQLObject ProcedureIOStable = WQLObject.getWQLObject("ST_IVT_regionIO"); - JSONObject IosObj = ProcedureIOStable.query("task_id='" + task_id + "' and is_delete ='0'").uniqueResult(0); - if (ObjectUtil.isEmpty(IosObj)) { - throw new BadRequestException("未找到任务号为'" + taskObj.getString("task_code") + "'的入库单据!"); - } + JSONObject param = new JSONObject(); - param.put("material_id", IosObj.getString("material_id")); - param.put("area_type", IosObj.getString("end_area")); - param.put("vehicle_code", IosObj.getString("vehicle_code")); - JSONObject inStructObj = PointFindUtil.getInStruct(param); - if (ObjectUtil.isEmpty(inStructObj)) { - throw new BadRequestException("未找到合适的入库仓位!"); + param.put("flag", "1"); + JSONObject endPoint = WQL.getWO("QSCH_yqxSendMaterial_01").addParamMap(param).process().uniqueResult(0); + if (ObjectUtil.isEmpty(endPoint)) { + taskObj.put("remark", "电梯无可用点"); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); + } else { + //锁住点位 + endPoint.put("lock_type", "2"); + endPoint.put("task_id", task_id); + pointTab.update(endPoint); + + //修改任务状态 + taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); + taskObj.put("update_optname", SecurityUtils.getCurrentNickName()); + taskObj.put("update_time", DateUtil.now()); + taskTab.update(taskObj); } - //修改单据状态,将终点填入 - IosObj.put("bill_status", "20"); - IosObj.put("end_point_code", inStructObj.getString("struct_code")); - ProcedureIOStable.update(IosObj); - //终点加锁 - HashMap lock_map = new HashMap(); - lock_map.put("lock_type", "2"); - WQLObject.getWQLObject("sch_base_point").update(lock_map, "point_code = '" + inStructObj.getString("struct_code") + "'"); - //修改任务状态 - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); - taskObj.put("update_optname", SecurityUtils.getCurrentNickName()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); } } @Override @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - //请求参数 载具、起点、终点 - String vehicle_code = form.getString("vehicle_code"); - String vehicle_type = form.getString("vehicle_type"); - String point_code1 = form.getString("point_code1"); - String point_code2 = form.getString("point_code2"); + public String createTask(JSONObject whereJson) { + String point_code1 = whereJson.getString("point_code1"); + String vehicle_type = whereJson.getString("vehicle_type"); + String vehicle_code = whereJson.getString("vehicle_code"); + String qty = whereJson.getString("qty"); - WQLObject taskTable = WQLObject.getWQLObject("SCH_BASE_Task"); - WQLObject iosTable = WQLObject.getWQLObject("ST_IVT_regionIO"); + //生产工单表【PDM_BD_WorkOrder】 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); + //点位基础表【SCH_BASE_Point】 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); + String device_code = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0).getString("device_code"); + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); - if (StrUtil.isEmpty(point_code1)) { - throw new BadRequestException("起点不能为空!"); - } - //判断起点有没有未完成的指令 - JSONObject beforTaskObj = taskTable. - query("is_delete='0' and point_code1='" + point_code1 + "' and task_status <>'" + TaskStatusEnum.FINISHED.getCode() + "'") - .uniqueResult(0); - if (ObjectUtil.isNotEmpty(beforTaskObj)) { - throw new BadRequestException("存在指令号为'" + beforTaskObj.getString("task_code") + "' 未完成!"); - } + SchTaskDto dto = SchTaskDto.builder() + .task_id(IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("task_type") + .task_status(TaskStatusEnum.SURE_START.getCode()) + .point_code1(point_code1) + .vehicle_code(vehicle_code) + .material_info_id(workOrderObj.getLong("workorder_id")) + .material_id(workOrderObj.getLong("material_id")) + .vehicle_type(vehicle_type) + .handle_class(THIS_CLASS) + .material_qty(qty) + .create_time(DateUtil.now()) + .request_param(whereJson.toJSONString()) + .build(); + //任务表【SCH_BASE_Task】 + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); - - if (StrUtil.isEmpty(point_code2)) { - // 终点为空需要找终点 - JSONObject param = new JSONObject(); - param.put("point_code1", point_code1); - JSONObject endPoint = this.findEndPoint(param); - point_code2 = endPoint.getString("point_code2"); - } - - //终点点加锁 - WQLObject pointTable = WQLObject.getWQLObject("sch_base_point"); - JSONObject endPointObj = pointTable.query("point_code='" + point_code2 + "'").uniqueResult(0); - endPointObj.put("lock_type", "2"); - pointTable.update(endPointObj); - - // 创建任务 - PointService pointService = SpringContextHolder.getBean(PointService.class); - - JSONObject taskObj = new JSONObject(); - CodeUtil.getNewCode("TASK_CODE"); - Long task_id = IdUtil.getSnowflake(1, 1).nextId(); - taskObj.put("task_id", task_id); - taskObj.put("task_code", CodeUtil.getNewCode("TASK_CODE")); - taskObj.put("task_type", "01"); - taskObj.put("vehicle_type", vehicle_type); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskObj.put("point_code1", point_code1); - PointDto startPoint = pointService.findByCode(point_code1); - taskObj.put("start_area", startPoint.getRegion_id()); - taskObj.put("request_param", form.toJSONString()); - taskObj.put("point_code2", point_code2); - PointDto nextPoint = pointService.findByCode(point_code2); - taskObj.put("next_area", nextPoint.getRegion_id()); - taskObj.put("vehicle_code", vehicle_code); - taskObj.put("handle_class", THIS_CLASS); - taskObj.put("is_auto_issue", "1"); - taskObj.put("create_name", SecurityUtils.getCurrentUsername()); - taskObj.put("create_id", SecurityUtils.getCurrentUserId()); - taskObj.put("create_time", DateUtil.now()); - taskObj.put("is_delete", "0"); - taskTable.insert(taskObj); - return String.valueOf(task_id); + //创建好立即下发 + this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); } @@ -283,7 +228,28 @@ public class YqxSendMaterialTask extends AbstractAcsTask { @Override public List addTask() { - return null; + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0'").getResultJSONArray(0); + + ArrayList acsTaskArr = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code3")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + acsTaskArr.add(dto); + } + return acsTaskArr; } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hkxSendMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hkxSendMaterial_01.wql new file mode 100644 index 0000000..eb1abda --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hkxSendMaterial_01.wql @@ -0,0 +1,68 @@ +[交易说明] + 交易名: 豪凯线送料请求 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + 输入.region_code TYPEAS s_string + 输入.material_id TYPEAS s_string + 输入.vehicle_type TYPEAS s_string + + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + + IF 输入.flag = "1" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name + FROM + SCH_BASE_Point p + WHERE + lock_type = '1' + AND is_used = '1' + AND is_delete = '0' + OPTION 输入.vehicle_type <> "" + p.can_vehicle_type like 输入.vehicle_type + ENDOPTION + OPTION 输入.region_code <> "" + p.region_code = 输入.region_code + ENDOPTION + ORDER BY row_num,col_num,layer_num + ENDSELECT + ENDQUERY + ENDIF + + + diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yqxSendMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yqxSendMaterial_01.wql new file mode 100644 index 0000000..0e1582e --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yqxSendMaterial_01.wql @@ -0,0 +1,62 @@ +[交易说明] + 交易名: 油漆线送料请求 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + 输入.region_code TYPEAS s_string + 输入.material_id TYPEAS s_string + 输入.vehicle_type TYPEAS s_string + + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + + IF 输入.flag = "1" + QUERY + SELECT + p.point_id, + p.point_code, + p.point_name + FROM + SCH_BASE_Point p + WHERE + lock_type = '1' + AND is_used = '1' + AND is_delete = '0' + and (point_code = 'SSX01A2' or point_code = 'SSX02A1') + ENDSELECT + ENDQUERY + ENDIF + + + diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/wms.xls b/lms/nladmin-system/src/main/java/org/nl/wms/wms.xls index 02b9b58258dfcd14dbff6eb5054e72a66f1af417..b96744a172e772650cb15f24b093e98120ee2092 100644 GIT binary patch delta 14424 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 RFVzYGN_(-Whce3Ye*pZc2wDID From 1cd159b1573086992fdf55f62a2f4daeef739194 Mon Sep 17 00:00:00 2001 From: ldj_willow Date: Tue, 25 Oct 2022 12:53:13 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../acs/service/impl/AcsToWmsServiceImpl.java | 28 +++--- .../main/java/org/nl/wms/sch/SchTaskDto.java | 69 +++++++++----- .../org/nl/wms/sch/service/TaskService.java | 27 +----- .../wms/sch/service/impl/TaskServiceImpl.java | 44 +++------ .../src/main/java/org/nl/wms/wms.xls | Bin 285184 -> 286208 bytes .../src/main/resources/logback-spring.xml | 89 ++++++++++++------ .../src/views/wms/sch/task/index.vue | 3 +- 7 files changed, 135 insertions(+), 125 deletions(-) diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java index 268dbe9..efc82ae 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java @@ -21,7 +21,6 @@ import org.nl.wms.pdm.service.dto.DeviceDto; import org.nl.wms.sch.manage.TaskStatusEnum; import org.nl.wms.sch.service.PointService; import org.nl.wms.sch.service.TaskService; -import org.nl.wms.sch.service.dto.TaskDto; import org.nl.wms.sch.tasks.callEmpty.GjxCallEmpVehicleTask; import org.nl.wms.sch.tasks.callMaterial.CallMaterialTask; import org.nl.wms.sch.tasks.sendEmpty.HtSendEmpVehicleTask; @@ -60,8 +59,9 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { for (int i = 0; i < array.size(); i++) { JSONObject row = array.getJSONObject(i); String task_id = row.getString("task_id"); - TaskDto taskDto = taskService.findById(task_id); - String processing_class = taskDto.getHandle_class(); + JSONObject taskObj = WQLObject.getWQLObject("SCH_BASE_Task").query("task_id = '" + task_id + "'").uniqueResult(0); + // 任务处理类 + String processing_class = taskObj.getString("handle_class"); //1:执行中,2:完成 ,3:acs取消 String acs_task_status = row.getString("task_status"); String message = ""; @@ -106,7 +106,6 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { json.put("task_id", task_id); json.put("message", message); errArr.add(json); - } } @@ -121,20 +120,23 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { @LokiLog(type = LokiLogType.ACS_TO_LMS) @Override public String againApply(String task_id) { - log.info("输入参数:"+task_id); + log.info("输入参数:" + task_id); WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); String point_code = ""; + String message = ""; try { Class clz = Class.forName(jsonTask.getString("handle_class")); Object obj = clz.newInstance(); - Method m = obj.getClass().getDeclaredMethod("againApply",String.class); - point_code = (String) m.invoke(obj,task_id); + Method m = obj.getClass().getDeclaredMethod("againApply", String.class); + point_code = (String) m.invoke(obj, task_id); } catch (Exception e) { - + e.printStackTrace(); + message = e.getMessage(); + log.info("二次申请失败:{}", message); } - log.info("输出参数:"+point_code); + log.info("输出参数:" + point_code); return point_code; } @@ -183,8 +185,6 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { WQLObject taskTab = WQLObject.getWQLObject("sch_base_task");// 任务表 WQLObject regionTab = WQLObject.getWQLObject("ST_IVT_regionIO"); // 区域出入库表 WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); // 点位表 -// WQLObject veQtyTab = WQLObject.getWQLObject("PDM_BI_vehicleQty"); // 托盘对应数量表 - /* * 根据type判断是什么业务类型: @@ -207,7 +207,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { param.put("qty", qty); // 创建任务 GjxCallEmpVehicleTask taskBean = SpringContextHolder.getBean(GjxCallEmpVehicleTask.class); - taskBean.createTask(param); + taskBean.createTask(param); } else if (StrUtil.equals(type, "2")) { // 2.共挤线满托入库: 调用物料入库处理类创建任务 @@ -269,7 +269,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { param.put("vehicle_type", vehicle_type); // 创建任务 YqxSendEmpVehicleTask taskBean = SpringContextHolder.getBean(YqxSendEmpVehicleTask.class); - taskBean.createTask(param); + taskBean.createTask(param); } else if (StrUtil.equals(type, "6")) { @@ -341,7 +341,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { Long end_region_id = SpringContextHolder.getBean(PointService.class).findByCode(point_code2).getRegion_id(); jsonRegion.put("end_region_id", String.valueOf(end_region_id)); - jsonRegion.put("create_mode", "02"); + jsonRegion.put("create_mode", "2"); jsonRegion.put("create_id", SecurityUtils.getCurrentUserId()); jsonRegion.put("create_name", SecurityUtils.getCurrentNickName()); jsonRegion.put("create_time", DateUtil.now()); diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/SchTaskDto.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/SchTaskDto.java index ba4c9a5..313d52d 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/SchTaskDto.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/SchTaskDto.java @@ -27,6 +27,10 @@ public class SchTaskDto implements Serializable { * 任务编码 */ private String task_code; + /** + * 任务名称 + */ + private String task_name; /** * 任务类型 @@ -135,31 +139,6 @@ public class SchTaskDto implements Serializable { */ private String remark; - /** - * 备注1 - */ - private String remark2; - - /** - * 备注2 - */ - private String remark3; - - /** - * 是否删除 - */ - private String is_delete; - - /** - * 创建时间 - */ - private String create_time; - - /** - * 修改时间 - */ - private String update_time; - /** * 车号 */ @@ -179,4 +158,44 @@ public class SchTaskDto implements Serializable { * 下发任务的请求参数 */ private String response_param; + + + /** + * 是否删除 + */ + private String is_delete; + + /** + * 创建人 + */ + private Long create_id; + + /** + * 创建人 + */ + private String create_name; + /** + * 创建方式 + */ + private String create_mode; + + /** + * 创建时间 + */ + private String create_time; + + /** + * 修改人 + */ + private Long update_optid; + + /** + * 修改人 + */ + private String update_optname; + + /** + * 修改时间 + */ + private String update_time; } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/TaskService.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/TaskService.java index e8f4398..222cbc7 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/TaskService.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/TaskService.java @@ -1,10 +1,8 @@ package org.nl.wms.sch.service; -import org.nl.wms.sch.service.dto.TaskDto; import org.springframework.data.domain.Pageable; -import java.util.List; import java.util.Map; /** @@ -23,34 +21,11 @@ public interface TaskService { */ Map queryAll(Map whereJson, Pageable page); - /** - * 查询所有数据不分页 - * - * @param whereJson 条件参数 - * @return List - */ - List queryAll(Map whereJson); - - /** - * 根据ID查询 - * - * @param task_id - * @return Task - */ - TaskDto findById(String task_id); - - /** - * 根据编码查询 - * - * @param code code - * @return Task - */ - TaskDto findByCode(String code); - /** * 任务操作 * * @param param */ void operation(Map param); + } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/impl/TaskServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/impl/TaskServiceImpl.java index 612099e..f429446 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/impl/TaskServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/impl/TaskServiceImpl.java @@ -13,20 +13,26 @@ import lombok.extern.slf4j.Slf4j; import org.nl.modules.common.exception.BadRequestException; import org.nl.modules.wql.WQL; import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.modules.wql.util.SpringContextHolder; import org.nl.modules.wql.util.WqlUtil; import org.nl.wms.basedata.service.ClassstandardService; import org.nl.wms.basedata.service.dto.ClassstandardDto; import org.nl.wms.sch.service.PointService; import org.nl.wms.sch.service.RegionService; import org.nl.wms.sch.service.TaskService; -import org.nl.wms.sch.service.dto.TaskDto; +import org.nl.wms.sch.tasks.callEmpty.GjxCallEmpVehicleTask; +import org.nl.wms.sch.tasks.callMaterial.CallMaterialTask; +import org.nl.wms.sch.tasks.sendEmpty.HtSendEmpVehicleTask; +import org.nl.wms.sch.tasks.sendEmpty.YqxSendEmpVehicleTask; +import org.nl.wms.sch.tasks.sendMaterial.GjxSendMaterialTask; +import org.nl.wms.sch.tasks.sendMaterial.HkxSendMaterialTask; +import org.nl.wms.sch.tasks.sendMaterial.YqxSendMaterialTask; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -92,16 +98,16 @@ public class TaskServiceImpl implements TaskService { //点位基础表【SCH_BASE_Point】 WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - for ( int i = 0; i < content.size(); i++) { + for (int i = 0; i < content.size(); i++) { JSONObject taskObj = content.getJSONObject(i); String point_code1 = taskObj.getString("point_code1"); - if (ObjectUtil.isNotEmpty(point_code1)){ + if (ObjectUtil.isNotEmpty(point_code1)) { JSONObject point1 = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); taskObj.put("point1_region_name", point1.getString("region_name")); } String point_code2 = taskObj.getString("point_code2"); - if (ObjectUtil.isNotEmpty(point_code2)){ + if (ObjectUtil.isNotEmpty(point_code2)) { JSONObject point2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); taskObj.put("point2_region_name", point2.getString("region_name")); } @@ -111,37 +117,13 @@ public class TaskServiceImpl implements TaskService { return json; } - @Override - public List queryAll(Map whereJson) { - WQLObject wo = WQLObject.getWQLObject("sch_base_task"); - JSONArray arr = wo.query().getResultJSONArray(0); - List list = arr.toJavaList(TaskDto.class); - return list; - } - - @Override - public TaskDto findById(String task_id) { - WQLObject wo = WQLObject.getWQLObject("sch_base_task"); - JSONObject json = wo.query("task_id = '" + task_id + "'").uniqueResult(0); - final TaskDto obj = json.toJavaObject(TaskDto.class); - return obj; - } - - @Override - public TaskDto findByCode(String code) { - WQLObject wo = WQLObject.getWQLObject("sch_base_task"); - JSONObject json = wo.query("task_code ='" + code + "'").uniqueResult(0); - final TaskDto obj = json.toJavaObject(TaskDto.class); - return obj; - } - @Override public void operation(Map map) { String task_id = MapUtil.getStr(map, "task_id"); String method_name = MapUtil.getStr(map, "method_name"); - TaskDto dto = this.findById(task_id); + JSONObject taskObj = WQLObject.getWQLObject("SCH_BASE_Task").query("task_id = '" + task_id + "'").uniqueResult(0); // 任务处理类 - String processing_class = dto.getHandle_class(); + String processing_class = taskObj.getString("handle_class"); String message = ""; // 根据任务类型获取对应的任务操作类 try { diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/wms.xls b/lms/nladmin-system/src/main/java/org/nl/wms/wms.xls index b96744a172e772650cb15f24b093e98120ee2092..6db139ee3ed38641e20a70239a634c206cf77447 100644 GIT binary patch delta 44809 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≈2uNm7@4OW2h8tYGbGr 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 delta 44278 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 AH2?qr diff --git a/lms/nladmin-system/src/main/resources/logback-spring.xml b/lms/nladmin-system/src/main/resources/logback-spring.xml index ac1dd00..dbc1ded 100644 --- a/lms/nladmin-system/src/main/resources/logback-spring.xml +++ b/lms/nladmin-system/src/main/resources/logback-spring.xml @@ -81,37 +81,40 @@ https://juejin.cn/post/6844903775631572999 - - - - - - - - - - + + + + + + + - + - + - + - + + + + + + + @@ -119,27 +122,57 @@ https://juejin.cn/post/6844903775631572999 - + - + - - + + + - - + + + - - + + + - - + + + - - + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lms/nladmin-ui/src/views/wms/sch/task/index.vue b/lms/nladmin-ui/src/views/wms/sch/task/index.vue index abfa16d..587ec72 100644 --- a/lms/nladmin-ui/src/views/wms/sch/task/index.vue +++ b/lms/nladmin-ui/src/views/wms/sch/task/index.vue @@ -116,7 +116,8 @@ - + + From 2ebf0f99524bf80ded22bfa2e87fb796b6700f9f Mon Sep 17 00:00:00 2001 From: ldj_willow Date: Tue, 25 Oct 2022 13:02:07 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sendMaterial/GjxSendMaterialTask.java | 1 + .../sendMaterial/HkxSendMaterialTask.java | 31 +------------------ .../sendMaterial/YqxSendMaterialTask.java | 1 + .../src/views/wms/sch/task/index.vue | 5 ++- 4 files changed, 5 insertions(+), 33 deletions(-) diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterialTask.java index 64cac96..2338c0c 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterialTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/GjxSendMaterialTask.java @@ -248,6 +248,7 @@ public class GjxSendMaterialTask extends AbstractAcsTask { .task_id(IdUtil.getLongId()) .task_code(CodeUtil.getNewCode("TASK_CODE")) .task_type("task_type") + .task_name("共挤线满料") .task_status(TaskStatusEnum.SURE_START.getCode()) .point_code1(point_code1) .vehicle_code(vehicle_code) diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HkxSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HkxSendMaterialTask.java index 44b646a..3a85d27 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HkxSendMaterialTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HkxSendMaterialTask.java @@ -213,6 +213,7 @@ public class HkxSendMaterialTask extends AbstractAcsTask { .task_id(IdUtil.getLongId()) .task_code(CodeUtil.getNewCode("TASK_CODE")) .task_type("task_type") + .task_name("豪凯线满料") .task_status(TaskStatusEnum.SURE_START.getCode()) .point_code1(point_code1) .vehicle_code(vehicle_code) @@ -246,34 +247,4 @@ public class HkxSendMaterialTask extends AbstractAcsTask { public void cancel(String task_id) { } - - @Transactional(rollbackFor = Exception.class) - @Override - public String againApply(String task_id) { - /* - * 再次下发任务处理方法 - * 涉及业务:入空载具、出空载具、入物料、出物料 - */ - - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); // 点位表 - - JSONObject taskObj = taskTab.query("task_id ='" + task_id + "'").uniqueResult(0); - JSONObject jsonPoint2 = pointTab.query("point_code = '" + taskObj.getString("point_code2") + "'").uniqueResult(0); - - // 根据 区域、块、列找到第一个有物料的货位 - JSONObject jsonOnePoint = pointTab.query("region_id = '" + jsonPoint2.getString("region_id") + - "' and block_num = '" + jsonPoint2.getString("block_num") + - "' and col_num = '" + jsonPoint2.getString("col_num") + - "' and point_status = '1' order by row_num desc").uniqueResult(0); - - if (ObjectUtil.isEmpty(jsonOnePoint)) throw new BadRequestException("该列库存状态有误,请检查!"); - - taskObj.put("point_code3", jsonOnePoint.getString("point_code")); - taskObj.put("remark", "二次申请货位"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - - return jsonOnePoint.getString("point_code"); - } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java index 4d1c278..9bf6525 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YqxSendMaterialTask.java @@ -153,6 +153,7 @@ public class YqxSendMaterialTask extends AbstractAcsTask { .task_id(IdUtil.getLongId()) .task_code(CodeUtil.getNewCode("TASK_CODE")) .task_type("task_type") + .task_name("油漆线满料") .task_status(TaskStatusEnum.SURE_START.getCode()) .point_code1(point_code1) .vehicle_code(vehicle_code) diff --git a/lms/nladmin-ui/src/views/wms/sch/task/index.vue b/lms/nladmin-ui/src/views/wms/sch/task/index.vue index 587ec72..46edee5 100644 --- a/lms/nladmin-ui/src/views/wms/sch/task/index.vue +++ b/lms/nladmin-ui/src/views/wms/sch/task/index.vue @@ -116,7 +116,7 @@ - + @@ -124,12 +124,11 @@ - + - Date: Tue, 25 Oct 2022 13:59:31 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../acs/service/impl/AcsToWmsServiceImpl.java | 3 +- .../callEmpty/GjxCallEmpVehicleTask.java | 79 ++- .../callEmpty/YqxCallEmpVehicleTask.java | 499 +++++++++++------- .../wql/QSCH_YqxCallEmpVehicleTask.wql | 60 +++ 4 files changed, 436 insertions(+), 205 deletions(-) create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_YqxCallEmpVehicleTask.wql diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java index 268dbe9..8be944a 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/impl/AcsToWmsServiceImpl.java @@ -23,6 +23,7 @@ import org.nl.wms.sch.service.PointService; import org.nl.wms.sch.service.TaskService; import org.nl.wms.sch.service.dto.TaskDto; import org.nl.wms.sch.tasks.callEmpty.GjxCallEmpVehicleTask; +import org.nl.wms.sch.tasks.callEmpty.YqxCallEmpVehicleTask; import org.nl.wms.sch.tasks.callMaterial.CallMaterialTask; import org.nl.wms.sch.tasks.sendEmpty.HtSendEmpVehicleTask; import org.nl.wms.sch.tasks.sendEmpty.YqxSendEmpVehicleTask; @@ -230,7 +231,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { param.put("point_code2", point_code); param.put("qty", qty); // 创建任务 - GjxCallEmpVehicleTask taskBean = SpringContextHolder.getBean(GjxCallEmpVehicleTask.class); + YqxCallEmpVehicleTask taskBean = SpringContextHolder.getBean(YqxCallEmpVehicleTask.class); String task_id = taskBean.createTask(param); } else if (StrUtil.equals(type, "4")) { // 4.油漆线申请物料: 调用物料出库库处理类创建任务 diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java index 0ba30cc..95ae0cf 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/GjxCallEmpVehicleTask.java @@ -23,6 +23,7 @@ import org.nl.wms.sch.tasks.RegionTypeEnum; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.List; @Service @@ -45,10 +46,47 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); if (StrUtil.equals(status, "0")) { - // 取消删除任务 + /* + * 取消删除 + * 1.终点为叠盘架更新起点点位、等待点点位、叠盘架点位 + * 2.终点为供给线更新叠盘架点位 + */ if (StrUtil.equals(jsonTask.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { throw new BadRequestException("已完成不能取消!"); } + + String point_code1 = jsonTask.getString("point_code1"); + String point_code2 = jsonTask.getString("point_code2"); + + JSONObject jsonEnd = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + // 终点在叠盘架 + if (StrUtil.equals(jsonEnd.getString("region_id"), RegionTypeEnum.DPJQB.getId())) { + JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + // 判断此起点是否是等待点 + if (!StrUtil.equals(jsonStart.getString("row_num"), "9")) { + // 如果不是等待点更新等待点状态 + JSONObject jsonEmpWait = pointTab.query("region_id = '" + jsonStart.getString("region_id") + + "' and block_num = '" + jsonStart.getString("block_num") + + "' and col_num = '" + jsonStart.getString("col_num") + + "' and row_num = '9'").uniqueResult(0); + + jsonEmpWait.put("lock_type", "1"); + pointTab.update(jsonEmpWait); + } + jsonStart.put("lock_type", "1"); + pointTab.update(jsonStart); + + // 更新终点(叠盘架状态) + jsonEnd.put("lock_type", "1"); + pointTab.update(jsonEnd); + + } else { + // 终点在供给线 + JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + jsonStart.put("lock_type", "1"); + pointTab.update(jsonStart); + } + taskTab.delete("task_id = '" + task_id + "'"); } @@ -111,7 +149,7 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { jsonTask2.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); taskTab.update(jsonTask2); } else { - // 终点在油漆线: 更新起点(叠盘架)数量 + // 终点在供给线线: 更新起点(叠盘架)数量 JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); jsonStart.put("vehicle_qty",NumberUtil.sub(jsonStart.getString("vehicle_qty"),"1")); jsonStart.put("lock_type", "1"); @@ -121,11 +159,7 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { } @Override - public List addTask() { - return null; - } - - @Override + @Transactional(rollbackFor = Exception.class) public void findStartPoint() { WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 @@ -222,7 +256,7 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { pointTab.update(jsonStartPoint); } else { // 判断等待点是否是 未锁定、为空载具 - if (StrUtil.equals(jsonEmpWait.getString("lock_type"), "1") && StrUtil.equals(jsonEmpWait.getString("point_status"), "2")) { + if (StrUtil.equals(jsonEmpWait.getString("lock_type"), "1")) { // 创建 养生A区空载具 --> 叠盘架 SchTaskDto dto = SchTaskDto.builder() .task_id(org.nl.wms.util.IdUtil.getLongId()) @@ -243,6 +277,9 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { // 锁起点 jsonStartPoint.put("lock_type", "2"); pointTab.update(jsonStartPoint); + // 锁等待点 + jsonEmpWait.put("lock_type","2"); + pointTab.update(jsonEmpWait); } else { continue; } @@ -305,6 +342,32 @@ public class GjxCallEmpVehicleTask extends AbstractAcsTask { } + @Override + public List addTask() { + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '"+THIS_CLASS+"' and task_status = '"+TaskStatusEnum.START_AND_POINT.getCode()+"' and is_delete ='0'").getResultJSONArray(0); + + ArrayList resultList = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code3")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + resultList.add(dto); + } + return resultList; + } + @Transactional(rollbackFor = Exception.class) public boolean isTask(String point_code) { /* diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java index 98c5697..082a161 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java @@ -6,6 +6,7 @@ import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -17,6 +18,7 @@ import org.nl.modules.wql.core.bean.WQLObject; import org.nl.modules.wql.util.SpringContextHolder; import org.nl.wms.pdm.service.DeviceService; import org.nl.wms.pdm.service.dto.DeviceDto; +import org.nl.wms.sch.SchTaskDto; import org.nl.wms.sch.manage.AbstractAcsTask; import org.nl.wms.sch.manage.TaskStatusEnum; import org.nl.wms.sch.service.PointService; @@ -27,6 +29,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.List; @Service @@ -36,7 +39,6 @@ public class YqxCallEmpVehicleTask extends AbstractAcsTask { private final String THIS_CLASS = YqxCallEmpVehicleTask.class.getName(); - @Override @Transactional(rollbackFor = Exception.class) public void updateTaskStatus(JSONObject taskObj, String status) { @@ -47,7 +49,47 @@ public class YqxCallEmpVehicleTask extends AbstractAcsTask { JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); if (StrUtil.equals(status, "0")) { - // 取消删除任务 + /* + * 取消删除 + * 1.终点为叠盘架更新起点点位、等待点点位、叠盘架点位 + * 2.终点为油漆线更新叠盘架点位 + */ + if (StrUtil.equals(jsonTask.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { + throw new BadRequestException("已完成不能取消!"); + } + + String point_code1 = jsonTask.getString("point_code1"); + String point_code2 = jsonTask.getString("point_code2"); + + JSONObject jsonEnd = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + // 终点在叠盘架 + if (StrUtil.equals(jsonEnd.getString("region_id"), RegionTypeEnum.DPJQA.getId())) { + JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + // 判断此起点是否是等待点 + if (!StrUtil.equals(jsonStart.getString("row_num"), "9")) { + // 如果不是等待点更新等待点状态 + JSONObject jsonEmpWait = pointTab.query("region_id = '" + jsonStart.getString("region_id") + + "' and block_num = '" + jsonStart.getString("block_num") + + "' and col_num = '" + jsonStart.getString("col_num") + + "' and row_num = '9'").uniqueResult(0); + + jsonEmpWait.put("lock_type", "1"); + pointTab.update(jsonEmpWait); + } + jsonStart.put("lock_type", "1"); + pointTab.update(jsonStart); + + // 更新终点(叠盘架状态) + jsonEnd.put("lock_type", "1"); + pointTab.update(jsonEnd); + + } else { + // 终点在油漆线 + JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + jsonStart.put("lock_type", "1"); + pointTab.update(jsonStart); + } + taskTab.delete("task_id = '" + task_id + "'"); } @@ -60,107 +102,243 @@ public class YqxCallEmpVehicleTask extends AbstractAcsTask { } if (StrUtil.equals(status, TaskStatusEnum.FINISHED.getCode())) { - // 更改任务状态为完成 + /* + * 更改任务状态为完成 + * 1.终点为叠盘架更新叠盘架数量、起点点位状态、等待位状态,更新任务组状态 + * 2.终点为油漆线,更新起点载具数量 + */ jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); jsonTask.put("update_optid", SecurityUtils.getCurrentUserId()); jsonTask.put("update_optname", SecurityUtils.getCurrentUsername()); jsonTask.put("update_time", DateUtil.now()); taskTab.update(jsonTask); - PointService point = SpringContextHolder.getBean(PointService.class); - // 校验起点是否存在 - PointDto point_code1 = point.findByCode(jsonTask.getString("point_code1")); - if (ObjectUtil.isEmpty(point_code1)) throw new BadRequestException("未找到可用点位:" + point_code1); - // 校验终点是否存在 - PointDto point_code2 = point.findByCode(jsonTask.getString("point_code2")); - if (ObjectUtil.isEmpty(point_code1)) throw new BadRequestException("未找到可用点位:" + point_code2); + // 判断终点在哪里 + String point_code1 = jsonTask.getString("point_code1"); + String point_code2 = jsonTask.getString("point_code2"); - // 1.更新点位数量 2.解锁点位 - int vehicle_qty = JSONObject.parseObject(JSON.toJSONString(point_code1)).getIntValue("vehicle_qty"); - BigDecimal vehicle_qty_point = NumberUtil.sub(String.valueOf(vehicle_qty), String.valueOf(1)); + JSONObject jsonEnd = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); + // 终点在叠盘架 + if (StrUtil.equals(jsonEnd.getString("region_id"), RegionTypeEnum.DPJQA.getId())) { + // 更新起点点位状态 + JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + // 判断此起点是否是等待点 + if (!StrUtil.equals(jsonStart.getString("row_num"), "9")) { + // 如果不是等待点更新等待点状态 + JSONObject jsonEmpWait = pointTab.query("region_id = '" + jsonStart.getString("region_id") + + "' and block_num = '" + jsonStart.getString("block_num") + + "' and col_num = '" + jsonStart.getString("col_num") + + "' and row_num = '9'").uniqueResult(0); - point_code1.setVehicle_qty(vehicle_qty_point); - if (StrUtil.equals(vehicle_qty_point.toString(), "0")) { - point_code1.setPoint_status("00"); - point_code1.setVehicle_type(""); + jsonEmpWait.put("lock_type", "1"); + pointTab.update(jsonEmpWait); + } + + jsonStart.put("point_status", "1"); + jsonStart.put("lock_type", "1"); + jsonStart.put("vehicle_type", ""); + jsonStart.put("vehicle_code", ""); + jsonStart.put("vehicle_qty", 0); + pointTab.update(jsonStart); + + // 更新终点(叠盘架状态) + jsonEnd.put("vehicle_qty", NumberUtil.add(jsonEnd.getString("vehicle_qty"),jsonTask.getString("vehicle_qty"))); + jsonEnd.put("lock_type", "1"); + pointTab.update(jsonEnd); + + // 更新任务组状态 + JSONObject jsonTask2 = taskTab.query("task_group_id = '" + jsonTask.getString("task_group_id") + "' and task_id <> '" + jsonTask.getString("task_id") + "'").uniqueResult(0); + // 判断叠盘架数量是否 < 需求数量 (暂时只能<需求数量) + if (jsonEnd.getIntValue("vehicle_qty") < jsonTask2.getIntValue("vehicle_qty")) { + jsonTask2.put("vehicle_qty", jsonEnd.getIntValue("vehicle_qty")); + } + jsonTask2.put("point_code1", jsonEnd.getString("point_code")); + jsonTask2.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); + taskTab.update(jsonTask2); + } else { + // 终点在油漆线: 更新起点(叠盘架)数量 + JSONObject jsonStart = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); + jsonStart.put("vehicle_qty",NumberUtil.sub(jsonStart.getString("vehicle_qty"),jsonTask.getString("vehicle_qty"))); + jsonStart.put("lock_type", "1"); + pointTab.update(jsonStart); } - point_code1.setLock_type("00"); - pointTab.update(JSONObject.parseObject(JSON.toJSONString(point_code1))); } } + @Override + @Transactional(rollbackFor = Exception.class) + public void findStartPoint() { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 + + JSONArray taskArr = taskTab.query("is_delete = '0' and handle_class = '" + this.THIS_CLASS + "' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); + for (int i = 0; i < taskArr.size(); i++) { + // 创建任务 + JSONObject jsonTask = taskArr.getJSONObject(i); + String vehicle_type = jsonTask.getString("vehicle_type"); + + // 找叠盘架是否与对应的载具类型 + JSONObject jsonDpjStart = pointTab.query("region_id = '" + RegionTypeEnum.DPJQA.getId() + "' and can_vehicle_type = '" + vehicle_type + "' and lock_type = '1' and is_used = '1' and is_delete = '0' and vehicle_qty <> '0'").uniqueResult(0); + + if (ObjectUtil.isNotEmpty(jsonDpjStart)) { + // 判断叠盘架是否有任务 有就下一个任务 + boolean is_point = this.isTask(jsonDpjStart.getString("point_code")); + if (!is_point) continue; + + // 判断叠盘架数量是否 < 需求数量 (暂时只能<需求数量) + if (jsonDpjStart.getIntValue("vehicle_qty") < jsonTask.getIntValue("vehicle_qty")) { + jsonTask.put("vehicle_qty", jsonDpjStart.getIntValue("vehicle_qty")); + } + + // 更新任务起点 + jsonTask.put("point_code1", jsonDpjStart.getString("point_code")); + jsonTask.put("task_status", TaskStatusEnum.START_AND_POINT); + taskTab.update(jsonTask); + + } else { + // 判断叠盘架载具数量是否是0 + JSONObject jsonDpjStart2 = pointTab.query("region_id = '" + RegionTypeEnum.DPJQA.getId() + "' and can_vehicle_type = '" + vehicle_type + "' and lock_type = '1' and is_used = '1' and is_delete = '0' and vehicle_qty = '0'").uniqueResult(0); + if (ObjectUtil.isEmpty(jsonDpjStart2)) continue; + + // 判断叠盘架是否有任务 + boolean is_point = this.isTask(jsonDpjStart2.getString("point_code")); + if (!is_point) continue; + + // 找叠盘架暂存位是否有空托盘 + JSONObject map = new JSONObject(); + map.put("flag", "1"); + map.put("vehicle_type", vehicle_type); + + JSONObject jsonZcKtp = WQL.getWO("QSCH_YqxCallEmpVehicleTask").addParamMap(map).process().uniqueResult(0); + if (ObjectUtil.isNotEmpty(jsonZcKtp)) { + // 创建任务:空载具暂存位 --> 叠盘架 + SchTaskDto dto = SchTaskDto.builder() + .task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_status(TaskStatusEnum.START_AND_POINT.getCode()) + .point_code1(jsonZcKtp.getString("point_code")) + .point_code2(jsonDpjStart2.getString("point_code")) + .vehicle_code(jsonZcKtp.getString("vehicle_code")) + .vehicle_type(jsonZcKtp.getString("vehicle_type")) + .vehicle_qty(jsonZcKtp.getIntValue("vehicle_qty")) + .task_group_id(jsonTask.getLong("task_group_id")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + // 锁定起点 + jsonZcKtp.put("lock_type", "2"); + pointTab.update(jsonZcKtp); + } else { + // 空托盘暂存区没有就到养生A区找: 先找到出库等待点 + JSONObject jsonEmpWait = pointTab.query("region_id = '" + RegionTypeEnum.YSAQKTPQ01.getId() + + "' and row_num = '9' and can_vehicle_type = '" + vehicle_type + + "' and is_used = '1' and is_delete = '0'").uniqueResult(0); + if (ObjectUtil.isEmpty(jsonEmpWait)) continue; + + JSONObject jsonStartPoint = pointTab.query("region_id = '" + jsonEmpWait.getString("region_id") + + "' and block_num = '" + jsonEmpWait.getString("block_num") + + "' and col_num = '" + jsonEmpWait.getString("col_num") + + "' and point_status = '2' and lock_type = '1' order by out_empty_seq DESC").uniqueResult(0); + if (ObjectUtil.isEmpty(jsonStartPoint)) continue; + + // 判断找到的空载具点位是否是等待点 + if (StrUtil.equals(jsonEmpWait.getString("point_code"), jsonStartPoint.getString("point_code"))) { + // 创建 养生A区空载具等待点 --> 叠盘架 + SchTaskDto dto = SchTaskDto.builder() + .task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_status(TaskStatusEnum.START_AND_POINT.getCode()) + .point_code1(jsonStartPoint.getString("point_code")) + .point_code2(jsonDpjStart2.getString("point_code")) + .vehicle_code(jsonStartPoint.getString("vehicle_code")) + .vehicle_type(jsonStartPoint.getString("vehicle_type")) + .vehicle_qty(jsonStartPoint.getIntValue("vehicle_qty")) + .task_group_id(jsonTask.getLong("task_group_id")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + // 锁起点 + jsonStartPoint.put("lock_type", "2"); + pointTab.update(jsonStartPoint); + } else { + // 判断等待点是否是 未锁定 + if (StrUtil.equals(jsonEmpWait.getString("lock_type"), "1")) { + // 创建 养生A区空载具 --> 叠盘架 + SchTaskDto dto = SchTaskDto.builder() + .task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_status(TaskStatusEnum.START_AND_POINT.getCode()) + .point_code1(jsonStartPoint.getString("point_code")) + .point_code2(jsonDpjStart2.getString("point_code")) + .vehicle_code(jsonStartPoint.getString("vehicle_code")) + .vehicle_type(jsonStartPoint.getString("vehicle_type")) + .vehicle_qty(jsonStartPoint.getIntValue("vehicle_qty")) + .task_group_id(jsonTask.getLong("task_group_id")) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); + // 锁起点 + jsonStartPoint.put("lock_type", "2"); + pointTab.update(jsonStartPoint); + // 锁等待点 + jsonEmpWait.put("lock_type", "2"); + pointTab.update(jsonEmpWait); + } else { + continue; + } + } + } + } + } + + } @Override @Transactional(rollbackFor = Exception.class) public String createTask(JSONObject form) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); - - String point_code1 = form.getString("point_code1"); - String point_code2 = form.getString("point_code2"); - String qty = form.getString("qty"); - String vehicle_type = form.getString("vehicle_type"); - - // 出库终点不能为空 - if (ObjectUtil.isEmpty(point_code2)) { - throw new BadRequestException("终点不能为空"); - } else { - // 判断终点是否有正在执行的任务 - JSONObject beforTaskObj = taskTab.query("is_delete='0' and point_code2='" + point_code2 + "' and task_status <>'" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(beforTaskObj)) - throw new BadRequestException("存在任务号为'" + beforTaskObj.getString("task_code") + "' 未完成!"); - } - // 载具数量不能为空 - if (ObjectUtil.isEmpty(qty)) throw new BadRequestException("载具数量不能为空"); - /* - * 1. 点对点: 起点和终点都确定,直接创建任务 - * 2. 终点确定: 需要找到对应起点,在创建任务 具体找起点货位的规则在findBeginPoint()中 + * 1.先生成确定终点的任务 + * 2.通过findStartPoint()找起点 + * 3.下发给ACS */ - //起点不确定 - if (ObjectUtil.isEmpty(point_code1)) { + WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 + WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); // 生产工单表 + WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); //点位基础表 - JSONObject param = new JSONObject(); - param.put("point_code2",point_code2); - param.put("vehicle_qty",qty); + String point_code2 = form.getString("point_code1"); + String device_code = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0).getString("device_code"); - JSONObject json = this.findBeginPoint(param); - point_code1 = json.getString("start_point_code"); - vehicle_type = json.getString("vehicle_type"); - } else { - // 判断终点是否是空位 - JSONObject jsonPoint = pointTab.query("point_code = '" + point_code1 + "' and lock_type = '00' and point_status <> '02' and is_delete = '0' and is_used = '1'").uniqueResult(0); - if (ObjectUtil.isEmpty(jsonPoint)) throw new BadRequestException("起点点位不可用或不存在"); - } + JSONObject workOrderObj = workOrderTab.query("device_code = '" + device_code + "' and order_status = '3' and is_delete ='0'").uniqueResult(0); + if (ObjectUtil.isEmpty(workOrderObj)) throw new BadRequestException("该设备当前未生产或者已删除"); + SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) + .task_code(CodeUtil.getNewCode("TASK_CODE")) + .task_type("") + .task_status(TaskStatusEnum.SURE_END.getCode()) + .point_code2(point_code2) + .vehicle_code(form.getString("vehicle_code")) + .vehicle_type(workOrderObj.getString("vehicle_type")) + .vehicle_qty(form.getIntValue("qty")) + .task_group_id(org.nl.wms.util.IdUtil.getLongId()) + .handle_class(THIS_CLASS) + .create_time(DateUtil.now()) + .build(); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + taskTab.insert(json); - - // 创建任务 - JSONObject jsonTask = new JSONObject(); - String task_id = IdUtil.getSnowflake(1, 1).nextId() + ""; - - jsonTask.put("task_id", task_id); - - jsonTask.put("task_code", CodeUtil.getNewCode("TASK_CODE")); - jsonTask.put("task_type", "04"); - jsonTask.put("task_status", "01"); - jsonTask.put("point_code1", point_code1); - jsonTask.put("point_code2", point_code2); - jsonTask.put("handle_class", THIS_CLASS); - jsonTask.put("vehicle_type", vehicle_type); - jsonTask.put("create_name", SecurityUtils.getCurrentUsername()); - jsonTask.put("create_id", SecurityUtils.getCurrentUserId()); - jsonTask.put("create_time", DateUtil.now()); - jsonTask.put("acs_task_type", "1"); - taskTab.insert(jsonTask); - - // 锁定起点点位 - JSONObject jsonPoint = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - jsonPoint.put("lock_type", "02"); - pointTab.update(jsonPoint); - - return task_id; + this.findStartPoint(); +// this.immediateNotifyAcs(); + return String.valueOf(dto.getTask_id()); } @Override @@ -171,128 +349,57 @@ public class YqxCallEmpVehicleTask extends AbstractAcsTask { } - @Override public void cancel(String task_id) { } - @Transactional(rollbackFor = Exception.class) - public JSONObject findBeginPoint(JSONObject json) { - String point_code2 = json.getString("point_code2"); - String vehicle_qty = json.getString("vehicle_qty"); - if (ObjectUtil.isEmpty(point_code2)) throw new BadRequestException("终点不能为空"); - if (ObjectUtil.isEmpty(vehicle_qty)) throw new BadRequestException("载具数量不能为空"); - - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); - WQLObject regionTab = WQLObject.getWQLObject("SCH_BASE_Region"); - WQLObject orderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - // 根据终点区域判断优先的起点区域 - JSONObject jsonPointEnd = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(jsonPointEnd)) throw new BadRequestException("终点点位不存在"); - JSONObject jsonRegionEnd = regionTab.query("region_id ='" + jsonPointEnd.getString("region_id") + "'").uniqueResult(0); - - // 根据起点找到对应设备,根据设备查询工单表中 - 正在运行的工单中的载具类型 - String device_code = point_code2.substring(0, point_code2.indexOf("_")); - - DeviceService deviceBean = SpringContextHolder.getBean(DeviceService.class); - DeviceDto deviceDto = deviceBean.findByCode(device_code); - if (ObjectUtil.isEmpty(deviceDto)) throw new BadRequestException("此设备不存在"); - JSONObject jsonOrder = orderTab.query("device_id = '" + deviceDto.getDevice_id() + "' and order_status = '02' and is_delete = '0'").uniqueResult(0); - if (ObjectUtil.isEmpty(jsonOrder)) throw new BadRequestException("此设备未在生产中或不存在"); - - //当前设备所需要的载具类型 - String vehicle_type = jsonOrder.getString("vehicle_type"); - /* - * 空托盘出库任务: - * 1.叠盘架B区、养生A区 --> 共挤线 (优先级:1叠盘架B区 2养生A区) - * 2.叠盘架A区、养生A区 --> 油漆线 (优先级:1叠盘架A区 2养生A区) - */ - String point_code1 = ""; - JSONObject map = new JSONObject(); - if (StrUtil.equals(jsonRegionEnd.getString("region_code"), RegionTypeEnum.GJQY.getCode())) { - //1、判断是否有拆托盘任务。 - taskTab.query("task_type= 'gjxsqkp' "); - - //2、判断是否有到该叠盘位的堆叠任务。 - - - - //1、判断叠盘架B是否有对应类型的空载具 - JSONObject jsonDpjB = pointTab.query("point_status ='2' and lock_type='00' and can_vehicle_type = '" + vehicle_type + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(jsonDpjB)) {//没有则去空托盘缓存区B和养生A区找 - - } - - - // 共挤线呼叫空托盘业务:查找叠盘架B区是否有满足条件的点位 - map.put("flag", "1"); - map.put("vehicle_qty", vehicle_qty); - map.put("vehicle_type", jsonOrder.getString("vehicle_type")); - map.put("region_code", RegionTypeEnum.DPJQB.getCode()); - JSONObject jsonStartPointDPB = WQL.getWO("ST_VEHICLE_OUT_02").addParamMap(map).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(jsonStartPointDPB)) { - point_code1 = jsonStartPointDPB.getString("point_code"); - } else { - // 为空说明叠盘架B区没有,则去养生A区找 : 只能找数量为1的空托盘 - map.put("flag", "3"); - map.put("region_code", RegionTypeEnum.YSQA.getCode()); - JSONObject jsonStartPointYSA = WQL.getWO("ST_VEHICLE_OUT_02").addParamMap(map).process().uniqueResult(0); - - if (ObjectUtil.isNotEmpty(jsonStartPointYSA)) { - point_code1 = jsonStartPointYSA.getString("point_code"); - } else { - throw new BadRequestException("没有满足需求数量的点位"); - /* // 如果没有则需要从养生区A区里找到 > 1的货位 出库到叠盘架B中 - map.put("flag", "1"); - map.put("region_code", RegionTypeEnum.YSQA.getCode()); - // 起点 - JSONObject jsonStart = WQL.getWO("ST_VEHICLE_OUT_02").addParamMap(map).process().uniqueResult(0); - if (ObjectUtil.isEmpty(jsonStart)) throw new BadRequestException("没有满足需求数量的点位"); - // 终点 - JSONObject jsonEnd = pointTab.query("region_id = '" + RegionTypeEnum.DPJQB.getId() + "' and point_status = '00' and lock_type = '00' and is_used = '1' and is_delete = '0'").uniqueResult(0); - if (ObjectUtil.isEmpty(jsonEnd)) throw new BadRequestException("叠盘架B货位不足"); - - JSONObject parem = new JSONObject(); - parem.put("point_code1",jsonStart.getString("point_code")); - parem.put("point_code2",jsonEnd.getString("point_code")); - parem.put("qty",jsonStart.getString("vehicle_qty")); - parem.put("vehicle_type",jsonStart.getString("vehicle_qty")); - String task_id = this.createTask(parem); - - // 生成 叠盘架 -> 共挤线的任务 返回叠盘架B的点位code - point_code1 = jsonEnd.getString("point_code");*/ - } - - } - - } else if (StrUtil.equals(jsonRegionEnd.getString("region_code"), RegionTypeEnum.YQQY.getCode())) { - // 油漆线呼叫空托盘业务:查找叠盘架A区是否有满足条件的点位 - map.put("flag", "1"); - map.put("vehicle_qty", vehicle_qty); - map.put("vehicle_type", jsonOrder.getString("vehicle_type")); - map.put("region_code", RegionTypeEnum.DPJQA.getCode()); - JSONObject jsonStartPointDPA = WQL.getWO("ST_VEHICLE_OUT_02").addParamMap(map).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(jsonStartPointDPA)) { - point_code1 = jsonStartPointDPA.getString("point_code"); - } else { - // 为空说明叠盘架A区没有,则去养生A区找 - map.put("flag", "3"); - map.put("region_code", RegionTypeEnum.YSQA.getCode()); - JSONObject jsonStartPointYSA = WQL.getWO("ST_VEHICLE_OUT_02").addParamMap(map).process().uniqueResult(0); - if (ObjectUtil.isEmpty(jsonStartPointYSA)) throw new BadRequestException("没有满足需求数量的点位"); - point_code1 = jsonStartPointYSA.getString("point_code"); - } - } - JSONObject resuft = new JSONObject(); - resuft.put("point_code1", point_code1); - resuft.put("vehicle_type", jsonOrder.getString("vehicle_type")); - return resuft; - } - @Override public List addTask() { - return null; + /* + * 下发给ACS时需要特殊处理 + */ + JSONArray arr = WQLObject.getWQLObject("SCH_BASE_Task").query("handle_class = '"+THIS_CLASS+"' and task_status = '"+TaskStatusEnum.START_AND_POINT.getCode()+"' and is_delete ='0'").getResultJSONArray(0); + + ArrayList resultList = new ArrayList<>(); + for (int i = 0; i < arr.size(); i++) { + JSONObject json = arr.getJSONObject(i); + AcsTaskDto dto = AcsTaskDto.builder() + .task_id(json.getString("task_id")) + .task_code(json.getString("task_code")) + .task_type(json.getString("acs_task_type")) + .start_device_code(json.getString("point_code1")) + .next_device_code(json.getString("point_code3")) + .vehicle_code(json.getString("vehicle_code")) + .vehicle_type(json.getString("vehicle_type")) + .priority(json.getString("priority")) + .remark(json.getString("remark")) + .build(); + resultList.add(dto); + } + return resultList; + } + + @Transactional(rollbackFor = Exception.class) + public boolean isTask(String point_code) { + /* + * 判断点位是否有任务存在 + */ + WQLObject tab = WQLObject.getWQLObject("SCH_BASE_Task"); + + boolean result; + + JSONObject jsonPointCode1 = tab.query("point_code1 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); + JSONObject jsonPointCode2 = tab.query("point_code2 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); + JSONObject jsonPointCode3 = tab.query("point_code3 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); + JSONObject jsonPointCode4 = tab.query("point_code4 = '" + point_code + "' and task_status <> '7' and is_delete = '0'").uniqueResult(0); + + if (ObjectUtil.isEmpty(jsonPointCode1) && ObjectUtil.isEmpty(jsonPointCode2) && ObjectUtil.isEmpty(jsonPointCode3) && ObjectUtil.isEmpty(jsonPointCode4)) { + result = true; + } else { + result = false; + } + + return result; } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_YqxCallEmpVehicleTask.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_YqxCallEmpVehicleTask.wql new file mode 100644 index 0000000..8163667 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_YqxCallEmpVehicleTask.wql @@ -0,0 +1,60 @@ +[交易说明] + 交易名: 油漆线申请空盘 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + 输入.vehicle_type TYPEAS s_string + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + + IF 输入.flag = "1" + QUERY + SELECT + * + FROM + SCH_BASE_Point + WHERE + is_used = '1' + AND is_delete = '0' + AND lock_type = '1' + AND point_status = '2' + AND region_code = 'KTPHCQA01' + + OPTION 输入.vehicle_type <> "" + can_vehicle_type = 输入.vehicle_type + ENDOPTION + + ENDSELECT + ENDQUERY + ENDIF \ No newline at end of file From 2f99d5ffef85a85091f9e9c16ab63600958a85cb Mon Sep 17 00:00:00 2001 From: liuxy Date: Tue, 25 Oct 2022 14:00:06 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java | 1 + 1 file changed, 1 insertion(+) diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java index 082a161..db94cc2 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YqxCallEmpVehicleTask.java @@ -294,6 +294,7 @@ public class YqxCallEmpVehicleTask extends AbstractAcsTask { pointTab.update(jsonEmpWait); } else { continue; + } } }