From 18b3f9b31fb9d28fc0d0039ac0a160a8c16843aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=B1=9F=E7=8E=AE?= Date: Fri, 14 Apr 2023 10:18:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lnsh/lnsh_rgv/LnshRGVDeviceDriver.java | 13 + .../main/resources/config/application-dev.yml | 4 +- .../src/main/resources/config/application.yml | 2 +- ...裕家居LMS系统.postman_collection.json | 489 ------------ .../src/main/java/org/nl/AppRun.java | 2 + .../main/java/org/nl/config/PdaAspect.java | 22 + .../nl/modules/common/api/CommonResult.java | 218 +++--- .../common/api/RestBusinessTemplate.java | 130 ++-- .../nl/modules/common/utils/CommonUtils.java | 24 + .../common/utils/enums/PointStatusEnum.java | 92 +-- .../utils/enums/ProductionStatisticsEnum.java | 84 +-- .../org/nl/modules/security/rest/DesUtil.java | 129 ---- .../service/impl/GenCodeServiceImpl.java | 5 +- .../org/nl/modules/system/util/CodeUtil.java | 14 +- .../src/main/java/org/nl/start/Init.java | 8 +- .../nl/wms/basedata/eum/LNSHMaterialUnit.java | 26 + .../org/nl/wms/basedata/eum/TrueOrFalse.java | 31 + .../nl/wms/basedata/eum/VehicleStatus.java | 26 + .../org/nl/wms/basedata/eum/VehicleType.java | 32 + .../wms/basedata/rest/VehicleController.java | 42 +- .../wms/basedata/service/VehicleService.java | 13 +- .../basedata/service/dto/MaterialbaseDto.java | 67 +- .../wms/basedata/service/dto/VehicleDto.java | 87 +-- .../service/impl/MaterialbaseServiceImpl.java | 123 ++- .../service/impl/VehicleServiceImpl.java | 112 +-- .../nl/wms/basedata/wql/QMD_ME_MATERIAL.wql | 32 +- .../nl/wms/basedata/wql/QMD_PB_VEHICLE.wql | 24 +- .../cockpit/service/dto/DeviceDetailDto.java | 196 ++--- .../cockpit/service/dto/DeviceStatusDto.java | 106 +-- .../wms/ext/acs/rest/AcsToWmsController.java | 17 +- .../wms/ext/acs/service/AcsToWmsService.java | 8 +- .../wms/ext/acs/service/WmsToAcsService.java | 4 + .../acs/service/impl/AcsToWmsServiceImpl.java | 714 ++++++++++-------- .../org/nl/wms/ext/auto/AutoQueryTask.java | 141 ---- .../org/nl/wms/ext/wql/AUTO_QUERYTASK.wql | 92 --- .../org/nl/wms/pda/anno/PdaAnnotation.java | 8 + .../org/nl/wms/pda/rest/PdaController.java | 213 +----- .../org/nl/wms/pda/service/PdaService.java | 79 +- .../wms/pda/service/impl/PdaServiceImpl.java | 187 +---- .../java/org/nl/wms/pda/util/PdaUtils.java | 28 +- .../main/java/org/nl/wms/pda/wql/LNSH_PDA.wql | 141 ---- .../wql/PDA.wql} | 43 +- .../org/nl/wms/pdm/rest/DeviceController.java | 77 ++ .../org/nl/wms/pdm/service/DeviceService.java | 68 ++ .../nl/wms/pdm/service/dto/WorkorderDto.java | 8 + .../pdm/service/impl/DeviceServiceImpl.java | 138 ++++ .../service/impl/WorkorderServiceImpl.java | 115 +-- .../org/nl/wms/pdm/wql/MPS_PRODUCEDURE001.wql | 46 +- .../src/main/java/org/nl/wms/sch/AcsUtil.java | 3 +- .../java/org/nl/wms/sch/manage/ACSSystem.java | 14 + .../nl/wms/sch/manage/AbstractAcsTask.java | 115 ++- .../org/nl/wms/sch/manage/AutoCreate.java | 14 + .../org/nl/wms/sch/manage/AutoCreateTask.java | 21 +- .../org/nl/wms/sch/manage/CreateMode.java | 32 + .../org/nl/wms/sch/manage/FinishTypeEnum.java | 25 - .../java/org/nl/wms/sch/manage/LockType.java | 34 + .../org/nl/wms/sch/manage/OperationType.java | 24 + .../org/nl/wms/sch/manage/PointStatus.java | 29 + .../java/org/nl/wms/sch/manage/Region.java | 41 + .../org/nl/wms/sch/manage/RegionEnum.java | 43 -- .../org/nl/wms/sch/manage/TaskStatus.java | 26 + .../org/nl/wms/sch/manage/TaskStatusEnum.java | 28 - .../java/org/nl/wms/sch/manage/TaskType.java | 30 + .../nl/wms/sch/manage/UpdateTaskStatus.java | 21 + .../wms/sch/manage/UpdateTaskStatusEnum.java | 28 - .../org/nl/wms/sch/manage/WorkOrderEnum.java | 20 +- .../org/nl/wms/sch/rest/PointController.java | 46 +- .../org/nl/wms/sch/rest/TaskController.java | 20 +- .../org/nl/wms/sch/service/PointService.java | 2 + .../org/nl/wms/sch/service/dto/PointDto.java | 84 --- .../sch/service/impl/PointServiceImpl.java | 68 +- .../wms/sch/service/impl/TaskServiceImpl.java | 30 +- .../AcsTaskDto.java => task/AcsTaskDTO.java} | 4 +- .../sch/task/call/empty/HLCallEmptyTask.java | 108 +++ .../sch/task/call/empty/YZCallEmptyTask.java | 207 +++++ .../call/empty/wql/CALL_EMPTY_TASK.wql} | 58 +- .../call/material/SZCallMaterialTask.java | 209 +++++ .../call/material/wql/CALL_MATERIAL_TASK.wql | 79 ++ .../send/material/HLSendMaterialTask.java | 83 ++ .../send/material/SZSendMaterialTask.java | 199 +++++ .../send/material/YZSendMaterialTask.java | 194 +++++ .../send/material/wql/SEND_MATERIAL_TASK.wql} | 41 +- .../org/nl/wms/sch/task/util/TaskUtils.java | 110 +++ .../nl/wms/sch/tasks/PointToPointTask.java | 79 -- .../org/nl/wms/sch/tasks/PointUpdateUtil.java | 94 --- .../autoCallMaterial/RykCallMaterialTask.java | 312 -------- .../wql/QSCH_rykCallMaterial_01.wql | 63 -- .../callEmpty/FjCallEmptyVehicleTask.java | 307 -------- .../callEmpty/HnCallEmptyVehicleTask.java | 260 ------- .../callEmpty/YzjCallEmptyVehicleTask.java | 306 -------- .../wql/QSCH_fjCallEmptyVehicle_01.wql | 88 --- .../wql/QSCH_hnCallEmptyVehicle_01.wql | 64 -- .../wql/QSCH_yzjCallEmptyVehicle_01.wql | 79 -- .../callMaterial/FjCallMaterialTask.java | 273 ------- .../callMaterial/YzjCallMaterialTask.java | 294 -------- .../wql/QSCH_cyCallMaterial_01.wql | 68 -- .../wql/QSCH_yzjCallMaterial_01.wql | 71 -- .../org/nl/wms/sch/tasks/cpOut/CpOutTask.java | 269 ------- .../tasks/sendEmpty/DpSendEmpVehicleTask.java | 243 ------ .../tasks/sendEmpty/FjSendEmpVehicleTask.java | 225 ------ .../sendEmpty/YzjSendEmpVehicleTask.java | 238 ------ .../wql/QSCH_yzjSendEmptyVehicle_01.wql | 70 -- .../sendMaterial/FjSendMaterialTask.java | 462 ------------ .../sendMaterial/HnSendMaterialTask.java | 341 --------- .../tasks/sendMaterial/SendMaterialTask.java | 230 ------ .../sendMaterial/SzSendMaterialTask.java | 279 ------- .../sendMaterial/YzjSendMaterialTask.java | 313 -------- .../wql/QSCH_hnSendMaterial_01.wql | 105 --- .../wql/QSCH_yzSendMaterial_01.wql | 81 -- .../java/org/nl/wms/sch/util/PointUtils.java | 15 + .../org/nl/wms/sch/wql/QSCH_BASE_POINT.wql | 9 +- .../java/org/nl/wms/sch/wql/QSCH_TASK_01.wql | 2 +- .../src/main/java/org/nl/wms/sch/wql/sch.xls | Bin 179712 -> 0 bytes .../src/main/java/org/nl/wms/wms.xls | Bin 296960 -> 264192 bytes .../src/main/resources/banner.txt | 12 +- .../main/resources/config/application-dev.yml | 6 +- .../resources/config/application-prod.yml | 84 +-- .../src/main/resources/config/application.yml | 1 + .../src/main/resources/logback-spring.xml | 2 +- .../src/test/java/org/nl/test/PointTest.java | 41 + .../src/test/java/org/nl/test/TempTest.java | 30 + lms/nladmin-ui/src/api/wms/pdm/device.js | 74 ++ lms/nladmin-ui/src/api/wms/sch/point.js | 9 +- .../src/components/Crud/UD.operation.vue | 2 +- lms/nladmin-ui/src/settings.js | 2 +- .../src/views/system/dept/index.vue | 2 +- .../src/views/system/dict/dictDetail.vue | 2 +- .../src/views/system/dict/index.vue | 2 +- .../src/views/system/grid/index.vue | 2 +- .../views/system/logicflow/image/index.vue | 2 +- .../src/views/system/logicflow/index.vue | 2 +- .../src/views/system/menu/index.vue | 2 +- .../src/views/system/param/index.vue | 2 +- .../src/views/system/role/index.vue | 2 +- .../src/views/system/timing/index.vue | 2 +- .../src/views/system/user/index.vue | 2 +- .../src/views/tools/codeGen/codeDetail.vue | 2 +- .../src/views/tools/codeGen/index.vue | 2 +- .../src/views/tools/storage/index.vue | 2 +- .../src/views/wms/basedata/class/index.vue | 2 +- .../src/views/wms/basedata/customer/index.vue | 2 +- .../src/views/wms/basedata/material/index.vue | 291 +++---- .../src/views/wms/basedata/measure/index.vue | 2 +- .../src/views/wms/basedata/supp/index.vue | 2 +- .../src/views/wms/basedata/vehicle/index.vue | 231 +++--- .../src/views/wms/pdm/device/index.vue | 199 +++++ .../src/views/wms/pdm/workerorder/index.vue | 338 ++++----- .../src/views/wms/pub/DeviceDialog.vue | 106 +-- .../src/views/wms/pub/MaterDialog.vue | 39 +- .../src/views/wms/sch/point/index.vue | 295 ++++---- .../src/views/wms/sch/region/index.vue | 63 +- .../src/views/wms/st/cppoint/cppInRegion.vue | 188 +++++ .../src/views/wms/st/cppoint/cppInventory.vue | 401 ++++++++++ .../src/views/wms/st/cppoint/cppOutRegion.vue | 206 +++++ .../src/views/wms/st/cppoint/index.vue | 31 + lms/nladmin-ui/src/views/wms/st/regionio.js | 35 + lms/nladmin-ui/src/views/wms/st/structivt.js | 43 ++ lms/nladmin-ui/src/views/wms/st/ysa/index.vue | 32 + .../src/views/wms/st/ysa/inventory.vue | 412 ++++++++++ .../src/views/wms/st/ysa/ysqInRegion.vue | 188 +++++ .../src/views/wms/st/ysa/ysqOutRegion.vue | 190 +++++ 161 files changed, 6167 insertions(+), 9030 deletions(-) delete mode 100644 lms/nladmin-system/doc/永裕家居LMS系统.postman_collection.json create mode 100644 lms/nladmin-system/src/main/java/org/nl/config/PdaAspect.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/modules/common/utils/CommonUtils.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/modules/security/rest/DesUtil.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/LNSHMaterialUnit.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/TrueOrFalse.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/VehicleStatus.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/VehicleType.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/ext/auto/AutoQueryTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/ext/wql/AUTO_QUERYTASK.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/pda/anno/PdaAnnotation.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/pda/wql/LNSH_PDA.wql rename lms/nladmin-system/src/main/java/org/nl/wms/{sch/tasks/sendMaterial/wql/QSCH_szSendMaterial_01.wql => pda/wql/PDA.wql} (58%) create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/pdm/rest/DeviceController.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/DeviceService.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/impl/DeviceServiceImpl.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/ACSSystem.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoCreate.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/CreateMode.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/FinishTypeEnum.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/LockType.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/OperationType.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/PointStatus.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/Region.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/RegionEnum.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskStatus.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskStatusEnum.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskType.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatus.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatusEnum.java rename lms/nladmin-system/src/main/java/org/nl/wms/sch/{tasks/AcsTaskDto.java => task/AcsTaskDTO.java} (91%) create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/empty/HLCallEmptyTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/empty/YZCallEmptyTask.java rename lms/nladmin-system/src/main/java/org/nl/wms/sch/{tasks/sendMaterial/wql/QSCH_fjSendMaterial_01.wql => task/call/empty/wql/CALL_EMPTY_TASK.wql} (51%) create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/material/SZCallMaterialTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/material/wql/CALL_MATERIAL_TASK.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/HLSendMaterialTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/SZSendMaterialTask.java create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/YZSendMaterialTask.java rename lms/nladmin-system/src/main/java/org/nl/wms/sch/{tasks/cpOut/wql/QSCH_cpOut_01.wql => task/send/material/wql/SEND_MATERIAL_TASK.wql} (57%) create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/task/util/TaskUtils.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/PointToPointTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/PointUpdateUtil.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/autoCallMaterial/RykCallMaterialTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/autoCallMaterial/wql/QSCH_rykCallMaterial_01.wql delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/FjCallEmptyVehicleTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/HnCallEmptyVehicleTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YzjCallEmptyVehicleTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_fjCallEmptyVehicle_01.wql delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_hnCallEmptyVehicle_01.wql delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_yzjCallEmptyVehicle_01.wql delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/FjCallMaterialTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/YzjCallMaterialTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_cyCallMaterial_01.wql delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_yzjCallMaterial_01.wql delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/cpOut/CpOutTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/DpSendEmpVehicleTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/FjSendEmpVehicleTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/YzjSendEmpVehicleTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/wql/QSCH_yzjSendEmptyVehicle_01.wql delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/FjSendMaterialTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HnSendMaterialTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SendMaterialTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SzSendMaterialTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YzjSendMaterialTask.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hnSendMaterial_01.wql delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yzSendMaterial_01.wql create mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/util/PointUtils.java delete mode 100644 lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/sch.xls create mode 100644 lms/nladmin-system/src/test/java/org/nl/test/PointTest.java create mode 100644 lms/nladmin-system/src/test/java/org/nl/test/TempTest.java create mode 100644 lms/nladmin-ui/src/api/wms/pdm/device.js create mode 100644 lms/nladmin-ui/src/views/wms/pdm/device/index.vue create mode 100644 lms/nladmin-ui/src/views/wms/st/cppoint/cppInRegion.vue create mode 100644 lms/nladmin-ui/src/views/wms/st/cppoint/cppInventory.vue create mode 100644 lms/nladmin-ui/src/views/wms/st/cppoint/cppOutRegion.vue create mode 100644 lms/nladmin-ui/src/views/wms/st/cppoint/index.vue create mode 100644 lms/nladmin-ui/src/views/wms/st/regionio.js create mode 100644 lms/nladmin-ui/src/views/wms/st/structivt.js create mode 100644 lms/nladmin-ui/src/views/wms/st/ysa/index.vue create mode 100644 lms/nladmin-ui/src/views/wms/st/ysa/inventory.vue create mode 100644 lms/nladmin-ui/src/views/wms/st/ysa/ysqInRegion.vue create mode 100644 lms/nladmin-ui/src/views/wms/st/ysa/ysqOutRegion.vue diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDeviceDriver.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDeviceDriver.java index 4551e63..ce3d3d8 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDeviceDriver.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/lnsh/lnsh_rgv/LnshRGVDeviceDriver.java @@ -567,4 +567,17 @@ public class LnshRGVDeviceDriver extends AbstractOpcDeviceDriver implements Devi ReadUtil.write(itemMap, server); } + + public void writeMap(Map map) { + HashMap writeMap = new HashMap<>(); + for (Map.Entry e : map.entrySet()) { + String key = this.getDevice().getOpc_server_code() + "." + this.getDevice().getOpc_plc_code() + "." + this.getDevice().getDevice_code() + + "." + e.getKey(); + writeMap.put(key, e.getValue()); + } + + String opcservcerid = this.getDevice().getOpc_server_id(); + Server server = ReadUtil.getServer(opcservcerid); + ReadUtil.write(writeMap, server); + } } diff --git a/acs/nladmin-system/src/main/resources/config/application-dev.yml b/acs/nladmin-system/src/main/resources/config/application-dev.yml index 88b1a59..1d3349c 100644 --- a/acs/nladmin-system/src/main/resources/config/application-dev.yml +++ b/acs/nladmin-system/src/main/resources/config/application-dev.yml @@ -6,10 +6,10 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy - url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.81.252}:${DB_PORT:3306}/${DB_NAME:lnsh_acs2}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true + url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:lnsh_acs2}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true # url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.81.252}:${DB_PORT:3306}/${DB_NAME:yongyu_acs2}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true username: ${DB_USER:root} - password: ${DB_PWD:Root.123456} + password: ${DB_PWD:zjw123} # password: ${DB_PWD:Root.123456} # 初始连接数 initial-size: 5 diff --git a/acs/nladmin-system/src/main/resources/config/application.yml b/acs/nladmin-system/src/main/resources/config/application.yml index 7e3fbea..a4d00ab 100644 --- a/acs/nladmin-system/src/main/resources/config/application.yml +++ b/acs/nladmin-system/src/main/resources/config/application.yml @@ -2,7 +2,7 @@ spring: freemarker: check-template-location: false profiles: - active: dev + active: prod jackson: time-zone: GMT+8 data: diff --git a/lms/nladmin-system/doc/永裕家居LMS系统.postman_collection.json b/lms/nladmin-system/doc/永裕家居LMS系统.postman_collection.json deleted file mode 100644 index 0c91cb5..0000000 --- a/lms/nladmin-system/doc/永裕家居LMS系统.postman_collection.json +++ /dev/null @@ -1,489 +0,0 @@ -{ - "info": { - "_postman_id": "584232a7-9ae4-4ca2-b4e5-d9e66870957e", - "name": "永裕家居LMS系统", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" - }, - "item": [ - { - "name": "示例", - "description": "", - "item": [ - { - "name": "LMS登录", - "event": [ - { - "listen": "prerequest", - "script": { - "id": "56672d9d-9bac-4f23-b77e-809647ef5df4", - "type": "text/javascript", - "exec": [ - "" - ] - } - }, - { - "listen": "test", - "script": { - "id": "48d9e766-7014-4243-80de-81d63be07da5", - "type": "text/javascript", - "exec": [ - "//postman使用:https://blog.csdn.net/wangyiyan315/article/details/122441791", - "", - "var JsonData = JSON.parse(responseBody); //定义一个变量,并且将请求返回的内容赋给该变量", - "pm.globals.set(\"lms_token\", JsonData.token.slice(7)); //7代表去掉token前面的Bearer加空格", - "" - ] - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\n\t\n\t\"username\":\"admin\",\n\t\"password\":\"uefvHbyUCADkudW1MV+/yw9XBWR2Z+KDyq+dqQ+ozr1loClUgqm4XQPsUl87IsXetYBWRDLo7HC++20VHlW80g==\"\n}" - }, - "url": { - "raw": "{{lms_url}}/mobile/auth/login", - "host": [ - "{{lms_url}}" - ], - "path": [ - "mobile", - "auth", - "login" - ] - }, - "description": "LMS登录并设置返回的token" - }, - "response": [] - }, - { - "name": "系统参数分页查询-示例", - "event": [ - { - "listen": "prerequest", - "script": { - "id": "4f07b550-ab9c-41a4-8dbf-f889ae50b246", - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{lms_token}}", - "type": "string" - } - ] - }, - "method": "GET", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "/api/param" - }, - "url": { - "raw": "{{lms_url}}/api/param?sort=id,desc&size=10&page=0", - "host": [ - "{{lms_url}}" - ], - "path": [ - "api", - "param" - ], - "query": [ - { - "key": "sort", - "value": "id,desc" - }, - { - "key": "size", - "value": "10" - }, - { - "key": "page", - "value": "0" - }, - { - "key": null, - "value": null - }, - { - "key": null, - "value": null - } - ] - }, - "description": "求方法参数:{\"whereJson\":{\"sort\":\"id,desc\",\"size\":\"10\",\"page\":\"0\"}}" - }, - "response": [] - }, - { - "name": "根据编码获取值-示例", - "event": [ - { - "listen": "prerequest", - "script": { - "id": "4f07b550-ab9c-41a4-8dbf-f889ae50b246", - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{lms_token}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "IS_CONNECT_ACS" - }, - "url": { - "raw": "{{lms_url}}/api/param/getValueByCode", - "host": [ - "{{lms_url}}" - ], - "path": [ - "api", - "param", - "getValueByCode" - ] - }, - "description": "求方法参数:{\"whereJson\":{\"sort\":\"id,desc\",\"size\":\"10\",\"page\":\"0\"}}" - }, - "response": [] - }, - { - "name": "删除参数-示例", - "event": [ - { - "listen": "prerequest", - "script": { - "id": "4f07b550-ab9c-41a4-8dbf-f889ae50b246", - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{lms_token}}", - "type": "string" - } - ] - }, - "method": "DELETE", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "[\"0c1d96d335cd4dd6aa0a4bee4b1c45fe\"]" - }, - "url": { - "raw": "{{lms_url}}/api/param", - "host": [ - "{{lms_url}}" - ], - "path": [ - "api", - "param" - ] - }, - "description": "求方法参数:{\"whereJson\":{\"sort\":\"id,desc\",\"size\":\"10\",\"page\":\"0\"}}" - }, - "response": [] - }, - { - "name": "新增参数-示例", - "event": [ - { - "listen": "prerequest", - "script": { - "id": "4f07b550-ab9c-41a4-8dbf-f889ae50b246", - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{lms_token}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\"code\":\"test22\",\"is_active\":\"1\",\"remark\":\"test11\",\"name\":\"test11\",\"value\":\"test11\"}" - }, - "url": { - "raw": "{{lms_url}}/api/param", - "host": [ - "{{lms_url}}" - ], - "path": [ - "api", - "param" - ] - }, - "description": "求方法参数:{\"whereJson\":{\"sort\":\"id,desc\",\"size\":\"10\",\"page\":\"0\"}}" - }, - "response": [] - }, - { - "name": "修改参数-示例", - "event": [ - { - "listen": "prerequest", - "script": { - "id": "4f07b550-ab9c-41a4-8dbf-f889ae50b246", - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{lms_token}}", - "type": "string" - } - ] - }, - "method": "PUT", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\"code\":\"test22\",\"is_active\":\"8\",\"create_time\":\"2022-10-14 13:33:52\",\"remark\":\"888\",\"update_time\":\"2022-10-14 13:33:52\",\"update_optname\":\"管理员\",\"create_id\":1,\"name\":\"888\",\"id\":\"3f1901b5814d40908bad602854b22aa6\",\"value\":\"8888\",\"update_optid\":1,\"create_name\":\"管理员\"}" - }, - "url": { - "raw": "{{lms_url}}/api/param", - "host": [ - "{{lms_url}}" - ], - "path": [ - "api", - "param" - ] - }, - "description": "求方法参数:{\"whereJson\":{\"sort\":\"id,desc\",\"size\":\"10\",\"page\":\"0\"}}" - }, - "response": [] - } - ] - }, - { - "name": "ACS请求LMS", - "description": "", - "item": [ - { - "name": "共挤线申请空盘", - "event": [ - { - "listen": "prerequest", - "script": { - "id": "4f07b550-ab9c-41a4-8dbf-f889ae50b246", - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{lms_token}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\"type\":\"1\",\"point_code\":\"GJX01_K\",\"vehicle_code\":\"001\",\"qty\":\"100\",\"vehicle_type\":\"01\",\"vehicle_num\":\"1\"}" - }, - "url": { - "raw": "{{lms_url}}/api/wms/task/apply", - "host": [ - "{{lms_url}}" - ], - "path": [ - "api", - "wms", - "task", - "apply" - ] - }, - "description": "求方法参数:{\"whereJson\":{\"sort\":\"id,desc\",\"size\":\"10\",\"page\":\"0\"}}" - }, - "response": [] - }, - { - "name": "油漆线空盘入库", - "event": [ - { - "listen": "prerequest", - "script": { - "id": "4f07b550-ab9c-41a4-8dbf-f889ae50b246", - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "request": { - "auth": { - "type": "bearer", - "bearer": [ - { - "key": "token", - "value": "{{lms_token}}", - "type": "string" - } - ] - }, - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\"code\":\"test22\",\"is_active\":\"1\",\"remark\":\"test11\",\"name\":\"test11\",\"value\":\"test11\"}" - }, - "url": { - "raw": "{{lms_url}}/api/param", - "host": [ - "{{lms_url}}" - ], - "path": [ - "api", - "param" - ] - }, - "description": "求方法参数:{\"whereJson\":{\"sort\":\"id,desc\",\"size\":\"10\",\"page\":\"0\"}}" - }, - "response": [] - } - ] - } - ], - "event": [ - { - "listen": "prerequest", - "script": { - "id": "32f60779-6a66-4d77-80e3-1bc0040e7650", - "type": "text/javascript", - "exec": [ - "" - ] - } - }, - { - "listen": "test", - "script": { - "id": "fb339152-4984-49bb-8955-3e24baac67ae", - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "variable": [ - { - "id": "9b318f5e-373b-4f36-93a5-d131f4f76446", - "key": "lms_url", - "value": "http://localhost:8010", - "type": "string", - "description": "" - }, - { - "id": "5557e8ff-f6ac-45b0-a950-4a8c139d1ae0", - "key": "acs_url", - "value": "http://localhost:8010", - "type": "string", - "description": "" - } - ] -} \ No newline at end of file diff --git a/lms/nladmin-system/src/main/java/org/nl/AppRun.java b/lms/nladmin-system/src/main/java/org/nl/AppRun.java index 2fa3edd..557183a 100644 --- a/lms/nladmin-system/src/main/java/org/nl/AppRun.java +++ b/lms/nladmin-system/src/main/java/org/nl/AppRun.java @@ -11,6 +11,7 @@ import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactor import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.transaction.annotation.EnableTransactionManagement; @@ -25,6 +26,7 @@ import org.springframework.web.bind.annotation.RestController; * @date 2021/2/22 9:20:19 */ @EnableAsync +@EnableAspectJAutoProxy @RestController @Api(hidden = true) @SpringBootApplication(exclude = { diff --git a/lms/nladmin-system/src/main/java/org/nl/config/PdaAspect.java b/lms/nladmin-system/src/main/java/org/nl/config/PdaAspect.java new file mode 100644 index 0000000..97e3784 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/config/PdaAspect.java @@ -0,0 +1,22 @@ +package org.nl.config; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.wms.pda.util.PdaUtils; +import org.springframework.stereotype.Component; + +@Component +@Aspect +public class PdaAspect { + + @Around("@annotation(org.nl.wms.pda.anno.PdaAnnotation)") + private Object around(ProceedingJoinPoint pjp) { + try { + return pjp.proceed(); + } catch (Throwable e) { + return PdaUtils.buildFailResultJSON(e.getMessage()); + } + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/modules/common/api/CommonResult.java b/lms/nladmin-system/src/main/java/org/nl/modules/common/api/CommonResult.java index 3536868..e47ff19 100644 --- a/lms/nladmin-system/src/main/java/org/nl/modules/common/api/CommonResult.java +++ b/lms/nladmin-system/src/main/java/org/nl/modules/common/api/CommonResult.java @@ -7,135 +7,135 @@ package org.nl.modules.common.api; * @date 2023-03-02 */ public class CommonResult { - private long code; - private String desc; - private T result; + private long code; + private String desc; + private T result; - public CommonResult() { - } + public CommonResult() { + } - protected CommonResult(T result) { - this.result = result; - this.desc = ResultCode.SUCCESS.getDesc(); - this.code = ResultCode.SUCCESS.getCode(); - } + protected CommonResult(T result) { + this.result = result; + this.desc = ResultCode.SUCCESS.getDesc(); + this.code = ResultCode.SUCCESS.getCode(); + } - protected CommonResult(long code, String desc, T result) { - this.code = code; - this.desc = desc; - this.result = result; - } + protected CommonResult(long code, String desc, T result) { + this.code = code; + this.desc = desc; + this.result = result; + } - /** - * 成功返回结果 + /** + * 成功返回结果 - */ - public static CommonResult success() { - return new CommonResult<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getDesc(), null); - } + */ + public static CommonResult success() { + return new CommonResult<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getDesc(), null); + } - /** - * 成功返回结果 - * - * @param result 获取的数据 - */ - public static CommonResult success(T result) { - return new CommonResult<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getDesc(), result); - } + /** + * 成功返回结果 + * + * @param result 获取的数据 + */ + public static CommonResult success(T result) { + return new CommonResult<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getDesc(), result); + } - /** - * 成功返回结果 - * - * @param result 获取的数据 - * @param desc 提示信息 - */ - public static CommonResult success(T result, String desc) { - return new CommonResult<>(ResultCode.SUCCESS.getCode(), desc, result); - } + /** + * 成功返回结果 + * + * @param result 获取的数据 + * @param desc 提示信息 + */ + public static CommonResult success(T result, String desc) { + return new CommonResult<>(ResultCode.SUCCESS.getCode(), desc, result); + } - /** - * 失败返回结果 - * @param errorCode 错误码 - */ - public static CommonResult failed(IErrorCode errorCode) { - return new CommonResult<>(errorCode.getCode(), errorCode.getDesc(), null); - } + /** + * 失败返回结果 + * @param errorCode 错误码 + */ + public static CommonResult failed(IErrorCode errorCode) { + return new CommonResult<>(errorCode.getCode(), errorCode.getDesc(), null); + } - /** - * 失败返回结果 - * @param errorCode 错误码 - * @param desc 错误信息 - */ - public static CommonResult failed(IErrorCode errorCode,String desc) { - return new CommonResult<>(errorCode.getCode(), desc, null); - } + /** + * 失败返回结果 + * @param errorCode 错误码 + * @param desc 错误信息 + */ + public static CommonResult failed(IErrorCode errorCode,String desc) { + return new CommonResult<>(errorCode.getCode(), desc, null); + } - /** - * 失败返回结果 - * @param desc 提示信息 - */ - public static CommonResult failed(String desc) { - return new CommonResult<>(ResultCode.FAILED.getCode(), desc, null); - } + /** + * 失败返回结果 + * @param desc 提示信息 + */ + public static CommonResult failed(String desc) { + return new CommonResult<>(ResultCode.FAILED.getCode(), desc, null); + } - /** - * 失败返回结果 - */ - public static CommonResult failed() { - return failed(ResultCode.FAILED); - } + /** + * 失败返回结果 + */ + public static CommonResult failed() { + return failed(ResultCode.FAILED); + } - /** - * 参数验证失败返回结果 - */ - public static CommonResult validateFailed() { - return failed(ResultCode.VALIDATE_FAILED); - } + /** + * 参数验证失败返回结果 + */ + public static CommonResult validateFailed() { + return failed(ResultCode.VALIDATE_FAILED); + } - /** - * 参数验证失败返回结果 - * @param desc 提示信息 - */ - public static CommonResult validateFailed(String desc) { - return new CommonResult<>(ResultCode.MISS_PARAMETER.getCode(), desc, null); - } + /** + * 参数验证失败返回结果 + * @param desc 提示信息 + */ + public static CommonResult validateFailed(String desc) { + return new CommonResult<>(ResultCode.MISS_PARAMETER.getCode(), desc, null); + } - /** - * 未登录返回结果 - */ - public static CommonResult unauthorized(T result) { - return new CommonResult<>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getDesc(), result); - } + /** + * 未登录返回结果 + */ + public static CommonResult unauthorized(T result) { + return new CommonResult<>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getDesc(), result); + } - /** - * 未授权返回结果 - */ - public static CommonResult forbidden(T result) { - return new CommonResult<>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getDesc(), result); - } + /** + * 未授权返回结果 + */ + public static CommonResult forbidden(T result) { + return new CommonResult<>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getDesc(), result); + } - public long getCode() { - return code; - } + public long getCode() { + return code; + } - public void setCode(long code) { - this.code = code; - } + public void setCode(long code) { + this.code = code; + } - public String getDesc() { - return desc; - } + public String getDesc() { + return desc; + } - public void setDesc(String desc) { - this.desc = desc; - } + public void setDesc(String desc) { + this.desc = desc; + } - public T getResult() { - return result; - } + public T getResult() { + return result; + } - public void setResult(T result) { - this.result = result; - } + public void setResult(T result) { + this.result = result; + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/modules/common/api/RestBusinessTemplate.java b/lms/nladmin-system/src/main/java/org/nl/modules/common/api/RestBusinessTemplate.java index b915ffd..d552619 100644 --- a/lms/nladmin-system/src/main/java/org/nl/modules/common/api/RestBusinessTemplate.java +++ b/lms/nladmin-system/src/main/java/org/nl/modules/common/api/RestBusinessTemplate.java @@ -11,75 +11,69 @@ import org.nl.modules.common.exception.BizCoreException; * @date 2023-03-02 */ @Slf4j -public class RestBusinessTemplate{ - public static CommonResult execute(Callback callback) { - CommonResult result = new CommonResult<>(); - try { - result.setCode(ResultCode.SUCCESS.getCode()); - result.setDesc(ResultCode.SUCCESS.getDesc()); - T object = callback.doExecute(); - if(object != null) { - result.setResult(object); - } - } - catch(BizCoreException e) { - String errorMsg; - if(StringUtils.isNotBlank(e.getErrorMsg())) { - errorMsg = e.getErrorMsg(); - } - else if(e.getCode() != null) { - errorMsg = e.getCode().getDesc(); - } - else{ - errorMsg = e.getMessage(); - } - log.error(e.getErrorMsg()); - ResultCode code = e.getCode() == null ? ResultCode.FAILED : e.getCode(); - result.setCode(code.getCode()); - result.setDesc(errorMsg); - } - catch(Exception e) { - log.error("execute error", e); - result.setCode(ResultCode.FAILED.getCode()); - result.setDesc(ResultCode.FAILED.getDesc()); - } - return result; - } +public class RestBusinessTemplate { + public static CommonResult execute(Callback callback) { + CommonResult result = new CommonResult<>(); + try { + result.setCode(ResultCode.SUCCESS.getCode()); + result.setDesc(ResultCode.SUCCESS.getDesc()); + T object = callback.doExecute(); + if (object != null) { + result.setResult(object); + } + } catch (BizCoreException e) { + String errorMsg; + if (StringUtils.isNotBlank(e.getErrorMsg())) { + errorMsg = e.getErrorMsg(); + } else if (e.getCode() != null) { + errorMsg = e.getCode().getDesc(); + } else { + errorMsg = e.getMessage(); + } + log.error(e.getErrorMsg()); + ResultCode code = e.getCode() == null ? ResultCode.FAILED : e.getCode(); + result.setCode(code.getCode()); + result.setDesc(errorMsg); + } catch (Exception e) { + log.error("execute error", e); + result.setCode(ResultCode.FAILED.getCode()); + result.setDesc(ResultCode.FAILED.getDesc()); + } + return result; + } - public static CommonResult execute(VoidCallback callback) { - CommonResult result = new CommonResult<>(); - try { - callback.execute(); - result.setCode(ResultCode.SUCCESS.getCode()); - result.setDesc(ResultCode.SUCCESS.getDesc()); - } - catch(BizCoreException e) { - log.error("", e); - ResultCode code = e.getCode() == null ? ResultCode.FAILED : e.getCode(); - result.setCode(code.getCode()); - result.setDesc(StringUtils.isBlank(e.getMessage()) ? code.getDesc() : e.getMessage()); - } - catch(Exception e) { - log.error("execute error", e); - result.setCode(ResultCode.FAILED.getCode()); - result.setDesc(ResultCode.FAILED.getDesc()); - } - return result; - } + public static CommonResult execute(VoidCallback callback) { + CommonResult result = new CommonResult<>(); + try { + callback.execute(); + result.setCode(ResultCode.SUCCESS.getCode()); + result.setDesc(ResultCode.SUCCESS.getDesc()); + } catch (BizCoreException e) { + log.error("", e); + ResultCode code = e.getCode() == null ? ResultCode.FAILED : e.getCode(); + result.setCode(code.getCode()); + result.setDesc(StringUtils.isBlank(e.getMessage()) ? code.getDesc() : e.getMessage()); + } catch (Exception e) { + log.error("execute error", e); + result.setCode(ResultCode.FAILED.getCode()); + result.setDesc(ResultCode.FAILED.getDesc()); + } + return result; + } - /** - * 执行回调 - * - * @param - */ - public interface Callback{ - T doExecute(); - } + /** + * 执行回调 + * + * @param + */ + public interface Callback { + T doExecute(); + } - /** - * 执行回调 - */ - public interface VoidCallback{ - void execute(); - } + /** + * 执行回调 + */ + public interface VoidCallback { + void execute(); + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/modules/common/utils/CommonUtils.java b/lms/nladmin-system/src/main/java/org/nl/modules/common/utils/CommonUtils.java new file mode 100644 index 0000000..e8cb864 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/modules/common/utils/CommonUtils.java @@ -0,0 +1,24 @@ +package org.nl.modules.common.utils; + +/** + * @author zhangjiangwei + * @date 2023/04/05 15:05 + */ +public class CommonUtils { + + public static String idsArrayToInStr(Long[] ids) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ids.length; i++) { + if (i == 0) { + sb.append("("); + } + sb.append("'").append(ids[i]).append("'"); + if (i == ids.length - 1) { + sb.append(")"); + } else { + sb.append(","); + } + } + return sb.toString(); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/modules/common/utils/enums/PointStatusEnum.java b/lms/nladmin-system/src/main/java/org/nl/modules/common/utils/enums/PointStatusEnum.java index 1398d90..9af3319 100644 --- a/lms/nladmin-system/src/main/java/org/nl/modules/common/utils/enums/PointStatusEnum.java +++ b/lms/nladmin-system/src/main/java/org/nl/modules/common/utils/enums/PointStatusEnum.java @@ -6,57 +6,57 @@ package org.nl.modules.common.utils.enums; * @since 2023-03-01 */ public enum PointStatusEnum{ - /** - * 暂停 - */ - STOP("暂停", "1"), - /** - * 运行 - */ - RUN("运行中", "2"), - /** - * 故障 - */ - FAULT("故障", "3"), - /** - * 关机 - */ - SHUTDOWN("关机", "4"); - private String name; - private String index; + /** + * 暂停 + */ + STOP("暂停", "1"), + /** + * 运行 + */ + RUN("运行中", "2"), + /** + * 故障 + */ + FAULT("故障", "3"), + /** + * 关机 + */ + SHUTDOWN("关机", "4"); + private String name; + private String index; - PointStatusEnum(String name, String index) { - this.name = name; - this.index = index; - } + PointStatusEnum(String name, String index) { + this.name = name; + this.index = index; + } - public static String getName(String index) { - for(PointStatusEnum c : PointStatusEnum.values()) { - if(c.getIndex().equals(index)) { - return c.name; - } - } - return null; - } + public static String getName(String index) { + for(PointStatusEnum c : PointStatusEnum.values()) { + if(c.getIndex().equals(index)) { + return c.name; + } + } + return null; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - public String getIndex() { - return index; - } + public String getIndex() { + return index; + } - public void setIndex(String index) { - this.index = index; - } + public void setIndex(String index) { + this.index = index; + } - @Override - public String toString() { - return this.index + "_" + this.name; - } + @Override + public String toString() { + return this.index + "_" + this.name; + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/modules/common/utils/enums/ProductionStatisticsEnum.java b/lms/nladmin-system/src/main/java/org/nl/modules/common/utils/enums/ProductionStatisticsEnum.java index abca936..7560c22 100644 --- a/lms/nladmin-system/src/main/java/org/nl/modules/common/utils/enums/ProductionStatisticsEnum.java +++ b/lms/nladmin-system/src/main/java/org/nl/modules/common/utils/enums/ProductionStatisticsEnum.java @@ -6,53 +6,53 @@ package org.nl.modules.common.utils.enums; * @since 2023-03-01 */ public enum ProductionStatisticsEnum{ - /** - * 今日压制量 - */ - CRUSH("今日压制量", "2"), - /** - * 今日干燥量 - */ - DRY("今日干燥量", "3"), - /** - * 今日成品量 - */ - FINISHED("今日成品量", "4"); - private String name; - private String index; + /** + * 今日压制量 + */ + CRUSH("今日压制量", "2"), + /** + * 今日干燥量 + */ + DRY("今日干燥量", "3"), + /** + * 今日成品量 + */ + FINISHED("今日成品量", "4"); + private String name; + private String index; - ProductionStatisticsEnum(String name, String index) { - this.name = name; - this.index = index; - } + ProductionStatisticsEnum(String name, String index) { + this.name = name; + this.index = index; + } - public static String getName(String index) { - for(ProductionStatisticsEnum c : ProductionStatisticsEnum.values()) { - if(c.getIndex().equals(index)) { - return c.name; - } - } - return null; - } + public static String getName(String index) { + for(ProductionStatisticsEnum c : ProductionStatisticsEnum.values()) { + if(c.getIndex().equals(index)) { + return c.name; + } + } + return null; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - public String getIndex() { - return index; - } + public String getIndex() { + return index; + } - public void setIndex(String index) { - this.index = index; - } + public void setIndex(String index) { + this.index = index; + } - @Override - public String toString() { - return this.index + "_" + this.name; - } + @Override + public String toString() { + return this.index + "_" + this.name; + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/modules/security/rest/DesUtil.java b/lms/nladmin-system/src/main/java/org/nl/modules/security/rest/DesUtil.java deleted file mode 100644 index 89f9a32..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/modules/security/rest/DesUtil.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.nl.modules.security.rest; - -// -// Source code recreated from a .class file by IntelliJ IDEA -// (powered by FernFlower decompiler) -// - - -import sun.misc.BASE64Decoder; -import sun.misc.BASE64Encoder; - -import javax.crypto.Cipher; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.DESKeySpec; -import javax.crypto.spec.IvParameterSpec; -import java.io.IOException; -import java.security.SecureRandom; - -/** - * Des加密解密算法工具类 - */ -public class DesUtil { - //加密算法是des - private static final String ALGORITHM = "DES"; - //转换格式 - private static final String TRANSFORMATION = "DES/CBC/PKCS5Padding"; - - /** - * 加密 - * - * @param src 数据源 - * @param key 密钥,长度必须是8的倍数 - * @return 返回加密后的数据 - * @throws Exception 出错 - */ - public static byte[] encrypt(byte[] src, byte[] key) throws Exception { - // DES算法要求有一个可信任的随机数源 - SecureRandom sr = new SecureRandom(); - // 从原始密匙数据建立 DESKeySpec对象 - DESKeySpec dks = new DESKeySpec(key); - // 建立一个密匙工厂,然后用它把DESKeySpec转换成 - // 一个SecretKey对象 - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); - SecretKey securekey = keyFactory.generateSecret(dks); - // Cipher对象实际完成加密操作 - Cipher cipher = Cipher.getInstance(TRANSFORMATION); - // 用密匙原始化Cipher对象 - cipher.init(Cipher.ENCRYPT_MODE, securekey, new IvParameterSpec(key)); - // 现在,获取数据并加密 - // 正式执行加密操作 - return cipher.doFinal(src); - } - - /** - * 解密 - * - * @param src 数据源 - * @param key 密钥,长度必须是8的倍数 - * @return 返回解密后的原始数据 - * @throws Exception 出错 - */ - public static byte[] decrypt(byte[] src, byte[] key) throws Exception { - // DES算法要求有一个可信任的随机数源 - SecureRandom sr = new SecureRandom(); - // 从原始密匙数据建立一个DESKeySpec对象 - DESKeySpec dks = new DESKeySpec(key); - // 建立一个密匙工厂,然后用它把DESKeySpec对象转换成 - // 一个SecretKey对象 - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); - SecretKey securekey = keyFactory.generateSecret(dks); - // Cipher对象实际完成解密操作 - Cipher cipher = Cipher.getInstance(TRANSFORMATION); - // 用密匙原始化Cipher对象 - cipher.init(Cipher.DECRYPT_MODE, securekey, new IvParameterSpec(key)); - // 现在,获取数据并解密 - // 正式执行解密操作 - return cipher.doFinal(src); - } - - /** - * Description 根据键值进行加密 - * - * @param data - * @param key 加密键byte数组 - * @return - * @throws Exception - */ - public static String encrypt(String data, String key) throws Exception { - byte[] bt = encrypt(data.getBytes("UTF-8"), key.getBytes("UTF-8")); - - BASE64Encoder encoder = new BASE64Encoder(); - return encoder.encode(bt); - - //return new String(Base64.encodeBase64(bt), "UTF-8"); - } - - /** - * Description 根据键值进行解密 - * - * @param data - * @param key 加密键byte数组 - * @return - * @throws IOException - * @throws Exception - */ - public static String decrypt(String data, String key) throws Exception { - if (data == null) - return null; - BASE64Decoder decoder = new BASE64Decoder(); - byte[] buf = decoder.decodeBuffer(data); - - byte[] bt = decrypt(buf, key.getBytes("UTF-8")); - return new String(bt, "UTF-8"); - } - - - public static void main(String[] args) throws Exception { - //uL8fXioyU2M= - String key = "11111111"; - String pp = encrypt("123456", key); - System.out.println("加密:" + pp); - - String mm2 = decrypt(pp, key); - System.out.println("解密:" + mm2); - - } - -} diff --git a/lms/nladmin-system/src/main/java/org/nl/modules/system/service/impl/GenCodeServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/modules/system/service/impl/GenCodeServiceImpl.java index a49dd33..541e59e 100644 --- a/lms/nladmin-system/src/main/java/org/nl/modules/system/service/impl/GenCodeServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/modules/system/service/impl/GenCodeServiceImpl.java @@ -14,6 +14,8 @@ import org.nl.modules.wql.core.bean.WQLObject; import org.nl.modules.wql.util.WqlUtil; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import java.util.Date; import java.util.HashMap; @@ -95,8 +97,9 @@ public class GenCodeServiceImpl implements GenCodeService { WQLObject.getWQLObject("sys_code_rule").update(json); } + @Transactional(propagation = Propagation.REQUIRES_NEW) @Override - public synchronized String codeDemo(Map form) { + public String codeDemo(Map form) { String code = (String) form.get("code"); String id = this.queryIdByCode(code); //如果flag=1就执行更新数据库的操作 diff --git a/lms/nladmin-system/src/main/java/org/nl/modules/system/util/CodeUtil.java b/lms/nladmin-system/src/main/java/org/nl/modules/system/util/CodeUtil.java index 1c12c85..2a39a39 100644 --- a/lms/nladmin-system/src/main/java/org/nl/modules/system/util/CodeUtil.java +++ b/lms/nladmin-system/src/main/java/org/nl/modules/system/util/CodeUtil.java @@ -7,12 +7,14 @@ import java.util.HashMap; public class CodeUtil { - public static String getNewCode(String ruleCode){ - String flag = "1"; - HashMap map = new HashMap<>(); - map.put("flag",flag); - map.put("code",ruleCode); - return SpringContextHolder.getBean(GenCodeService.class).codeDemo(map); + public static String getNewCode(String ruleCode){ + synchronized (ruleCode) { + String flag = "1"; + HashMap map = new HashMap<>(); + map.put("flag", flag); + map.put("code", ruleCode); + return SpringContextHolder.getBean(GenCodeService.class).codeDemo(map); + } } } diff --git a/lms/nladmin-system/src/main/java/org/nl/start/Init.java b/lms/nladmin-system/src/main/java/org/nl/start/Init.java index 9417a40..121bec5 100644 --- a/lms/nladmin-system/src/main/java/org/nl/start/Init.java +++ b/lms/nladmin-system/src/main/java/org/nl/start/Init.java @@ -18,8 +18,10 @@ import org.springframework.stereotype.Component; public class Init implements ApplicationRunner { @Override - public void run(ApplicationArguments args) throws Exception { - System.out.println("项目启动成功!"); + public void run(ApplicationArguments args) { + System.out.println(">>================================================================<<\n" + + ">> 项目启动成功 <<\n" + + ">>================================================================<<"); } private void initPoint() { @@ -42,7 +44,7 @@ public class Init implements ApplicationRunner { } - String point_code = 2+""+block_num + col_numS+"-" + row_numS +"-"+ "01"; + String point_code = 2 + "" + block_num + col_numS + "-" + row_numS + "-" + "01"; String point_name = col_num + "排" + row_num + "列1层"; json.put("point_code", point_code); json.put("point_name", point_name); diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/LNSHMaterialUnit.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/LNSHMaterialUnit.java new file mode 100644 index 0000000..85508bf --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/LNSHMaterialUnit.java @@ -0,0 +1,26 @@ +package org.nl.wms.basedata.eum; + +import lombok.RequiredArgsConstructor; + +/** + * @author zhangjiangwei + * @date 2023/04/05 17:28 + */ +@RequiredArgsConstructor +public enum LNSHMaterialUnit { + + BLOCK("块", "0"), + TON("吨", "1"); + + private final String label; + + private final String value; + + public String label() { + return this.label; + } + + public String value() { + return this.value; + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/TrueOrFalse.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/TrueOrFalse.java new file mode 100644 index 0000000..d8ef9ff --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/TrueOrFalse.java @@ -0,0 +1,31 @@ +package org.nl.wms.basedata.eum; + +import lombok.RequiredArgsConstructor; + +/** + * @author zhangjiangwei + * @date 2023/03/03 10:05 + */ +@RequiredArgsConstructor +public enum TrueOrFalse { + + FALSE("否", "0"), + TRUE("是", "1"); + + private final String label; + + private final String value; + + public String label() { + return this.label; + } + + public String value() { + return this.value; + } + + + public static boolean trueOrFalse(String value) { + return TRUE.value.equals(value); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/VehicleStatus.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/VehicleStatus.java new file mode 100644 index 0000000..d556037 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/VehicleStatus.java @@ -0,0 +1,26 @@ +package org.nl.wms.basedata.eum; + +import lombok.RequiredArgsConstructor; + +/** + * @author zhangjiangwei + * @date 2023/03/02 15:33 + */ +@RequiredArgsConstructor +public enum VehicleStatus { + + EMPTY("无货", "0"), + NOT_EMPTY("有货", "1"); + + private final String label; + + private final String value; + + public String label() { + return this.label; + } + + public String value() { + return this.value; + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/VehicleType.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/VehicleType.java new file mode 100644 index 0000000..e67b576 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/eum/VehicleType.java @@ -0,0 +1,32 @@ +package org.nl.wms.basedata.eum; + +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * @author zhangjiangwei + * @date 2023/03/02 15:27 + */ +@RequiredArgsConstructor +public enum VehicleType { + + CUP("料盅", "1"), + STEEL_TRAY("钢托盘", "2"); + + private final String label; + private final String value; + + public String label() { + return this.label; + } + + public String value() { + return this.value; + } + + public static VehicleType get(String value) { + return Arrays.stream(VehicleType.values()).filter(vt -> vt.value.equals(value)).collect(Collectors.toList()).get(0); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/rest/VehicleController.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/rest/VehicleController.java index 5a0e830..5859307 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/rest/VehicleController.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/rest/VehicleController.java @@ -3,27 +3,27 @@ package org.nl.wms.basedata.rest; import com.alibaba.fastjson.JSONObject; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.logging.annotation.Log; import org.nl.wms.basedata.service.VehicleService; import org.nl.wms.basedata.service.dto.VehicleDto; import org.springframework.data.domain.Pageable; -import lombok.RequiredArgsConstructor; -import org.nl.modules.logging.annotation.Log; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import cn.dev33.satoken.annotation.SaCheckPermission; -import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import io.swagger.annotations.*; + import java.util.Map; -import lombok.extern.slf4j.Slf4j; /** -* @author lyd -* @date 2022-10-18 -**/ + * @author lyd + * @date 2022-10-18 + **/ @RestController @RequiredArgsConstructor -@Api(tags = "载具维护管理") +@Api(tags = "载具管理") @RequestMapping("/api/vehicle") @Slf4j public class VehicleController { @@ -31,27 +31,27 @@ public class VehicleController { private final VehicleService vehicleService; @GetMapping - @Log("查询载具维护") - @ApiOperation("查询载具维护") + @Log("查询载具") + @ApiOperation("查询载具") //@SaCheckPermission("@el.check('vehicle:list')") - public ResponseEntity query(@RequestParam Map whereJson, Pageable page){ - return new ResponseEntity<>(vehicleService.queryAll(whereJson,page),HttpStatus.OK); + public ResponseEntity query(@RequestParam Map param, Pageable page) { + return new ResponseEntity<>(vehicleService.queryAll(param, page), HttpStatus.OK); } @PostMapping - @Log("新增载具维护") - @ApiOperation("新增载具维护") + @Log("新增载具") + @ApiOperation("新增载具") //@SaCheckPermission("@el.check('vehicle:add')") - public ResponseEntity create(@Validated @RequestBody JSONObject WhereJson){ - - return new ResponseEntity<>(vehicleService.create(WhereJson),HttpStatus.CREATED); + public ResponseEntity create(@RequestBody JSONObject param) { + vehicleService.create(param); + return new ResponseEntity<>(HttpStatus.CREATED); } @PutMapping @Log("修改载具维护") @ApiOperation("修改载具维护") //@SaCheckPermission("@el.check('vehicle:edit')") - public ResponseEntity update(@Validated @RequestBody VehicleDto dto){ + public ResponseEntity update(@RequestBody VehicleDto dto) { vehicleService.update(dto); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } @@ -70,6 +70,6 @@ public class VehicleController { @ApiOperation("获取起始载具号") public ResponseEntity getVehicle(@PathVariable String code) { JSONObject json = vehicleService.getVehicle(code); - return new ResponseEntity<>(json,HttpStatus.OK); + return new ResponseEntity<>(json, HttpStatus.OK); } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/VehicleService.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/VehicleService.java index 0840abd..b295e0d 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/VehicleService.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/VehicleService.java @@ -5,10 +5,9 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.nl.wms.basedata.service.dto.VehicleDto; import org.springframework.data.domain.Pageable; -import java.util.Map; + import java.util.List; -import java.io.IOException; -import javax.servlet.http.HttpServletResponse; +import java.util.Map; /** * @description 服务接口 @@ -19,11 +18,11 @@ public interface VehicleService { /** * 查询数据分页 - * @param whereJson 条件 + * @param param 条件 * @param page 分页参数 * @return Map */ - Map queryAll(Map whereJson, Pageable page); + Map queryAll(Map param, Pageable page); /** * 查询所有数据不分页 @@ -49,9 +48,9 @@ public interface VehicleService { /** * 创建 - * @param WhereJson / + * @param param / */ - JSONArray create(JSONObject WhereJson); + void create(JSONObject param); /** * 编辑 diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/dto/MaterialbaseDto.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/dto/MaterialbaseDto.java index 379afec..caa2692 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/dto/MaterialbaseDto.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/dto/MaterialbaseDto.java @@ -21,56 +21,21 @@ public class MaterialbaseDto implements Serializable { @JsonSerialize(using = ToStringSerializer.class) private Long material_id; - /** - * 物料编码 - */ private String material_code; - /** - * 物料名称 - */ - private String material_name; + private Integer standing_time; - private String material_spec; + private Integer threshold_time; - private String material_model; + private Integer product_code; - private String english_name; + private Integer a; - private long base_unit_id; + private Integer b; - private long assist_unit_id; - private String base_unit_name; + private Integer h; - private String approve_fileno; - - private String print_no; - - /** - * 物料分类 - */ - private Long material_type_id; - - private Long len_unit_id; - - private BigDecimal length; - - private BigDecimal width; - - private BigDecimal height; - - /** - * 计量单位 - */ - private Long weight_unit_id; - - private BigDecimal gross_weight; - - private BigDecimal net_weight; - - private Long cubage_unit_id; - - private BigDecimal cubage; + private Integer w; private Long create_id; @@ -84,26 +49,10 @@ public class MaterialbaseDto implements Serializable { private String update_time; - private String is_used_time; - /** * 是否启用 */ private String is_used; - private String is_delete; - - private String ext_id; - - private String material_height_type; - - private String AlongSide; // A长边 - private String BshortSide; // B短边 - private String Htrapezoidal; // H梯形高 - private String Wthickness; // W厚度 - - private Long ass_unit_id; - - - private Integer standing_time; + private Double weight; } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/dto/VehicleDto.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/dto/VehicleDto.java index c8fe954..82369de 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/dto/VehicleDto.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/dto/VehicleDto.java @@ -1,75 +1,70 @@ package org.nl.wms.basedata.service.dto; import lombok.Data; - import java.math.BigDecimal; + +import java.math.BigDecimal; import java.io.Serializable; - import com.fasterxml.jackson.databind.annotation.JsonSerialize; - import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; /** -* @description / -* @author lyd -* @date 2022-10-18 -**/ + * @author lyd + * @description / + * @date 2022-10-18 + **/ @Data public class VehicleDto implements Serializable { /** 载具标识 */ - /** 防止精度丢失 */ - @JsonSerialize(using= ToStringSerializer.class) + /** + * 防止精度丢失 + */ + @JsonSerialize(using = ToStringSerializer.class) private Long vehicle_id; - /** 载具编码 */ + /** + * 载具编码 + */ private String vehicle_code; - /** 载具名称 */ - private String vehicle_name; - - /** 一维码 */ - private String one_code; - - /** 二维码 */ - private String two_code; - - /** RFID编码 */ - private String rfid_code; - - /** 载具类型 */ + /** + * 载具类型 + */ private String vehicle_type; - /** 载具宽度 */ - private BigDecimal vehicle_width; + /** + * 载具状态 + */ + private String vehicle_status; - /** 载具长度 */ - private BigDecimal vehicle_long; - - /** 载具高度 */ - private BigDecimal vehicle_height; - - /** 载具超仓位类型 */ - private String overstruct_type; - - /** 占仓位数 */ - private BigDecimal occupystruct_qty; - - /** 外部标识 */ - private String ext_id; - - /** 创建人 */ + /** + * 创建人 + */ private Long create_id; - /** 创建人 */ + /** + * 创建人 + */ private String create_name; - /** 创建时间 */ + /** + * 创建时间 + */ 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/basedata/service/impl/MaterialbaseServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/impl/MaterialbaseServiceImpl.java index 8b69b3f..546303c 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/impl/MaterialbaseServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/impl/MaterialbaseServiceImpl.java @@ -13,6 +13,7 @@ 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.CommonUtils; import org.nl.modules.common.utils.SecurityUtils; import org.nl.modules.wql.WQL; import org.nl.modules.wql.core.bean.WQLObject; @@ -44,59 +45,13 @@ public class MaterialbaseServiceImpl implements MaterialbaseService { @Override public Map queryAll(Map whereJson, Pageable page) { - String search = MapUtil.getStr(whereJson, "search"); - //物料限制的时候使用,初始化页面 - String class_idStr = MapUtil.getStr(whereJson, "class_idStr"); - String material_type_id = MapUtil.getStr(whereJson, "material_type_id"); - String class_code = MapUtil.getStr(whereJson, "class_code"); - String ids = MapUtil.getStr(whereJson, "ids"); - + String name = MapUtil.getStr(whereJson, "name"); HashMap map = new HashMap<>(); map.put("flag", "1"); + map.put("search", name); - if (!StrUtil.isEmpty(search)) { - //处理转义字符 - if (search.contains("\\")) { - search = search.replace("\\", "\\\\\\"); - } - map.put("search", "%" + search + "%"); - } - - //处理物料当前节点的所有子节点 - if (!StrUtil.isEmpty(material_type_id)) { - map.put("material_type_id", material_type_id); - String classIds = classstandardService.getChildIdStr(material_type_id); - map.put("classIds", classIds); - } else if (ObjectUtil.isNotEmpty(class_idStr)) { - String classIds = classstandardService.getAllChildIdStr(class_idStr); - map.put("classIds", classIds); - } - - if (!StrUtil.isEmpty(class_code)) { - map.put("class_code", class_code + "%"); - } - - StringBuffer where = new StringBuffer(); - if (StrUtil.isNotEmpty(ids)) { - ids = ids.replaceAll("\'", ""); - String[] strs = ids.split(","); - where.append("("); - for (int i = 0; i < strs.length; ) { - where.append("class.class_code like '" + strs[i] + "%'"); - i++; - if (i < strs.length) { - where.append(" or "); - } - } - where.append(")"); - map.put("idssql", where.toString()); - } else { - map.put("idssql", "1=1"); - } - - JSONObject jo = WQL.getWO("QMD_ME_MATERIAL").addParamMap(map).pageQuery(WqlUtil.getHttpContext(page), "material_id"); - return jo; + return WQL.getWO("QMD_ME_MATERIAL").addParamMap(map).pageQuery(WqlUtil.getHttpContext(page), "create_time DESC"); } @Override @@ -134,20 +89,55 @@ public class MaterialbaseServiceImpl implements MaterialbaseService { @Override @Transactional(rollbackFor = Exception.class) public void create(MaterialbaseDto dto) { + WQLObject wo = WQLObject.getWQLObject("md_me_materialbase"); + String material_code = dto.getMaterial_code(); + JSONObject material = wo.query("material_code = '" + material_code + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(material)) { + throw new BadRequestException("物料编码 [" + material_code + "] 已存在!"); + } + Long currentUserId = SecurityUtils.getCurrentUserId(); String nickName = SecurityUtils.getCurrentNickName(); String now = DateUtil.now(); - dto.setMaterial_id(IdUtil.getSnowflake(1, 1).nextId()); + long id = IdUtil.getSnowflake(1, 1).nextId(); + dto.setMaterial_id(id); dto.setCreate_id(currentUserId); dto.setCreate_name(nickName); dto.setUpdate_optid(currentUserId); dto.setUpdate_optname(nickName); dto.setUpdate_time(now); dto.setCreate_time(now); - WQLObject wo = WQLObject.getWQLObject("md_me_materialbase"); JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); wo.insert(json); + + // 解析物料编码 ZLMCZ1001C122211GM001BD20-8 + JSONObject material_detail = new JSONObject(); + material_detail.put("material_id", id); + material_detail.put("material_code", material_code); + WQLObject dict_detail_table = WQLObject.getWQLObject("sys_dict_detail"); + String furnace_code = material_code.substring(0, 2); + JSONObject furnace_name = dict_detail_table.query("name = 'furnace' AND value = '" + furnace_code + "'").uniqueResult(0); + if (ObjectUtil.isEmpty(furnace_name)) { + throw new BadRequestException("物料编码解析错误:未知炉型!"); + } + material_detail.put("product_name", furnace_name.getString("label") + "镁碳砖"); + material_detail.put("order_number", material_code.substring(11, 16)); + material_detail.put("customer_name", material_code.substring(16, 21)); + String product_grade_code = material_code.substring(21, 23); + JSONObject product_grade = dict_detail_table.query("name = 'product_grade' AND value = '" + product_grade_code + "'").uniqueResult(0); + if (ObjectUtil.isEmpty(product_grade)) { + throw new BadRequestException("物料编码解析错误:未知牌号!"); + } + material_detail.put("product_grade", product_grade.getString("label")); + material_detail.put("brick_type", material_code.substring(23)); + material_detail.put("create_id", currentUserId); + material_detail.put("create_name", nickName); + material_detail.put("create_time", now); + material_detail.put("update_optid", currentUserId); + material_detail.put("update_optname", nickName); + material_detail.put("update_time", now); + WQLObject.getWQLObject("md_me_material_detail").insert(material_detail); } @Override @@ -173,38 +163,13 @@ public class MaterialbaseServiceImpl implements MaterialbaseService { @Override @Transactional(rollbackFor = Exception.class) public void deleteAll(Long[] ids) { - Long currentUserId = SecurityUtils.getCurrentUserId(); - String nickName = SecurityUtils.getCurrentNickName(); - String now = DateUtil.now(); - - WQLObject wo = WQLObject.getWQLObject("md_me_materialbase"); - for (Long material_id : ids) { - JSONObject param = new JSONObject(); - param.put("material_id", String.valueOf(material_id)); - param.put("is_delete", "1"); - param.put("update_optid", currentUserId); - param.put("update_optname", nickName); - param.put("update_time", now); - wo.update(param); - } + String ids_str = CommonUtils.idsArrayToInStr(ids); + WQLObject.getWQLObject("md_me_materialbase").delete("material_id IN " + ids_str); + WQLObject.getWQLObject("md_me_material_detail").delete("material_id IN " + ids_str); } @Override public boolean isAlongMaterType(String materOpt_code, String material_id, String material_type_id) { - if (ObjectUtil.isNotEmpty(material_id)) { - Long long_mater = Long.parseLong(material_id); - material_type_id = this.findById(long_mater).getMaterial_type_id() + ""; - } - if (ObjectUtil.isEmpty(material_type_id)) { - throw new BadRequestException("物料类型不能为空!"); - } - String class_idStr = MaterOptTypeEnum.getObj(materOpt_code).getString("class_idStr"); - - Set set = classstandardService.getAllChildIdSet(class_idStr); - if (ObjectUtil.isNotEmpty(set)) { - return set.contains(material_type_id); - } - return false; } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/impl/VehicleServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/impl/VehicleServiceImpl.java index 8fdd0c7..3b32fa5 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/impl/VehicleServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/service/impl/VehicleServiceImpl.java @@ -2,13 +2,15 @@ package org.nl.wms.basedata.service.impl; -import cn.hutool.core.map.MapUtil; import com.alibaba.fastjson.JSON; import lombok.RequiredArgsConstructor; import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.CommonUtils; import org.nl.modules.system.service.impl.GenCodeServiceImpl; -import org.nl.modules.system.util.CodeUtil; import org.nl.modules.wql.WQL; +import org.nl.modules.wql.util.WqlUtil; +import org.nl.wms.basedata.eum.VehicleStatus; +import org.nl.wms.basedata.eum.VehicleType; import org.nl.wms.basedata.service.VehicleService; import org.nl.wms.basedata.service.dto.VehicleDto; import org.springframework.stereotype.Service; @@ -16,6 +18,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.data.domain.Pageable; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -25,37 +28,31 @@ import cn.hutool.core.util.IdUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.nl.modules.common.utils.SecurityUtils; -import org.nl.modules.wql.core.bean.ResultBean; import org.nl.modules.wql.core.bean.WQLObject; -import org.nl.modules.wql.util.WqlUtil; import lombok.extern.slf4j.Slf4j; import cn.hutool.core.util.ObjectUtil; /** -* @description 服务实现 -* @author lyd -* @date 2022-10-18 -**/ + * @author lyd + * @description 服务实现 + * @date 2022-10-18 + **/ @Service @RequiredArgsConstructor @Slf4j public class VehicleServiceImpl implements VehicleService { @Override - public Map queryAll(Map whereJson, Pageable page){ - String vehicle_code = MapUtil.getStr(whereJson, "vehicle_code"); - - JSONObject map = new JSONObject(); - map.put("flag", "1"); - map.put("vehicle_type", MapUtil.getStr(whereJson, "vehicle_type")); - if (ObjectUtil.isNotEmpty(vehicle_code)) map.put("vehicle_code","%"+vehicle_code+"%"); - - JSONObject json = WQL.getWO("QMD_PB_VEHICLE").addParamMap(map).pageQuery(WqlUtil.getHttpContext(page), "create_time DESC"); - return json; + public Map queryAll(Map param, Pageable page) { + return WQL + .getWO("QMD_PB_VEHICLE") + .addParam("flag", "1") + .addParamMap(param) + .pageQuery(WqlUtil.getHttpContext(page), "create_time DESC"); } @Override - public List queryAll(Map whereJson){ + public List queryAll(Map whereJson) { WQLObject wo = WQLObject.getWQLObject("md_pb_vehicle"); JSONArray arr = wo.query().getResultJSONArray(0); if (ObjectUtil.isNotEmpty(arr)) return arr.toJavaList(VehicleDto.class); @@ -66,63 +63,38 @@ public class VehicleServiceImpl implements VehicleService { public VehicleDto findById(Long vehicle_id) { WQLObject wo = WQLObject.getWQLObject("md_pb_vehicle"); JSONObject json = wo.query("vehicle_id = '" + vehicle_id + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(json)){ - return json.toJavaObject( VehicleDto.class); + if (ObjectUtil.isNotEmpty(json)) { + return json.toJavaObject(VehicleDto.class); } return null; } @Override - public VehicleDto findByCode(String code) { + public VehicleDto findByCode(String code) { WQLObject wo = WQLObject.getWQLObject("md_pb_vehicle"); - JSONObject json = wo.query("code ='" + code + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(json)){ - return json.toJavaObject( VehicleDto.class); + JSONObject json = wo.query("vehicle_code ='" + code + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(json)) { + return json.toJavaObject(VehicleDto.class); } return null; } @Override @Transactional(rollbackFor = Exception.class) - public JSONArray create(JSONObject WhereJson) { + public void create(JSONObject param) { + WQLObject vehicle_table = WQLObject.getWQLObject("md_pb_vehicle"); - WQLObject wo = WQLObject.getWQLObject("md_pb_vehicle"); - - Long currentUserId = SecurityUtils.getCurrentUserId(); - String nickName = SecurityUtils.getCurrentNickName(); - String now = DateUtil.now(); - - String vehicle_type = WhereJson.getString("vehicle_type"); - String code = ""; - switch (vehicle_type) { - case "01": - code = "1m3_ttp"; - break; - case "02": - code = "1m6_ttp"; - break; - case "03": - code = "1m9_ttp"; - break; + String vehicle_code = param.getString("vehicle_code"); + String vehicle_type = param.getString("vehicle_type"); + if (ObjectUtil.isNotEmpty(vehicle_table.query("vehicle_code = '" + vehicle_code + "' AND vehicle_type = '" + vehicle_type + "'").uniqueResult(0))) { + throw new BadRequestException(VehicleType.get(vehicle_type).label() + " [" + vehicle_code + "] 已存在!"); } - JSONArray resultCodeArr = new JSONArray(); - int num = WhereJson.getIntValue("num"); - for (int i = 0; i < num; i++) { - VehicleDto dto = new VehicleDto(); - dto.setVehicle_id(IdUtil.getSnowflake(1,1).nextId()); - dto.setVehicle_code(CodeUtil.getNewCode(code)); - dto.setVehicle_name(dto.getVehicle_code()); - dto.setVehicle_type(vehicle_type); - dto.setCreate_id(currentUserId); - dto.setCreate_name(nickName); - dto.setCreate_time(now); - - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - wo.insert(json); - resultCodeArr.add(dto.getVehicle_code()); - } - return resultCodeArr; + param.put("vehicle_id", IdUtil.getSnowflake().nextId()); + param.put("create_id", SecurityUtils.getCurrentUserId()); + param.put("create_name", SecurityUtils.getCurrentNickName()); + param.put("create_time", DateUtil.now()); + vehicle_table.insert(param); } @Override @@ -131,6 +103,8 @@ public class VehicleServiceImpl implements VehicleService { VehicleDto entity = this.findById(dto.getVehicle_id()); if (entity == null) throw new BadRequestException("被删除或无权限,操作失败!"); + // todo 更新前检查载具是否真的有货 + Long currentUserId = SecurityUtils.getCurrentUserId(); String nickName = SecurityUtils.getCurrentNickName(); @@ -147,20 +121,8 @@ public class VehicleServiceImpl implements VehicleService { @Override @Transactional(rollbackFor = Exception.class) public void deleteAll(Long[] ids) { - Long currentUserId = SecurityUtils.getCurrentUserId(); - String nickName = SecurityUtils.getCurrentNickName(); - String now = DateUtil.now(); - - WQLObject wo = WQLObject.getWQLObject("md_pb_vehicle"); - for (Long vehicle_id: ids) { - JSONObject param = new JSONObject(); - param.put("vehicle_id", String.valueOf(vehicle_id)); - param.put("is_delete", "1"); - param.put("update_optid", currentUserId); - param.put("update_optname", nickName); - param.put("update_time", now); - wo.update(param); - } + String ids_str = CommonUtils.idsArrayToInStr(ids); + WQLObject.getWQLObject("md_pb_vehicle").delete("vehicle_id IN " + ids_str); } @Override diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/wql/QMD_ME_MATERIAL.wql b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/wql/QMD_ME_MATERIAL.wql index abae5b6..34abc0f 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/wql/QMD_ME_MATERIAL.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/wql/QMD_ME_MATERIAL.wql @@ -44,32 +44,18 @@ IF 输入.flag = "1" PAGEQUERY SELECT - mb.*, - class.class_code, - class.class_name, - unit_name, - '50' as standard_weight, - unit_name as base_unit_id_name + mb.* FROM md_me_materialbase mb - LEFT JOIN MD_PB_ClassStandard class ON class.class_id = mb.material_type_id - LEFT JOIN md_pb_measureunit unit ON unit.measure_unit_id = mb.base_unit_id WHERE - mb.is_delete = '0' - and 输入.idssql - OPTION 输入.search <> "" - ( - mb.material_code like 输入.search - OR - mb.material_name like 输入.search - ) - ENDOPTION - OPTION 输入.class_code <> "" - class.class_code like 输入.class_code - ENDOPTION - OPTION 输入.classIds <> "" - class.class_id in 输入.classIds - ENDOPTION + 1 = 1 + OPTION 输入.search <> "" + ( + mb.material_code like '%' 输入.search '%' + OR + mb.material_name like '%' 输入.search '%' + ) + ENDOPTION ENDSELECT ENDPAGEQUERY ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/wql/QMD_PB_VEHICLE.wql b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/wql/QMD_PB_VEHICLE.wql index 214993c..bd8f199 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/basedata/wql/QMD_PB_VEHICLE.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/basedata/wql/QMD_PB_VEHICLE.wql @@ -1,5 +1,5 @@ [交易说明] - 交易名: 载具分页查询 + 交易名: 载具 所属模块: 功能简述: 版权所有: @@ -13,9 +13,10 @@ ################################################# ## 表字段对应输入参数 ################################################# - 输入.flag TYPEAS s_string - 输入.vehicle_type TYPEAS s_string - 输入.vehicle_code TYPEAS s_string + 输入.flag TYPEAS s_string + 输入.vehicle_code TYPEAS s_string + 输入.vehicle_type TYPEAS s_string + 输入.vehicle_status TYPEAS s_string [临时表] --这边列出来的临时表就会在运行期动态创建 @@ -46,19 +47,16 @@ FROM md_pb_vehicle WHERE - 1=1 - + 1 = 1 OPTION 输入.vehicle_code <> "" - vehicle_code like 输入.vehicle_code + vehicle_code LIKE '%' 输入.vehicle_code '%' ENDOPTION - OPTION 输入.vehicle_type <> "" - vehicle_type = 输入.vehicle_type + vehicle_type = 输入.vehicle_type ENDOPTION - + OPTION 输入.vehicle_status <> "" + vehicle_status = 输入.vehicle_status + ENOPTION ENDSELECT ENDPAGEQUERY ENDIF - - - diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/cockpit/service/dto/DeviceDetailDto.java b/lms/nladmin-system/src/main/java/org/nl/wms/cockpit/service/dto/DeviceDetailDto.java index a9f1720..77ec134 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/cockpit/service/dto/DeviceDetailDto.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/cockpit/service/dto/DeviceDetailDto.java @@ -21,102 +21,102 @@ import java.util.List; @Builder @NoArgsConstructor @AllArgsConstructor -public class DeviceDetailDto extends DeviceStatusDto{ - /** - * 混碾机,压力机,窑外层弹出框已生产数量 - */ - @ApiModelProperty(value = "/**已生产数量*/") - private String real_qty; - /** - * 载具 - */ - @ApiModelProperty(value = "/**载具*/") - private String vehicle_code; - /** - * 入库时间 - */ - @ApiModelProperty(value = "/**入库时间*/") - private String instorage_time; - /** - * 搬运托盘数 - */ - @ApiModelProperty(value = "/**搬运托盘数*/") - private String pallet_qty; - /** - * 搬入准备车道 - */ - @ApiModelProperty(value = "/**搬入准备车道*/") - private String ready_lane; - /** - * 窑1窑车数 - */ - @ApiModelProperty(value = "/**窑1窑车数*/") - private String first_kiln_qty; - /** - * 窑2窑车数 - */ - @ApiModelProperty(value = "/**窑2窑车数*/") - private String second_kiln_qty; - /** - * 搬入1号窑 - */ - @ApiModelProperty(value = "/**搬入1号窑*/") - private String move_first_kiln; - /** - * 搬入2号窑 - */ - @ApiModelProperty(value = "/**搬入2号窑*/") - private String move_second_kiln; - /** - * 当前窑车数 - */ - @ApiModelProperty(value = "/**当前窑车数*/") - private String present_kiln_qty; - /** - * 容量 - */ - @ApiModelProperty(value = "/**容量*/") - private String volume; - /** - * 故障信息 - */ - @ApiModelProperty(value = "/**故障信息*/") - private String faulty_info; - /** - * 完成托盘数 - */ - @ApiModelProperty(value = "/**完成托盘数*/") - private String finish_pallet_qty; - /** - * 机械手完成托盘数 - */ - @ApiModelProperty(value = "/**机械手完成托盘数*/") - private String mechanical_pallet_qty; - /** - * 机械手完成数量 - */ - @ApiModelProperty(value = "/**机械手完成数量*/") - private String mechanical_arm_qty; - /** - * 包装机完成数量 - */ - @ApiModelProperty(value = "/**包装机完成数量*/") - private String pack_qty; - /** - * 完成跺数 - */ - @ApiModelProperty(value = "/**完成跺数*/") - private String finish_pile_qty; - /** - * 混碾机,破碎机本日生产信息 - */ - List mixingList; - /** - * 压力机,机械手本日生产信息 - */ - List crushingList; - /** - * 窑本日生产信息 - */ - List mKilnList; +public class DeviceDetailDto extends DeviceStatusDto { + /** + * 混碾机,压力机,窑外层弹出框已生产数量 + */ + @ApiModelProperty(value = "/**已生产数量*/") + private String real_qty; + /** + * 载具 + */ + @ApiModelProperty(value = "/**载具*/") + private String vehicle_code; + /** + * 入库时间 + */ + @ApiModelProperty(value = "/**入库时间*/") + private String instorage_time; + /** + * 搬运托盘数 + */ + @ApiModelProperty(value = "/**搬运托盘数*/") + private String pallet_qty; + /** + * 搬入准备车道 + */ + @ApiModelProperty(value = "/**搬入准备车道*/") + private String ready_lane; + /** + * 窑1窑车数 + */ + @ApiModelProperty(value = "/**窑1窑车数*/") + private String first_kiln_qty; + /** + * 窑2窑车数 + */ + @ApiModelProperty(value = "/**窑2窑车数*/") + private String second_kiln_qty; + /** + * 搬入1号窑 + */ + @ApiModelProperty(value = "/**搬入1号窑*/") + private String move_first_kiln; + /** + * 搬入2号窑 + */ + @ApiModelProperty(value = "/**搬入2号窑*/") + private String move_second_kiln; + /** + * 当前窑车数 + */ + @ApiModelProperty(value = "/**当前窑车数*/") + private String present_kiln_qty; + /** + * 容量 + */ + @ApiModelProperty(value = "/**容量*/") + private String volume; + /** + * 故障信息 + */ + @ApiModelProperty(value = "/**故障信息*/") + private String faulty_info; + /** + * 完成托盘数 + */ + @ApiModelProperty(value = "/**完成托盘数*/") + private String finish_pallet_qty; + /** + * 机械手完成托盘数 + */ + @ApiModelProperty(value = "/**机械手完成托盘数*/") + private String mechanical_pallet_qty; + /** + * 机械手完成数量 + */ + @ApiModelProperty(value = "/**机械手完成数量*/") + private String mechanical_arm_qty; + /** + * 包装机完成数量 + */ + @ApiModelProperty(value = "/**包装机完成数量*/") + private String pack_qty; + /** + * 完成跺数 + */ + @ApiModelProperty(value = "/**完成跺数*/") + private String finish_pile_qty; + /** + * 混碾机,破碎机本日生产信息 + */ + List mixingList; + /** + * 压力机,机械手本日生产信息 + */ + List crushingList; + /** + * 窑本日生产信息 + */ + List mKilnList; } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/cockpit/service/dto/DeviceStatusDto.java b/lms/nladmin-system/src/main/java/org/nl/wms/cockpit/service/dto/DeviceStatusDto.java index 6e76042..1a1af3d 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/cockpit/service/dto/DeviceStatusDto.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/cockpit/service/dto/DeviceStatusDto.java @@ -18,57 +18,57 @@ import java.math.BigDecimal; @NoArgsConstructor @AllArgsConstructor public class DeviceStatusDto implements Serializable{ - /** - * 点位标识 - */ - @JsonSerialize(using = ToStringSerializer.class) - private Long point_id; - /** - * 点位编码 - */ - private String point_code; - /** - * 设备名称 - */ - private String point_name; - /** - * 设备状态枚举 - */ - private String point_status; - /** - * 设备状态:1未生产2已下发3生产中4暂停5完成 - */ - private String point_status_name; - /** - * 当前生产物料ID - */ - private Long material_id; - /** - * 当前生产名称 - */ - private String material_name; - /** - * 重量(如混料 24.00*0.89,0.89为重量) - */ - private BigDecimal ivt_weight; - /** - * 已工作时间 - */ - private String work_time; - /** - * 已生产数量 - */ - private BigDecimal ivt_qty; - /** - * 载具数量(当前窑车数) - */ - private Integer vehicle_qty; - /** - * 容量 - */ - private BigDecimal vehicle_max_qty; - /** - * 设备图片 - */ - private String device_url; + /** + * 点位标识 + */ + @JsonSerialize(using = ToStringSerializer.class) + private Long point_id; + /** + * 点位编码 + */ + private String point_code; + /** + * 设备名称 + */ + private String point_name; + /** + * 设备状态枚举 + */ + private String point_status; + /** + * 设备状态:1未生产2已下发3生产中4暂停5完成 + */ + private String point_status_name; + /** + * 当前生产物料ID + */ + private Long material_id; + /** + * 当前生产名称 + */ + private String material_name; + /** + * 重量(如混料 24.00*0.89,0.89为重量) + */ + private BigDecimal ivt_weight; + /** + * 已工作时间 + */ + private String work_time; + /** + * 已生产数量 + */ + private BigDecimal ivt_qty; + /** + * 载具数量(当前窑车数) + */ + private Integer vehicle_qty; + /** + * 容量 + */ + private BigDecimal vehicle_max_qty; + /** + * 设备图片 + */ + private String device_url; } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/rest/AcsToWmsController.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/rest/AcsToWmsController.java index 3c5796f..1aa6346 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/rest/AcsToWmsController.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/rest/AcsToWmsController.java @@ -86,7 +86,6 @@ public class AcsToWmsController { @PostMapping("/ispackage") @Log("ACS给WMS请求是否优先包装") @ApiOperation("ACS给WMS请求是否优先包装") - public ResponseEntity ispackage(@RequestBody Map whereJson) { return new ResponseEntity<>(acsToWmsService.ispackage(whereJson), HttpStatus.OK); } @@ -131,4 +130,20 @@ public class AcsToWmsController { public ResponseEntity againApply(@RequestBody String task_id) { return new ResponseEntity<>(acsToWmsService.againApply(task_id), HttpStatus.OK); } + + @PostMapping("/feedbackVehicleType") + @Log("更新覆膜机条码") + @ApiOperation("更新覆膜机条码") + @SaIgnore + public ResponseEntity feedbackVehicleType(@RequestBody JSONObject param) { + return new ResponseEntity<>(acsToWmsService.feedbackVehicleType(param), HttpStatus.OK); + } + + @PostMapping("/getVehicleInfo") + @Log("根据载具编码获取托盘信息") + @ApiOperation("根据载具编码获取托盘信息") + @SaIgnore + public ResponseEntity getVehicleInfo(@RequestBody JSONObject whereJson) { + return new ResponseEntity<>(acsToWmsService.getVehicleInfo(whereJson), HttpStatus.OK); + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/AcsToWmsService.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/AcsToWmsService.java index 2752bd7..c185173 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/AcsToWmsService.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/AcsToWmsService.java @@ -46,10 +46,10 @@ public interface AcsToWmsService { * ACS客户端--->LMS服务端 * 任务申请 * - * @param whereJson 条件 + * @param param 条件 * @return JSONObject */ - JSONObject apply(JSONObject whereJson) ; + JSONObject apply(JSONObject param) ; /** * ACS机械手给WMS发送任务 @@ -100,4 +100,8 @@ public interface AcsToWmsService { * @return Map */ Map getVehicleInfoByDeviceCode(Map jsonObject); + + JSONObject feedbackVehicleType(JSONObject param); + + JSONObject getVehicleInfo(JSONObject whereJson); } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/WmsToAcsService.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/WmsToAcsService.java index 7cd3033..7987298 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/WmsToAcsService.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/ext/acs/service/WmsToAcsService.java @@ -62,4 +62,8 @@ public interface WmsToAcsService { * @return */ JSONObject getTray(JSONArray whereJson); + + /** + * 获取点位 + */ } 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 f9ff307..0f82680 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 @@ -13,30 +13,25 @@ import org.nl.modules.common.exception.BadRequestException; import org.nl.modules.system.util.CodeUtil; import org.nl.modules.wql.core.bean.WQLObject; import org.nl.modules.wql.util.SpringContextHolder; +import org.nl.wms.basedata.eum.TrueOrFalse; +import org.nl.wms.basedata.eum.VehicleStatus; +import org.nl.wms.basedata.eum.VehicleType; import org.nl.wms.basedata.service.dto.VehicleDto; import org.nl.wms.ext.acs.service.AcsToWmsService; - import org.nl.wms.sch.manage.*; -import org.nl.wms.sch.service.TaskService; -import org.nl.wms.sch.tasks.callEmpty.FjCallEmptyVehicleTask; -import org.nl.wms.sch.tasks.callEmpty.HnCallEmptyVehicleTask; -import org.nl.wms.sch.tasks.callEmpty.YzjCallEmptyVehicleTask; -import org.nl.wms.sch.tasks.callMaterial.FjCallMaterialTask; -import org.nl.wms.sch.tasks.callMaterial.YzjCallMaterialTask; -import org.nl.wms.sch.tasks.sendEmpty.DpSendEmpVehicleTask; -import org.nl.wms.sch.tasks.sendEmpty.FjSendEmpVehicleTask; -import org.nl.wms.sch.tasks.sendEmpty.YzjSendEmpVehicleTask; -import org.nl.wms.sch.tasks.sendMaterial.FjSendMaterialTask; -import org.nl.wms.sch.tasks.sendMaterial.HnSendMaterialTask; -import org.nl.wms.sch.tasks.sendMaterial.SzSendMaterialTask; -import org.nl.wms.sch.tasks.sendMaterial.YzjSendMaterialTask; +import org.nl.wms.sch.task.call.empty.HLCallEmptyTask; +import org.nl.wms.sch.task.call.empty.YZCallEmptyTask; +import org.nl.wms.sch.task.call.material.SZCallMaterialTask; +import org.nl.wms.sch.task.send.material.HLSendMaterialTask; +import org.nl.wms.sch.task.send.material.SZSendMaterialTask; +import org.nl.wms.sch.task.send.material.YZSendMaterialTask; +import org.nl.wms.sch.task.util.TaskUtils; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -45,19 +40,28 @@ import java.util.concurrent.TimeUnit; @RequiredArgsConstructor @Slf4j public class AcsToWmsServiceImpl implements AcsToWmsService { - private final TaskService taskService; private final RedissonClient redissonClient; + private final HLCallEmptyTask hlCallEmptyTask; + + private final HLSendMaterialTask hlSendMaterialTask; + + private final YZCallEmptyTask yzCallEmptyTask; + + private final YZSendMaterialTask yzSendMaterialTask; + + private final SZSendMaterialTask szSendMaterialTask; + /** * task_id:任务标识 * task_code:任务编码 * task_status:1:执行中,2:完成 ,3:acs取消 * * @param string 条件 - * @returnzss + * @return zss */ - + @Transactional(rollbackFor = Exception.class) @Override public Map receiveTaskStatusAcs(String string) { JSONArray array = JSONArray.parseArray(string); @@ -65,10 +69,13 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { JSONArray errArr = new JSONArray(); for (int i = 0; i < array.size(); i++) { JSONObject row = array.getJSONObject(i); - String task_id = row.getString("ext_task_uuid"); - if (ObjectUtil.isEmpty(task_id)) throw new BadRequestException("任务号不能为空"); - row.put("task_id", task_id); - JSONObject taskObj = WQLObject.getWQLObject("SCH_BASE_Task").query("task_id = '" + task_id + "'").uniqueResult(0); + String task_code = row.getString("task_code"); + if (ObjectUtil.isEmpty(task_code)) throw new BadRequestException("任务编码不能为空!"); + String task_id = row.getString("task_id"); + JSONObject taskObj = WQLObject.getWQLObject("SCH_BASE_Task").query("task_code = '" + task_code + "'").uniqueResult(0); + if (ObjectUtil.isEmpty(taskObj)) { + throw new BadRequestException("未找到任务编码为 [" + task_code + "] 的任务"); + } // 任务处理类 String processing_class = taskObj.getString("handle_class"); //1:执行中,2:完成 ,3:acs取消 @@ -76,40 +83,27 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { String message = ""; String status = ""; if ("1".equals(acs_task_status)) { - status = UpdateTaskStatusEnum.EXECUTION.getCode(); + status = TaskStatus.EXECUTING.value(); } if ("2".equals(acs_task_status)) { - status = UpdateTaskStatusEnum.FORCEFINISH.getCode(); + status = TaskStatus.FINISHED.value(); } if ("3".equals(acs_task_status)) { - status = UpdateTaskStatusEnum.CANCEL.getCode(); + status = TaskStatus.CANCELLED.value(); } // 任务处理类 try { Class clz = Class.forName(processing_class); - Object obj = clz.newInstance(); - // 调用每个任务类的updateTaskStatus()强制结束方法 - Method m = obj.getClass().getDeclaredMethod("updateTaskStatus", JSONObject.class, String.class); - m.invoke(obj, row, status); - } catch (InvocationTargetException e) { - e.printStackTrace(); - //空指针 - if (ObjectUtil.isNull(e.getTargetException().getMessage())) { - message = e.getTargetException().toString(); + AbstractAcsTask task_bean = (AbstractAcsTask) SpringContextHolder.getBean(clz); + if ("4".equals(acs_task_status)) { + task_bean.pickUpComplete(taskObj); } else { - message = e.getTargetException().getMessage(); + task_bean.updateTaskStatus(taskObj, status); } - log.info("任务状态更新失败:{}", message); - - JSONObject json = new JSONObject(); - json.put("task_id", task_id); - json.put("message", message); - errArr.add(json); - } catch (Exception e) { e.printStackTrace(); message = e.getMessage(); - log.info("任务状态更新失败:{}", message); + log.error("任务状态更新失败:{}", message); JSONObject json = new JSONObject(); json.put("task_id", task_id); @@ -120,7 +114,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { JSONObject result = new JSONObject(); result.put("status", HttpStatus.OK.value()); - result.put("message", "任务状态反馈成功!"); + result.put("message", "任务状态反馈成功!"); result.put("data", new JSONObject()); result.put("errArr", errArr); return result; @@ -131,7 +125,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { public String againApply(String task_id) { log.info("输入参数:" + task_id); WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); + JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "' and task_status <> '" + TaskStatus.FINISHED.value() + "'").uniqueResult(0); if (ObjectUtil.isEmpty(jsonTask)) throw new BadRequestException("任务已删除或已完成!"); String point_code = ""; @@ -182,166 +176,113 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { @Override @Transactional(rollbackFor = Exception.class) - public JSONObject apply(JSONObject whereJson) { - String type = whereJson.getString("type"); - String point_code = whereJson.getString("device_code"); - String vehicle_code = whereJson.getString("vehicle_code"); - String is_full = whereJson.getString("is_full"); - String weight = whereJson.getString("weight"); - String qty = whereJson.getString("qty"); - - RLock lock = redissonClient.getLock("acs_to_wms:" + type); - boolean tryLock = false; + public JSONObject apply(JSONObject param) { + String point_code = param.getString("device_code"); + if (StrUtil.isBlank(point_code)) { + throw new BadRequestException("点位不能为空!"); + } + RLock lock = redissonClient.getFairLock("acs_to_wms:" + point_code); + boolean try_lock = false; try { - tryLock = lock.tryLock(5, TimeUnit.SECONDS); - if (tryLock) { - if (ObjectUtil.isEmpty(type)) throw new BadRequestException("类型不能为空"); - if (ObjectUtil.isEmpty(point_code)) throw new BadRequestException("点位不能为空"); + try_lock = lock.tryLock(5, TimeUnit.SECONDS); + if (try_lock) { + JSONObject point = param.getJSONObject("point"); + if (ObjectUtil.isEmpty(point)) { + point = WQLObject + .getWQLObject("sch_base_point") + .query("is_used = '1' AND point_code = '" + point_code + "'") + .uniqueResult(0); + if (ObjectUtil.isEmpty(point)) { + throw new BadRequestException("[" + point_code + "] 已删除或未启用!"); + } + } + TaskUtils.isLocked(point); - /** - * 类型映射 - * 1: 送料入库 - * 2: 叫料出库 - * 3: 送空托盘 - * 4: 叫空托盘 - */ - String regionId = WQLObject - .getWQLObject("sch_base_point") - .query("point_code = '" + point_code + "'") - .uniqueResult(0) - .getString("region_id"); + String type = param.getString("type"); + if (StrUtil.isBlank(type)) { + throw new BadRequestException("任务类型不能为空!"); + } - RegionEnum regionEnum = RegionEnum.get(regionId); + Region region = Region.get(point.getString("region_code")); - // 参数统一获取 - JSONObject param = new JSONObject(); - param.put("vehicle_code", vehicle_code); - param.put("is_full", is_full); - param.put("weight", weight); - param.put("qty", qty); - - /* - * 根据type判断是什么业务类型: - * 1.混碾机送料入库-困料货架 - * 2.混碾机呼叫空托盘 - * 3.压制机上料位叫料出库 - * 4.压制机上料位送空盅 - * 5.压制机满料入库 - * 6.压制机呼叫空钢托盘 - * 8.烧制送料入库 - * 9.分拣叫料出库 - * 10.分拣送空钢托盘 - * 11.分拣送料入库 - * 12.分拣呼叫木托盘 - * 13.叠盘区送空钢托盘 - */ + JSONObject method_param = new JSONObject(); + method_param.put("point", point); + method_param.put("create_mode", CreateMode.ACSSQ.value()); + String request_param = param.getString("request_param"); + if (StrUtil.isBlank(request_param)) { + request_param = param.toJSONString(); + } + method_param.put("request_param", request_param); + method_param.put("create_id", ACSSystem.id); + method_param.put("create_name", ACSSystem.nick_name); switch (type) { case "1": - switch (regionEnum) { - case HNQ: - // 1.混碾机送料入库:混碾机物料送到困料货架 - // 创建任务 - param.put("point_code1", point_code); // 起点 - SpringContextHolder.getBean(HnSendMaterialTask.class).createTask(param); + // 送料 + String vehicle_code = param.getString("vehicle_code"); + if (StrUtil.isBlank(vehicle_code) || "0".equals(vehicle_code)) { + throw new BadRequestException("载具号不能为空!"); + } + method_param.put("vehicle_code", TaskUtils.formatVehicleCode(vehicle_code)); + + switch (region) { + case HL: + hlSendMaterialTask.createTask(method_param); break; - case YZQ: - // 5.压制机满料入库 - param.put("point_code1", point_code); // 起点 - param.put("group_id", whereJson.getString("group_id")); // 组盘标识 - 机械手过来的 - // 创建任务 - SpringContextHolder.getBean(YzjSendMaterialTask.class).createTask(param); + case YZ: + method_param.put("workorder", param.getJSONObject("workorder")); + method_param.put("vd", param.getJSONObject("vd")); + yzSendMaterialTask.createTask(method_param); break; - case YQ: - // 8.烧制送料入库 - param.put("point_code1", point_code); // 起点 - SpringContextHolder.getBean(SzSendMaterialTask.class).createTask(param); - break; - case ZDCDX: - // 11.分拣送料入库 - param.put("point_code1", point_code); // 起点 - param.put("group_id", whereJson.getString("group_id")); // 组盘标识 - 机械手过来的 - SpringContextHolder.getBean(FjSendMaterialTask.class).createTask(param); + case SZ: + szSendMaterialTask.createTask(method_param); break; default: - throw new BadRequestException("ACS任务类型错误"); + throw new BadRequestException("[" + region.label() + "] 不存在送料任务!"); } break; case "2": - switch (regionEnum) { - case YZQ: - // 3.压制机叫料任务 - param.put("point_code2", point_code); // 终点 - // 创建任务 - SpringContextHolder.getBean(YzjCallMaterialTask.class).createTask(param); - break; - case ZDCDX: - // 9.分拣叫料出库 - param.put("point_code2", point_code); // 终点 - SpringContextHolder.getBean(FjCallMaterialTask.class).createTask(param); + // 叫料 + switch (region) { + case FJ: break; default: - throw new BadRequestException("ACS任务类型错误"); + throw new BadRequestException("[" + region.label() + "] 不存在叫料任务!"); } break; case "3": - switch (regionEnum) { - case YZQ: - // 4.压制机送空盅 - param.put("point_code1", point_code); // 起点 - // 创建任务 - SpringContextHolder.getBean(YzjSendEmpVehicleTask.class).createTask(param); - break; - case ZDCDX: - // 10.分拣送钢托盘 - param.put("point_code1", point_code); // 起点 - SpringContextHolder.getBean(FjSendEmpVehicleTask.class).createTask(param); - break; - case KGTDPQ: - // 13.叠盘区送空钢托盘 - param.put("point_code1", point_code); // 起点 - SpringContextHolder.getBean(DpSendEmpVehicleTask.class).createTask(param); - break; - default: - throw new BadRequestException("ACS任务类型错误"); - } + // 送空 break; case "4": - switch (regionEnum) { - case HNQ: - // 2.混碾机呼叫空托盘 - param.put("point_code2", point_code); // 终点 - // 创建任务 - SpringContextHolder.getBean(HnCallEmptyVehicleTask.class).createTask(param); + // 叫空 + switch (region) { + case HL: + hlCallEmptyTask.createTask(method_param); break; - case YZQ: - // 6.压制机呼叫空托盘 - param.put("point_code2", point_code); // 终点 - // 创建任务 - SpringContextHolder.getBean(YzjCallEmptyVehicleTask.class).createTask(param); + case YZ: + yzCallEmptyTask.createTask(method_param); break; - case ZDCDX: - // 12.分拣呼叫木托盘 - param.put("point_code2", point_code); // 起点 - SpringContextHolder.getBean(FjCallEmptyVehicleTask.class).createTask(param); + case GTK: break; default: - throw new BadRequestException("ACS任务类型错误"); + throw new BadRequestException("[" + region.label() + "] 不存在叫空任务!"); } break; default: - throw new BadRequestException("ACS任务类型错误"); + throw new BadRequestException("未知任务类型!"); } - - } - } catch (Exception e) { - e.printStackTrace(); + } catch (InterruptedException e) { + log.error("lock fail!", e); } finally { - if (tryLock) { + if (try_lock) { lock.unlock(); } } - return null; + + JSONObject result = new JSONObject(); + result.put("message", "申请任务成功!"); + result.put("status", HttpStatus.OK.value()); + return result; } /** @@ -350,97 +291,135 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { * * @param jsonObject */ + @Transactional(rollbackFor = Exception.class) @Override public void manipulatorApply(JSONObject jsonObject) { - WQLObject groupTab = WQLObject.getWQLObject("st_buss_vehiclegroup"); - //组盘 - JSONObject produceInfoByCode = new JSONObject(); - String device_code = jsonObject.getString("device_code"); // 对接位 - // vehicle_code 载具编码 - String vehicle_code = String.format("%04d", jsonObject.getIntValue("vehicle_code")); - String qty = String.valueOf(jsonObject.get("qty")); - produceInfoByCode = this.getProduceInfoByCode(device_code); // 获取设备的 - String material_id = produceInfoByCode.getString("material_id"); - String cust_id = produceInfoByCode.getString("cust_id"); - String producetask_id = produceInfoByCode.getString("workorder_id"); - // 物料 - JSONObject materialObj = WQLObject - .getWQLObject("MD_ME_MaterialBase") - .query("material_id = '" + material_id + "'") + String point_code = jsonObject.getString("device_code"); // 对接位 + if (StrUtil.isBlank(point_code)) { + throw new BadRequestException("点位不能为空!"); + } + String vehicle_code = jsonObject.getString("vehicle_code"); + vehicle_code = TaskUtils.formatVehicleCode(vehicle_code); + if ("0000".equals(vehicle_code)) { + throw new BadRequestException("载具编码不能为空!"); + } + String qty = jsonObject.getString("qty"); + if (StrUtil.isBlank(qty)) { + throw new BadRequestException("数量不能为空!"); + } + String weight = jsonObject.getString("weight"); + if (StrUtil.isBlank(weight)) { + throw new BadRequestException("重量不能为空!"); + } + String is_full = jsonObject.getString("is_full"); + if (StrUtil.isBlank(is_full)) { + throw new BadRequestException("是否满拖不能为空!"); + } + + JSONObject point = WQLObject + .getWQLObject("sch_base_point") + .query("is_used = '1' AND point_code = '" + point_code + "'") .uniqueResult(0); + if (ObjectUtil.isEmpty(point)) { + throw new BadRequestException("[" + point_code + "] 已删除或未启用!"); + } + TaskUtils.isLocked(point); - groupTab.delete("vehicle_code = '" + vehicle_code + "'"); + JSONObject work_order = TaskUtils.hasWorkOrder(point); + + String vehicle_type = null; + if (work_order.getString("device_code").startsWith("FJ")) { + vehicle_type = work_order.getString("vehicle_type"); + } else if (work_order.getString("device_code").startsWith("YZ")) { + vehicle_type = VehicleType.STEEL_TRAY.value(); + } else if (work_order.getString("device_code").startsWith("HL")) { + vehicle_type = VehicleType.CUP.value(); + } + + WQLObject vd_table = WQLObject.getWQLObject("st_ivt_vehicle_detail"); + JSONObject vd_update = new JSONObject(); + vd_update.put("is_delete", TrueOrFalse.TRUE.value()); + vd_table.update(vd_update, "vehicle_type = '" + vehicle_type + "' AND vehicle_code = '" + vehicle_code + "'"); + + JSONObject vd = new JSONObject(); + vd.put("vd_id", IdUtil.getSnowflake(1, 1).nextId()); + vd.put("vehicle_type", VehicleType.STEEL_TRAY.value()); + vd.put("vehicle_code", vehicle_code); + vd.put("material_id", work_order.getString("material_id")); + vd.put("qty", qty); + vd.put("weight", weight); + vd.put("is_full", is_full); + vd.put("workorder_id", work_order.getString("workorder_id")); + vd.put("point_code", point_code); + vd.put("tray_high", jsonObject.get("tray_high")); + vd.put("crib_category", jsonObject.get("crib_category")); + vd.put("palletX1_line", jsonObject.get("palletX1_line")); + vd.put("palletY1_row", jsonObject.get("palletY1_row")); + vd.put("palletA1_angle", jsonObject.get("palletA1_angle")); + vd.put("palletX2_line", jsonObject.get("palletX2_line")); + vd.put("palletY2_row", jsonObject.get("palletY2_row")); + vd.put("palletA2_angle", jsonObject.get("palletA2_angle")); + vd.put("palletX3_line", jsonObject.get("palletX3_line")); + vd.put("palletY3_row", jsonObject.get("palletY3_row")); + vd.put("palletA3_angle", jsonObject.get("palletA3_angle")); + vd.put("pressCribX1_line", jsonObject.get("pressCribX1_line")); + vd.put("pressCribY1_row", jsonObject.get("pressCribY1_row")); + vd.put("pressCribA1_angle", jsonObject.get("pressCribA1_angle")); + vd.put("pressCribX2_line", jsonObject.get("pressCribX2_line")); + vd.put("pressCribY2_row", jsonObject.get("pressCribY2_row")); + vd.put("pressCribA2_angle", jsonObject.get("pressCribA2_angle")); + vd.put("pressCribX3_line", jsonObject.get("pressCribX3_line")); + vd.put("pressCribY3_row", jsonObject.get("pressCribY3_row")); + vd.put("pressCribA3_angle", jsonObject.get("pressCribA3_angle")); + vd.put("Zoffset", jsonObject.get("Zoffset")); + vd.put("pallet_layerQty", jsonObject.get("pallet_layerQty")); + vd.put("pressCrib_layerQty", jsonObject.get("pressCrib_layerQty")); + vd.put("codeLayerX1_interval", jsonObject.get("codeLayerX1_interval")); + vd.put("codeLayerY1_interval", jsonObject.get("codeLayerY1_interval")); + vd.put("codeLayerX2_interval", jsonObject.get("codeLayerX2_interval")); + vd.put("codeLayerY2_interval", jsonObject.get("codeLayerY2_interval")); + vd.put("codeLayerX3_interval", jsonObject.get("codeLayerX3_interval")); + vd.put("codeLayerY3_interval", jsonObject.get("codeLayerY3_interval")); + vd.put("codeLayerX1_offset", jsonObject.get("codeLayerX1_offset")); + vd.put("codeLayerY1_offset", jsonObject.get("codeLayerY1_offset")); + vd.put("codeLayerX2_offset", jsonObject.get("codeLayerX2_offset")); + vd.put("codeLayerY2_offset", jsonObject.get("codeLayerY2_offset")); + vd.put("codeLayerX3_offset", jsonObject.get("codeLayerX3_offset")); + vd.put("codeLayerY3_offset", jsonObject.get("codeLayerY3_offset")); + vd.put("pressLayerX1_interval", jsonObject.get("pressLayerX1_interval")); + vd.put("pressLayerY1_interval", jsonObject.get("pressLayerY1_interval")); + vd.put("pressLayerX2_interval", jsonObject.get("pressLayerX2_interval")); + vd.put("pressLayerY2_interval", jsonObject.get("pressLayerY2_interval")); + vd.put("pressLayerX3_interval", jsonObject.get("pressLayerX3_interval")); + vd.put("pressLayerY3_interval", jsonObject.get("pressLayerY3_interval")); + vd.put("pressLayerX1_offset", jsonObject.get("pressLayerX1_offset")); + vd.put("pressLayerY1_offset", jsonObject.get("pressLayerY1_offset")); + vd.put("pressLayerX2_offset", jsonObject.get("pressLayerX2_offset")); + vd.put("pressLayerY2_offset", jsonObject.get("pressLayerY2_offset")); + vd.put("pressLayerX3_offset", jsonObject.get("pressLayerX3_offset")); + vd.put("pressLayerY3_offset", jsonObject.get("pressLayerY3_offset")); + vd.put("tool_coordinate", jsonObject.get("tool_coordinate")); + vd.put("create_id", ACSSystem.id); + vd.put("create_name", ACSSystem.nick_name); + vd.put("create_time", DateUtil.now()); + vd.put("is_delete", TrueOrFalse.FALSE.value()); + vd.put("is_fire", TrueOrFalse.FALSE.value()); + vd.put("is_in_kiln", TrueOrFalse.trueOrFalse(is_full) ? TrueOrFalse.TRUE.value() : TrueOrFalse.FALSE.value()); + vd_table.insert(vd); + + JSONObject vehicle_update = new JSONObject(); + vehicle_update.put("vehicle_status", VehicleStatus.NOT_EMPTY.value()); + WQLObject.getWQLObject("md_pb_vehicle").update(vehicle_update, "vehicle_type = '" + vehicle_type + "' AND vehicle_code = '" + vehicle_code + "'"); - JSONObject groupObj = new JSONObject(); - groupObj.put("group_id", IdUtil.getSnowflake(1, 1).nextId()); - groupObj.put("vehicle_code", vehicle_code); - groupObj.put("material_uuid", material_id); - groupObj.put("material_code", materialObj.getString("material_code")); - groupObj.put("material_name", materialObj.getString("material_name")); - groupObj.put("cust_id", cust_id); - groupObj.put("qty", qty); - groupObj.put("producetask_id", producetask_id); - groupObj.put("tray_qty", jsonObject.get("tray_qty")); - groupObj.put("crib_category", jsonObject.get("crib_category")); - groupObj.put("tray_high", jsonObject.get("tray_high")); - groupObj.put("palletX1_line", jsonObject.get("palletX1_line")); - groupObj.put("palletY1_row", jsonObject.get("palletY1_row")); - groupObj.put("palletA1_angle", jsonObject.get("palletA1_angle")); - groupObj.put("palletX2_line", jsonObject.get("palletX2_line")); - groupObj.put("palletY2_row", jsonObject.get("palletY2_row")); - groupObj.put("palletA2_angle", jsonObject.get("palletA2_angle")); - groupObj.put("palletX3_line", jsonObject.get("palletX3_line")); - groupObj.put("palletY3_row", jsonObject.get("palletY3_row")); - groupObj.put("pressCribX1_line", jsonObject.get("pressCribX1_line")); - groupObj.put("palletA3_angle", jsonObject.get("palletA3_angle")); - groupObj.put("pressCribY1_row", jsonObject.get("pressCribY1_row")); - groupObj.put("pressCribA1_angle", jsonObject.get("pressCribA1_angle")); - groupObj.put("pressCribX2_line", jsonObject.get("pressCribX2_line")); - groupObj.put("pressCribY2_row", jsonObject.get("pressCribY2_row")); - groupObj.put("pressCribA2_angle", jsonObject.get("pressCribA2_angle")); - groupObj.put("pressCribX3_line", jsonObject.get("pressCribX3_line")); - groupObj.put("pressCribY3_row", jsonObject.get("pressCribY3_row")); - groupObj.put("pressCribA3_angle", jsonObject.get("pressCribA3_angle")); - groupObj.put("Zoffset", jsonObject.get("Zoffset")); - groupObj.put("pallet_layerQty", jsonObject.get("pallet_layerQty")); - groupObj.put("pressCrib_layerQty", jsonObject.get("pressCrib_layerQty")); - groupObj.put("codeLayerX1_interval", jsonObject.get("codeLayerX1_interval")); - groupObj.put("codeLayerY1_interval", jsonObject.get("codeLayerY1_interval")); - groupObj.put("pressCrib_layerQty", jsonObject.get("pressCrib_layerQty")); - groupObj.put("codeLayerX2_interval", jsonObject.get("codeLayerX2_interval")); - groupObj.put("codeLayerY2_interval", jsonObject.get("codeLayerY2_interval")); - groupObj.put("codeLayerX3_interval", jsonObject.get("codeLayerX3_interval")); - groupObj.put("codeLayerY3_interval", jsonObject.get("codeLayerY3_interval")); - groupObj.put("codeLayerY1_offset", jsonObject.get("codeLayerY1_offset")); - groupObj.put("codeLayerX1_offset", jsonObject.get("codeLayerX1_offset")); - groupObj.put("codeLayerX3_interval", jsonObject.get("codeLayerX3_interval")); - groupObj.put("codeLayerX2_offset", jsonObject.get("codeLayerX2_offset")); - groupObj.put("codeLayerX3_offset", jsonObject.get("codeLayerX3_offset")); - groupObj.put("codeLayerY3_offset", jsonObject.get("codeLayerY3_offset")); - groupObj.put("pressLayerX1_interval", jsonObject.get("pressLayerX1_interval")); - groupObj.put("pressLayerY1_interval", jsonObject.get("pressLayerY1_interval")); - groupObj.put("pressLayerX2_interval", jsonObject.get("pressLayerX2_interval")); - groupObj.put("pressLayerY2_interval", jsonObject.get("pressLayerY2_interval")); - groupObj.put("pressLayerX3_interval", jsonObject.get("pressLayerX3_interval")); - groupObj.put("pressLayerY3_interval", jsonObject.get("pressLayerY3_interval")); - groupObj.put("pressLayerX1_offset", jsonObject.get("pressLayerX1_offset")); - groupObj.put("pressLayerY1_offset", jsonObject.get("pressLayerY1_offset")); - groupObj.put("pressLayerX2_offset", jsonObject.get("pressLayerX2_offset")); - groupObj.put("pressLayerY2_offset", jsonObject.get("pressLayerY2_offset")); - groupObj.put("pressLayerX3_offset", jsonObject.get("pressLayerX3_offset")); - groupObj.put("pressLayerY3_offset", jsonObject.get("pressLayerY3_offset")); - groupObj.put("one_cribTotal", jsonObject.get("one_cribTotal")); - groupObj.put("two_cribTotal", jsonObject.get("two_cribTotal")); - groupObj.put("one_qty", jsonObject.get("one_qty")); - groupObj.put("two_qty", jsonObject.get("two_qty")); - groupObj.put("tool_coordinate", jsonObject.get("tool_coordinate")); - groupObj.put("create_id", "22"); - groupObj.put("create_name", "ACS系统"); - groupObj.put("create_time", DateUtil.now()); - groupTab.insert(groupObj); // 入库 - jsonObject.put("type", "1"); - this.apply(jsonObject); + JSONObject param = new JSONObject(); + param.put("device_code", point.getString("point_code")); + param.put("point", point); + param.put("workorder", work_order); + param.put("vd", vd); + param.put("type", "1"); + param.put("request_param", jsonObject); + this.apply(param); } /** @@ -491,7 +470,6 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { String now = DateUtil.now(); dto.setVehicle_code(vehicle_code); dto.setCreate_id(currentUserId); - dto.setVehicle_name(vehicle_code); dto.setCreate_name(nickName); dto.setUpdate_optid(currentUserId); dto.setUpdate_optname(nickName); @@ -528,54 +506,55 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { @Override @Transactional(rollbackFor = Exception.class) public Map sureWorkOrder(Map jsonObject) { - // 工单编号、设备编号、物料编号、数量、类型 - String workorder_code = (String) jsonObject.get("workorder_code"); - String device_code = (String) jsonObject.get("device_code"); - String material_code = (String) jsonObject.get("material_code"); - String qty = String.valueOf(jsonObject.get("qty")); String type = (String) jsonObject.get("type"); if (StrUtil.isEmpty(type)) { throw new BadRequestException("类型不能为空!"); } - WQLObject taskTable = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - JSONObject orderObj = taskTable.query("workorder_code = '" + workorder_code + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(orderObj)) { - throw new BadRequestException("未找到工单号为'" + workorder_code + "'的工单信息!"); + String workorder_code = (String) jsonObject.get("workorder_code"); + if (StrUtil.isEmpty(type)) { + throw new BadRequestException("工单编码不能为空!"); } - JSONObject materialObj = WQLObject.getWQLObject("MD_ME_MaterialBase").query("material_code = '" + material_code + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(materialObj)) throw new BadRequestException("当前物料不存在!"); - //1为确认 - //2为生产中 - //3为完成 - if (StrUtil.equals(type, "1")) { - if (StrUtil.isEmpty(workorder_code)) { - throw new BadRequestException("工单号不能为空!"); + WQLObject workorder_table = WQLObject.getWQLObject("pdm_bd_workorder"); + JSONObject workorder = workorder_table + .query("workorder_code = '" + workorder_code + "'") + .uniqueResult(0); + + if ("1".equals(type)) { + // 排产确认 + if (workorder.getIntValue("order_status") < 3) { + workorder.put("order_status", WorkOrderEnum.ORDER_STATUS_PRODUCING.value()); + workorder.put("realproducestart_date", DateUtil.now()); + workorder_table.update(workorder); } - if (StrUtil.isEmpty(device_code)) { - throw new BadRequestException("设备点位不能为空!"); - } - if (StrUtil.isEmpty(material_code)) { - throw new BadRequestException("物料编码不能为空!"); + } else if ("2".equals(type)) { + // 工单完成 + String qty = (String) jsonObject.get("qty"); + if (StrUtil.isBlank(qty)) { + throw new BadRequestException("数量不能为空!"); } - if (!StrUtil.equals(materialObj.getString("material_id"), orderObj.getString("material_id"))) { - throw new BadRequestException("物料标识不一样!"); - } - orderObj.put("order_status", WorkOrderEnum.ORDER_STATUS_DELIVERED.getCode()); + if (workorder.getIntValue("order_status") < 5) { + workorder.put("order_status", WorkOrderEnum.ORDER_STATUS_FINISH.value()); + workorder.put("real_qty", qty); + String unqualified_qty = (String) jsonObject.get("unqualified_qty"); + if (StrUtil.isNotBlank(unqualified_qty) && !"0".equals(unqualified_qty)) { + workorder.put("unqualified_qty", unqualified_qty); + } + String qualified_qty = (String) jsonObject.get("qualified_qty"); + if (StrUtil.isNotBlank(qualified_qty) && !"0".equals(qualified_qty)) { + workorder.put("qualified_qty", qualified_qty); + } else { + workorder.put("qualified_qty", Integer.parseInt(qty) - workorder.getIntValue("unqualified_qty")); + } + workorder.put("realproduceend_date", DateUtil.now()); + workorder_table.update(workorder); + } } - if (StrUtil.equals("2", type)) { - orderObj.put("producetask_status", WorkOrderEnum.ORDER_STATUS_PRODUCING.getCode()); - } - if (StrUtil.equals("3", type)) { - orderObj.put("producetask_status", WorkOrderEnum.ORDER_STATUS_FINISH.getCode()); - orderObj.put("real_qty", qty); - } - taskTable.update(orderObj); + JSONObject result = new JSONObject(); result.put("status", HttpStatus.OK.value()); - result.put("message", "任务状态反馈成功!"); - result.put("data", new JSONObject()); + result.put("message", "反馈工单状态成功"); return result; } @@ -638,33 +617,45 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { */ @Override public Map getVehicleInfoByDeviceCode(Map jsonObject) { - JSONObject vehicleObj = new JSONObject(); - WQLObject groupTab = WQLObject.getWQLObject("st_buss_vehiclegroup"); - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - WQLObject materialTab = WQLObject.getWQLObject("MD_ME_MaterialBase"); - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); String point_code = (String) jsonObject.get("device_code"); - JSONObject point = pointTab.query("point_code = '" + point_code + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(point)) throw new BadRequestException("未找到点位编码为'" + point_code + "'的点位信息"); - String group_id = point.getString("group_id"); - JSONObject vehicleObj2 = groupTab.query("group_id = '" + group_id + "' AND is_delete='0'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(vehicleObj2)) vehicleObj = vehicleObj2; - // 获取工单 - String device_code = point.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("该设备当前未生产或者已删除"); - // 还需要返回砖型 - String material_id = workOrderObj.getString("material_id"); - JSONObject materialObj = materialTab.query("material_id = '" + material_id + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(materialObj)) throw new BadRequestException("物料不能为空"); - vehicleObj.put("AlongSide", materialObj.get("alongside")); - vehicleObj.put("BshortSide", materialObj.get("bshortside")); - vehicleObj.put("Htrapezoidal", materialObj.get("htrapezoidal")); - vehicleObj.put("Wthickness", materialObj.get("wthickness")); + if (StrUtil.isBlank(point_code)) { + throw new BadRequestException("点位不能为空!"); + } + JSONObject point = WQLObject + .getWQLObject("sch_base_point") + .query("is_used = '1' AND point_code = '" + point_code + "'") + .uniqueResult(0); + if (ObjectUtil.isEmpty(point)) { + throw new BadRequestException("[" + point_code + "] 已删除或未启用!"); + } + TaskUtils.isLocked(point); + String vehicle_type = point.getString("vehicle_type"); + String vehicle_code = point.getString("vehicle_code"); + if (StrUtil.isBlank(vehicle_type) || StrUtil.isBlank(vehicle_code)) { + throw new BadRequestException("[" + point_code + "] 上缺少载具类型或载具编码!"); + } + + JSONObject data = null; + if (!"0000".equals(vehicle_code)) { + data = WQLObject + .getWQLObject("st_ivt_vehicle_detail") + .query("is_delete = '0' AND vehicle_type = '" + vehicle_type + "' AND vehicle_code = '" + vehicle_code + "'") + .uniqueResult(0); + } + if (ObjectUtil.isNotEmpty(data)) { + assert data != null; + JSONObject material = WQLObject.getWQLObject("md_me_materialbase").query("material_id = " + data.getString("material_id")).uniqueResult(0); + data.put("product_code", material.getString("product_code")); + data.put("AlongSide", material.getString("a")); + data.put("BshortSide", material.getString("b")); + data.put("Htrapezoidal", material.getString("h")); + data.put("Wthickness", material.getString("w")); + } + JSONObject result = new JSONObject(); result.put("status", HttpStatus.OK.value()); - result.put("message", "反馈成功!"); - result.put("data", vehicleObj); + result.put("message", "获取托盘信息成功!"); + result.put("data", data); return result; } @@ -682,4 +673,91 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { } return productTaskObj; } + + @Override + public JSONObject feedbackVehicleType(JSONObject param) { + String point_code = param.getString("device_code"); + if (StrUtil.isBlank(point_code)) { + throw new BadRequestException("点位不能为空!"); + } + String vehicle_type = param.getString("vehicle_type"); + if (StrUtil.isBlank(vehicle_type)) { + throw new BadRequestException("载具类型不能为空!"); + } + + JSONObject update = new JSONObject(); + update.put("vehicle_type", String.valueOf(Integer.parseInt(vehicle_type) + 2)); + WQLObject + .getWQLObject("sch_base_point") + .update(update, "point_code = '" + point_code + "'"); + + JSONObject result = new JSONObject(); + result.put("status", HttpStatus.OK.value()); + result.put("message", "反馈成功"); + return result; + } + + @Override + public JSONObject getVehicleInfo(JSONObject whereJson) { + String point_code = whereJson.getString("device_code"); + if (StrUtil.isBlank(point_code)) { + throw new BadRequestException("点位不能为空!"); + } + String vehicle_code = whereJson.getString("vehicle_code"); + if (StrUtil.isBlank(vehicle_code) || "0".equals(vehicle_code)) { + throw new BadRequestException("载具编码不能为空!"); + } + JSONObject point = WQLObject + .getWQLObject("sch_base_point") + .query("is_used = '1' AND point_code = '" + point_code + "'") + .uniqueResult(0); + if (ObjectUtil.isEmpty(point)) { + throw new BadRequestException("[" + point_code + "] 已删除或未启用!"); + } + TaskUtils.isLocked(point); + + String region_code = point.getString("region_code"); + String vehicle_type = null; + if (Region.HL.value().equals(region_code)) { + vehicle_type = VehicleType.CUP.value(); + } else if (Region.YZ.value().equals(region_code)) { + vehicle_type = VehicleType.STEEL_TRAY.value(); + } else if (Region.FJ.value().equals(region_code)) { + if ("1".equals(point.getString("point_type"))) { + // 拆垛对接位 + vehicle_type = VehicleType.STEEL_TRAY.value(); + } else if ("2".equals(point.getString("point_type"))) { + // 码垛对接位 + JSONObject workorder = TaskUtils.hasWorkOrder(point); + vehicle_type = workorder.getString("vehicle_type"); + } + } + + if (StrUtil.isBlank(vehicle_type)) { + throw new BadRequestException("未知载具类型! b "); + } + + JSONObject data = null; + if (!"0000".equals(vehicle_code)) { + data = WQLObject + .getWQLObject("st_ivt_vehicle_detail") + .query("is_delete = '0' AND vehicle_type = '" + vehicle_type + "' AND vehicle_code = '" + vehicle_code + "'") + .uniqueResult(0); + } + if (ObjectUtil.isNotEmpty(data)) { + assert data != null; + JSONObject material = WQLObject.getWQLObject("md_me_materialbase").query("material_id = " + data.getString("material_id")).uniqueResult(0); + data.put("product_code", material.getString("product_code")); + data.put("AlongSide", material.getString("a")); + data.put("BshortSide", material.getString("b")); + data.put("Htrapezoidal", material.getString("h")); + data.put("Wthickness", material.getString("w")); + } + + JSONObject result = new JSONObject(); + result.put("status", HttpStatus.OK.value()); + result.put("message", "获取托盘信息成功!"); + result.put("data", data); + return result; + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/auto/AutoQueryTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/ext/auto/AutoQueryTask.java deleted file mode 100644 index 7614ba1..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/auto/AutoQueryTask.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.nl.wms.ext.auto; - -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -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.ext.acs.service.WmsToAcsService; -import org.nl.wms.sch.manage.TaskStatusEnum; -import org.nl.wms.sch.tasks.PointToPointTask; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -@Slf4j -public class AutoQueryTask { - - private final WmsToAcsService wmsToAcsService; - - @Transactional - public void run() { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - - PointToPointTask pointTaskBean = SpringContextHolder.getBean(PointToPointTask.class); - - // 1.查找起点为油漆线 物料下料位的任务 - JSONArray taskArr = WQL.getWO("AUTO_QUERYTASK").addParam("flag", "1").process().getResultJSONArray(0); - - for (int i = 0; i < taskArr.size(); i++) { - JSONObject jsonTask = taskArr.getJSONObject(i); - /* - * 1.查找输送线有没有空位 输送线1对1关系 调用获取点位状态接口 - * 2.判断有空位的输送线是否有任务:起点和终点都要判断 - * 输送线点位:SSX01A1 - SSX01A2 ,SSX02A1 - SSX02A2 - */ - // 2.查找输送线空位,调用获取点位状态接口 - JSONArray paramArr = new JSONArray(); - - JSONObject pointA1 = new JSONObject(); - pointA1.put("device_code", "SSX01A1"); - paramArr.add(pointA1); - - JSONObject pointA2 = new JSONObject(); - pointA2.put("device_code", "SSX01A2"); - paramArr.add(pointA2); - - JSONObject pointB1 = new JSONObject(); - pointB1.put("device_code", "SSX02A1"); - paramArr.add(pointB1); - - JSONObject pointB2 = new JSONObject(); - pointB2.put("device_code", "SSX02A2"); - paramArr.add(pointB2); - - JSONObject result = wmsToAcsService.getPointStatus(paramArr); - - if (StrUtil.equals(result.getString("status"), "200")) { - JSONObject jsonPointAfter = new JSONObject(); // 处理后的json - - JSONArray dataArr = result.getJSONArray("data"); - // 3.处理返回的数据,处理后为json,key为点位编码,value为状态 - for (int j = 0; j < dataArr.size(); j++) { - JSONObject jsonObject = dataArr.getJSONObject(j); - - String device_code = jsonObject.getString("device_code"); - switch (device_code) { - case "SSX01A1" : - jsonPointAfter.put("SSX01A1",jsonObject.getString("move")); - break; - case "SSX01A2" : - jsonPointAfter.put("SSX01A2",jsonObject.getString("move")); - break; - case "SSX02A1" : - jsonPointAfter.put("SSX02A1",jsonObject.getString("move")); - break; - case "SSX02A2" : - jsonPointAfter.put("SSX02A2",jsonObject.getString("move")); - break; - } - } - JSONObject map = new JSONObject(); - // 4.1判断SSX01A1 、 SSX01A2是否是空位 无任务 - if (StrUtil.equals(jsonPointAfter.getString("SSX01A1"), "0") && StrUtil.equals(jsonPointAfter.getString("SSX01A2"), "0")) { - // 4.2如果都是空位 则判断是否有正在进行的任务 - map.put("flag", "2"); - map.put("point_code1", "('SSX01A1','SSX01A2')"); - // 查找起点是否有任务 - JSONArray is_stara = WQL.getWO("AUTO_QUERYTASK").addParamMap(map).process().getResultJSONArray(0); - // 查询终点是否有任务 - map.put("flag", "3"); - map.put("end_point_code", "('SSX01A1','SSX01A2')"); - JSONArray is_end = WQL.getWO("AUTO_QUERYTASK").addParamMap(map).process().getResultJSONArray(0); - - if (ObjectUtil.isEmpty(is_stara) && ObjectUtil.isEmpty(is_end)) { - // 4.3.更新任务终点点位 - jsonTask.put("point_code2", "SSX01A1"); - taskTab.update(jsonTask); - // 4.4.下发ACS - JSONObject jsonResultAcs = pointTaskBean.notifyAcs(jsonTask.getString("task_id")); - - if (StrUtil.equals(jsonResultAcs.getString("status"), "200")) { - // 4.5.下发成功、更新任务状态 - jsonTask.put("task_status", TaskStatusEnum.ISSUE.getCode()); - taskTab.update(jsonTask); - } - // 5.1判断SSX02A1 、 SSX02A2是否是空位 无任务 - } else if (StrUtil.equals(jsonPointAfter.getString("SSX02A1"), "0") && StrUtil.equals(jsonPointAfter.getString("SSX02A2"), "0")) { - // 5.2如果都是空位 则判断是否有正在进行的任务 - map.put("flag", "2"); - map.put("point_code1", "('SSX02A1','SSX02A2')"); - // 查找起点是否有任务 - JSONArray is_stara2 = WQL.getWO("AUTO_QUERYTASK").addParamMap(map).process().getResultJSONArray(0); - // 查询终点是否有任务 - map.put("flag", "3"); - map.put("end_point_code", "('SSX02A1','SSX02A2')"); - JSONArray is_end2 = WQL.getWO("AUTO_QUERYTASK").addParamMap(map).process().getResultJSONArray(0); - - if (ObjectUtil.isEmpty(is_stara2) && ObjectUtil.isEmpty(is_end2)) { - // 5.3.更新任务终点点位 - jsonTask.put("point_code2", "SSX02A1"); - taskTab.update(jsonTask); - // 5.4.下发ACS - JSONObject jsonResultAcs = pointTaskBean.notifyAcs(jsonTask.getString("task_id")); - - if (StrUtil.equals(jsonResultAcs.getString("status"), "200")) { - // 4.5.下发成功、更新任务状态 - jsonTask.put("task_status", TaskStatusEnum.ISSUE.getCode()); - taskTab.update(jsonTask); - } - } - } - } - } - } - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/ext/wql/AUTO_QUERYTASK.wql b/lms/nladmin-system/src/main/java/org/nl/wms/ext/wql/AUTO_QUERYTASK.wql deleted file mode 100644 index 616375a..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/ext/wql/AUTO_QUERYTASK.wql +++ /dev/null @@ -1,92 +0,0 @@ -[交易说明] - 交易名: 二楼到一楼业务 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 - -[IO定义] - ################################################# - ## 表字段对应输入参数 - ################################################# - 输入.flag TYPEAS s_string - 输入.point_code1 TYPEAS f_string - 输入.end_point_code TYPEAS f_string - - -[临时表] - --这边列出来的临时表就会在运行期动态创建 - -[临时变量] - --所有中间过程变量均可在此处定义 - -[业务过程] - - ########################################## - # 1、输入输出检查 # - ########################################## - - - ########################################## - # 2、主过程前处理 # - ########################################## - - - ########################################## - # 3、业务主过程 # - ########################################## - - IF 输入.flag = "1" - QUERY - SELECT - task.* - FROM - SCH_BASE_Task task - WHERE - task.is_delete = '0' - AND task.task_status = '1' - AND task.point_code1 in ('YQX01_WX','YQX02_WX') - - ENDSELECT - ENDQUERY - ENDIF - - IF 输入.flag = "2" - QUERY - SELECT - task.* - FROM - SCH_BASE_Task task - WHERE - task.is_delete = '0' - AND task.task_status <> '99' - - OPTION 输入.point_code1 <> "" - task.point_code1 in 输入.point_code1 - ENDOPTION - - ENDSELECT - ENDQUERY - ENDIF - - IF 输入.flag = "3" - QUERY - SELECT - task.* - FROM - SCH_BASE_Task task - WHERE - task.is_delete = '0' - AND task.task_status <> '99' - - OPTION 输入.end_point_code <> "" - task.point_code2 in 输入.end_point_code - ENDOPTION - - ENDSELECT - ENDQUERY - ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pda/anno/PdaAnnotation.java b/lms/nladmin-system/src/main/java/org/nl/wms/pda/anno/PdaAnnotation.java new file mode 100644 index 0000000..ab92352 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pda/anno/PdaAnnotation.java @@ -0,0 +1,8 @@ +package org.nl.wms.pda.anno; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +public @interface PdaAnnotation { +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pda/rest/PdaController.java b/lms/nladmin-system/src/main/java/org/nl/wms/pda/rest/PdaController.java index e08029e..1570563 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/pda/rest/PdaController.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pda/rest/PdaController.java @@ -6,11 +6,11 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; import org.nl.modules.logging.annotation.Log; -import org.nl.wms.pda.service.PdaService; import org.nl.wms.pda.util.PdaUtils; -import org.nl.wms.sch.manage.RegionEnum; -import org.springframework.http.ResponseEntity; +import org.nl.wms.pda.anno.PdaAnnotation; +import org.nl.wms.pda.service.PdaService; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -31,192 +31,41 @@ public class PdaController { private final PdaService pdaService; - @PostMapping("/warehouse") - @Log("查询所有库区") - @ApiOperation("查询所有库区") - public ResponseEntity warehouse() { - log.info("辽宁晟华手持 [查询所有库区] 接口被请求"); - - try { - return PdaUtils.buildSuccessResponseEntity(pdaService.warehouse()); - } catch (Exception e) { - return PdaUtils.buildFailResponseEntity(e.getMessage()); - } + @PostMapping("/queryRegion") + @Log("查询区域") + @ApiOperation("查询区域") + @PdaAnnotation + public JSONObject queryRegion() { + return PdaUtils.buildSuccessResultJSON(pdaService.queryRegion()); } - @PostMapping("/point") - @Log("根据区域查询点位") - @ApiOperation("根据区域查询点位") - public ResponseEntity point(@RequestBody JSONObject param) { - log.info("辽宁晟华手持 [根据区域查询点位] 接口被请求, 请求参数-{}", param); - - String region_code = param.getString("region_code"); - if (StrUtil.isEmpty(region_code)) { - return PdaUtils.buildFailResponseEntity("区域不能为空"); - } - - try { - return PdaUtils.buildSuccessResponseEntity(pdaService.point(region_code)); - } catch (Exception e) { - return PdaUtils.buildFailResponseEntity(e.getMessage()); + @PostMapping("/queryPoint") + @Log("查询对接位") + @ApiOperation("查询对接位") + @PdaAnnotation + public JSONObject queryPoint(@RequestBody JSONObject request_body) { + String type = request_body.getString("type"); + if (StrUtil.isBlank(type)) { + throw new BadRequestException("未知界面!"); } + return PdaUtils.buildSuccessResultJSON(pdaService.queryPoint(type)); } - @PostMapping("/pointInfo") - @Log("查询点位详细信息") - @ApiOperation("查询点位详细信息") - public ResponseEntity pointInfo(@RequestBody JSONObject param) { - log.info("辽宁晟华手持 [查询点位详细信息] 接口被请求, 请求参数-{}", param); - - String region_code = param.getString("region_code"); - if (StrUtil.isEmpty(region_code)) { - return PdaUtils.buildFailResponseEntity("区域不能为空"); + @PostMapping("/createTask") + @Log("创建任务") + @ApiOperation("创建任务") + @PdaAnnotation + public JSONObject createTask(@RequestBody JSONObject request_body) { + String type = request_body.getString("type"); + if (StrUtil.isBlank(type)) { + throw new BadRequestException("未知任务类型!"); } - String point_code = param.getString("point_code"); - if (StrUtil.isEmpty(point_code)) { - return PdaUtils.buildFailResponseEntity("点位不能为空"); + String point_code = request_body.getString("point_code"); + if (StrUtil.isBlank(point_code)) { + throw new BadRequestException("点位不能为空!"); } - try { - return PdaUtils.buildSuccessResponseEntity(pdaService.pointInfo(region_code, point_code)); - } catch (Exception e) { - return PdaUtils.buildFailResponseEntity(e.getMessage()); - } - } - - @PostMapping("/material") - @Log("查询物料") - @ApiOperation("查询物料") - public ResponseEntity material(@RequestBody JSONObject param) { - log.info("辽宁晟华手持 [查询物料] 接口被请求, 请求参数-{}", param); - - try { - return PdaUtils.buildSuccessResponseEntity(pdaService.material( - param.getString("condition") - )); - } catch (Exception e) { - return PdaUtils.buildFailResponseEntity(e.getMessage()); - } - } - - @PostMapping("/stockOperation") - @Log("库存操作") - @ApiOperation("库存操作") - public ResponseEntity stockOperation(@RequestBody JSONObject param) { - log.info("辽宁晟华手持 [库存操作] 接口被请求, 请求参数-{}", param); - - try { - String type = param.getString("type"); - if (StrUtil.isEmpty(type)) { - return PdaUtils.buildFailResponseEntity("请点击确认或清空"); - } else { - String region_code = param.getString("region_code"); - if (StrUtil.isEmpty(region_code)) { - return PdaUtils.buildFailResponseEntity("区域不能为空"); - } - String point_code = param.getString("point_code"); - if (StrUtil.isEmpty(point_code)) { - return PdaUtils.buildFailResponseEntity("点位不能为空"); - } - - switch (type) { - case "1": - // 确认 - String vehicle_code = param.getString("vehicle_code"); - if (!StrUtil.equals(region_code, RegionEnum.RYZCQ.getCode()) && StrUtil.isEmpty(vehicle_code)) { - return PdaUtils.buildFailResponseEntity("载具编码不能为空"); - } - String qty = param.getString("qty"); - if (StrUtil.isEmpty(qty)) { - return PdaUtils.buildFailResponseEntity("物料数量/重量不能为空"); - } - String is_full = param.getString("is_full"); - if (StrUtil.isEmpty(is_full)) { - return PdaUtils.buildFailResponseEntity("是否满托不能为空"); - } - - pdaService.updateStock(region_code, point_code, vehicle_code, qty, is_full); - break; - case "2": - // 清空 - pdaService.emptyStock(point_code); - break; - default: - return PdaUtils.buildFailResponseEntity("操作错误"); - } - - return PdaUtils.buildSuccessResponseEntity(null); - } - } catch (Exception e) { - return PdaUtils.buildFailResponseEntity(e.getMessage()); - } - } - - @PostMapping("/queryYZCallMaterialPoint") - @Log("查询压制叫料点位") - @ApiOperation("查询压制叫料点位") - public ResponseEntity queryYZCallMaterialPoint() { - log.info("辽宁晟华手持 [查询压制叫料点位] 接口被请求"); - - try { - return PdaUtils.buildSuccessResponseEntity(pdaService.queryYZCallMaterialPoint()); - } catch (Exception e) { - return PdaUtils.buildFailResponseEntity(e.getMessage()); - } - } - - @PostMapping("/yzCallMaterial") - @Log("压制叫料") - @ApiOperation("压制叫料") - public ResponseEntity yzCallMaterial(@RequestBody JSONObject param) { - log.info("辽宁晟华手持 [压制叫料] 接口被请求, 请求参数-{}", param); - - String point_code = param.getString("point_code"); - if (StrUtil.isEmpty(point_code)) { - return PdaUtils.buildFailResponseEntity("点位不能为空"); - } - - try { - pdaService.yzCallMaterial(point_code); - return PdaUtils.buildSuccessResponseEntity(null); - } catch (Exception e) { - return PdaUtils.buildFailResponseEntity(e.getMessage()); - } - } - - @PostMapping("/queryEmptyCupPoint") - @Log("查询空盅点位") - @ApiOperation("查询空盅点位") - public ResponseEntity queryEmptyCupPoint() { - log.info("辽宁晟华手持 [查询空盅点位] 接口被请求"); - - try { - return PdaUtils.buildSuccessResponseEntity(pdaService.queryEmptyCupPoint()); - } catch (Exception e) { - return PdaUtils.buildFailResponseEntity(e.getMessage()); - } - } - - @PostMapping("/sendEmptyCup") - @Log("送空盅") - @ApiOperation("送空盅") - public ResponseEntity sendEmptyCup(@RequestBody JSONObject param) { - log.info("辽宁晟华手持 [送空盅] 接口被请求, 请求参数-{}", param); - - String point_code = param.getString("point_code"); - if (StrUtil.isEmpty(point_code)) { - return PdaUtils.buildFailResponseEntity("点位不能为空"); - } - String vehicle_code = param.getString("vehicle_code"); - if (StrUtil.isEmpty(vehicle_code)) { - return PdaUtils.buildFailResponseEntity("料盅编码不能为空"); - } - - try { - pdaService.sendEmptyCup(point_code, vehicle_code); - return PdaUtils.buildSuccessResponseEntity(null); - } catch (Exception e) { - return PdaUtils.buildFailResponseEntity(e.getMessage()); - } + pdaService.createTask(request_body); + return PdaUtils.buildSuccessResultJSON(null); } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pda/service/PdaService.java b/lms/nladmin-system/src/main/java/org/nl/wms/pda/service/PdaService.java index b17209f..133fe42 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/pda/service/PdaService.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pda/service/PdaService.java @@ -1,6 +1,5 @@ package org.nl.wms.pda.service; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; @@ -12,82 +11,10 @@ import com.alibaba.fastjson.JSONObject; */ public interface PdaService { - /** - * 查询所有区域 - * - * @return 所有区域的编码和名称 - */ - JSONArray warehouse(); - /** - * 根据区域查询点位 - * - * @param region_code 区域编码 - * @return 该区域下的点位编码、名称和状态 - */ - JSONArray point(String region_code); + JSONArray queryRegion(); - /** - * 查询点位详细信息 - * - * @param region_code 区域编码 - * @param point_code 点位编码 - * @return 点位上的组盘信息 - */ - JSONObject pointInfo(String region_code, String point_code); + JSONArray queryPoint(String type); - /** - * 查询所有物料 - * - * @param condition 查询条件, 用于模糊查询 - * @return 物料的编码和名称 - */ - JSONArray material(String condition); - - /** - * 库存操作-点击确认 - * - * @param region_code 区域编码 - * @param point_code 点位编码 - * @param vehicle_code 载具编码, 如果是入窑暂存区该参数将被无视 - * @param qty 物料数量/重量 - * @param is_full 是否满托 - */ - void updateStock(String region_code, String point_code, String vehicle_code, String qty, String is_full); - - /** - * 库存操作-点击清空 - * - * @param point_code 点位编码 - */ - void emptyStock(String point_code); - - /** - * 查询压制叫料点位 - * - * @return 压制叫料点位编码和名称 - */ - JSONArray queryYZCallMaterialPoint(); - - /** - * 压制叫料 - * - * @param point_code 点位编码 - */ - void yzCallMaterial(String point_code); - - /** - * 查询空盅点位 - * - * @return 空盅点位编码和名称 - */ - JSONArray queryEmptyCupPoint(); - - /** - * 送空盅 - * - * @param point_code 点位编码 - * @param vehicle_code 料盅编码 - */ - void sendEmptyCup(String point_code, String vehicle_code); + void createTask(JSONObject request_param); } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pda/service/impl/PdaServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/pda/service/impl/PdaServiceImpl.java index 803368a..6d79e68 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/pda/service/impl/PdaServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pda/service/impl/PdaServiceImpl.java @@ -1,19 +1,18 @@ package org.nl.wms.pda.service.impl; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; 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.wql.WQL; import org.nl.modules.wql.core.bean.WQLObject; import org.nl.wms.pda.service.PdaService; -import org.nl.wms.sch.manage.RegionEnum; -import org.nl.wms.sch.manage.TaskStatusEnum; -import org.nl.wms.sch.tasks.callMaterial.YzjCallMaterialTask; -import org.nl.wms.sch.tasks.sendEmpty.YzjSendEmpVehicleTask; +import org.nl.wms.sch.manage.CreateMode; +import org.nl.wms.sch.task.send.material.HLSendMaterialTask; +import org.nl.wms.sch.task.util.TaskUtils; import org.springframework.stereotype.Service; /** @@ -25,177 +24,65 @@ import org.springframework.stereotype.Service; @Slf4j public class PdaServiceImpl implements PdaService { - private final YzjCallMaterialTask yzjCallMaterialTask; - - private final YzjSendEmpVehicleTask yzjSendEmpVehicleTask; + private final HLSendMaterialTask hlSendMaterialTask; /** * 查询所有区域 * - * @return 所有区域的编码和名称 + * @return 所有区域信息 */ @Override - public JSONArray warehouse() { - return WQL.getWO("LNSH_PDA").addParam("flag", "1").process().getResultJSONArray(0); + public JSONArray queryRegion() { + return WQLObject + .getWQLObject("sch_base_region") + .query() + .getResultJSONArray(0); } /** - * 根据区域查询点位 + * 查询对接位 * - * @param region_code 区域编码 - * @return 该区域下的点位编码、名称和状态 + * @param type 手持界面 HLSL-混料送料 + * @return 对接位信息 */ @Override - public JSONArray point(String region_code) { + public JSONArray queryPoint(String type) { return WQL - .getWO("LNSH_PDA") - .addParam("flag", "2") - .addParam("region_code", region_code) + .getWO("PDA") + .addParam("flag", "1") + .addParam("type", type) .process() .getResultJSONArray(0); } /** - * 查询点位详细信息 + * 创建任务 * - * @param region_code 区域编码 - * @param point_code 点位编码 - * @return 点位上的组盘信息 + * @param request_param 请求带的参数 */ @Override - public JSONObject pointInfo(String region_code, String point_code) { - JSONObject info = WQL - .getWO("LNSH_PDA") - .addParam("flag", "3") - .addParam("point_code", point_code) - .process() - .uniqueResult(0); - - // 如果区域位于入窑暂存区 则不展示载具编码 - if (StrUtil.equals(region_code, RegionEnum.RYZCQ.getCode())) { - info.put("has_vehicle_code", "0"); - } - - return info; - } - - /** - * 查询所有物料 - * - * @param condition 查询条件, 用于模糊查询 - * @return 物料的编码和名称 - */ - @Override - public JSONArray material(String condition) { - return WQL - .getWO("LNSH_PDA") - .addParam("flag", "4") - .addParam("condition", condition) - .process() - .getResultJSONArray(0); - } - - /** - * 库存操作-点击确认 - * - * @param region_code 区域编码 - * @param point_code 点位编码 - * @param vehicle_code 载具编码, 如果是入窑暂存区该参数将被无视 - * @param qty 物料数量/重量 - * @param is_full 是否满托 - */ - @Override - public void updateStock(String region_code, String point_code, String vehicle_code, String qty, String is_full) { - - } - - /** - * 库存操作-点击清空 - * - * @param point_code 点位编码 - */ - @Override - public void emptyStock(String point_code) { - - } - - /** - * 查询压制叫料点位 - * - * @return 压制叫料点位编码和名称 - */ - @Override - public JSONArray queryYZCallMaterialPoint() { - return WQL.getWO("LNSH_PDA").addParam("flag", "5").process().getResultJSONArray(0); - } - - /** - * 压制叫料 - * - * @param point_code 点位编码 - */ - @Override - public void yzCallMaterial(String point_code) { - isAvailable(point_code); - - yzjCallMaterialTask.createTask(new JSONObject() {{ - put("point_code2", point_code); - }}); - } - - /** - * 查询空盅点位 - * - * @return 空盅点位编码和名称 - */ - @Override - public JSONArray queryEmptyCupPoint() { - return WQL.getWO("LNSH_PDA").addParam("flag", "6").process().getResultJSONArray(0); - } - - /** - * 送空盅 - * - * @param point_code 点位编码 - */ - @Override - public void sendEmptyCup(String point_code, String vehicle_code) { - JSONObject point = isAvailable(point_code); - - yzjSendEmpVehicleTask.createTask(new JSONObject() {{ - put("point_code1", point_code); - put("vehicle_code", vehicle_code); - put("vehicle_type", StrUtil.equals(point.getString("point_type"), "2") ? "2" : "1"); - }}); - } - - /** - * 查询点位是否可用 - * 如果点位未被删除 且 未被禁用 且 不存在未完成的任务 即为可用 - * 不可用将报错 - * - * @param point_code 点位编码 - * @return 点位 - */ - private JSONObject isAvailable(String point_code) { + public void createTask(JSONObject request_param) { + String type = request_param.getString("type"); JSONObject point = WQLObject .getWQLObject("sch_base_point") - .query("is_delete = '0' AND is_used = '1' AND point_code = '" + point_code + "'") + .query("is_delete = '0' AND is_used = '1' AND point_code = '" + request_param.getString("point_code") + "'") .uniqueResult(0); if (ObjectUtil.isEmpty(point)) { - throw new BadRequestException("该点位已被删除或已禁用"); + throw new BadRequestException("点位已删除或未启用!"); } - - JSONObject task = WQLObject - .getWQLObject("sch_base_task") - .query("is_delete = '0' " + - "AND ( point_code1 = '" + point_code + "' OR point_code2 = '" + point_code + "' ) " + - "AND task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'") - .uniqueResult(0); - if (ObjectUtil.isNotEmpty(task)) { - throw new BadRequestException("该点位存在未完成的任务"); + JSONObject method_param = new JSONObject(); + method_param.put("create_mode", CreateMode.SCCJ.value()); + method_param.put("request_param", request_param); + method_param.put("create_id", SecurityUtils.getCurrentUserId()); + method_param.put("create_name", SecurityUtils.getCurrentNickName()); + switch (type) { + case "1": + // 混料机送料 + method_param.put("point", point); + method_param.put("vehicle_code", TaskUtils.formatVehicleCode(request_param.getString("vehicle_code"))); + hlSendMaterialTask.createTask(method_param); + break; + case "2": } - - return point; } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pda/util/PdaUtils.java b/lms/nladmin-system/src/main/java/org/nl/wms/pda/util/PdaUtils.java index 6789736..bbd7edf 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/pda/util/PdaUtils.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pda/util/PdaUtils.java @@ -2,8 +2,6 @@ package org.nl.wms.pda.util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; /** * 辽宁晟华手持工具类 @@ -13,28 +11,6 @@ import org.springframework.http.ResponseEntity; */ public final class PdaUtils { - /** - * 控制层调用方法 - * 创建操作成功返回的 ResponseEntity 并携带需要返回的数据 - * - * @param result 需要返回的数据, 可为 NULL - * @return 携带了返回数据的 ResponseEntity - */ - public static ResponseEntity buildSuccessResponseEntity(JSON result) { - return new ResponseEntity<>(buildSuccessJSON(result), HttpStatus.OK); - } - - /** - * 控制层调用方法 - * 创建操作失败返回的 ResponseEntity - * - * @param desc 错误提示, 可为 NULL - * @return 自定义错误提示的 ResponseEntity - */ - public static ResponseEntity buildFailResponseEntity(String desc) { - return new ResponseEntity<>(buildFailJSON(desc), HttpStatus.OK); - } - /** * 服务层调用方法 * 创建操作成功的 JSONObject 并携带需要返回的数据 @@ -42,7 +18,7 @@ public final class PdaUtils { * @param result 返回数据, 可为 NULL * @return 携带了返回数据的 JSONObject */ - public static JSONObject buildSuccessJSON(JSON result) { + public static JSONObject buildSuccessResultJSON(JSON result) { JSONObject resultJSON = new JSONObject(); resultJSON.put("code", "1"); resultJSON.put("desc", "操作成功"); @@ -57,7 +33,7 @@ public final class PdaUtils { * @param desc 错误提示, 可为 NULL * @return 自定义错误提示的 JSONObject */ - public static JSONObject buildFailJSON(String desc) { + public static JSONObject buildFailResultJSON(String desc) { JSONObject resultJSON = new JSONObject(); resultJSON.put("code", "0"); resultJSON.put("desc", desc); diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pda/wql/LNSH_PDA.wql b/lms/nladmin-system/src/main/java/org/nl/wms/pda/wql/LNSH_PDA.wql deleted file mode 100644 index 79f22cf..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/pda/wql/LNSH_PDA.wql +++ /dev/null @@ -1,141 +0,0 @@ -[交易说明] - 交易名: 基础点位分页查询 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 - -[IO定义] - ################################################# - ## 表字段对应输入参数 - ################################################# - 输入.flag TYPEAS s_string - 输入.region_code TYPEAS s_string - 输入.point_code TYPEAS s_string - 输入.condition TYPEAS s_string - - -[临时表] - --这边列出来的临时表就会在运行期动态创建 - -[临时变量] - --所有中间过程变量均可在此处定义 - -[业务过程] - - ########################################## - # 1、输入输出检查 # - ########################################## - - - ########################################## - # 2、主过程前处理 # - ########################################## - - - ########################################## - # 3、业务主过程 # - ########################################## - - IF 输入.flag = "1" - QUERY - SELECT - region_code, - region_name - FROM - sch_base_region - WHERE - region_code IN ( 'KLHJ', 'RYZCQ', 'CYZCQ', 'BZZCQ' ) - ENDSELECT - ENDQUERY - ENDIF - - IF 输入.flag = "2" - QUERY - SELECT - point.point_code, - point.point_name, - IF ( task1.task_code IS NULL AND task2.task_code IS NULL, point.point_status, '4' ) AS 'point_status' - FROM - sch_base_point point - LEFT JOIN sch_base_task task1 ON point.point_code = task1.point_code1 AND task1.task_status < '7' - LEFT JOIN sch_base_task task2 ON point.point_code = task2.point_code2 AND task1.task_status < '7' - WHERE - point.is_delete = '0' - AND point.is_used = '1' - AND point.region_code = 输入.region_code - ENDSELECT - ENDQUERY - ENDIF - - IF 输入.flag = "3" - QUERY - SELECT - point.vehicle_code, - `group`.material_code, - `group`.material_name, - `group`.qty, - `group`.is_full - FROM - sch_base_point point - INNER JOIN st_buss_vehiclegroup `group` ON point.group_id = `group`.group_id - WHERE - point.is_delete = '0' - AND point.is_used = '1' - AND point.point_code = 输入.point_code - ENDSELECT - ENDQEURY - ENDIF - - IF 输入.flag = "4" - QUERY - SELECT - material_code, - material_name - FROM - md_me_materialbase - WHERE - is_delete = '0' - OPTION 输入.condition <> "" - material_code LIKE CONCAT ( '%', 输入.condition, '%' ) - OR material_name LIKE CONCAT ( '%', 输入.condition, '%' ) - ENDOPTION - ENDSELECT - ENDQUERY - ENDIF - - IF 输入.flag = "5" - QUERY - SELECT - point_code, - point_name - FROM - sch_base_point - WHERE - is_used = '1' - AND is_delete = '0' - AND region_code = 'KLHJ' - AND point_type = '3' - ENDSELECT - ENDQUERY - ENDIF - - IF 输入.flag = "6" - QUERY - SELECT - point_code, - point_name - FROM - `sch_base_point` - WHERE - is_used = '1' - AND is_delete = '0' - AND region_code = 'KLHJ' - AND point_type IN ( '2', '4' ) - ENDSELECT - ENDQUERY - ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_szSendMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/pda/wql/PDA.wql similarity index 58% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_szSendMaterial_01.wql rename to lms/nladmin-system/src/main/java/org/nl/wms/pda/wql/PDA.wql index 46428f1..30562c4 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_szSendMaterial_01.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pda/wql/PDA.wql @@ -1,5 +1,5 @@ [交易说明] - 交易名: 烧制入库 + 交易名: 手持 所属模块: 功能简述: 版权所有: @@ -13,11 +13,8 @@ ################################################# ## 表字段对应输入参数 ################################################# - 输入.flag TYPEAS s_string - 输入.region_code TYPEAS s_string - 输入.material_id TYPEAS s_string - 输入.vehicle_type TYPEAS s_string - + 输入.flag TYPEAS s_string + 输入.type TYPEAS s_string [临时表] --这边列出来的临时表就会在运行期动态创建 @@ -40,23 +37,23 @@ ########################################## # 3、业务主过程 # ########################################## - IF 输入.flag = "1" - QUERY - SELECT - p.point_id, - p.point_code, - p.point_name + + IF 输入.flag = "1" + QUERY + SELECT + point_id, + point_code, + point_name FROM - SCH_BASE_Point p + sch_base_point WHERE - lock_type = '1' + is_delete = '0' AND is_used = '1' - AND is_delete = '0' - AND point_status = '1' - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - ORDER BY col_num,row_num,layer_num - ENDSELECT - ENDQUERY - ENDIF + AND lock_type = '1' + OPTION 输入.type = "HL" + region_code = 'HL' + AND point_type IN ('1', '2') + ENDOPTION + ENDSELECT + ENDQUERY + ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pdm/rest/DeviceController.java b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/rest/DeviceController.java new file mode 100644 index 0000000..7dfbfbf --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/rest/DeviceController.java @@ -0,0 +1,77 @@ + +package org.nl.wms.pdm.rest; + + +import com.alibaba.fastjson.JSONObject; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.logging.annotation.Log; +import org.nl.wms.pdm.service.DeviceService; +import org.nl.wms.pdm.service.dto.DeviceDto; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +/** +* @author geng by +* @date 2022-05-25 +**/ +@RestController +@RequiredArgsConstructor +@Api(tags = "生产设备管理") +@RequestMapping("/api/device") +@Slf4j +public class DeviceController { + + private final DeviceService deviceService; + + @GetMapping + @Log("查询生产设备") + @ApiOperation("查询生产设备") + //@SaCheckPermission("device:list") + public ResponseEntity query(@RequestParam Map whereJson, Pageable page){ + return new ResponseEntity<>(deviceService.queryAll(whereJson,page),HttpStatus.OK); + } + + @PostMapping + @Log("新增生产设备") + @ApiOperation("新增生产设备") + //@SaCheckPermission("device:add") + public ResponseEntity create(@Validated @RequestBody DeviceDto dto){ + deviceService.create(dto); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @PutMapping + @Log("修改生产设备") + @ApiOperation("修改生产设备") + //@SaCheckPermission("device:edit") + public ResponseEntity update(@Validated @RequestBody DeviceDto dto){ + deviceService.update(dto); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除生产设备") + @ApiOperation("删除生产设备") + //@SaCheckPermission("device:del") + @DeleteMapping + public ResponseEntity delete(@RequestBody Long[] ids) { + deviceService.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + @PutMapping("/changeActive") + @Log("修改点位启用状态") + @ApiOperation("修改点位启用状态") + public ResponseEntity changeActive(@RequestBody JSONObject json) { + deviceService.changeActive(json); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/DeviceService.java b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/DeviceService.java new file mode 100644 index 0000000..147b5b8 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/DeviceService.java @@ -0,0 +1,68 @@ + +package org.nl.wms.pdm.service; + +import com.alibaba.fastjson.JSONObject; +import org.nl.wms.pdm.service.dto.DeviceDto; +import org.springframework.data.domain.Pageable; + +import java.util.List; +import java.util.Map; + +/** +* @description 服务接口 +* @author geng by +* @date 2022-05-25 +**/ +public interface DeviceService { + + /** + * 查询数据分页 + * @param whereJson 条件 + * @param page 分页参数 + * @return Map + */ + Map queryAll(Map whereJson, Pageable page); + + /** + * 查询所有数据不分页 + * @param whereJson 条件参数 + * @return List + */ + List queryAll(Map whereJson); + + /** + * 根据ID查询 + * @param device_id ID + * @return Device + */ + DeviceDto findById(Long device_id); + + /** + * 根据编码查询 + * @param code code + * @return Device + */ + DeviceDto findByCode(String code); + + + /** + * 创建 + * @param dto / + */ + void create(DeviceDto dto); + + /** + * 编辑 + * @param dto / + */ + void update(DeviceDto dto); + + /** + * 多选删除 + * @param ids / + */ + void deleteAll(Long[] ids); + + + void changeActive(JSONObject json); +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/dto/WorkorderDto.java b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/dto/WorkorderDto.java index 867232a..9ccfb31 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/dto/WorkorderDto.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/dto/WorkorderDto.java @@ -100,4 +100,12 @@ public class WorkorderDto implements Serializable { /** 阈值时间 */ private String warn_time; + + private Long device_id; + + private String is_urgent; + + private String is_pri; + + private String ext_code; } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/impl/DeviceServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/impl/DeviceServiceImpl.java new file mode 100644 index 0000000..9105e33 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/impl/DeviceServiceImpl.java @@ -0,0 +1,138 @@ + +package org.nl.wms.pdm.service.impl; + + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.map.MapUtil; +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; +import lombok.extern.slf4j.Slf4j; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.common.utils.SecurityUtils; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.modules.wql.util.WqlUtil; +import org.nl.wms.pdm.service.DeviceService; +import org.nl.wms.pdm.service.dto.DeviceDto; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +/** + * @author geng by + * @description 服务实现 + * @date 2022-05-25 + **/ +@Service +@RequiredArgsConstructor +@Slf4j +public class DeviceServiceImpl implements DeviceService { + + @Override + public Map queryAll(Map whereJson, Pageable page) { + String search = MapUtil.getStr(whereJson, "search"); + JSONObject map = new JSONObject(); + map.put("flag", "1"); + if (!StrUtil.isEmpty(search)) { + map.put("search", "%" + search + "%"); + } + JSONObject json = WQL.getWO("PDM_BI_DEVICE01").addParamMap(map).pageQuery(WqlUtil.getHttpContext(page), "device.device_model, device.device_code"); + return json; + } + + @Override + public List queryAll(Map whereJson) { + WQLObject wo = WQLObject.getWQLObject("pdm_bi_device"); + JSONArray arr = wo.query().getResultJSONArray(0); + if (ObjectUtil.isNotEmpty(arr)) return arr.toJavaList(DeviceDto.class); + return null; + } + + @Override + public DeviceDto findById(Long device_id) { + WQLObject wo = WQLObject.getWQLObject("pdm_bi_device"); + JSONObject json = wo.query("device_id = '" + device_id + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(json)) { + return json.toJavaObject(DeviceDto.class); + } + return null; + } + + @Override + public DeviceDto findByCode(String code) { + WQLObject wo = WQLObject.getWQLObject("pdm_bi_device"); + JSONObject json = wo.query("device_code ='" + code + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(json)) { + return json.toJavaObject(DeviceDto.class); + } + return null; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(DeviceDto dto) { + Long currentUserId = SecurityUtils.getCurrentUserId(); + String nickName = SecurityUtils.getCurrentNickName(); + String now = DateUtil.now(); + //编码唯一性校验 + String device_code = dto.getDevice_code(); + DeviceDto byCode = this.findByCode(device_code); + if (ObjectUtil.isNotEmpty(byCode)) throw new BadRequestException("编码已存在!"); + dto.setDevice_id(IdUtil.getSnowflake(1, 1).nextId()); + dto.setCreate_id(currentUserId); + dto.setCreate_name(nickName); + dto.setCreate_time(now); + + WQLObject wo = WQLObject.getWQLObject("pdm_bi_device"); + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + wo.insert(json); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(DeviceDto dto) { + DeviceDto entity = this.findById(dto.getDevice_id()); + if (entity == null) throw new BadRequestException("被删除或无权限,操作失败!"); + + //编码唯一性校验 + WQLObject wo = WQLObject.getWQLObject("pdm_bi_device"); + String where = "is_delete = '0' and device_code = '" + dto.getDevice_code() + "' and device_id != '" + dto.getDevice_id() + "'"; + + JSONObject jsonObject = wo.query(where).uniqueResult(0); + if (ObjectUtil.isNotEmpty(jsonObject)) { + throw new BadRequestException("编码已存在!"); + } + + + JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); + wo.update(json); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteAll(Long[] ids) { + WQLObject wo = WQLObject.getWQLObject("pdm_bi_device"); + for (Long device_id : ids) { + wo.delete("device_id = '" + device_id + "'"); + } + } + + @Override + public void changeActive(JSONObject json) { + String is_used = "1"; + if (StrUtil.equals("1", json.getString("is_used"))) { + is_used = "0"; + } + json.put("is_used", is_used); + WQLObject.getWQLObject("PDM_BI_Device").update(json); + } + +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/impl/WorkorderServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/impl/WorkorderServiceImpl.java index a0c2f2f..e375477 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/impl/WorkorderServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/service/impl/WorkorderServiceImpl.java @@ -11,22 +11,20 @@ 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.common.utils.dto.CurrentUser; 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.WqlUtil; -import org.nl.wms.basedata.service.ClassstandardService; +import org.nl.wms.basedata.eum.TrueOrFalse; +import org.nl.wms.basedata.eum.VehicleType; import org.nl.wms.ext.acs.service.WmsToAcsService; import org.nl.wms.pdm.service.WorkordeService; import org.nl.wms.pdm.service.dto.WorkorderDto; - +import org.nl.wms.sch.manage.WorkOrderEnum; import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -51,14 +49,9 @@ public class WorkorderServiceImpl implements WorkordeService { String material = MapUtil.getStr(whereJson, "material"); String begin_time = MapUtil.getStr(whereJson, "begin_time"); String end_time = MapUtil.getStr(whereJson, "end_time"); - String order_type_scode = MapUtil.getStr(whereJson, "order_type_scode"); String order_status = MapUtil.getStr(whereJson, "order_status"); - String shift_type_scode = MapUtil.getStr(whereJson, "shift_type_scode"); JSONObject map = new JSONObject(); map.put("flag", "1"); - map.put("order_type_scode", order_type_scode); - //map.put("order_status", order_status); - map.put("shift_type_scode", shift_type_scode); map.put("begin_time", begin_time); map.put("end_time", end_time); if (StrUtil.isNotEmpty(order_status)) { @@ -76,8 +69,6 @@ public class WorkorderServiceImpl implements WorkordeService { if (StrUtil.isNotEmpty(material)) { map.put("material", "%" + material + "%"); } - // 工序名称 - map.put("workorder_procedure", whereJson.get("workorder_procedure")); JSONObject jsonObject = WQL.getWO("MPS_PRODUCEDURE001").addParamMap(map).pageQuery(WqlUtil.getHttpContext(page), "ShiftOrder.update_time desc"); return jsonObject; } @@ -113,25 +104,40 @@ public class WorkorderServiceImpl implements WorkordeService { @Override @Transactional(rollbackFor = Exception.class) public void create(WorkorderDto dto) { - Long currentUserId = SecurityUtils.getCurrentUserId(); - String nickName = SecurityUtils.getCurrentNickName(); + JSONObject work_order = new JSONObject(); + work_order.put("workorder_id", IdUtil.getSnowflake().nextId()); + work_order.put("workorder_code", CodeUtil.getNewCode("PDM_SHIFTORDER")); + work_order.put("plan_qty", dto.getPlan_qty()); + work_order.put("planproducestart_date", dto.getPlanproducestart_date()); + work_order.put("planproduceend_date", dto.getPlanproduceend_date()); + work_order.put("material_id", dto.getMaterial_id()); + String device_code = dto.getDevice_code(); + String vehicle_type = dto.getVehicle_type(); + if (!device_code.startsWith("FJ")) { + if (device_code.startsWith("YZJ")) { + vehicle_type = VehicleType.STEEL_TRAY.value(); + } else if (device_code.startsWith("HLJ")) { + vehicle_type = VehicleType.CUP.value(); + } + } + work_order.put("vehicle_type", vehicle_type); + work_order.put("device_id", dto.getDevice_id()); + work_order.put("device_code", device_code); + work_order.put("order_status", WorkOrderEnum.ORDER_STATUS_UNPRODUCED.value()); + work_order.put("is_urgent", dto.getIs_urgent()); + work_order.put("is_pri", dto.getIs_pri()); + work_order.put("ext_code", dto.getExt_code()); + work_order.put("is_delete", TrueOrFalse.FALSE.value()); + Long user_id = SecurityUtils.getCurrentUserId(); + String nick_name = SecurityUtils.getCurrentNickName(); String now = DateUtil.now(); - CurrentUser currentUser = SecurityUtils.getCurrentUser(); - Long deptId = currentUser.getUser().getDeptId(); - String newCode = CodeUtil.getNewCode("PDM_SHIFTORDER"); - dto.setWorkorder_id(IdUtil.getSnowflake(1, 1).nextId()); - dto.setWorkorder_code(newCode); - dto.setCreate_id(currentUserId); - dto.setCreate_time(now); - dto.setCreate_name(nickName); - dto.setUpdate_optid(currentUserId); - dto.setUpdate_optname(nickName); - dto.setUpdate_time(now); - WQLObject wo = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - json.put("sysdeptid", deptId); - json.put("syscompanyid", deptId); - wo.insert(json); + work_order.put("create_id", user_id); + work_order.put("create_name", nick_name); + work_order.put("create_time", now); + work_order.put("update_optid", user_id); + work_order.put("update_optname", nick_name); + work_order.put("update_time", now); + WQLObject.getWQLObject("pdm_bd_workorder").insert(work_order); } @Override @@ -175,22 +181,43 @@ public class WorkorderServiceImpl implements WorkordeService { @Override @Transactional(rollbackFor = Exception.class) public void submits(JSONObject param) { - Long currentUserId = SecurityUtils.getCurrentUserId(); - String nickName = SecurityUtils.getCurrentNickName(); - String now = DateUtil.now(); + String workorder_id = param.getString("workorder_id"); + JSONObject submit_obj = WQL + .getWO("MPS_PRODUCEDURE001") + .addParam("flag", "5") + .addParam("workorder_id", workorder_id) + .process() + .uniqueResult(0); + if (submit_obj.getIntValue("order_status") > 1) { + throw new BadRequestException("工单已开工!"); + } - WQLObject wo = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - JSONObject json = wo.query("workorder_id = '" + param.getString("workorder_id") + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(json.getString("device_id"))) throw new BadRequestException("请先绑定设备"); + JSONObject workorder = WQLObject + .getWQLObject("pdm_bd_workorder") + .query("is_delete = '0' AND device_code = '" + submit_obj.getString("workorder_code") + "' AND order_status IN ('2', '3')") + .uniqueResult(0); + if (ObjectUtil.isNotEmpty(workorder)) { + throw new BadRequestException("该设备正在执行其它工单!"); + } - JSONArray orderArr = wo.query("device_id = '" + param.getString("device_id") + "' and order_status = '02'").getResultJSONArray(0); - if (ObjectUtil.isNotEmpty(orderArr)) throw new BadRequestException("当前设备正在生产中"); + JSONArray request = new JSONArray(); + request.add(submit_obj); + Map result; + try { + result = wmsToAcsService.order(request); + } catch (Exception e) { + log.error("工单开工报错!", e); + throw new RuntimeException(e); + } + if (HttpStatus.OK.value() != MapUtil.getInt(result, "status")) { + throw new BadRequestException(String.valueOf(result.get("message"))); + } - json.put("order_status", "02"); - json.put("update_optid", currentUserId); - json.put("update_optname", nickName); - json.put("update_time", now); - wo.update(json); + JSONObject order_status = new JSONObject(); + order_status.put("order_status", WorkOrderEnum.ORDER_STATUS_DELIVERED.value()); + WQLObject + .getWQLObject("pdm_bd_workorder") + .update(order_status, "workorder_id = " + workorder_id); } @Override diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/pdm/wql/MPS_PRODUCEDURE001.wql b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/wql/MPS_PRODUCEDURE001.wql index cea81bf..ea15295 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/pdm/wql/MPS_PRODUCEDURE001.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/pdm/wql/MPS_PRODUCEDURE001.wql @@ -55,11 +55,19 @@ SELECT ShiftOrder.*, material.material_code, +<<<<<<< Updated upstream material.material_name, material.material_spec FROM PDM_BD_WORKORDER ShiftOrder LEFT JOIN md_me_materialbase material ON material.material_id = ShiftOrder.material_id +======= + device.device_name + FROM + PDM_BD_WORKORDER ShiftOrder + LEFT JOIN md_me_materialbase material ON material.material_id = ShiftOrder.material_id + LEFT JOIN pdm_bi_device device ON ShiftOrder.device_id = device.device_id +>>>>>>> Stashed changes WHERE ShiftOrder.is_delete = '0' OPTION 输入.unFinish <> "" @@ -67,27 +75,19 @@ ENDOPTION OPTION 输入.order_status <> "" find_in_set( ShiftOrder.order_status, 输入.order_status) - ENDOPTION - OPTION 输入.shift_type_scode <> "" - ShiftOrder.shift_type_scode = 输入.shift_type_scode - ENDOPTION - OPTION 输入.workorder_procedure <> "" - ShiftOrder.workorder_procedure = 输入.workorder_procedure ENDOPTION OPTION 输入.begin_time <> "" - ShiftOrder.produce_date >= 输入.begin_time + ShiftOrder.planproducestart_date >= 输入.begin_time ENDOPTION OPTION 输入.end_time <> "" - ShiftOrder.produce_date <= 输入.end_time + ShiftOrder.planproduceend_date <= 输入.end_time ENDOPTION OPTION 输入.produceorder_code <> "" ShiftOrder.produceorder_code like 输入.produceorder_code ENDOPTION OPTION 输入.material <> "" ( - material.material_code like 输入.material or - material.material_name like 输入.material or - material.material_spec like 输入.material + material.material_code like '%' 输入.material '%' ) ENDOPTION ENDSELECT @@ -116,7 +116,6 @@ shiftOrder.*, workprocedure.workprocedure_name, material.material_code, - material.material_name, material.material_spec FROM PDM_BD_WORKORDER shiftOrder @@ -165,3 +164,26 @@ ENDQUERY ENDIF + IF 输入.flag = "6" + QUERY + SELECT + workorder.workorder_code, + workorder.plan_qty, + workorder.device_code, + workorder.order_status, + material.material_code, + material.product_code, + material.a, + material.b, + material.h, + material.w + FROM + pdm_bd_workorder workorder + LEFT JOIN md_me_materialbase material ON workorder.material_id = material.material_id + WHERE + workorder.is_delete = '0' + AND workorder.workorder_id = 输入.workorder_id + ENDSELECT + ENDQUERY + ENDIF + diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/AcsUtil.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/AcsUtil.java index 6884c31..c9aef1b 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/AcsUtil.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/AcsUtil.java @@ -41,8 +41,7 @@ public class AcsUtil { //网络不通 System.out.println(msg); result.put("status", HttpStatus.BAD_REQUEST); - result.put("message", "网络不通,操作失败!"); - result.put("data", new JSONObject()); + result.put("message", msg); } //acs抛异常这里 /*if (result.getString("status").equals(String.valueOf(HttpStatus.BAD_REQUEST.value()))) diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/ACSSystem.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/ACSSystem.java new file mode 100644 index 0000000..3c06f99 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/ACSSystem.java @@ -0,0 +1,14 @@ +package org.nl.wms.sch.manage; + +/** + * @author zhangjiangwei + * @date 2023/03/03 10:42 + */ +public class ACSSystem { + + public static final long id = 20L; + + public static final String username = "acs"; + + public static final String nick_name = "ACS系统"; +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AbstractAcsTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AbstractAcsTask.java index 1473a84..280abb6 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AbstractAcsTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AbstractAcsTask.java @@ -1,12 +1,18 @@ package org.nl.wms.sch.manage; +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 org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.wql.core.bean.WQLObject; import org.nl.wms.sch.AcsUtil; -import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.sch.task.AcsTaskDTO; +import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.List; /** @@ -24,7 +30,7 @@ public abstract class AbstractAcsTask { * @author ldjun * @created 2020年6月12日 下午5:55:25 */ - public List schedule() { + public List schedule() { this.autoCreate(); this.findStartPoint(); this.findNextPoint(); @@ -36,7 +42,34 @@ public abstract class AbstractAcsTask { * * @return */ - public abstract List addTask(); + public List addTask() { + JSONArray tasks = WQLObject + .getWQLObject("sch_base_task") + .query("is_delete = '0' AND task_status = " + TaskStatus.START_AND_END.value() + " AND handle_class = '" + this.getClass().getName() + "'") + .getResultJSONArray(0); + + ArrayList acsTasks = new ArrayList<>(); + for (Object o : tasks) { + JSONObject task = (JSONObject) o; + + AcsTaskDTO acsTask = AcsTaskDTO + .builder() + .task_id(task.getString("task_id")) + .task_code(task.getString("task_code")) + .task_type(task.getString("acs_task_type")) + .start_device_code(task.getString("point_code1")) + .next_device_code(task.getString("point_code2")) + .vehicle_code(task.getString("vehicle_code")) + .vehicle_type(task.getString("vehicle_type")) + .priority(task.getString("priority")) + .remark(task.getString("remark")) + .build(); + + acsTasks.add(acsTask); + } + + return acsTasks; + }; /** * @param taskObj 代表一条任务对象 @@ -107,15 +140,60 @@ public abstract class AbstractAcsTask { /** * */ - public JSONObject immediateNotifyAcs() { - List taskList = this.schedule(); - if (ObjectUtil.isNotEmpty(taskList)) { + public JSONObject immediateNotifyAcs(String taskId) { + WQLObject taskTable = WQLObject.getWQLObject("sch_base_task"); + JSONArray tasks = taskTable + .query("task_id = " + taskId) + .getResultJSONArray(0); - JSONArray arr = JSONArray.parseArray(JSON.toJSONString(taskList)); - return AcsUtil.notifyAcs("api/wms/task", arr); + if (ObjectUtil.isNotEmpty(tasks)) { + String taskStatus = ((JSONObject) tasks.get(0)).getString("task_status"); + if (!StrUtil.equals(taskStatus, TaskStatus.START_AND_END.value())) { + throw new BadRequestException("只能下发已确认起点和终点的任务"); + } + + JSONObject result = AcsUtil.notifyAcs("api/wms/task", tasks); + + String status = result.getString("status"); + String message = result.getString("message"); + //发送失败的任务JSON集合:task_id,message + JSONArray errArr = result.getJSONArray("errArr"); + + //任务下发以后,更新任务状态 + //成功 + if ("200".equals(status)) { + tasks.forEach(item -> { + JSONObject taskObj = new JSONObject(); + taskObj.put("task_id", ((JSONObject) item).getString("task_id")); + taskObj.put("task_status", TaskStatus.ISSUE.value()); + taskObj.put("remark", "下发成功"); + taskObj.put("update_time", DateUtil.now()); + taskTable.update(taskObj); + }); + } else {//下发失败 + tasks.forEach(item -> { + JSONObject taskObj = new JSONObject(); + taskObj.put("task_id", ((JSONObject) item).getString("task_id")); +// taskObj.put("task_status", TaskStatusEnum.ISSUE.getCode()); + taskObj.put("remark", "下发失败:" + message); + taskObj.put("update_time", DateUtil.now()); + taskTable.update(taskObj); + }); + } + //处理下发错误的任务 + if (ObjectUtil.isNotEmpty(errArr)) { + //处理下发失败的任务 + for (int i = 0; i < errArr.size(); i++) { + JSONObject taskObj = errArr.getJSONObject(i); + taskObj.put("remark", "下发失败:"+taskObj.getString("message")); + taskObj.put("update_time", DateUtil.now()); + taskTable.update(taskObj); + } + } + + return result; } return null; - } /** @@ -142,4 +220,23 @@ public abstract class AbstractAcsTask { return null; } + /** + * 取货完成 + */ + @Transactional(rollbackFor = Exception.class) + public void pickUpComplete(JSONObject task) { + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + JSONObject point1 = point_table.query("point_code = '" + task.getString("point_code1") + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(point1) + && LockType.TASK_LOCKED.value().equals(point1.getString("lock_type")) + && task.getString("task_code").equals(point1.getString("task_code"))) { + point1.put("lock_type", LockType.UNLOCKED.value()); + point1.put("task_code", ""); + point1.put("vehicle_type", ""); + point1.put("vehicle_code", ""); + point1.put("point_status", PointStatus.EMPTY.value()); + point_table.update(point1); + } + } + } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoCreate.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoCreate.java new file mode 100644 index 0000000..d85dabd --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoCreate.java @@ -0,0 +1,14 @@ +package org.nl.wms.sch.manage; + +/** + * @author zhangjiangwei + * @date 2023/04/12 21:44 + */ +public class AutoCreate { + + public static final long id = 21L; + + public static final String username = "auto"; + + public static final String nick_name = "自动"; +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoCreateTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoCreateTask.java index a299f32..507fe0a 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoCreateTask.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/AutoCreateTask.java @@ -8,13 +8,12 @@ import com.alibaba.fastjson.JSONObject; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.modules.wql.util.SpringContextHolder; import org.nl.wms.sch.AcsUtil; -import org.nl.wms.sch.tasks.AcsTaskDto; +import org.nl.wms.sch.task.AcsTaskDTO; import org.reflections.Reflections; import org.springframework.stereotype.Component; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -23,7 +22,7 @@ import java.util.Set; @Component public class AutoCreateTask { // 下发acs的任务集合 - private List taskList = null; + private List taskList = null; private Set> subTypes = null; WQLObject taskTab = null; @@ -31,7 +30,7 @@ public class AutoCreateTask { @SneakyThrows public void run() { if (ObjectUtil.isNull(subTypes) || subTypes.isEmpty()) { - Reflections reflections = new Reflections("org.nl.wms.sch.tasks"); + Reflections reflections = new Reflections("org.nl.wms.sch.task"); subTypes = reflections.getSubTypesOf(AbstractAcsTask.class); } if (ObjectUtil.isNull(taskTab)) taskTab = WQLObject.getWQLObject("sch_base_task"); @@ -45,16 +44,10 @@ public class AutoCreateTask { subTypes.forEach(clz -> { // 调用AbstractAcsTask类的每个子类的schedule()方法 try { - Object obj = clz.newInstance(); - //Method m = obj.getClass().getDeclaredMethod("schedule"); - Method m = obj.getClass().getMethod("schedule"); - List tasks = (List) m.invoke(obj); + List tasks = SpringContextHolder.getBean(clz).schedule(); if (ObjectUtil.isNotEmpty(tasks)) { taskList.addAll(tasks); } - } catch (InvocationTargetException e) { - e.printStackTrace(); - log.info("定时器执行失败:{}", e.getTargetException().getMessage()); } catch (Exception e) { e.printStackTrace(); log.info("定时器执行失败:{}", e.getMessage()); @@ -88,7 +81,7 @@ public class AutoCreateTask { taskList.forEach(item -> { JSONObject taskObj = new JSONObject(); taskObj.put("task_id", item.getTask_id()); - taskObj.put("task_status", TaskStatusEnum.ISSUE.getCode()); + taskObj.put("task_status", TaskStatus.ISSUE.value()); taskObj.put("remark", "下发成功"); taskObj.put("update_time", DateUtil.now()); taskTab.update(taskObj); @@ -108,7 +101,7 @@ public class AutoCreateTask { //处理下发失败的任务 for (int i = 0; i < errArr.size(); i++) { JSONObject taskObj = errArr.getJSONObject(i); - taskObj.put("remark", "下发失败:"+taskObj.getString("message")); + taskObj.put("remark", "下发失败:" + taskObj.getString("message")); taskObj.put("update_time", DateUtil.now()); taskTab.update(taskObj); } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/CreateMode.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/CreateMode.java new file mode 100644 index 0000000..3800c29 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/CreateMode.java @@ -0,0 +1,32 @@ +package org.nl.wms.sch.manage; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 生成方式枚举类 + * + * @author 张江玮 + * @date 2022/11/01 15:57 + */ +@AllArgsConstructor +public enum CreateMode { + + PCCS("PC产生", "1"), + ACSSQ("ACS申请", "2"), + SCCJ("手持创建", "3"), + WBJK("外部接口", "4"), + ZDSC("自动生成", "5"); + + private final String label; + + private final String value; + + public String label() { + return this.label; + } + + public String value() { + return this.value; + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/FinishTypeEnum.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/FinishTypeEnum.java deleted file mode 100644 index a64986f..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/FinishTypeEnum.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.nl.wms.sch.manage; - -/** - * 完成方式:00自动,01:手动 - */ -public enum FinishTypeEnum { - AUTO("00", "自动"), - WCS_DELETE("01", "手动"); - private String name; - private String code; - - private FinishTypeEnum(String code, String name) { - this.code = code; - this.name = name; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } -} - diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/LockType.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/LockType.java new file mode 100644 index 0000000..89915d5 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/LockType.java @@ -0,0 +1,34 @@ +package org.nl.wms.sch.manage; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * @author zhangjiangwei + * @date 2023/03/03 9:41 + */ +@RequiredArgsConstructor +public enum LockType { + + UNLOCKED("未锁定", "1"), + TASK_LOCKED("任务锁定", "2"); + + private final String label; + + private final String value; + + public String label() { + return this.label; + } + + public String value() { + return this.value; + } + + public static LockType get(String value) { + return Arrays.stream(LockType.values()).filter(lt -> lt.value.equals(value)).collect(Collectors.toList()).get(0); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/OperationType.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/OperationType.java new file mode 100644 index 0000000..3307a0b --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/OperationType.java @@ -0,0 +1,24 @@ +package org.nl.wms.sch.manage; + +import lombok.RequiredArgsConstructor; + +/** + * 操作类型 + */ +@RequiredArgsConstructor +public enum OperationType { + AUTO("自动", "1"), + MANUAL("手动", "2"); + + private final String label; + private final String value; + + public String label() { + return this.label; + } + + public String value() { + return this.value; + } +} + diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/PointStatus.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/PointStatus.java new file mode 100644 index 0000000..528c9dd --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/PointStatus.java @@ -0,0 +1,29 @@ +package org.nl.wms.sch.manage; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 任务状态 + * + * @author zhangjiangwei + * @date 2023/03/03 9:26 + */ +@RequiredArgsConstructor +public enum PointStatus { + + EMPTY("无货", "0"), + NOT_EMPTY("有货", "1"); + + private final String label; + + private final String value; + + public String label() { + return this.label; + } + + public String value() { + return this.value; + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/Region.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/Region.java new file mode 100644 index 0000000..24ce965 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/Region.java @@ -0,0 +1,41 @@ +package org.nl.wms.sch.manage; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * 区域枚举类 + * + * @author 张江玮 + * @date 2022/11/22 16:16 + */ +@RequiredArgsConstructor +public enum Region { + + HL("混料区", "HL"), + KLHJ("困料货架", "KLHJ"), + YZ("压制区", "YZ"), + CPHJ("成品货架", "CPHJ"), + SZ("烧制区", "SZ"), + FJ("分拣区", "FJ"), + BTHC("半托缓存区", "BTHC"), + GTK("钢托库", "GTK"); + + private final String label; + private final String value; + + public String label() { + return this.label; + } + + public String value() { + return this.value; + } + + public static Region get(String value) { + return Arrays.stream(Region.values()).filter(r -> r.value.equals(value)).collect(Collectors.toList()).get(0); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/RegionEnum.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/RegionEnum.java deleted file mode 100644 index c41ade8..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/RegionEnum.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.nl.wms.sch.manage; - -import cn.hutool.core.util.StrUtil; -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 区域枚举类 - * - * @author 张江玮 - * @date 2022/11/22 16:16 - */ -@AllArgsConstructor -@Getter -public enum RegionEnum { - - KLHJ("1590223405414748160", "KLHJ", "困料货架"), - RYZCQ("1590223672247980032", "RYZCQ", "入窑暂存区"), - CYZCQ("1590223771673956352", "CYZCQ", "出窑暂存区"), - BZZCQ("1590223846013800448", "BZZCQ", "包装暂存区"), - HNQ("1590223931246252032", "HNQ", "混碾区"), - YZQ("1590223991732310016", "YZQ", "压制区"), - YYJLZJ("1590224119046213632", "YYJLZJ", "液压机料盅架"), - YQ("1590224197186097152", "YQ", "窑区域"), - KGTCPQ("1590224331051503616", "KGTCPQ", "空钢托拆盘区"), - ZDCDX("1590224431970652160", "ZDCDX", "自动拆垛线"), - RGCPQ("1590224498601365504", "RGCPQ", "人工拆盘区域"), - BZQ("1590224549646045184", "BZQ", "包装区"), - KGTDPQ("1590224679409422336", "KGTDPQ", "空钢托叠盘区"); - - private String id; - private String code; - private String name; - - public static RegionEnum get(String id) { - for (RegionEnum regionEnum : RegionEnum.values()) { - if (StrUtil.equals(regionEnum.id, id)) { - return regionEnum; - } - } - return null; - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskStatus.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskStatus.java new file mode 100644 index 0000000..06a9ae5 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskStatus.java @@ -0,0 +1,26 @@ +package org.nl.wms.sch.manage; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum TaskStatus { + CREATED("生成", "1"), + SURE_START("确定起点", "2"), + SURE_END("确定终点", "3"), + START_AND_END("起点终点确认", "4"), + ISSUE("下发", "5"), + EXECUTING("执行中", "6"), + FINISHED("完成", "7"), + CANCELLED("取消", "8"); + + private final String label; + private final String value; + + public String label() { + return this.label; + } + + public String value() { + return this.value; + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskStatusEnum.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskStatusEnum.java deleted file mode 100644 index 8afd41e..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskStatusEnum.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.nl.wms.sch.manage; - -public enum TaskStatusEnum { - CREATED("1", "生成"), - SURE_START("2", "确定起点"), - SURE_END("3", "确定终点"), - START_AND_POINT("4", "起点终点确认"), - ISSUE("5", "下发"), - EXECUTING("6", "执行中"), - FINISHED("7", "完成"); - - private String name; - private String code; - - private TaskStatusEnum(String code, String name) { - this.code = code; - this.name = name; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } -} - diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskType.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskType.java new file mode 100644 index 0000000..fbad602 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/TaskType.java @@ -0,0 +1,30 @@ +package org.nl.wms.sch.manage; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +/** + * @author zhangjiangwei + * @date 2023/03/03 10:21 + */ +@RequiredArgsConstructor +public enum TaskType { + + SEND_MATERIAL("送料", "1"), + CALL_MATERIAL("叫料", "2"), + SEND_EMPTY("送空", "3"), + CALL_EMPTY("叫空", "4"); + + private final String label; + private final String value; + + public String label() { + return this.label; + } + + public String value() { + return this.value; + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatus.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatus.java new file mode 100644 index 0000000..a781445 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatus.java @@ -0,0 +1,21 @@ +package org.nl.wms.sch.manage; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * acs反馈任务状态 + * + * @author zhangjiangwei + * @date 2023/03/07 11:27 + */ +@RequiredArgsConstructor +@Getter +public enum UpdateTaskStatus { + CANCEL("任务取消", "0"), + EXECUTION("任务执行", "1"), + FINISHED("任务完成", "2"); + + private final String label; + private final String value; +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatusEnum.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatusEnum.java deleted file mode 100644 index 2b99f83..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/UpdateTaskStatusEnum.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.nl.wms.sch.manage; - -/** - * @author: lyd - * @description: 更新任务状态:ACS回传任务时任务状态 - * @Date: 2022/11/15 - */ -public enum UpdateTaskStatusEnum { - CANCEL("0","取消任务"), - EXECUTION("1","任务执行中"), - FORCEFINISH("2", "强制完成任务"); - - private final String code; - private final String name; - - UpdateTaskStatusEnum(String code, String name) { - this.code = code; - this.name = name; - } - - public String getCode() { - return code; - } - - public String getName() { - return name; - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/WorkOrderEnum.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/WorkOrderEnum.java index f5297a0..0169e03 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/WorkOrderEnum.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/manage/WorkOrderEnum.java @@ -1,10 +1,13 @@ package org.nl.wms.sch.manage; +import lombok.RequiredArgsConstructor; + /** * @author: lyd * @description: 工单枚举 * @Date: 2022/11/17 */ +@RequiredArgsConstructor public enum WorkOrderEnum { // 工单状态 ORDER_STATUS_UNPRODUCED("1", "未生产"), @@ -17,19 +20,14 @@ public enum WorkOrderEnum { IS_MIXIN_MATERIAL("2", "混料"), IS_OLD_MATERIAL("3", "旧料") ; - private final String code; - private final String name; + private final String value; + private final String label; - WorkOrderEnum(String code, String name) { - this.code = code; - this.name = name; + public String value() { + return this.value; } - public String getCode() { - return code; - } - - public String getName() { - return name; + public String label() { + return this.label; } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/rest/PointController.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/rest/PointController.java index ee3eb00..8dd392e 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/rest/PointController.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/rest/PointController.java @@ -71,6 +71,7 @@ public class PointController { pointService.deleteAll(ids); return new ResponseEntity<>(HttpStatus.OK); } + @PutMapping("/changeActive") @Log("修改点位启用状态") @ApiOperation("修改点位启用状态") @@ -92,14 +93,15 @@ public class PointController { @Log("查询点位管理") @ApiOperation("查询点位管理") //@SaCheckPermission("Point:list") - public ResponseEntity selectPoint(@RequestParam Map whereJson, Pageable page){ - return new ResponseEntity<>(pointService.selectPoint(whereJson,page),HttpStatus.OK); + public ResponseEntity selectPoint(@RequestParam Map whereJson, Pageable page) { + return new ResponseEntity<>(pointService.selectPoint(whereJson, page), HttpStatus.OK); } + @GetMapping("/getRegion") @Log("获取区域") @ApiOperation("获取区域") - public ResponseEntity getRegion(){ - return new ResponseEntity<>(pointService.getRegion(),HttpStatus.OK); + public ResponseEntity getRegion() { + return new ResponseEntity<>(pointService.getRegion(), HttpStatus.OK); } @Log("启动与禁用") @@ -119,36 +121,14 @@ public class PointController { } @GetMapping("/add") - @SaIgnore public ResponseEntity add() { - WQLObject sch_base_point = WQLObject.getWQLObject("SCH_BASE_Point"); - - String code = ""; - String name = "1排"; - for (int i = 1; i <= 10; i++) { - if (i < 10) { - code = "BTHC" + "0" + i; - } else { - code = "BTHC" + i; - } - JSONObject object = new JSONObject(); - object.put("point_id", IdUtil.getSnowflake(1, 1).nextId()); - object.put("point_code", code); - object.put("point_name", "半托缓存" + i); - object.put("region_id", "1590223846013800448"); - object.put("region_code", "BZZCQ"); - object.put("region_name", "包装暂存区"); - object.put("lock_type", "1"); - object.put("vehicle_max_qty", "0"); - object.put("vehicle_qty", "0"); - object.put("create_id", SecurityUtils.getCurrentUserId()); - object.put("update_optid", SecurityUtils.getCurrentUserId()); - object.put("create_name", SecurityUtils.getCurrentNickName()); - object.put("update_optname", SecurityUtils.getCurrentNickName()); - object.put("create_time", DateUtil.now()); - object.put("update_time", DateUtil.now()); - sch_base_point.insert(object); - } return new ResponseEntity<>(HttpStatus.NO_CONTENT); } + + @PostMapping("/getDevice") + @Log("获取设备列表") + @ApiOperation("获取设备列表") + public ResponseEntity getDevice() { + return new ResponseEntity<>(pointService.getDevice(), HttpStatus.OK); + } } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/rest/TaskController.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/rest/TaskController.java index cafc411..90ea8d6 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/rest/TaskController.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/rest/TaskController.java @@ -9,8 +9,8 @@ import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.nl.modules.logging.annotation.Log; -import org.nl.wms.sch.manage.FinishTypeEnum; -import org.nl.wms.sch.manage.TaskStatusEnum; +import org.nl.wms.sch.manage.OperationType; +import org.nl.wms.sch.manage.TaskStatus; import org.nl.wms.sch.service.TaskService; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; @@ -44,12 +44,12 @@ public class TaskController { @Log("获取任务状态列表") @ApiOperation("获取任务状态列表") public ResponseEntity getTaskStatus() { - TaskStatusEnum[] values = TaskStatusEnum.values(); + TaskStatus[] values = TaskStatus.values(); JSONArray arr = new JSONArray(); - for (TaskStatusEnum value : values) { + for (TaskStatus value : values) { JSONObject json = new JSONObject(); - json.put("code", value.getCode()); - json.put("name", value.getName()); + json.put("code", value.value()); + json.put("name", value.label()); arr.add(json); } //增加未完成状态 @@ -65,12 +65,12 @@ public class TaskController { @Log("获取任务类型列表") @ApiOperation("获取任务类型列表") public ResponseEntity getFinishType() { - FinishTypeEnum[] values = FinishTypeEnum.values(); + OperationType[] values = OperationType.values(); JSONArray arr = new JSONArray(); - for (FinishTypeEnum value : values) { + for (OperationType value : values) { JSONObject json = new JSONObject(); - json.put("code", value.getCode()); - json.put("name", value.getName()); + json.put("code", value.value()); + json.put("name", value.label()); arr.add(json); } return new ResponseEntity<>(arr, HttpStatus.OK); diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/PointService.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/PointService.java index d4eec70..5d112fb 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/PointService.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/PointService.java @@ -96,4 +96,6 @@ public interface PointService { * @param jsonObject */ void changeLock(JSONObject jsonObject); + + JSONArray getDevice(); } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/dto/PointDto.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/dto/PointDto.java index a27e6c7..68062d7 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/dto/PointDto.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/dto/PointDto.java @@ -46,54 +46,18 @@ public class PointDto implements Serializable { /** 设备编码 */ private String device_code; - /** MES设备编码 */ - private String mes_device_code; - - /** 允许的载具类型 */ - private String can_vehicle_type; - /** 载具类型 */ private String vehicle_type; /** 载具编码 */ private String vehicle_code; - /** 载具数量 */ - private String vehicle_qty; - - /** 块 */ - private BigDecimal block_num; - - /** 排 */ - private BigDecimal row_num; - - /** 列 */ - private BigDecimal col_num; - - /** 层 */ - private BigDecimal layer_num; - - /** 点位组编码 */ - private String point_group_code; - - /** 是否建工单 */ - private String is_have_workder; - /** 备注 */ private String remark; - /** 来源标识 */ - private Long source_id; - - /** 是否有光电 */ - private String is_light; - /** 是否启用 */ private String is_used; - /** 是否删除 */ - private String is_delete; - /** 创建人 */ private Long create_id; @@ -111,52 +75,4 @@ public class PointDto implements Serializable { /** 修改时间 */ private String update_time; - - /** 载具允许最大数量 */ - private BigDecimal vehicle_max_qty; - - /** 入库顺序 */ - private BigDecimal in_order_seq; - - /** 出库顺序 */ - private BigDecimal out_order_seq; - - /** 入空载具顺序 */ - private BigDecimal in_empty_seq; - - /** 出空载具顺序 */ - private BigDecimal out_empty_seq; - - /** 在执行的任务标识 */ - private Long task_id; - - /** 物料标识 */ - private String material_id; - - /** 批次 */ - private String pcsn; - - /** 库存数 */ - private BigDecimal ivt_qty; - - /** 计量单位标识 */ - private Long qty_unit_id; - - /** 库存数 */ - private BigDecimal ivt_weight; - - /** 计量单位标识 */ - private Long weight_unit_id; - - /** 入库时间 */ - private String instorage_time; - - /** 静置时间(分钟) */ - private BigDecimal standing_time; - - /** 是否关联库存表 */ - private String is_ref_ivt; - - /** 组盘标识 */ - private Long group_id; } diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/impl/PointServiceImpl.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/impl/PointServiceImpl.java index a3dd7f3..5f47843 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/impl/PointServiceImpl.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/service/impl/PointServiceImpl.java @@ -11,6 +11,7 @@ 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.CommonUtils; import org.nl.modules.common.utils.SecurityUtils; import org.nl.modules.wql.WQL; import org.nl.modules.wql.core.bean.WQLObject; @@ -19,13 +20,11 @@ import org.nl.wms.sch.service.PointService; import org.nl.wms.sch.service.RegionService; import org.nl.wms.sch.service.dto.PointDto; import org.nl.wms.sch.service.dto.RegionDto; -import org.nl.wms.sch.tasks.PointUpdateUtil; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -43,7 +42,7 @@ public class PointServiceImpl implements PointService { @Override public Map queryAll(Map whereJson, Pageable page) { - HashMap map = new HashMap(); + JSONObject map = new JSONObject(); map.put("flag", "1"); map.put("region_id", whereJson.get("region_id")); map.put("ids", whereJson.get("ids")); @@ -59,26 +58,14 @@ public class PointServiceImpl implements PointService { for (int i = 0; i < content.size(); i++) { JSONObject object = content.getJSONObject(i); Long region_id = object.getLong("region_id"); - String point_status = object.getString("point_status"); String point_type = object.getString("point_type"); RegionDto regionDto = regionService.findById(region_id); - String point_status_explain = regionDto.getPoint_status_explain(); String point_type_explain = regionDto.getPoint_type_explain(); - // 获取点位状态名称 - /*if (!ObjectUtil.isEmpty(point_status)) { - JSONObject statusArr = new JSONObject(); - String[] split = point_status_explain.split(","); - for ( int j = 0; j < split.length; j++) { - String[] status = split[j].split("-"); - statusArr.put(status[0], status[1]); - } - object.put("point_status_name", statusArr.getString(point_status)); - }*/ // 获取点位类型 if (!ObjectUtil.isEmpty(point_type)) { JSONObject typeArr = new JSONObject(); String[] split = point_type_explain.split(","); - for ( int j = 0; j < split.length; j++) { + for (int j = 0; j < split.length; j++) { String[] types = split[j].split("-"); typeArr.put(types[0], types[1]); } @@ -94,19 +81,17 @@ public class PointServiceImpl implements PointService { public List queryAll(Map whereJson) { WQLObject wo = WQLObject.getWQLObject("sch_base_point"); JSONArray arr = wo.query().getResultJSONArray(0); - List list = arr.toJavaList(PointDto.class); - return list; + return arr.toJavaList(PointDto.class); } @Override public PointDto findById(Long point_id) { WQLObject wo = WQLObject.getWQLObject("sch_base_point"); - JSONObject json = wo.query("point_id =" + point_id + "").uniqueResult(0); + JSONObject json = wo.query("point_id = " + point_id).uniqueResult(0); if (ObjectUtil.isNotEmpty(json)) { return json.toJavaObject(PointDto.class); } - final PointDto obj = json.toJavaObject(PointDto.class); - return obj; + return null; } @@ -169,27 +154,11 @@ public class PointServiceImpl implements PointService { String pointStatus = dto.getPoint_status(); if (ObjectUtil.isNotEmpty(pointStatus) && pointStatus.equals("1")) { // 空位 - dto.setMaterial_id(""); dto.setVehicle_type(""); dto.setVehicle_code(""); - dto.setVehicle_qty(""); - dto.setPcsn(""); - dto.setTask_id(null); - dto.setIvt_qty(BigDecimal.valueOf(0)); - dto.setInstorage_time(null); - dto.setStanding_time(BigDecimal.valueOf(0)); // PointUpdateUtil.clearPoint(dto.getPoint_code()); } else if (pointStatus.equals("2")) { // 空载具 - dto.setMaterial_id(null); - dto.setInstorage_time(now); - dto.setStanding_time(BigDecimal.valueOf(0)); } else if (pointStatus.equals("3")) { // 有料 - if (ObjectUtil.isEmpty(dto.getMaterial_id())) throw new BadRequestException("物料不能为空"); - if (ObjectUtil.isEmpty(dto.getIvt_qty())) throw new BadRequestException("库存数不能为空"); - JSONObject materialObj = materialBaseTab.query("material_id = '" + dto.getMaterial_id() + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(materialObj)) throw new BadRequestException("未找到该物料"); - dto.setStanding_time(materialObj.getBigDecimal("standing_time")); - dto.setInstorage_time(now); } JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); pointTab.update(json); @@ -199,20 +168,8 @@ public class PointServiceImpl implements PointService { @Override @Transactional(rollbackFor = Exception.class) public void deleteAll(Long[] ids) { - Long currentUserId = SecurityUtils.getCurrentUserId(); - String nickName = SecurityUtils.getCurrentNickName(); - String now = DateUtil.now(); - - WQLObject wo = WQLObject.getWQLObject("sch_base_point"); - for (Long point_id : ids) { - JSONObject param = new JSONObject(); - param.put("point_id", String.valueOf(point_id)); - param.put("is_delete", "1"); - param.put("update_optid", currentUserId); - param.put("update_optname", nickName); - param.put("update_time", now); - wo.update(param); - } + String ids_str = CommonUtils.idsArrayToInStr(ids); + WQLObject.getWQLObject("sch_base_point").delete("point_id IN " + ids_str); } @Override @@ -296,7 +253,7 @@ public class PointServiceImpl implements PointService { WQLObject wo = WQLObject.getWQLObject("sch_base_Point"); JSONArray data = jsonObject.getJSONArray("data"); String used = jsonObject.getString("used"); - for ( int i = 0; i < data.size(); i++ ) { + for (int i = 0; i < data.size(); i++) { JSONObject object = data.getJSONObject(i); if (used.equals("1")) object.put("is_used", 1); else object.put("is_used", 0); @@ -314,7 +271,7 @@ public class PointServiceImpl implements PointService { WQLObject wo = WQLObject.getWQLObject("sch_base_Point"); JSONArray data = jsonObject.getJSONArray("data"); String lock = jsonObject.getString("lock_type"); - for ( int i = 0; i < data.size(); i++ ) { + for (int i = 0; i < data.size(); i++) { JSONObject object = data.getJSONObject(i); if (lock.equals("1")) object.put("lock_type", 1); else object.put("lock_type", 2); @@ -336,4 +293,9 @@ public class PointServiceImpl implements PointService { } return load_series; } + + @Override + public JSONArray getDevice() { + return WQLObject.getWQLObject("pdm_bi_device").query("1 = 1", "device_code ASC").getResultJSONArray(0); + } } 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 e3251ff..4f34900 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,10 +13,12 @@ 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.manage.TaskStatusEnum; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatus; import org.nl.wms.sch.service.PointService; import org.nl.wms.sch.service.RegionService; import org.nl.wms.sch.service.TaskService; @@ -123,23 +125,24 @@ public class TaskServiceImpl implements TaskService { String task_id = MapUtil.getStr(map, "task_id"); String method_name = MapUtil.getStr(map, "method_name"); JSONObject taskObj = WQLObject.getWQLObject("SCH_BASE_Task").query("task_id = '" + task_id + "'").uniqueResult(0); - if (taskObj.getString("task_status").equals(TaskStatusEnum.FINISHED.getCode())) throw new BadRequestException("任务已完成!"); + if (taskObj.getString("task_status").equals(TaskStatus.FINISHED.value())) throw new BadRequestException("任务已完成!"); // 任务处理类 String processing_class = taskObj.getString("handle_class"); String message = ""; // 根据任务类型获取对应的任务操作类 try { Class clz = Class.forName(processing_class); - Object obj = clz.newInstance(); + AbstractAcsTask task = (AbstractAcsTask) SpringContextHolder.getBean(clz); // 调用每个任务类的method_name()强制结束方法 - Method m; - JSONObject result; + JSONObject result = null; if (method_name.equals("immediateNotifyAcs")) { // 立即下发不需要参数 - m = obj.getClass().getMethod(method_name); - result = (JSONObject) m.invoke(obj); - } else { - m = obj.getClass().getMethod(method_name, String.class); - result = (JSONObject) m.invoke(obj, task_id); + result = task.immediateNotifyAcs(task_id); + } + if (method_name.equals("forceFinish")) { + task.forceFinish(task_id); + } + if (method_name.equals("cancel")) { + task.cancel(task_id); } if (ObjectUtil.isEmpty(result)) return; JSONArray arr = result.getJSONArray("errArr"); @@ -159,13 +162,6 @@ public class TaskServiceImpl implements TaskService { param.put("remark", "操作成功"); wo.update(param); } - } catch (InvocationTargetException e) { - if (ObjectUtil.isNull(e.getTargetException().getMessage())) { - message = e.getTargetException().toString(); - } else { - message = e.getTargetException().getMessage(); - } - throw new BadRequestException(message); } catch (Exception e) { e.printStackTrace(); throw new BadRequestException("任务操作失败!"); diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/AcsTaskDto.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/AcsTaskDTO.java similarity index 91% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/AcsTaskDto.java rename to lms/nladmin-system/src/main/java/org/nl/wms/sch/task/AcsTaskDTO.java index c76d653..50228d0 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/AcsTaskDto.java +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/AcsTaskDTO.java @@ -1,11 +1,11 @@ -package org.nl.wms.sch.tasks; +package org.nl.wms.sch.task; import lombok.Builder; import lombok.Data; @Data @Builder -public class AcsTaskDto { +public class AcsTaskDTO { //任务标识 private String task_id; //任务编码 diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/empty/HLCallEmptyTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/empty/HLCallEmptyTask.java new file mode 100644 index 0000000..4d305dc --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/empty/HLCallEmptyTask.java @@ -0,0 +1,108 @@ +package org.nl.wms.sch.task.call.empty; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.basedata.eum.TrueOrFalse; +import org.nl.wms.basedata.eum.VehicleType; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.LockType; +import org.nl.wms.sch.manage.TaskStatus; +import org.nl.wms.sch.manage.TaskType; +import org.nl.wms.sch.task.util.TaskUtils; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * 辽宁晟华混料 叫空 任务类 + * + * @author zhangjiangwei + * @date 2023/03/03 9:08 + */ +@RequiredArgsConstructor +@Component +public class HLCallEmptyTask extends AbstractAcsTask { + + @Override + public void updateTaskStatus(JSONObject taskObj, String status) { + + } + + @Transactional(rollbackFor = Exception.class) + @Override + public String createTask(JSONObject form) { + JSONObject point = form.getJSONObject("point"); + + TaskUtils.isEmpty(point); + TaskUtils.isLocked(point); + JSONObject work_order = TaskUtils.hasWorkOrder(point); + + JSONObject task = TaskUtils.buildTask( + "混料机叫空托盘", + TaskType.CALL_EMPTY.value(), + TaskStatus.SURE_END.value(), + null, + point.getString("point_code"), + null, + VehicleType.CUP.value(), + null, + TrueOrFalse.trueOrFalse(work_order.getString("is_urgent")) ? "99" : "1", + HLCallEmptyTask.class.getName(), + form.getString("create_mode"), + form.getString("request_param"), + form.getString("create_id"), + form.getString("create_name") + ); + WQLObject.getWQLObject("sch_base_task").insert(task); + + return task.getString("task_id"); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void findStartPoint() { + WQLObject task_table = WQLObject.getWQLObject("sch_base_task"); + JSONArray tasks = task_table + .query("is_delete = '0' AND task_status = '" + TaskStatus.SURE_END.value() + "' AND handle_class = '" + HLCallEmptyTask.class.getName() + "'", "priority DESC, create_time ASC") + .getResultJSONArray(0); + + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + for (int i = 0; i < tasks.size(); i++) { + JSONObject task = tasks.getJSONObject(i); + + JSONObject point = WQL + .getWO("CALL_EMPTY_TASK") + .addParam("flag", "1") + .addParam("vehicle_type", task.getString("vehicle_type")) + .process() + .uniqueResult(0); + + if (ObjectUtil.isNotEmpty(point)) { + task.put("task_status", TaskStatus.START_AND_END.value()); + task.put("point_code1", point.getString("point_code")); + task.put("vehicle_code", point.getString("vehicle_code")); + task.put("remark", ""); + task_table.update(task); + + point.put("lock_type", LockType.TASK_LOCKED.value()); + point_table.update(point); + } else { + task.put("remark", "未找到合适的叫空载具点位!"); + task_table.update(task); + } + } + } + + @Override + public void forceFinish(String task_id) { + + } + + @Override + public void cancel(String task_id) { + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/empty/YZCallEmptyTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/empty/YZCallEmptyTask.java new file mode 100644 index 0000000..2522c83 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/empty/YZCallEmptyTask.java @@ -0,0 +1,207 @@ +package org.nl.wms.sch.task.call.empty; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.basedata.eum.TrueOrFalse; +import org.nl.wms.basedata.eum.VehicleType; +import org.nl.wms.sch.manage.*; +import org.nl.wms.sch.task.util.TaskUtils; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * 辽宁晟华压制 叫空 任务类 + * + * @author zhangjiangwei + * @date 2023/04/04 11:36 + */ +@RequiredArgsConstructor +@Component +public class YZCallEmptyTask extends AbstractAcsTask { + + @Transactional(rollbackFor = Exception.class) + @Override + public void updateTaskStatus(JSONObject task, String status) { + if (TaskStatus.EXECUTING.value().equals(status)) { + task.put("task_status", TaskStatus.EXECUTING.value()); + TaskUtils.addACSUpdateColum(task); + WQLObject.getWQLObject("sch_base_task").update(task); + } else if (TaskStatus.FINISHED.value().equals(status)) { + this.finishTask(task, OperationType.AUTO); + } else if (TaskStatus.CANCELLED.value().equals(status)) { + this.cancelTask(task, OperationType.AUTO); + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public String createTask(JSONObject form) { + JSONObject point = form.getJSONObject("point"); + JSONObject work_order = form.getJSONObject("workorder"); + String priority = "1"; + if (ObjectUtil.isNotEmpty(work_order)) { + priority = TrueOrFalse.trueOrFalse(work_order.getString("is_urgent")) ? "99" : "1"; + } + + JSONObject task = TaskUtils.buildTask( + "压制区叫空", + TaskType.CALL_EMPTY.value(), + TaskStatus.SURE_END.value(), + null, + point.getString("point_code"), + null, + VehicleType.STEEL_TRAY.value(), + null, + priority, + YZCallEmptyTask.class.getName(), + form.getString("create_mode"), + form.getString("request_param"), + form.getString("create_id"), + form.getString("create_name") + ); + WQLObject.getWQLObject("sch_base_task").insert(task); + + point.put("lock_type", LockType.TASK_LOCKED.value()); + point.put("task_code", task.getString("task_code")); + WQLObject.getWQLObject("sch_base_point").update(point); + + return task.getString("task_id"); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void findStartPoint() { + WQLObject task_table = WQLObject.getWQLObject("sch_base_task"); + JSONArray tasks = task_table + .query("is_delete = '0' AND task_status = '" + TaskStatus.SURE_END.value() + "' AND handle_class = '" + YZCallEmptyTask.class.getName() + "'", "priority DESC, create_time ASC") + .getResultJSONArray(0); + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + + for (int i = 0; i < tasks.size(); i++) { + JSONObject task = tasks.getJSONObject(i); + + JSONObject point = WQL + .getWO("CALL_EMPTY_TASK") + .addParam("flag", "1") + .addParam("point_code", task.getString("point_code2")) + .process() + .uniqueResult(0); + if (ObjectUtil.isEmpty(point)) { + point = WQL + .getWO("CALL_EMPTY_TASK") + .addParam("flag", "2") + .process() + .uniqueResult(0); + } + if (ObjectUtil.isNotEmpty(point)) { + task.put("task_status", TaskStatus.START_AND_END.value()); + task.put("point_code1", point.getString("point_code")); + task.put("vehicle_code", TaskUtils.formatVehicleCode(point.getString("vehicle_code"))); + task.put("remark", ""); + task_table.update(task); + + point.put("lock_type", LockType.TASK_LOCKED.value()); + point.put("task_code", task.getString("task_code")); + point_table.update(point); + } + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void forceFinish(String task_id) { + JSONObject task = WQLObject.getWQLObject("sch_base_task").query("task_id = " + task_id).uniqueResult(0); + if (ObjectUtil.isEmpty(task)) { + throw new BadRequestException("未找到任务!"); + } + this.finishTask(task, OperationType.MANUAL); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void cancel(String task_id) { + JSONObject task = WQLObject.getWQLObject("sch_base_task").query("task_id = " + task_id).uniqueResult(0); + if (ObjectUtil.isEmpty(task)) { + throw new BadRequestException("未找到任务!"); + } + this.cancelTask(task, OperationType.MANUAL); + } + + @Transactional(rollbackFor = Exception.class) + public void cancelTask(JSONObject task, OperationType operation_type) { + task.put("task_status", TaskStatus.CANCELLED.value()); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(task); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(task); + } + WQLObject.getWQLObject("sch_base_task").update(task); + + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + JSONObject point1 = point_table.query("point_code = '" + task.getString("point_code1") + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(point1) + && LockType.TASK_LOCKED.value().equals(point1.getString("lock_type")) + && task.getString("task_code").equals(point1.getString("task_code"))) { + point1.put("lock_type", LockType.UNLOCKED.value()); + point1.put("task_code", ""); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point1); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point1); + } + point_table.update(point1); + } + + JSONObject point2 = new JSONObject(); + point2.put("lock_type", LockType.UNLOCKED.value()); + point2.put("task_code", ""); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point2); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point2); + } + point_table.update(point2, "point_code = '" + task.getString("point_code2") + "'"); + } + + @Transactional(rollbackFor = Exception.class) + public void finishTask(JSONObject task, OperationType operation_type) { + task.put("task_status", TaskStatus.FINISHED.value()); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(task); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(task); + } + WQLObject.getWQLObject("sch_base_task").update(task); + + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + JSONObject point1 = point_table.query("point_code = '" + task.getString("point_code1") + "'").uniqueResult(0); + if (LockType.TASK_LOCKED.value().equals(point1.getString("lock_type")) + && task.getString("task_code").equals(point1.getString("task_code"))) { + point1.put("lock_type", LockType.UNLOCKED.value()); + point1.put("task_code", ""); + point1.put("vehicle_type", ""); + point1.put("vehicle_code", ""); + point1.put("point_status", PointStatus.EMPTY.value()); + TaskUtils.addCurrentUpdateColum(point1); + point_table.update(point1); + } + + JSONObject point2 = new JSONObject(); + point2.put("lock_type", LockType.UNLOCKED.value()); + point2.put("task_code", ""); + point2.put("vehicle_type", task.getString("vehicle_type")); + point2.put("vehicle_code", task.getString("vehicle_code")); + point2.put("point_status", PointStatus.NOT_EMPTY.value()); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point2); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point2); + } + point_table.update(point2, "point_code = '" + task.getString("point_code2") + "'"); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_fjSendMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/empty/wql/CALL_EMPTY_TASK.wql similarity index 51% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_fjSendMaterial_01.wql rename to lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/empty/wql/CALL_EMPTY_TASK.wql index b00f35b..f14b4bf 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_fjSendMaterial_01.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/empty/wql/CALL_EMPTY_TASK.wql @@ -1,5 +1,5 @@ [交易说明] - 交易名: 分拣送料 + 交易名: 叫空托盘 所属模块: 功能简述: 版权所有: @@ -13,11 +13,8 @@ ################################################# ## 表字段对应输入参数 ################################################# - 输入.flag TYPEAS s_string - 输入.region_code TYPEAS s_string - 输入.material_id TYPEAS s_string - 输入.vehicle_type TYPEAS s_string - + 输入.flag TYPEAS s_string + 输入.point_code TYPEAS s_string [临时表] --这边列出来的临时表就会在运行期动态创建 @@ -38,38 +35,41 @@ ########################################## - # 3、业务主过程 # + # 3、业务主过程 # ########################################## - IF 输入.flag = "1" - QUERY - SELECT - p.point_id, - p.point_code, - p.point_name + + IF 输入.flag = "1" + QUERY + SELECT + * FROM - SCH_BASE_Point p + sch_base_point point + LEFT JOIN st_ivt_vehicle_detail vd ON point.vehicle_type = vd.vehicle_type + AND point.vehicle_code = vd.vehicle_code WHERE - lock_type = '1' - AND is_used = '1' - AND is_delete = '0' - AND point_status = '1' - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - ORDER BY p.instorage_time - ENDSELECT - ENDQUERY - ENDIF + point.is_used = '1' + AND point.lock_type = '1' + AND point.region_code = 'CPHJ' + AND point.point_status = '1' + AND point.vehicle_type = '2' + AND vd.is_delete = '0' + AND vd.point_code = 输入.point_code + AND vd.is_full = '0' + ENDSELECT + ENDQUERY + ENDIF IF 输入.flag = "2" QUERY SELECT - p.point_code AS device_code + * FROM - SCH_BASE_Point p + sch_base_point WHERE - region_code = 'RGCPQ' - AND point_type = '2' + is_used = '1' + AND lock_type = '1' + AND region_code = 'GTK' + AND point_type = '3' ENDSELECT ENDQUERY ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/material/SZCallMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/material/SZCallMaterialTask.java new file mode 100644 index 0000000..e4a3e51 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/material/SZCallMaterialTask.java @@ -0,0 +1,209 @@ +package org.nl.wms.sch.task.call.material; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.basedata.eum.VehicleType; +import org.nl.wms.sch.manage.*; +import org.nl.wms.sch.task.util.TaskUtils; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * @author zhangjiangwei + * @date 2023/04/07 15:51 + */ +@RequiredArgsConstructor +@Component +public class SZCallMaterialTask extends AbstractAcsTask { + + @Transactional(rollbackFor = Exception.class) + @Override + public void autoCreate() { + JSONArray points = WQL.getWO("CALL_MATERIAL_TASK").addParam("flag", "1").process().getResultJSONArray(0); + if (ObjectUtil.isNotEmpty(points) && !points.isEmpty()) { + JSONObject form = new JSONObject(); + form.put("create_mode", CreateMode.ZDSC.value()); + form.put("create_id", AutoCreate.id); + form.put("create_name", AutoCreate.nick_name); + form.put("request_param", "auto"); + for (int i = 0; i < points.size(); i++) { + JSONObject point = points.getJSONObject(i); + form.put("point", point); + this.createTask(form); + } + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void updateTaskStatus(JSONObject task, String status) { + if (TaskStatus.EXECUTING.value().equals(status)) { + task.put("task_status", TaskStatus.EXECUTING.value()); + TaskUtils.addACSUpdateColum(task); + WQLObject.getWQLObject("sch_base_task").update(task); + } else if (TaskStatus.FINISHED.value().equals(status)) { + this.finishTask(task, OperationType.AUTO); + } else if (TaskStatus.CANCELLED.value().equals(status)) { + this.cancelTask(task, OperationType.AUTO); + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public String createTask(JSONObject form) { + JSONObject point = form.getJSONObject("point"); + + JSONObject task = TaskUtils.buildTask( + "烧制区叫料", + TaskType.CALL_MATERIAL.value(), + TaskStatus.SURE_END.value(), + null, + point.getString("point_code"), + null, + VehicleType.STEEL_TRAY.value(), + null, + "1", + SZCallMaterialTask.class.getName(), + form.getString("create_mode"), + form.getString("request_param"), + form.getString("create_id"), + form.getString("create_name") + ); + WQLObject.getWQLObject("sch_base_task").insert(task); + + point.put("lock_type", LockType.TASK_LOCKED.value()); + point.put("task_code", task.getString("task_code")); + WQLObject.getWQLObject("sch_base_point").update(point); + + return task.getString("task_id"); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void findStartPoint() { + WQLObject task_table = WQLObject.getWQLObject("sch_base_task"); + JSONArray tasks = task_table + .query("is_delete = '0' AND task_status = '" + TaskStatus.SURE_END.value() + "' AND handle_class = '" + SZCallMaterialTask.class.getName() + "'", "priority DESC, create_time ASC") + .getResultJSONArray(0); + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + + for (int i = 0; i < tasks.size(); i++) { + JSONObject task = tasks.getJSONObject(i); + + JSONObject point = WQL + .getWO("CALL_MATERIAL_TASK") + .addParam("flag", "1") + .process() + .uniqueResult(0); + + if (ObjectUtil.isNotEmpty(point)) { + task.put("task_status", TaskStatus.START_AND_END.value()); + task.put("point_code1", point.getString("point_code")); + task.put("material_id", point.getString("material_id")); + task.put("vehicle_code", TaskUtils.formatVehicleCode(point.getString("vehicle_code"))); + task.put("remark", ""); + task_table.update(task); + + JSONObject point_update = new JSONObject(); + point_update.put("lock_type", LockType.TASK_LOCKED.value()); + point_update.put("task_code", task.getString("task_code")); + point_table.update(point_update, "point_id = " + point.getLongValue("point_id")); + } + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void forceFinish(String task_id) { + JSONObject task = WQLObject.getWQLObject("sch_base_task").query("task_id = " + task_id).uniqueResult(0); + if (ObjectUtil.isEmpty(task)) { + throw new BadRequestException("未找到任务!"); + } + this.finishTask(task, OperationType.MANUAL); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void cancel(String task_id) { + JSONObject task = WQLObject.getWQLObject("sch_base_task").query("task_id = " + task_id).uniqueResult(0); + if (ObjectUtil.isEmpty(task)) { + throw new BadRequestException("未找到任务!"); + } + this.cancelTask(task, OperationType.MANUAL); + } + + @Transactional(rollbackFor = Exception.class) + public void cancelTask(JSONObject task, OperationType operation_type) { + task.put("task_status", TaskStatus.CANCELLED.value()); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(task); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(task); + } + WQLObject.getWQLObject("sch_base_task").update(task); + + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + JSONObject point1 = point_table.query("point_code = '" + task.getString("point_code1") + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(point1) + && LockType.TASK_LOCKED.value().equals(point1.getString("lock_type")) + && task.getString("task_code").equals(point1.getString("task_code"))) { + point1.put("lock_type", LockType.UNLOCKED.value()); + point1.put("task_code", ""); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point1); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point1); + } + point_table.update(point1); + } + + JSONObject point2 = new JSONObject(); + point2.put("lock_type", LockType.UNLOCKED.value()); + point2.put("task_code", ""); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point2); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point2); + } + point_table.update(point2, "point_code = '" + task.getString("point_code2") + "'"); + } + + @Transactional(rollbackFor = Exception.class) + public void finishTask(JSONObject task, OperationType operation_type) { + task.put("task_status", TaskStatus.FINISHED.value()); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(task); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(task); + } + WQLObject.getWQLObject("sch_base_task").update(task); + + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + JSONObject point1 = point_table.query("point_code = '" + task.getString("point_code1") + "'").uniqueResult(0); + if (LockType.TASK_LOCKED.value().equals(point1.getString("lock_type")) + && task.getString("task_code").equals(point1.getString("task_code"))) { + point1.put("lock_type", LockType.UNLOCKED.value()); + point1.put("task_code", ""); + point1.put("vehicle_type", ""); + point1.put("vehicle_code", ""); + point1.put("point_status", PointStatus.EMPTY.value()); + TaskUtils.addCurrentUpdateColum(point1); + point_table.update(point1); + } + + JSONObject point2 = new JSONObject(); + point2.put("lock_type", LockType.UNLOCKED.value()); + point2.put("task_code", ""); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point2); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point2); + } + point_table.update(point2, "point_code = '" + task.getString("point_code2") + "'"); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/material/wql/CALL_MATERIAL_TASK.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/material/wql/CALL_MATERIAL_TASK.wql new file mode 100644 index 0000000..03f14d2 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/call/material/wql/CALL_MATERIAL_TASK.wql @@ -0,0 +1,79 @@ +[交易说明] + 交易名: 叫空托盘 + 所属模块: + 功能简述: + 版权所有: + 表引用: + 版本经历: + +[数据库] + --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 + +[IO定义] + ################################################# + ## 表字段对应输入参数 + ################################################# + 输入.flag TYPEAS s_string + +[临时表] + --这边列出来的临时表就会在运行期动态创建 + +[临时变量] + --所有中间过程变量均可在此处定义 + +[业务过程] + + ########################################## + # 1、输入输出检查 # + ########################################## + + + ########################################## + # 2、主过程前处理 # + ########################################## + + + ########################################## + # 3、业务主过程 # + ########################################## + + IF flag = "1" + QUERY + SELECT + point.*, + vd.material_id, + workorder.is_urgent + FROM + sch_base_point point + JOIN st_ivt_vehicle_detail vd ON point.vehicle_type = vd.vehicle_type + AND point.vehicle_code = vd.vehicle_code + AND vd.is_delete = '0' + LEFT JOIN pdm_bd_workorder workorder ON vd.workorder_id = workorder.workorder_id + WHERE + point.is_used = '1' + AND point.lock_type = '1' + AND point.region_code = 'CPHJ' + AND point.point_status = '1' + AND point.vehicle_type = '2' + AND vd.is_fire = '0' + AND vd.if_in_kiln = '1' + ORDER BY + workorder.is_urgent DESC, vd.create_time ASC + ENDSELECT + ENDQUERY + ENDIF + + IF 输入.flag = "2" + QUERY + SELECT + * + FROM + sch_base_point + WHERE + is_used = '1' + AND lock_type = '1' + AND region_code = 'SZ' + AND point_type = '1' + ENDSELECT + ENDQUERY + ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/HLSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/HLSendMaterialTask.java new file mode 100644 index 0000000..1487abc --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/HLSendMaterialTask.java @@ -0,0 +1,83 @@ +package org.nl.wms.sch.task.send.material; + +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.basedata.eum.TrueOrFalse; +import org.nl.wms.basedata.eum.VehicleType; +import org.nl.wms.sch.manage.AbstractAcsTask; +import org.nl.wms.sch.manage.TaskStatus; +import org.nl.wms.sch.manage.TaskType; +import org.nl.wms.sch.task.util.TaskUtils; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * 辽宁晟华混料 送料入库 任务类 + * + * @author zhangjiangwei + * @date 2023/03/06 14:28 + */ +@RequiredArgsConstructor +@Component +public class HLSendMaterialTask extends AbstractAcsTask { + + + @Override + public void updateTaskStatus(JSONObject taskObj, String status) { + + } + + @Override + @Transactional + public String createTask(JSONObject form) { + JSONObject point = form.getJSONObject("point"); + + TaskUtils.isLocked(point); + JSONObject work_order = TaskUtils.hasWorkOrder(point); + + String vehicle_code = form.getString("vehicle_code"); + if ("0000".equals(vehicle_code)) { + throw new BadRequestException("载具编码不能为空!"); + } + + // todo 组盘 + + JSONObject task = TaskUtils.buildTask( + "混料机送料入库", + TaskType.SEND_MATERIAL.value(), + TaskStatus.SURE_START.value(), + point.getString("point_code"), + null, + work_order.getString("material_id"), + VehicleType.CUP.value(), + vehicle_code, + TrueOrFalse.trueOrFalse(work_order.getString("is_urgent")) ? "99" : "1", + HLSendMaterialTask.class.getName(), + form.getString("create_mode"), + form.getString("request_param"), + form.getString("create_id"), + form.getString("create_name") + ); + WQLObject.getWQLObject("sch_base_task").insert(task); + + return task.getString("task_id"); + } + + @Override + @Transactional + public void findNextPoint() { + + } + + @Override + public void forceFinish(String task_id) { + + } + + @Override + public void cancel(String task_id) { + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/SZSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/SZSendMaterialTask.java new file mode 100644 index 0000000..e631cc8 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/SZSendMaterialTask.java @@ -0,0 +1,199 @@ +package org.nl.wms.sch.task.send.material; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.basedata.eum.VehicleType; +import org.nl.wms.sch.manage.*; +import org.nl.wms.sch.task.util.TaskUtils; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * @author zhangjiangwei + * @date 2023/04/12 22:12 + */ +@RequiredArgsConstructor +@Component +public class SZSendMaterialTask extends AbstractAcsTask { + + @Transactional(rollbackFor = Exception.class) + @Override + public void updateTaskStatus(JSONObject task, String status) { + if (TaskStatus.EXECUTING.value().equals(status)) { + task.put("task_status", TaskStatus.EXECUTING.value()); + TaskUtils.addACSUpdateColum(task); + WQLObject.getWQLObject("sch_base_task").update(task); + } else if (TaskStatus.FINISHED.value().equals(status)) { + this.finishTask(task, OperationType.AUTO); + } else if (TaskStatus.CANCELLED.value().equals(status)) { + this.cancelTask(task, OperationType.AUTO); + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public String createTask(JSONObject form) { + JSONObject point = form.getJSONObject("point"); + String vehicle_code = form.getString("vehicle_code"); + WQLObject vd_table = WQLObject.getWQLObject("st_ivt_vehicle_detail"); + JSONObject vd = vd_table + .query("is_delete = '0' AND vehicle_type = '2' AND vehicle_code = '" + vehicle_code + "'") + .uniqueResult(0); + if (ObjectUtil.isEmpty(vd)) { + throw new BadRequestException("未找到 [" + vehicle_code + "] 的组盘信息!"); + } + vd.put("is_fire", "1"); + vd.put("is_in_kiln", "0"); + vd_table.update(vd); + + JSONObject task = TaskUtils.buildTask( + "烧制区送料", + TaskType.SEND_MATERIAL.value(), + TaskStatus.SURE_START.value(), + point.getString("point_code"), + null, + vd.getString("material_id"), + VehicleType.STEEL_TRAY.value(), + vehicle_code, + "1", + SZSendMaterialTask.class.getName(), + form.getString("create_mode"), + form.getString("request_param"), + form.getString("create_id"), + form.getString("create_name") + ); + WQLObject.getWQLObject("sch_base_task").insert(task); + + point.put("lock_type", LockType.TASK_LOCKED.value()); + point.put("task_code", task.getString("task_code")); + WQLObject.getWQLObject("sch_base_point").update(point); + + return task.getString("task_id"); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void findNextPoint() { + WQLObject task_table = WQLObject.getWQLObject("sch_base_task"); + JSONArray tasks = task_table + .query("is_delete = '0' AND task_status = '" + TaskStatus.SURE_START.value() + "' AND handle_class = '" + SZSendMaterialTask.class.getName() + "'", "priority DESC, create_time ASC") + .getResultJSONArray(0); + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + + for (int i = 0; i < tasks.size(); i++) { + JSONObject task = tasks.getJSONObject(i); + + JSONObject point = WQL + .getWO("SEND_MATERIAL_TASK") + .addParam("flag", "1") + .process() + .uniqueResult(0); + + if (ObjectUtil.isNotEmpty(point)) { + task.put("task_status", TaskStatus.START_AND_END.value()); + task.put("point_code2", point.getString("point_code")); + task.put("remark", ""); + task_table.update(task); + + point.put("lock_type", LockType.TASK_LOCKED.value()); + point.put("task_code", task.getString("task_code")); + point_table.update(point); + } + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void forceFinish(String task_id) { + JSONObject task = WQLObject.getWQLObject("sch_base_task").query("task_id = " + task_id).uniqueResult(0); + if (ObjectUtil.isEmpty(task)) { + throw new BadRequestException("未找到任务!"); + } + this.finishTask(task, OperationType.MANUAL); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void cancel(String task_id) { + JSONObject task = WQLObject.getWQLObject("sch_base_task").query("task_id = " + task_id).uniqueResult(0); + if (ObjectUtil.isEmpty(task)) { + throw new BadRequestException("未找到任务!"); + } + this.cancelTask(task, OperationType.MANUAL); + } + + @Transactional(rollbackFor = Exception.class) + public void cancelTask(JSONObject task, OperationType operation_type) { + task.put("task_status", TaskStatus.CANCELLED.value()); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(task); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(task); + } + WQLObject.getWQLObject("sch_base_task").update(task); + + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + JSONObject point1 = point_table.query("point_code = '" + task.getString("point_code1") + "'").uniqueResult(0); + if (LockType.TASK_LOCKED.value().equals(point1.getString("lock_type")) + && task.getString("task_code").equals(point1.getString("task_code"))) { + point1.put("lock_type", LockType.UNLOCKED.value()); + point1.put("task_code", ""); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point1); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point1); + } + point_table.update(point1); + } + + JSONObject point2 = new JSONObject(); + point2.put("lock_type", LockType.UNLOCKED.value()); + point2.put("task_code", ""); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point2); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point2); + } + point_table.update(point2, "point_code = '" + task.getString("point_code2") + "'"); + } + + @Transactional(rollbackFor = Exception.class) + public void finishTask(JSONObject task, OperationType operation_type) { + task.put("task_status", TaskStatus.FINISHED.value()); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(task); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(task); + } + WQLObject.getWQLObject("sch_base_task").update(task); + + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + JSONObject point1 = point_table.query("point_code = '" + task.getString("point_code1") + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(point1) + && LockType.TASK_LOCKED.value().equals(point1.getString("lock_type")) + && task.getString("task_code").equals(point1.getString("task_code"))) { + point1.put("lock_type", LockType.UNLOCKED.value()); + point1.put("task_code", ""); + TaskUtils.addCurrentUpdateColum(point1); + point_table.update(point1); + } + + JSONObject point2 = new JSONObject(); + point2.put("lock_type", LockType.UNLOCKED.value()); + point2.put("task_code", ""); + point2.put("vehicle_type", task.getString("vehicle_type")); + point2.put("vehicle_code", task.getString("vehicle_code")); + point2.put("point_status", PointStatus.NOT_EMPTY.value()); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point2); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point2); + } + point_table.update(point2, "point_code = '" + task.getString("point_code2") + "'"); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/YZSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/YZSendMaterialTask.java new file mode 100644 index 0000000..f6c8045 --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/YZSendMaterialTask.java @@ -0,0 +1,194 @@ +package org.nl.wms.sch.task.send.material; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import org.nl.modules.common.exception.BadRequestException; +import org.nl.modules.wql.WQL; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.basedata.eum.TrueOrFalse; +import org.nl.wms.basedata.eum.VehicleType; +import org.nl.wms.sch.manage.*; +import org.nl.wms.sch.task.util.TaskUtils; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * @author zhangjiangwei + * @date 2023/04/05 17:39 + */ +@RequiredArgsConstructor +@Component +public class YZSendMaterialTask extends AbstractAcsTask { + + @Transactional(rollbackFor = Exception.class) + @Override + public void updateTaskStatus(JSONObject task, String status) { + if (TaskStatus.EXECUTING.value().equals(status)) { + task.put("task_status", TaskStatus.EXECUTING.value()); + TaskUtils.addACSUpdateColum(task); + WQLObject.getWQLObject("sch_base_task").update(task); + } else if (TaskStatus.FINISHED.value().equals(status)) { + this.finishTask(task, OperationType.AUTO); + } else if (TaskStatus.CANCELLED.value().equals(status)) { + this.cancelTask(task, OperationType.AUTO); + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public String createTask(JSONObject form) { + JSONObject point = form.getJSONObject("point"); + JSONObject work_order = form.getJSONObject("workorder"); + JSONObject vd = form.getJSONObject("vd"); + + JSONObject task = TaskUtils.buildTask( + "压制区送料", + TaskType.SEND_MATERIAL.value(), + TaskStatus.SURE_START.value(), + point.getString("point_code"), + null, + work_order.getString("material_id"), + VehicleType.STEEL_TRAY.value(), + vd.getString("vehicle_code"), + TrueOrFalse.trueOrFalse(work_order.getString("is_urgent")) ? "99" : "1", + YZSendMaterialTask.class.getName(), + form.getString("create_mode"), + form.getString("request_param"), + form.getString("create_id"), + form.getString("create_name") + ); + WQLObject.getWQLObject("sch_base_task").insert(task); + + point.put("lock_type", LockType.TASK_LOCKED.value()); + point.put("task_code", task.getString("task_code")); + WQLObject.getWQLObject("sch_base_point").update(point); + + return task.getString("task_id"); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void findNextPoint() { + WQLObject task_table = WQLObject.getWQLObject("sch_base_task"); + JSONArray tasks = task_table + .query("is_delete = '0' AND task_status = '" + TaskStatus.SURE_START.value() + "' AND handle_class = '" + YZSendMaterialTask.class.getName() + "'", "priority DESC, create_time ASC") + .getResultJSONArray(0); + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + + for (int i = 0; i < tasks.size(); i++) { + JSONObject task = tasks.getJSONObject(i); + + JSONObject point = WQL + .getWO("SEND_MATERIAL_TASK") + .addParam("flag", "1") + .process() + .uniqueResult(0); + + if (ObjectUtil.isNotEmpty(point)) { + task.put("task_status", TaskStatus.START_AND_END.value()); + task.put("point_code2", point.getString("point_code")); + task.put("remark", ""); + task_table.update(task); + + point.put("lock_type", LockType.TASK_LOCKED.value()); + point.put("task_code", task.getString("task_code")); + point_table.update(point); + } + } + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void forceFinish(String task_id) { + JSONObject task = WQLObject.getWQLObject("sch_base_task").query("task_id = " + task_id).uniqueResult(0); + if (ObjectUtil.isEmpty(task)) { + throw new BadRequestException("未找到任务!"); + } + this.finishTask(task, OperationType.MANUAL); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void cancel(String task_id) { + JSONObject task = WQLObject.getWQLObject("sch_base_task").query("task_id = " + task_id).uniqueResult(0); + if (ObjectUtil.isEmpty(task)) { + throw new BadRequestException("未找到任务!"); + } + this.cancelTask(task, OperationType.MANUAL); + } + + @Transactional(rollbackFor = Exception.class) + public void cancelTask(JSONObject task, OperationType operation_type) { + task.put("task_status", TaskStatus.CANCELLED.value()); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(task); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(task); + } + WQLObject.getWQLObject("sch_base_task").update(task); + + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + JSONObject point1 = point_table.query("point_code = '" + task.getString("point_code1") + "'").uniqueResult(0); + if (LockType.TASK_LOCKED.value().equals(point1.getString("lock_type")) + && task.getString("task_code").equals(point1.getString("task_code"))) { + point1.put("lock_type", LockType.UNLOCKED.value()); + point1.put("task_code", ""); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point1); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point1); + } + point_table.update(point1); + } + + JSONObject point2 = new JSONObject(); + point2.put("lock_type", LockType.UNLOCKED.value()); + point2.put("task_code", ""); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point2); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point2); + } + point_table.update(point2, "point_code = '" + task.getString("point_code2") + "'"); + } + + @Transactional(rollbackFor = Exception.class) + public void finishTask(JSONObject task, OperationType operation_type) { + task.put("task_status", TaskStatus.FINISHED.value()); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(task); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(task); + } + WQLObject.getWQLObject("sch_base_task").update(task); + + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + JSONObject point1 = point_table.query("point_code = '" + task.getString("point_code1") + "'").uniqueResult(0); + if (ObjectUtil.isNotEmpty(point1) + && LockType.TASK_LOCKED.value().equals(point1.getString("lock_type")) + && task.getString("task_code").equals(point1.getString("task_code"))) { + point1.put("lock_type", LockType.UNLOCKED.value()); + point1.put("task_code", ""); + point1.put("vehicle_type", ""); + point1.put("vehicle_code", ""); + point1.put("point_status", PointStatus.EMPTY.value()); + TaskUtils.addCurrentUpdateColum(point1); + point_table.update(point1); + } + + JSONObject point2 = new JSONObject(); + point2.put("lock_type", LockType.UNLOCKED.value()); + point2.put("task_code", ""); + point2.put("vehicle_type", task.getString("vehicle_type")); + point2.put("vehicle_code", task.getString("vehicle_code")); + point2.put("point_status", PointStatus.NOT_EMPTY.value()); + if (operation_type == OperationType.AUTO) { + TaskUtils.addACSUpdateColum(point2); + } else if (operation_type == OperationType.MANUAL) { + TaskUtils.addCurrentUpdateColum(point2); + } + point_table.update(point2, "point_code = '" + task.getString("point_code2") + "'"); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/cpOut/wql/QSCH_cpOut_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/wql/SEND_MATERIAL_TASK.wql similarity index 57% rename from lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/cpOut/wql/QSCH_cpOut_01.wql rename to lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/wql/SEND_MATERIAL_TASK.wql index 7546033..dd5394d 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/cpOut/wql/QSCH_cpOut_01.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/send/material/wql/SEND_MATERIAL_TASK.wql @@ -1,5 +1,5 @@ [交易说明] - 交易名: 成品出库 + 交易名: 送料入库 所属模块: 功能简述: 版权所有: @@ -13,8 +13,9 @@ ################################################# ## 表字段对应输入参数 ################################################# - 输入.flag TYPEAS s_string - 输入.region_code TYPEAS s_string + 输入.flag TYPEAS s_string + 输入.point_type TYPEAS s_string + 输入.device_code TYPEAS s_string [临时表] --这边列出来的临时表就会在运行期动态创建 @@ -38,22 +39,18 @@ # 3、业务主过程 # ########################################## - IF 输入.flag = "1" - QUERY - SELECT - * - FROM - SCH_BASE_Point - WHERE - is_used = '1' - AND is_delete = '0' - AND lock_type = '1' - AND is_used = '1' - AND point_status = '1' - OPTION 输入.region_code <> "" - region_code = 输入.region_code - ENDOPTION - ORDER BY point_code - ENDSELECT - ENDQUERY - ENDIF \ No newline at end of file + IF 输入.flag = "1" + QUERY + SELECT + * + FROM + sch_base_point + WHERE + is_used = '1' + AND lock_type = '1' + AND region_code = 'CPHJ' + AND point_type = '1' + AND point_status = '0' + ENDSELECT + ENDQUERY + ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/util/TaskUtils.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/util/TaskUtils.java new file mode 100644 index 0000000..dcc131a --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/task/util/TaskUtils.java @@ -0,0 +1,110 @@ +package org.nl.wms.sch.task.util; + +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.JSONObject; +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.core.bean.WQLObject; +import org.nl.wms.sch.manage.ACSSystem; +import org.nl.wms.sch.manage.LockType; +import org.nl.wms.sch.manage.PointStatus; + +/** + * 辽宁晟华任务工具类 + * + * @author zhangjiangwei + * @date 2023/03/06 14:32 + */ +public class TaskUtils { + + public static void isEmpty(JSONObject point) { + if (PointStatus.NOT_EMPTY.value().equals(point.getString("point_status"))) { + throw new BadRequestException("[" + point.getString("point_code") + "] 上有货!"); + } + } + + public static void isLocked(JSONObject point) { + String lock_type = point.getString("lock_type"); + if (!LockType.UNLOCKED.value().equals(lock_type)) { + throw new BadRequestException("[" + point.getString("point_code") + "] 已被" + LockType.get(lock_type).label() + "!"); + } + } + + public static JSONObject hasWorkOrder(JSONObject point) { + String device_code = point.getString("device_code"); + JSONObject work_order = WQLObject + .getWQLObject("pdm_bd_workorder") + .query("is_delete = '0' AND device_code = '" + device_code + "' AND order_status = '3'") + .uniqueResult(0); + if (ObjectUtil.isEmpty(work_order)) { + throw new BadRequestException("[" + point.getString("point_code") + "] 所属设备 [" + device_code + "] 未开始生产!"); + } + return work_order; + } + + public static JSONObject buildTask( + String task_name, + String task_type, + String task_status, + String point_code1, + String point_code2, + String material_id, + String vehicle_type, + String vehicle_code, + String priority, + String handle_class, + String create_mode, + String request_param, + String create_id, + String create_name + ) { + JSONObject task = new JSONObject(); + task.put("task_id", IdUtil.getSnowflake().nextId()); + task.put("task_code", CodeUtil.getNewCode("TASK_CODE")); + task.put("task_name", task_name); + task.put("task_type", task_type); + task.put("task_status", task_status); + task.put("point_code1", point_code1); + task.put("point_code2", point_code2); + task.put("material_id", material_id); + task.put("vehicle_type", vehicle_type); + task.put("vehicle_code", vehicle_code); + task.put("priority", priority); + task.put("handle_class", handle_class); + task.put("create_mode", create_mode); + task.put("request_param", request_param); + task.put("create_id", create_id); + task.put("create_name", create_name); + task.put("create_time", DateUtil.now()); + return task; + } + + public static String formatVehicleCode(String vehicle_code) { + if (StrUtil.isBlank(vehicle_code)) { + return "0000"; + } + + StringBuilder vehicle_code_builder = new StringBuilder(vehicle_code); + for (int i = vehicle_code_builder.length(); i < 4; i++) { + vehicle_code_builder.insert(0, "0"); + } + vehicle_code = vehicle_code_builder.toString(); + return vehicle_code; + } + + public static void addACSUpdateColum(JSONObject row) { + row.put("update_optid", ACSSystem.id); + row.put("update_optname", ACSSystem.nick_name); + row.put("update_time", DateUtil.now()); + } + + public static void addCurrentUpdateColum(JSONObject row) { + row.put("update_optid", SecurityUtils.getCurrentUserId()); + row.put("update_optname", SecurityUtils.getCurrentNickName()); + row.put("update_time", DateUtil.now()); + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/PointToPointTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/PointToPointTask.java deleted file mode 100644 index 4e6e115..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/PointToPointTask.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.nl.wms.sch.tasks; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.StrUtil; -import com.alibaba.fastjson.JSONObject; -import org.nl.modules.common.utils.SecurityUtils; -import org.nl.modules.wql.core.bean.WQLObject; -import org.nl.wms.sch.manage.AbstractAcsTask; -import org.nl.wms.sch.manage.TaskStatusEnum; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -/** - * 普通点对点任务 - */ -@Service -public class PointToPointTask extends AbstractAcsTask { - - @Override - @Transactional - public void updateTaskStatus(JSONObject taskObj, String status) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - - String task_id = taskObj.getString("task_id"); - JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - - if (StrUtil.equals(status,"0")) { - // 取消删除任务 - taskTab.delete("task_id = '"+task_id+"'"); - } - - if (TaskStatusEnum.EXECUTING.getCode().equals(status)) { - // 更新任务状态为执行中 - jsonTask.put("task_status", TaskStatusEnum.EXECUTING.getCode()); - jsonTask.put("update_time", DateUtil.now()); - jsonTask.put("car_no", taskObj.getString("car_no")); - taskTab.update(jsonTask); - } - - if(StrUtil.equals(status, TaskStatusEnum.FINISHED.getCode())) { - // 完成 - 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); - } - - } - - - - @Override - @Transactional - public String createTask(JSONObject form) { - return null; - } - - @Override - public void forceFinish(String task_id) { - JSONObject taskObj = WQLObject.getWQLObject("SCH_BASE_Task").query("task_id = '" + task_id + "'").uniqueResult(0); - this.updateTaskStatus(taskObj, TaskStatusEnum.FINISHED.getCode()); - } - - @Override - public List addTask() { - return null; - } - - - - - @Override - public void cancel(String task_id) { - - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/PointUpdateUtil.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/PointUpdateUtil.java deleted file mode 100644 index 5086027..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/PointUpdateUtil.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.nl.wms.sch.tasks; - -import cn.hutool.core.date.DateUtil; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import org.nl.modules.common.exception.BadRequestException; -import org.nl.modules.wql.core.bean.WQLObject; -import org.nl.wms.ext.acs.service.impl.WmsToAcsServiceImpl; -import org.nl.wms.sch.manage.PointEnum; - -/** - * @author: lyd - * @description: 点位更新工具类 - * @Date: 2022/11/23 - */ -public class PointUpdateUtil { - /** - * 清理点位 - */ - public static void clearPoint(String point_code) { - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); - JSONObject pointObj = pointTab.query("point_code = '" + point_code + "'").uniqueResult(0); - pointObj.put("point_status", PointEnum.POINT_STATUS_EMPTY_POSITION.getCode()); - pointObj.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointObj.put("vehicle_type", ""); - pointObj.put("vehicle_code", ""); - pointObj.put("vehicle_qty", "0"); - pointObj.put("material_id", ""); - pointObj.put("pcsn", ""); - pointObj.put("ivt_qty", "0"); - pointObj.put("qty_unit_id", ""); - pointObj.put("ivt_weight", "0"); - pointObj.put("weight_unit_id", ""); - pointObj.put("instorage_time", ""); - pointObj.put("is_full", "0"); - pointObj.put("standing_time", "0"); - pointObj.put("warn_time", "0"); - pointObj.put("group_id", ""); - pointTab.update(pointObj); - } - - /** - * 点位:空载具 - */ - public static void setVehicle(JSONObject jsonObject) { - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); - JSONObject pointObj = pointTab.query("point_code = '" + jsonObject.getString("point_code") + "'").uniqueResult(0); - pointObj.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointObj.put("point_status", PointEnum.POINT_STATUS_EMPTY_VEHICLE.getCode()); - pointObj.put("vehicle_code", jsonObject.getString("vehicle_code")); - pointObj.put("vehicle_qty", "1"); - pointObj.put("instorage_time", DateUtil.now()); - pointObj.put("is_full", "1"); - pointObj.put("ivt_qty", "0"); - pointObj.put("pcsn", null); - pointObj.put("material_id", null); - pointObj.put("standing_time", "0"); - pointTab.update(pointObj); - } - - /** - * 访问acs获取点位数据更新点位信息: - * 分拣呼叫空托盘、空钢托盘叠盘架 - * @param pointCodes - * @deprecated 只更新点位状态和载具类型 - */ - public static void updatePoint(JSONArray pointCodes) { - WQLObject pointTable = WQLObject.getWQLObject("sch_base_point"); - WmsToAcsServiceImpl wmsToAcsService = new WmsToAcsServiceImpl(); - // 向ACS查询点位状态 - JSONObject pointStatus = wmsToAcsService.getPointStatus(pointCodes); - // 找到对应的载具类型再去下发 - JSONArray deviceDatas = pointStatus.getJSONArray("data"); - for (int j = 0; j < deviceDatas.size(); j++) { - JSONObject pointObj = deviceDatas.getJSONObject(j); - String point_code = pointObj.getString("device_code"); - String mode = pointObj.getString("mode"); // 工作状态:0脱机,其他正常 - String error = pointObj.getString("error"); // 0是正常 - String point_status = pointObj.getString("move"); // 点位状态:0无货,1有货(具体是空载具还是物料不知道) - //将托盘类型456.... - String vehicle_type = pointObj.getString("container_type"); - if (mode.equals("0") || !error.equals("0")) { - // 点位异常 - vehicle_type = ""; - point_status = "0"; - if (point_code.startsWith("BZX")) point_status = "1"; - } - JSONObject pointObj2 = pointTable.query("point_code = '" + point_code + "'").uniqueResult(0); - pointObj2.put("point_status", Integer.parseInt(point_status) + 1); // 1空位, 2空载具 - pointObj2.put("vehicle_type", vehicle_type); - pointTable.update(pointObj2); - } - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/autoCallMaterial/RykCallMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/autoCallMaterial/RykCallMaterialTask.java deleted file mode 100644 index a812af2..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/autoCallMaterial/RykCallMaterialTask.java +++ /dev/null @@ -1,312 +0,0 @@ -package org.nl.wms.sch.tasks.autoCallMaterial; - -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 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.*; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.PointUpdateUtil; -import org.nl.wms.util.IdUtil; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author: lyd - * @description: 入窑缓存自动送料 - * @Date: 2022/11/24 - */ -public class RykCallMaterialTask extends AbstractAcsTask { - private final String THIS_CLASS = RykCallMaterialTask.class.getName(); - /** - * 添加任务进行下发 - * - * @return - */ - @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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @Override - 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); - String point_code2 = taskObj.getString("point_code2"); - // 物料点 - JSONObject material_point = pointTab.query("point_code = '" + taskObj.getString("point_code1") + "'").uniqueResult(0); - //任务取消 - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - // 取消删除任务 - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - - if (ObjectUtil.isNotEmpty(material_point)) { - // 点位解锁 - material_point.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(material_point); - } - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().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, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - // 更改任务状态为完成 - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - - if (ObjectUtil.isEmpty(material_point)) return; - - //区域出入表【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", RegionIOEnum.IO_TYPE_OUT.getCode()); // 出库 - regionIoObj.put("region_id", material_point.getString("region_id")); - regionIoObj.put("region_code", material_point.getString("region_code")); - regionIoObj.put("region_name", material_point.getString("region_name")); - regionIoObj.put("material_id", taskObj.getString("material_id")); - regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); - regionIoObj.put("qty", material_point.getString("qty")); - regionIoObj.put("ivt_weight", material_point.getString("weight")); - regionIoObj.put("bill_status", RegionIOEnum.BILL_STATUS_FINISH.getCode()); - regionIoObj.put("start_point_code", taskObj.getString("point_code1")); - regionIoObj.put("end_point_code", point_code2); - regionIoObj.put("create_mode", RegionIOEnum.CREATE_MODE_ACS.getCode()); - regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - regionIoObj.put("create_id", "22"); - regionIoObj.put("create_name", "ACS系统"); - regionIoObj.put("create_time", DateUtil.now()); - regionIoTab.insert(regionIoObj); - - /** - * 完成后将组盘id和任务id赋值到入窑口 - */ -// JSONObject uniqueResult = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); -// uniqueResult.put("group_id", material_point.getString("group_id")); -// uniqueResult.put("task_id", material_point.getString("task_id")); -// pointTab.update(uniqueResult); - // 物料点位解锁 并设置空位 - PointUpdateUtil.clearPoint(material_point.getString("point_code")); - } - } - - /** - * 自动生成任务 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void autoCreate() { - String point_code2 = "RYW"; - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //点位基础表【SCH_BASE_Point】 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + point_code2 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) return; -// JSONObject object = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); -// if (ObjectUtil.isNotEmpty(object.getString("group_id"))) return; - // 判断是否有货 - // 获取RYW - JSONArray pointCodes = new JSONArray(); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("device_code", "RYW"); - pointCodes.add(jsonObject); - // 更新点位 - PointUpdateUtil.updatePoint(pointCodes); - JSONObject object1 = pointTab.query("point_code = 'RYW'").uniqueResult(0); - if (object1.getString("point_status").equals("2")) return; // 代表有货就不需要继续执行 - - SchTaskDto dto = SchTaskDto.builder() - .task_id(IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("task_type") - .task_name("烧制出库") - .task_status(TaskStatusEnum.SURE_END.getCode()) - .point_code2(point_code2) - .vehicle_type(PointEnum.VEHICLE_TYPE_STEEL_TRAY.getCode()) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - */ - @Override - public String createTask(JSONObject form) { - String point_code2 = form.getString("point_code2"); - String qty = form.getString("qty"); - - //生产工单表【PDM_BD_WorkOrder】 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + point_code2 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code2 + "存在未完成的任务"); - //点位基础表【SCH_BASE_Point】 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - String device_code = pointTab.query("point_code = '" + point_code2 + "'").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_name("烧制出库") - .material_qty(qty) - .task_status(TaskStatusEnum.SURE_END.getCode()) - .point_code2(point_code2) - .workorder_id(workOrderObj.getLong("workorder_id")) - .material_id(workOrderObj.getLong("material_id")) - .vehicle_type(PointEnum.VEHICLE_TYPE_STEEL_TRAY.getCode()) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .request_param(form.toJSONString()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - //创建好立即下发 - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @returninvoke - * @discription 确定任务起点 - * @author ldjun - * @created 2020年6月12日 下午6:01:30 - */ - @Override - public void findStartPoint() { - - // 到入窑缓存区找一托物料 - 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 = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); - for (int i = 0; i < taskArr.size(); i++) { - JSONObject taskObj = taskArr.getJSONObject(i); - String material_id = taskObj.getString("material_id"); - JSONObject queryParam = new JSONObject(); - queryParam.put("flag", "1"); - queryParam.put("material_id", material_id); - queryParam.put("region_code", "RYZCQ"); - // 到入窑暂存区找,找满拖的 - JSONObject json1 = WQL.getWO("QSCH_rykCallMaterial_01").addParamMap(queryParam).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(json1)) { - // 拿到点位 - JSONObject material_point = pointTab.query("point_id = '" + json1.getString("point_id") + "' and lock_type = '1'").uniqueResult(0); - if (ObjectUtil.isEmpty(material_point)) throw new BadRequestException("数据错误,请校验!"); - // 物料点位上锁 - material_point.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(material_point); - - taskObj.put("point_code1", material_point.getString("point_code")); - taskObj.put("material_id", material_point.getString("material_id")); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskObj.put("task_id", taskObj.getString("task_id")); - taskObj.put("group_id", json1.getString("group_id")); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } else { - taskObj.put("remark", "入窑暂存区无所需物料"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } - - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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,"0"); - else { - throw new BadRequestException("未找到该任务或者任务已完成!"); - } - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/autoCallMaterial/wql/QSCH_rykCallMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/autoCallMaterial/wql/QSCH_rykCallMaterial_01.wql deleted file mode 100644 index f94a735..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/autoCallMaterial/wql/QSCH_rykCallMaterial_01.wql +++ /dev/null @@ -1,63 +0,0 @@ -[交易说明] - 交易名: 入窑口自动任务 - 叫料 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为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 - * - FROM - SCH_BASE_Point p - WHERE - p.is_used = '1' - AND is_delete = '0' - AND lock_type = '1' - AND point_status = '3' - AND is_full = '1' - OPTION 输入.material_id <> "" - p.material_id = 输入.material_id - ENDOPTION - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - ENDSELECT - ENDQUERY - ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/FjCallEmptyVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/FjCallEmptyVehicleTask.java deleted file mode 100644 index 5b64898..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/FjCallEmptyVehicleTask.java +++ /dev/null @@ -1,307 +0,0 @@ -package org.nl.wms.sch.tasks.callEmpty; - -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.ext.acs.service.WmsToAcsService; -import org.nl.wms.sch.SchTaskDto; -import org.nl.wms.sch.manage.*; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.PointUpdateUtil; -import org.nl.wms.util.IdUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author: lyd - * @description: 分拣呼叫木托盘 - * @Date: 2022/11/14 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class FjCallEmptyVehicleTask extends AbstractAcsTask { - private final String THIS_CLASS = FjCallEmptyVehicleTask.class.getName(); - - @Autowired - private WmsToAcsService wmsToAcsService; - /** - * 添加任务进行下发 - * - * @return - */ - @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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @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"); - WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); - WQLObject groupTab = WQLObject.getWQLObject("st_buss_vehiclegroup"); - - String task_id = task.getString("task_id"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - JSONObject requestObj = taskObj.getJSONObject("request_param"); - - String point_code1 = taskObj.getString("point_code1"); - JSONObject startPoint = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - /* - * 取消任务 - */ - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - if (ObjectUtil.isEmpty(startPoint)) return; - startPoint.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(startPoint); - } - - if (StrUtil.equals(status, UpdateTaskStatusEnum.EXECUTION.getCode())) { - // 更新任务状态为执行中 - taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskObj.put("car_no", task.getString("car_no")); - taskTab.update(taskObj); - } - - if (StrUtil.equals(status, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - /* - * 更改任务状态为完成 - */ - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - - if (ObjectUtil.isEmpty(startPoint)) return; - if (startPoint.getString("point_code").startsWith("BT")) { // 包装缓存位 - JSONObject groupObj = groupTab.query("group_id = '" + taskObj.getString("group_id") + "'").uniqueResult(0); - 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", RegionIOEnum.IO_TYPE_OUT.getCode()); // 出库 - regionIoObj.put("region_id", startPoint.getString("region_id")); - regionIoObj.put("region_code", startPoint.getString("region_code")); - regionIoObj.put("region_name", startPoint.getString("region_name")); - regionIoObj.put("material_id", taskObj.getString("material_id")); - regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); - regionIoObj.put("qty", groupObj.getString("qty")); - regionIoObj.put("weight_unit_id", RegionIOEnum.UNIT_ID_B.getCode()); - regionIoObj.put("bill_status", RegionIOEnum.BILL_STATUS_FINISH.getCode()); - regionIoObj.put("start_point_code", taskObj.getString("point_code1")); - regionIoObj.put("end_point_code", taskObj.getString("point_code2")); - regionIoObj.put("create_mode", RegionIOEnum.CREATE_MODE_ACS.getCode()); - regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - regionIoObj.put("create_id", "22"); - regionIoObj.put("create_name", "ACS系统"); - regionIoObj.put("create_time", DateUtil.now()); - regionIoTab.insert(regionIoObj); - // 点位更新,起点:空位,解锁; - PointUpdateUtil.clearPoint(startPoint.getString("point_code")); - } else { // 钢托盘每次就一个 - startPoint.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); // 出口点 - } - pointTab.update(startPoint); - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); // 生产工单表 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); //点位基础表 - - //任务表【SCH_BASE_Task】 - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + form.getString("point_code2") + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + form.getString("point_code2") + "存在未完成的任务"); - - - String point_code2 = form.getString("point_code2"); - String device_code = pointTab.query("point_code = '" + point_code2 + "'").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(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .task_name("分拣呼叫木托盘") - .task_status(TaskStatusEnum.SURE_END.getCode()) - .point_code2(point_code2) - .acs_task_type("3") - .vehicle_type(workOrderObj.getString("vehicle_type")) - .vehicle_qty(1) -// .task_group_id(org.nl.wms.util.IdUtil.getLongId()) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .request_param(form.toJSONString()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @returninvoke - * @discription 确定任务起点 - * @author ldjun - * @created 2020年6月12日 下午6:01:30 - */ - @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 taskObj = taskArr.getJSONObject(i); - String vehicle_type = taskObj.getString("vehicle_type"); - // 寻找入窑暂存区是否有半托 - JSONObject noFull = new JSONObject(); - noFull.put("flag", "1"); - noFull.put("region_code", "BZZCQ"); - noFull.put("material_id", taskObj.getString("material_id")); - JSONObject noFullPoint = WQL.getWO("QSCH_fjCallEmptyVehicle_01").addParamMap(noFull).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(noFullPoint)) { // 找到半满托盘,叫料出库 - taskObj.put("update_time", DateUtil.now()); - taskObj.put("point_code1", noFullPoint.getString("point_code")); - taskObj.put("group_id", noFullPoint.getString("group_id")); // 组盘信息挪到任务中 - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskObj.put("remark", ""); - taskTab.update(taskObj); - - //锁住起点 - noFullPoint.put("task_id", taskObj.getString("task_id")); - noFullPoint.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(noFullPoint); - } else { // 没有就呼叫空的木托盘 - // 获取所有的托盘堆叠位 - JSONArray pointCodes = WQL.getWO("QSCH_fjSendMaterial_01").addParam("flag", "2").process().getResultJSONArray(0); - // 更新点位 - PointUpdateUtil.updatePoint(pointCodes); - // 找到载具类型符合的覆膜机位置:真正的位置在device_code - JSONObject emptyTray = pointTab.query("region_code = 'RGCPQ' AND vehicle_type = '" + - taskObj.getString("vehicle_type") + "' AND point_status = '2' " + - "AND is_used = '1' AND is_delete = '0' AND point_type = '2'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(emptyTray)) { - // 判断出口是否锁住 - JSONObject exitPoint = pointTab.query("point_code = '" + - emptyTray.getString("device_code") + "'" + - " AND lock_type = '1'").uniqueResult(0); - if (ObjectUtil.isEmpty(exitPoint)) return; // 出口点锁住就不能呼叫空盘 - // 向ACS申请传送一个空木托盘 - JSONArray jsonArray = new JSONArray(); - JSONObject data = new JSONObject(); - data.put("device_code", exitPoint.getString("point_code")); - jsonArray.add(data); - wmsToAcsService.getTray(jsonArray); - // 去搬运 - taskObj.put("point_code1", exitPoint.getString("point_code")); - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", ""); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(taskObj); - // 锁住出口点 - exitPoint.put("task_id", taskObj.getString("task_id")); - exitPoint.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(exitPoint); - } else { - taskObj.put("remark", "暂无空托盘"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } - } - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.CANCEL.getCode()); - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/HnCallEmptyVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/HnCallEmptyVehicleTask.java deleted file mode 100644 index 2aa5bd8..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/HnCallEmptyVehicleTask.java +++ /dev/null @@ -1,260 +0,0 @@ -package org.nl.wms.sch.tasks.callEmpty; - -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.PointEnum; -import org.nl.wms.sch.manage.TaskStatusEnum; -import org.nl.wms.sch.manage.UpdateTaskStatusEnum; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.PointUpdateUtil; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author: lyd - * @description: 混碾呼叫空盅 - * @Date: 2022/11/9 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class HnCallEmptyVehicleTask extends AbstractAcsTask { - - private final String THIS_CLASS = HnCallEmptyVehicleTask.class.getName(); - - /** - * 添加任务进行下发 - * - * @return - */ - @Override - @Transactional(rollbackFor = Exception.class) - 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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @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, UpdateTaskStatusEnum.CANCEL.getCode())) { - /* - * 取消任务 - */ - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - - String point_code1 = task.getString("point_code1"); - if (ObjectUtil.isNotEmpty(point_code1)) { - JSONObject endPoint = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - endPoint.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(endPoint); - } - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().equals(status)) { - // 更新任务状态为执行中 - taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskObj.put("car_no", task.getString("car_no")); - taskTab.update(taskObj); - } - - if (StrUtil.equals(status, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - /* - * 更改任务状态为完成 - */ - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); - taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - - /** - * 点位更新,起点:空位 - */ - String point_code1 = taskObj.getString("point_code1"); - if (ObjectUtil.isEmpty(point_code1)) return; - PointUpdateUtil.clearPoint(point_code1); - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - /* - * 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"); //点位基础表 - - //任务表【SCH_BASE_Task】 - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + form.getString("point_code2") + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + form.getString("point_code2") + "存在未完成的任务"); - - String point_code2 = form.getString("point_code2"); - String device_code = pointTab.query("point_code = '" + point_code2 + "'").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(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .task_name("混碾机叫空盅") - .task_status(TaskStatusEnum.SURE_END.getCode()) - .point_code2(point_code2) - .acs_task_type("3") - .workorder_id(workOrderObj.getLong("workorder_id")) - .vehicle_code(form.getString("vehicle_code")) - .vehicle_type(workOrderObj.getString("is_new"))//载具类型统一用载具表维护 - .vehicle_qty(form.getIntValue("qty")) - .task_group_id(org.nl.wms.util.IdUtil.getLongId()) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .request_param(form.toJSONString()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @returninvoke - * @discription 确定任务起点 - * @author ldjun - * @created 2020年6月12日 下午6:01:30 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void findStartPoint() { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); // 工单表 - - 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 taskObj = taskArr.getJSONObject(i); - // 获取工单 - String workorder_id = taskObj.getString("workorder_id"); - JSONObject workOrderObj = workOrderTab.query("workorder_id = '" + workorder_id + "'").uniqueResult(0); - - JSONObject param1 = new JSONObject(); - param1.put("flag", "1"); - param1.put("region_code", "KLHJ"); - param1.put("is_new", workOrderObj.getString("is_new")); - // 直接到困料货架找一个空载具 (需要区分新旧载具) - JSONObject startPoint = WQL.getWO("QSCH_hnCallEmptyVehicle_01").addParamMap(param1).process().uniqueResult(0); - if (ObjectUtil.isEmpty(startPoint)) { - taskObj.put("remark", "困料货架无可用载具!"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } else { - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", ""); - taskObj.put("point_code1", startPoint.getString("point_code")); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(taskObj); - - //锁住起点 - startPoint.put("task_id", taskObj.getString("task_id")); - startPoint.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(startPoint); - } - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.CANCEL.getCode()); - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YzjCallEmptyVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YzjCallEmptyVehicleTask.java deleted file mode 100644 index 21fb7c8..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/YzjCallEmptyVehicleTask.java +++ /dev/null @@ -1,306 +0,0 @@ -package org.nl.wms.sch.tasks.callEmpty; - -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.*; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.PointUpdateUtil; -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; - -/** - * @author: lyd - * @description: 压制机呼叫空钢托盘 - * @Date: 2022/11/10 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class YzjCallEmptyVehicleTask extends AbstractAcsTask { - private final String THIS_CLASS = YzjCallEmptyVehicleTask.class.getName(); - /** - * 添加任务进行下发 - * - * @return - */ - @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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,1:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @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"); - WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); - - String task_id = task.getString("task_id"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - - String point_code1 = taskObj.getString("point_code1"); - String point_code2 = taskObj.getString("point_code2"); - - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - /* - * 取消任务 - */ - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - if (ObjectUtil.isNotEmpty(point_code1)) { - JSONObject startPoint = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - startPoint.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(startPoint); - } - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().equals(status)) { - // 更新任务状态为执行中 - taskObj.put("task_status", TaskStatusEnum.EXECUTING.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskObj.put("car_no", task.getString("car_no")); - taskTab.update(taskObj); - } - - if (StrUtil.equals(status,UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - /* - * 更改任务状态为完成 - */ - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); - taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - JSONObject startPoint = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(startPoint)) return; - if (point_code1.startsWith("R")) { // 入窑缓存位 - 半托出库 - // 插入出库单 - 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", RegionIOEnum.IO_TYPE_OUT.getCode()); // 出库 - regionIoObj.put("region_id", startPoint.getString("region_id")); - regionIoObj.put("region_code", startPoint.getString("region_code")); - regionIoObj.put("region_name", startPoint.getString("region_name")); - regionIoObj.put("material_id", taskObj.getString("material_id")); - regionIoObj.put("vehicle_code", taskObj.getString("vehicle_code")); - regionIoObj.put("weight_unit_id", RegionIOEnum.UNIT_ID_B.getCode()); - regionIoObj.put("bill_status", RegionIOEnum.BILL_STATUS_FINISH.getCode()); - regionIoObj.put("start_point_code", taskObj.getString("point_code1")); - regionIoObj.put("end_point_code", taskObj.getString("point_code2")); - regionIoObj.put("create_mode", RegionIOEnum.CREATE_MODE_ACS.getCode()); - regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - regionIoObj.put("create_id", "22"); - regionIoObj.put("create_name", "ACS系统"); - regionIoObj.put("create_time", DateUtil.now()); - regionIoTab.insert(regionIoObj); - // 点位更新,起点:空位,解锁; - PointUpdateUtil.clearPoint(startPoint.getString("point_code")); - // 终点:压制机对接位,将半托的组盘id放进去 - JSONObject endPoint = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - endPoint.put("group_id", taskObj.getString("group_id")); - pointTab.update(endPoint); - } - // 起点解锁 - JSONObject object = pointTab.query("point_code = '" + startPoint.getString("point_code") + "'").uniqueResult(0); - object.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(object); - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - /* - * 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"); //点位基础表 - - //任务表【SCH_BASE_Task】 - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + form.getString("point_code2") + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + form.getString("point_code2") + "存在未完成的任务"); - - String point_code2 = form.getString("point_code2"); - String device_code = pointTab.query("point_code = '" + point_code2 + "'").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(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .task_name("压制机叫空载具") - .task_status(TaskStatusEnum.SURE_END.getCode()) - .point_code2(point_code2) - .acs_task_type("2") - .material_id(workOrderObj.getLong("material_id")) - .workorder_id(workOrderObj.getLong("workorder_id")) - .vehicle_type(PointEnum.VEHICLE_TYPE_STEEL_TRAY.getCode()) - .vehicle_qty(form.getIntValue("qty")) - .task_group_id(org.nl.wms.util.IdUtil.getLongId()) - .handle_class(THIS_CLASS) - .request_param(form.toJSONString()) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @returninvoke - * @discription 确定任务起点 - * @author ldjun - * @created 2020年6月12日 下午6:01:30 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void findStartPoint() { - // 找托盘:先找库存上是否有半满托盘,如果没有就到KGTDDW05找空钢托盘 - 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 taskObj = taskArr.getJSONObject(i); - // 寻找入窑暂存区是否有半托 - JSONObject noFull = new JSONObject(); - noFull.put("flag", "1"); - noFull.put("region_code", "RYZCQ"); - noFull.put("material_id", taskObj.getString("material_id")); - JSONObject noFullPoint = WQL.getWO("QSCH_yzjCallEmptyVehicle_01").addParamMap(noFull).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(noFullPoint)) { // 找到半满托盘,叫料出库 - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", ""); - taskObj.put("group_id", noFullPoint.getString("group_id")); // 组盘信息挪到任务中 - taskObj.put("point_code1", noFullPoint.getString("point_code")); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(taskObj); - - //锁住起点 - noFullPoint.put("task_id", taskObj.getString("task_id")); - noFullPoint.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(noFullPoint); - } else { // 到KGTDDW05找空钢托盘 - // 访问acs更新点位状态 - // 向ACS查询是否有空钢托盘 - JSONArray params = new JSONArray(); - JSONObject deviceCode = new JSONObject(); - deviceCode.put("device_code", "KGTDDW05"); - params.add(deviceCode); - PointUpdateUtil.updatePoint(params); - JSONObject param = new JSONObject(); - param.put("flag", "2"); - param.put("region_code", "KGTCPQ"); - param.put("point_code", "KGTDDW05"); - JSONObject kgtPoint = WQL.getWO("QSCH_yzjCallEmptyVehicle_01").addParamMap(param).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(kgtPoint)) { - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", ""); - taskObj.put("point_code1", kgtPoint.getString("point_code")); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(taskObj); - - //锁住起点 - kgtPoint.put("task_id", taskObj.getString("task_id")); - kgtPoint.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(kgtPoint); - } else { - taskObj.put("remark", "未找到可用的载具!"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } - } - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.CANCEL.getCode()); - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_fjCallEmptyVehicle_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_fjCallEmptyVehicle_01.wql deleted file mode 100644 index a0339da..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_fjCallEmptyVehicle_01.wql +++ /dev/null @@ -1,88 +0,0 @@ -[交易说明] - 交易名: 分拣码垛呼叫空载具 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为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 - * - FROM - SCH_BASE_Point p - WHERE - lock_type = '1' - AND is_used = '1' - AND is_delete = '0' - AND is_full = '0' - AND point_status = '3' - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - OPTION 输入.material_id <> "" - p.material_id = 输入.material_id - ENDOPTION - ORDER BY instorage_time - ENDSELECT - ENDQUERY - ENDIF - IF 输入.flag = "2" - 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_status = '2' - AND point_type = '2' - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - OPTION 输入.vehicle_type <> "" - p.vehicle_type = 输入.vehicle_type - ENDOPTION - ORDER BY col_num,row_num,layer_num - ENDSELECT - ENDQUERY - ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_hnCallEmptyVehicle_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_hnCallEmptyVehicle_01.wql deleted file mode 100644 index 682220d..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_hnCallEmptyVehicle_01.wql +++ /dev/null @@ -1,64 +0,0 @@ -[交易说明] - 交易名: 混碾机呼叫空载具 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 - -[IO定义] - ################################################# - ## 表字段对应输入参数 - ################################################# - 输入.flag TYPEAS s_string - 输入.region_code TYPEAS s_string - 输入.material_id TYPEAS s_string - 输入.is_new 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_status = '2' - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - OPTION 输入.is_new <> "" - p.vehicle_type = 输入.is_new - ENDOPTION - ENDSELECT - ENDQUERY - ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_yzjCallEmptyVehicle_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_yzjCallEmptyVehicle_01.wql deleted file mode 100644 index 8e620f6..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callEmpty/wql/QSCH_yzjCallEmptyVehicle_01.wql +++ /dev/null @@ -1,79 +0,0 @@ -[交易说明] - 交易名:压制机呼叫空钢托盘 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 - -[IO定义] - ################################################# - ## 表字段对应输入参数 - ################################################# - 输入.flag TYPEAS s_string - 输入.region_code TYPEAS s_string - 输入.material_id TYPEAS s_string - 输入.point_code TYPEAS s_string - - -[临时表] - --这边列出来的临时表就会在运行期动态创建 - -[临时变量] - --所有中间过程变量均可在此处定义 - -[业务过程] - - ########################################## - # 1、输入输出检查 # - ########################################## - - - ########################################## - # 2、主过程前处理 # - ########################################## - - - ########################################## - # 3、业务主过程 # - ########################################## - IF 输入.flag = "1" - QUERY - SELECT - * - FROM - SCH_BASE_Point p - WHERE - lock_type = '1' - AND is_used = '1' - AND is_full = '0' - AND is_delete = '0' - AND point_status = '3' - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - ENDSELECT - ENDQUERY - ENDIF - IF 输入.flag = "2" - QUERY - SELECT - * - FROM - SCH_BASE_Point p - WHERE - lock_type = '1' - AND is_used = '1' - AND is_delete = '0' - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - OPTION 输入.point_code <> "" - p.point_code = 输入.point_code - ENDOPTION - ENDSELECT - ENDQUERY - ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/FjCallMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/FjCallMaterialTask.java deleted file mode 100644 index 307c910..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/FjCallMaterialTask.java +++ /dev/null @@ -1,273 +0,0 @@ -package org.nl.wms.sch.tasks.callMaterial; - -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.*; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.PointUpdateUtil; -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; - -/** - * @author: lyd - * @description: 分拣叫料出库 - * @Date: 2022/11/11 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class FjCallMaterialTask extends AbstractAcsTask { - private final String THIS_CLASS = FjCallMaterialTask.class.getName(); - /** - * 添加任务进行下发 - * - * @return - */ - @Override - @Transactional(rollbackFor = Exception.class) - 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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @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); - // 物料点 - JSONObject material_point = pointTab.query("point_code = '" + taskObj.getString("point_code1") + "'").uniqueResult(0); - //任务取消 - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - // 取消删除任务 - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - - if (ObjectUtil.isNotEmpty(material_point)) { - // 点位解锁 - material_point.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(material_point); - } - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().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, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - // 更改任务状态为完成 - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - - if (ObjectUtil.isEmpty(material_point)) return; - - //区域出入表【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", RegionIOEnum.IO_TYPE_OUT.getCode()); // 出库 - regionIoObj.put("region_id", material_point.getString("region_id")); - regionIoObj.put("region_code", material_point.getString("region_code")); - regionIoObj.put("region_name", material_point.getString("region_name")); - regionIoObj.put("material_id", material_point.getString("material_id")); - regionIoObj.put("vehicle_code", material_point.getString("vehicle_code")); - regionIoObj.put("qty", material_point.getString("ivt_qty")); - regionIoObj.put("weight_unit_id", RegionIOEnum.UNIT_ID_B.getCode()); - regionIoObj.put("bill_status", RegionIOEnum.BILL_STATUS_FINISH.getCode()); - regionIoObj.put("start_point_code", taskObj.getString("point_code1")); - regionIoObj.put("end_point_code", taskObj.getString("point_code2")); - regionIoObj.put("create_mode", RegionIOEnum.CREATE_MODE_ACS.getCode()); - regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - regionIoObj.put("create_id", "22"); - regionIoObj.put("create_name", "ACS系统"); - regionIoObj.put("create_time", DateUtil.now()); - regionIoTab.insert(regionIoObj); - - //完成后 - // 物料点位解锁 并设置空位 - PointUpdateUtil.clearPoint(material_point.getString("point_code")); - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - String point_code2 = form.getString("point_code2"); - String qty = form.getString("qty"); - - //生产工单表【PDM_BD_WorkOrder】 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete = '0' and point_code2 = '" + point_code2 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code2 + "存在未完成的任务"); - //点位基础表【SCH_BASE_Point】 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - String device_code = pointTab.query("point_code = '" + point_code2 + "'").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_name("分拣出库") - .material_qty(qty) - .task_status(TaskStatusEnum.SURE_END.getCode()) - .point_code2(point_code2) - .workorder_id(workOrderObj.getLong("workorder_id")) - .material_id(workOrderObj.getLong("material_id")) - .vehicle_type(PointEnum.VEHICLE_TYPE_STEEL_TRAY.getCode()) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .request_param(form.toJSONString()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - //创建好立即下发 - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @returninvoke - * @discription 确定任务起点 - * @author ldjun - * @created 2020年6月12日 下午6:01:30 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void findStartPoint() { - // 到出窑缓存区找一托物料 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 - WQLObject groupTab = WQLObject.getWQLObject("st_buss_vehiclegroup"); // 组盘表 - JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); - for (int i = 0; i < taskArr.size(); i++) { - JSONObject taskObj = taskArr.getJSONObject(i); - String material_id = taskObj.getString("material_id"); - JSONObject queryParam = new JSONObject(); - queryParam.put("flag", "1"); - queryParam.put("material_id", material_id); - queryParam.put("region_code", "CYZCQ"); - // 到出窑暂存区找 - JSONObject json1 = WQL.getWO("QSCH_cyCallMaterial_01").addParamMap(queryParam).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(json1)) { - // 拿到点位 - JSONObject material_point = pointTab.query("point_id = '" + json1.getString("point_id") + "' and lock_type = '1'").uniqueResult(0); - if (ObjectUtil.isEmpty(material_point)) throw new BadRequestException("数据错误,请校验!"); - // 物料点位上锁 - material_point.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - material_point.put("task_id", taskObj.getString("task_id")); - pointTab.update(material_point); - - // 将组盘标识赋给任务 - taskObj.put("group_id", material_point.getString("group_id")); - JSONObject object = groupTab.query("group_id = '" + material_point.getString("group_id") + "'").uniqueResult(0); - taskObj.put("vehicle_code", object.getString("vehicle_code")); - taskObj.put("point_code1", material_point.getString("point_code")); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskObj.put("remark", ""); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } else { - taskObj.put("remark", "出窑暂存区无所需物料"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } - - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.CANCEL.getCode()); - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/YzjCallMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/YzjCallMaterialTask.java deleted file mode 100644 index b2a1348..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/YzjCallMaterialTask.java +++ /dev/null @@ -1,294 +0,0 @@ -package org.nl.wms.sch.tasks.callMaterial; - -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.apache.commons.lang3.StringUtils; -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.*; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.PointUpdateUtil; -import org.nl.wms.util.IdUtil; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.*; - -/** - * @author: lyd - * @description: 压制机叫料工序 - * @Date: 2022/11/10 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class YzjCallMaterialTask extends AbstractAcsTask { - private final String THIS_CLASS = YzjCallMaterialTask.class.getName(); - /** - * 添加任务进行下发 - * - * @return - */ - @Override - @Transactional(rollbackFor = Exception.class) - 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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @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); - // 物料点 - JSONObject material_point = pointTab.query("point_code = '" + taskObj.getString("point_code1") + "'").uniqueResult(0); - //任务取消 - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - // 取消删除任务 - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - - if (ObjectUtil.isEmpty(material_point)) return; - // 解锁 - material_point.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(material_point); - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().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, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - // 更改任务状态为完成 - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - if (ObjectUtil.isEmpty(material_point)) return; - JSONObject requestObj = taskObj.getJSONObject("request_param"); - // 区域出入表【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", RegionIOEnum.IO_TYPE_OUT.getCode()); // 出库 - regionIoObj.put("region_id", material_point.getString("region_id")); - regionIoObj.put("region_code", material_point.getString("region_code")); - regionIoObj.put("region_name", material_point.getString("region_name")); - regionIoObj.put("material_id", taskObj.getString("material_id")); - regionIoObj.put("ivt_weight", requestObj.getString("qty")); - regionIoObj.put("weight_unit_id", RegionIOEnum.UNIT_ID_T.getCode()); - regionIoObj.put("bill_status", RegionIOEnum.BILL_STATUS_FINISH.getCode()); - regionIoObj.put("start_point_code", taskObj.getString("point_code1")); - regionIoObj.put("end_point_code", taskObj.getString("point_code2")); - regionIoObj.put("create_mode", RegionIOEnum.CREATE_MODE_ACS.getCode()); - regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - regionIoObj.put("create_id", "22"); - regionIoObj.put("create_name", "ACS系统"); - regionIoObj.put("create_time", DateUtil.now()); - regionIoTab.insert(regionIoObj); - //完成后 - // 物料点位解锁 并设置空位 - PointUpdateUtil.clearPoint(material_point.getString("point_code")); - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - String point_code2 = form.getString("point_code2"); - - //生产工单表【PDM_BD_WorkOrder】 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code2 = '" + point_code2 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code2 + "存在未完成的任务"); - //点位基础表【SCH_BASE_Point】 - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - String device_code = pointTab.query("point_code = '" + point_code2 + "'").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 (workOrderObj.getString("is_new").equals(WorkOrderEnum.IS_NEW_MATERIAL.getCode()) && point_code2.endsWith("02")) { - // 不需要下发任务,也不能创建任务 - return null; - } - - SchTaskDto dto = SchTaskDto.builder() - .task_id(IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("task_type") - .task_name("压制机叫料") - .acs_task_type("2") - .vehicle_type(workOrderObj.getString("is_new")) - .workorder_id(workOrderObj.getLong("workorder_id")) - .task_status(TaskStatusEnum.SURE_END.getCode()) - .point_code2(point_code2) - .workorder_id(workOrderObj.getLong("workorder_id")) - .material_id(workOrderObj.getLong("material_id")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .request_param(form.toJSONString()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - //创建好立即下发 - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @returninvoke - * @discription 确定任务起点 - * @author ldjun - * @created 2020年6月12日 下午6:01:30 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void findStartPoint() { - /** - * 根据业务找对应的起点,直接到困料货架获取 - * 如果是普通压制机:区分新旧物料、新料有对接位,旧料需要查找放到哪个旧盅货架 - * 如果是液压机:手持呼叫,到困料货架查找相同物料的料盅(这里只能是新料盅) - */ - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); // 点位表 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); // 工单表 - WQLObject deviceTab = WQLObject.getWQLObject("PDM_BI_Device"); // 设备表 - - JSONArray taskArr = taskTab.query("handle_class = '" + THIS_CLASS + "'and is_delete = '0' and task_status = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); - for (int i = 0; i < taskArr.size(); i++) { - JSONObject taskObj = taskArr.getJSONObject(i); - // point_code2是对应的上料点 - String point_code2 = taskObj.getString("point_code2"); - JSONObject point = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - String device_code = point.getString("device_code"); - // 获取工单 - JSONObject workOrderObj = workOrderTab.query("workorder_id = '" + taskObj.getString("workorder_id") + "'").uniqueResult(0); - JSONObject deviceObj = deviceTab.query("device_code = '" + device_code + "'").uniqueResult(0); - String is_new = "1"; - if (deviceObj.getString("device_model").equals("3")) { // 普通压制机:区分新旧物料 - // 新物料終点不用修改 - if (workOrderObj.getString("is_new").equals(WorkOrderEnum.IS_MIXIN_MATERIAL.getCode()) && point_code2.endsWith("02")) { // 混料 - // 查找该设备对应的旧盅位 - JSONObject endPoint = pointTab.query("region_code = 'KLHJ' AND point_type = '4' AND device_code LIKE '%" + - point_code2 + "%' AND point_status = '1' AND is_used = '1' AND is_delete = '0' AND lock_type = '1'").uniqueResult(0); - point_code2 = endPoint.getString("point_code"); // 未锁的旧盅货架位 - is_new = "2"; - } - } - - String material_id = taskObj.getString("material_id"); - JSONObject queryParam = new JSONObject(); - queryParam.put("flag", "1"); - queryParam.put("material_id", material_id); - queryParam.put("region_code", "KLHJ"); - queryParam.put("is_new", is_new); - JSONObject json1 = WQL.getWO("QSCH_yzjCallMaterial_01").addParamMap(queryParam).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(json1)) { - // 拿到点位 - JSONObject material_point = pointTab.query("point_id = '" + json1.getString("point_id") + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(material_point)) throw new BadRequestException("数据错误,请校验!"); - // 物料点位上锁 - material_point.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - material_point.put("task_id", taskObj.getString("task_id")); - pointTab.update(material_point); - - taskObj.put("point_code2", point_code2); - taskObj.put("remark", ""); - taskObj.put("point_code1", material_point.getString("point_code")); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskObj.put("update_time", DateUtil.now()); - } else { - taskObj.put("remark", "困料货架无所需物料"); - taskObj.put("update_time", DateUtil.now()); - } - taskTab.update(taskObj); - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.CANCEL.getCode()); - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_cyCallMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_cyCallMaterial_01.wql deleted file mode 100644 index 674b0d4..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_cyCallMaterial_01.wql +++ /dev/null @@ -1,68 +0,0 @@ -[交易说明] - 交易名: 分拣叫料 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为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, - p.block_num, - p.col_num, - p.row_num - FROM - SCH_BASE_Point p - WHERE - p.is_used = '1' - AND is_delete = '0' - AND lock_type='1' - AND point_status = '3' - OPTION 输入.material_id <> "" - p.material_id = 输入.material_id - ENDOPTION - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - ORDER BY instorage_time - ENDSELECT - ENDQUERY - ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_yzjCallMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_yzjCallMaterial_01.wql deleted file mode 100644 index c324ca2..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/callMaterial/wql/QSCH_yzjCallMaterial_01.wql +++ /dev/null @@ -1,71 +0,0 @@ -[交易说明] - 交易名: 压制机叫料 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为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 p.is_used = '1' - AND standing_time is not null - AND now() > DATE_ADD(instorage_time,INTERVAL standing_time MINUTE) - AND is_delete = '0' - AND point_type = '1' - AND point_status = '3' - OPTION 输入.material_id <> "" - p.material_id = 输入.material_id - ENDOPTION - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - OPTION 输入.vehicle_type <> "" - p.vehicle_type like 输入.is_new - ENDOPTION - ORDER BY p.instorage_time - ENDSELECT - ENDQUERY - ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/cpOut/CpOutTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/cpOut/CpOutTask.java deleted file mode 100644 index 1cd708d..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/cpOut/CpOutTask.java +++ /dev/null @@ -1,269 +0,0 @@ -package org.nl.wms.sch.tasks.cpOut; - -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 CpOutTask extends AbstractAcsTask { - private final String THIS_CLASS = CpOutTask.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"); - WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); - - 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"); - JSONObject point2Obj = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("remark", "任务已取消"); - taskTab.update(taskObj); - - if (ObjectUtil.isNotEmpty(point2Obj)) { - // 释放终点点位 - point2Obj.put("lock_type", "1"); - point2Obj.put("point_status", "1"); - point2Obj.put("task_id", ""); - point2Obj.put("material_id", ""); - point2Obj.put("vehicle_type", ""); - point2Obj.put("vehicle_code", ""); - pointTab.update(point2Obj); - } - } - - 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); - - // 任务表的点位1:成品库区点 - String point_code1 = taskObj.getString("point_code1"); // 起点编码 - JSONObject point1Obj = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0);// 起点 - - //table_fk_id = 单据id - JSONObject regionIoObject = regionIoTab.query("iostorinv_id = '" + taskObj.getString("table_fk_id") + "'").uniqueResult(0); - - String point_code2 = taskObj.getString("point_code2"); // 终点编码:出库点位 - JSONObject point2Obj = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0);// 终点 - - // 修改区域出入库 - 起点点位解锁、点位状态更新 - 终点上锁、更新状态 - //区域出入表【st_ivt_regionIO】 - regionIoObject.put("end_point_code", point_code2); - regionIoObject.put("start_region_id", point1Obj.getString("region_id")); // 起点区域 - regionIoObject.put("end_region_id", point2Obj.getString("region_id")); // 终点区域 - regionIoObject.put("bill_status", "3"); // 单据状态 - regionIoObject.put("task_id", task_id); // 任务id - regionIoObject.put("update_optid", SecurityUtils.getCurrentUserId()); - regionIoObject.put("update_optname", SecurityUtils.getCurrentNickName()); - regionIoObject.put("update_time", DateUtil.now()); - regionIoTab.update(regionIoObject); - - //完成后修改点位 - // 点位解锁 并设置空位 - // 货位点 - point2Obj.put("lock_type", "2"); - point2Obj.put("point_status", "3"); - point2Obj.put("material_id", point1Obj.getString("material_id")); - point2Obj.put("pcsn", point1Obj.getString("pcsn")); - point2Obj.put("ivt_qty", point1Obj.getString("ivt_qty")); - point2Obj.put("instorage_time", point1Obj.getString("instorage_time")); - point2Obj.put("vehicle_type", point1Obj.getString("vehicle_type")); - point2Obj.put("vehicle_code", point1Obj.getString("vehicle_code")); - point2Obj.put("standing_time", point1Obj.getString("standing_time")); - // 起点 - point1Obj.put("lock_type", "1"); - point1Obj.put("point_status", "1"); - point1Obj.put("material_id", ""); - point1Obj.put("pcsn", ""); - point1Obj.put("ivt_qty", "0"); - point1Obj.put("instorage_time", ""); - point1Obj.put("vehicle_type", ""); - point1Obj.put("vehicle_code", ""); - point1Obj.put("standing_time", 0); - - pointTab.update(point1Obj); - pointTab.update(point2Obj); - } - - } - - @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 = '" + TaskStatusEnum.SURE_END.getCode() + "'").getResultJSONArray(0); - for (int i = 0; i < taskArr.size(); i++) { - JSONObject taskObj = taskArr.getJSONObject(i); - String material_id = taskObj.getString("material_id"); - JSONObject param1 = new JSONObject(); - param1.put("flag", "1"); - param1.put("material_id", material_id); - param1.put("region_code", "CPCKQ01"); - //1、找空位的终点 - JSONObject endPoint = WQL.getWO("QSCH_cpOut_01").addParamMap(param1).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(endPoint)) { - // 找到终点,上锁 - 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); - } else { - taskObj.put("remark", "成品出库区无可用货位"); - taskObj.put("update_time", DateUtil.now()); - } - - taskTab.update(taskObj); - - } - } - - @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) { - WQLObject pointTab = WQLObject.getWQLObject("SCH_BASE_Point"); - WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); - - String point_code1 = whereJson.getString("point_code1"); // 起点 - String vehicle_code = whereJson.getString("vehicle_code"); - String iostorinv_id = whereJson.getString("iostorinv_id"); - String material_id = whereJson.getString("material_id"); - - JSONObject point = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - String vehicle_type = point.getString("vehicle_type"); - - SchTaskDto dto = SchTaskDto.builder() - .task_id(IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("task_type") - .task_name("成品区出库") - .task_status(TaskStatusEnum.SURE_END.getCode()) - .point_code1(point_code1) - .vehicle_code(vehicle_code) - .vehicle_type(vehicle_type) - .handle_class(THIS_CLASS) - .material_id(Long.valueOf(material_id)) - .create_time(DateUtil.now()) - .request_param(whereJson.toJSONString()) - .table_name("st_ivt_regionIO") - .table_fk("iostorinv_id") - .table_fk_id(Long.valueOf(iostorinv_id)) - .build(); - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - // 单据设置执行中 - JSONObject iostorinv = regionIoTab.query("iostorinv_id = '" + iostorinv_id + "'").uniqueResult(0); - iostorinv.put("bill_status", "2"); - iostorinv.put("update_optid", SecurityUtils.getCurrentUserId()); - iostorinv.put("update_optname", SecurityUtils.getCurrentNickName()); - iostorinv.put("update_time", DateUtil.now()); - regionIoTab.update(iostorinv); - - //创建好立即下发 - 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"); - else { - throw new BadRequestException("未找到该任务或者任务已完成!"); - } - } - - @Override - public void cancel(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,"0"); - else throw new BadRequestException("任务已完成不能取消!"); - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/DpSendEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/DpSendEmpVehicleTask.java deleted file mode 100644 index 6539ad8..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/DpSendEmpVehicleTask.java +++ /dev/null @@ -1,243 +0,0 @@ -package org.nl.wms.sch.tasks.sendEmpty; - -import cn.hutool.core.date.DateUtil; -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; -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.core.bean.WQLObject; -import org.nl.wms.sch.SchTaskDto; -import org.nl.wms.sch.manage.AbstractAcsTask; -import org.nl.wms.sch.manage.PointEnum; -import org.nl.wms.sch.manage.TaskStatusEnum; -import org.nl.wms.sch.manage.UpdateTaskStatusEnum; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.PointUpdateUtil; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author: lyd - * @description: 叠盘送空载具 - * @Date: 2022/11/15 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class DpSendEmpVehicleTask extends AbstractAcsTask { - private final String THIS_CLASS = DpSendEmpVehicleTask.class.getName(); - /** - * 添加任务进行下发 - * - * @return - */ - @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_code2")) - .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; - } - - /** - * @param taskObj 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,1:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void updateTaskStatus(JSONObject taskObj, String status) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); - - String task_id = taskObj.getString("task_id"); - JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - String point_code1 = jsonTask.getString("point_code1"); - String point_code2 = jsonTask.getString("point_code2"); - - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - // 取消删除任务 - if (StrUtil.equals(jsonTask.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - // 解锁终点位置 - if (ObjectUtil.isNotEmpty(point_code2)) { // 未找到终点的取消只需要完成任务就行 - JSONObject point2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - point2.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(point2); - } - // 任务设置为完成 - jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); - jsonTask.put("remark", "已取消"); - taskTab.update(jsonTask); - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().equals(status)) { - // 更新任务状态为执行中 - jsonTask.put("task_status", TaskStatusEnum.EXECUTING.getCode()); - jsonTask.put("update_time", DateUtil.now()); - jsonTask.put("car_no", taskObj.getString("car_no")); - taskTab.update(jsonTask); - } - - if (StrUtil.equals(status, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - // 更改任务状态为完成 - jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); - jsonTask.put("update_optid", "22"); - jsonTask.put("update_optname", "ACS系统"); - jsonTask.put("update_time", DateUtil.now()); - taskTab.update(jsonTask); - // 释放点位 - if (ObjectUtil.isEmpty(point_code2)) return;// 防止只有确定起点的任务完成 - JSONObject point_2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - point_2.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - point_2.put("vehicle_code", jsonTask.getString("vehicle_code")); - point_2.put("vehicle_qty", NumberUtil.add(point_2.getString("vehicle_qty"), jsonTask.getString("vehicle_qty"))); - point_2.put("instorage_time", DateUtil.now()); - point_2.put("is_full", "1"); - point_2.put("ivt_qty", "0"); - point_2.put("pcsn", ""); - point_2.put("material_id", ""); - point_2.put("standing_time", "0"); - pointTab.update(point_2); - // 起点设置为空位 - JSONObject point_1 = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - point_1.put("point_status", PointEnum.POINT_STATUS_EMPTY_POSITION.getCode()); - pointTab.update(point_1); - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - // 送到KGTDDW01 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - - String point_code1 = form.getString("point_code1"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); - - SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .task_name("空钢托叠盘区->空钢托拆盘区") - .task_status(TaskStatusEnum.SURE_START.getCode()) - .point_code1(point_code1) - .vehicle_type(PointEnum.VEHICLE_TYPE_STEEL_TRAY.getCode()) - .vehicle_qty(form.getIntValue("qty")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @return - * @discription 确定下一点位 - * @author ldjun - * @created 2020年6月12日 下午6:01:06 - */ - @Override - @Transactional(rollbackFor = Exception.class) - 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); - // 请求acs查看堆叠位是否可以搬运,修改对应点的点位 - JSONArray params = new JSONArray(); - JSONObject param = new JSONObject(); - param.put("device_code", "KGTDDW01"); - params.add(param); - PointUpdateUtil.updatePoint(params); - // 直接找 - JSONObject endPoint = pointTab.query("point_code = 'KGTDDW01' AND lock_type = '1' AND is_used = '1' AND is_delete = '0' AND point_status = '1'").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("remark", ""); - 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", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(endPoint); - } - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.CANCEL.getCode()); - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/FjSendEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/FjSendEmpVehicleTask.java deleted file mode 100644 index b4282a4..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/FjSendEmpVehicleTask.java +++ /dev/null @@ -1,225 +0,0 @@ -package org.nl.wms.sch.tasks.sendEmpty; - -import cn.hutool.core.date.DateUtil; -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; -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.PointEnum; -import org.nl.wms.sch.manage.TaskStatusEnum; -import org.nl.wms.sch.manage.UpdateTaskStatusEnum; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author: lyd - * @description: 分拣送空钢托盘 - * @Date: 2022/11/11 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class FjSendEmpVehicleTask extends AbstractAcsTask { - private final String THIS_CLASS = FjSendEmpVehicleTask.class.getName(); - /** - * 添加任务进行下发 - * - * @return - */ - @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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @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); - String point_code2 = taskObj.getString("point_code2"); - - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - // 取消删除任务 - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - // 解锁终点位置 - if (ObjectUtil.isNotEmpty(point_code2)) { // 未找到终点的取消只需要完成任务就行 - JSONObject point2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - point2.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(point2); - } - // 任务设置为完成 - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().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, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - // 更改任务状态为完成 - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - // 释放点位 - if (ObjectUtil.isNotEmpty(point_code2)) { // 防止只有确定起点的任务完成 - JSONObject point_2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - point_2.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - point_2.put("vehicle_qty", NumberUtil.add(point_2.getString("vehicle_qty"), taskObj.getString("vehicle_qty"))); - pointTab.update(point_2); - } - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - // 送到叠盘区:KGTDTW01 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - - String point_code1 = form.getString("point_code1"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete = '0' and point_code2 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); - - SchTaskDto dto = SchTaskDto.builder().task_id(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .task_name("分拣送空钢托盘") - .task_status(TaskStatusEnum.SURE_START.getCode()) - .acs_task_type("4") - .point_code1(point_code1) - .vehicle_type(PointEnum.VEHICLE_TYPE_STEEL_TRAY.getCode()) - .vehicle_qty(1) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @return - * @discription 确定下一点位 - * @author ldjun - * @created 2020年6月12日 下午6:01:06 - */ - @Override - @Transactional(rollbackFor = Exception.class) - 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); - // 直接找 - JSONObject endPoint = pointTab.query("point_code = 'KGTDTW01' AND lock_type = '1'").uniqueResult(0); - if (ObjectUtil.isEmpty(endPoint)) { - taskObj.put("remark", "钢托盘叠托位不可用!"); - taskObj.put("task_status", TaskStatusEnum.SURE_START.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } else { - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", ""); - taskObj.put("point_code2", "KGTDTW01"); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(taskObj); - - //锁住终点 - endPoint.put("task_id", taskObj.getString("task_id")); - endPoint.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(endPoint); - } - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj,UpdateTaskStatusEnum.CANCEL.getCode()); - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/YzjSendEmpVehicleTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/YzjSendEmpVehicleTask.java deleted file mode 100644 index 9216cb6..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/YzjSendEmpVehicleTask.java +++ /dev/null @@ -1,238 +0,0 @@ -package org.nl.wms.sch.tasks.sendEmpty; - -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.apache.commons.lang3.StringUtils; -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.PointEnum; -import org.nl.wms.sch.manage.TaskStatusEnum; -import org.nl.wms.sch.manage.UpdateTaskStatusEnum; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.PointUpdateUtil; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author: lyd - * @description: 压制机送空盅入库 - * @Date: 2022/11/10 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class YzjSendEmpVehicleTask extends AbstractAcsTask { - private final String THIS_CLASS = YzjSendEmpVehicleTask.class.getName(); - /** - * 添加任务进行下发 - * - * @return - */ - @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_code2")) - .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; - } - - /** - * @param taskObj 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun 载具类型由载具表维护 - * @created 2019年4月17日 下午8:51:50 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void updateTaskStatus(JSONObject taskObj, String status) { - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - WQLObject pointTab = WQLObject.getWQLObject("sch_base_point"); - - String task_id = taskObj.getString("task_id"); - String point_code2 = taskObj.getString("point_code2"); - JSONObject jsonTask = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - // 取消删除任务 - if (StrUtil.equals(jsonTask.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - // 解锁终点位置 - if (ObjectUtil.isNotEmpty(point_code2)) { // 未找到终点的取消只需要完成任务就行 - JSONObject point2 = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - point2.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(point2); - } - // 任务设置为完成 - jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); - jsonTask.put("remark", "已取消"); - taskTab.update(jsonTask); - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().equals(status)) { - // 更新任务状态为执行中 - jsonTask.put("task_status", TaskStatusEnum.EXECUTING.getCode()); - jsonTask.put("update_time", DateUtil.now()); - jsonTask.put("car_no", taskObj.getString("car_no")); - taskTab.update(jsonTask); - } - - if (StrUtil.equals(status, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - // 更改任务状态为完成 - jsonTask.put("task_status", TaskStatusEnum.FINISHED.getCode()); - jsonTask.put("update_optid", "22"); - jsonTask.put("update_optname", "ACS系统"); - jsonTask.put("update_time", DateUtil.now()); - taskTab.update(jsonTask); - // 释放点位 - if (ObjectUtil.isNotEmpty(point_code2)) { // 防止只有确定起点的任务完成 - JSONObject jsonObject = new JSONObject(); - jsonObject.put("point_code", point_code2); - jsonObject.put("vehicle_code", jsonTask.getString("vehicle_code")); - PointUpdateUtil.setVehicle(jsonObject); - } - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - /* - * 1.先生成确定起点的任务 - * 2.通过findNextPoint()找终点 - * 3.下发给ACS - */ - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); // 任务表 - - String point_code1 = form.getString("point_code1"); - SchTaskDto dto = SchTaskDto.builder() - .task_id(org.nl.wms.util.IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("") - .task_name("压制机空盅入库") - .task_status(TaskStatusEnum.SURE_START.getCode()) - .point_code1(point_code1) - .vehicle_code(form.getString("vehicle_code")) // 送空盅需要 - .vehicle_type(form.getString("vehicle_type")) - .vehicle_qty(1) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @return - * @discription 确定下一点位 - * @author ldjun - * @created 2020年6月12日 下午6:01:06 - */ - @Override - @Transactional(rollbackFor = Exception.class) - 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", "KLHJ"); - param1.put("vehicle_type", "%" + vehicle_type + "%"); - //1、查找困料货架是否有空位,将空桶送过去,由于一个货架只放一个,不需要判定,有空位即可放 - JSONObject endPoint = WQL.getWO("QSCH_yzjSendEmptyVehicle_01").addParamMap(param1).process().uniqueResult(0); - if (ObjectUtil.isEmpty(endPoint)) { - taskObj.put("remark", "困料货架无可用货位!"); - taskObj.put("task_status", TaskStatusEnum.SURE_START.getCode()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - } else { - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", ""); - 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", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(endPoint); - } - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.CANCEL.getCode()); - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/wql/QSCH_yzjSendEmptyVehicle_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/wql/QSCH_yzjSendEmptyVehicle_01.wql deleted file mode 100644 index b2a0812..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendEmpty/wql/QSCH_yzjSendEmptyVehicle_01.wql +++ /dev/null @@ -1,70 +0,0 @@ -[交易说明] - 交易名: 压制机送空盘 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为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, - p.block_num, - p.col_num, - p.row_num - FROM - SCH_BASE_Point p - WHERE - p.is_used = '1' - AND is_delete = '0' - AND lock_type = '1' - AND point_status = '1' - OPTION 输入.material_id <> "" - p.material_id = 输入.material_id - ENDOPTION - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - OPTION 输入.vehicle_type <> "" - p.can_vehicle_type like 输入.vehicle_type - ENDOPTION - ENDSELECT - ENDQUERY - ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/FjSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/FjSendMaterialTask.java deleted file mode 100644 index 8e7f961..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/FjSendMaterialTask.java +++ /dev/null @@ -1,462 +0,0 @@ -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.modules.wql.util.SpringContextHolder; -import org.nl.wms.ext.acs.service.WmsToAcsService; -import org.nl.wms.ext.acs.service.impl.WmsToAcsServiceImpl; -import org.nl.wms.sch.SchTaskDto; -import org.nl.wms.sch.manage.*; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.sch.tasks.PointUpdateUtil; -import org.nl.wms.sch.tasks.callEmpty.FjCallEmptyVehicleTask; -import org.nl.wms.sch.tasks.sendEmpty.FjSendEmpVehicleTask; -import org.nl.wms.util.IdUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author: lyd - * @description: 分拣送料入库 - * @Date: 2022/11/14 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class FjSendMaterialTask extends AbstractAcsTask { - private final String THIS_CLASS = FjSendMaterialTask.class.getName(); - - /** - * 添加任务进行下发 - * - * @return - */ - @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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @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"); - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - WQLObject regionIoTab = WQLObject.getWQLObject("st_ivt_regionIO"); - - String task_id = task.getString("task_id"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - - //任务取消 - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - // 取消删除任务 - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - String point_code2 = taskObj.getString("point_code2"); - if (ObjectUtil.isNotEmpty(point_code2)) { - JSONObject endPoint = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - endPoint.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(endPoint); - } - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().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, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - /** - * 任务完成: - * 取木托盘完成,送物料完成 - */ - // 更改任务状态为完成 - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_optid", SecurityUtils.getCurrentUserId()); - taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - - String point_code1 = taskObj.getString("point_code1"); - String point_code2 = taskObj.getString("point_code2"); - JSONObject point1Obj = pointTab.query("point_code = '" + point_code1 + "'").uniqueResult(0); - JSONObject point2Obj = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - JSONObject requestObj = task.getJSONObject("request_param"); - //工单标识 - String workorder_id = taskObj.getString("workorder_id"); - JSONObject workorderObj = workOrderTab.query("workorder_id = '" + workorder_id + "'").uniqueResult(0); - String sort_seq = taskObj.getString("sort_seq"); - if (sort_seq.equals("1")) { // 取空托盘任务 - // 避免没有找到位置 - if (ObjectUtil.isEmpty(point1Obj)) return; - // 需要判断取的是否为半满或者是控盘 - // 半托 - if (point1Obj.getString("region_code").equals(RegionEnum.BZZCQ.getCode())) { - // 物料出库 - // 插入出库单 - 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", RegionIOEnum.IO_TYPE_OUT.getCode()); // 出库 - regionIoObj.put("region_id", point1Obj.getString("region_id")); - regionIoObj.put("region_code", point1Obj.getString("region_code")); - regionIoObj.put("region_name", point1Obj.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("weight_unit_id", RegionIOEnum.UNIT_ID_B.getCode()); - regionIoObj.put("bill_status", RegionIOEnum.BILL_STATUS_FINISH.getCode()); - regionIoObj.put("start_point_code", taskObj.getString("point_code1")); - regionIoObj.put("end_point_code", taskObj.getString("point_code2")); - regionIoObj.put("create_mode", RegionIOEnum.CREATE_MODE_ACS.getCode()); - 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); - // 点位更新,起点:空位,解锁; - PointUpdateUtil.clearPoint(point1Obj.getString("point_code")); - // 终点:码垛对接位,将半托的组盘id放进去 - point2Obj.put("group_id", taskObj.getString("group_id")); - pointTab.update(point2Obj); - } - // 起点解锁 - point1Obj.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(point1Obj); - } - if (sort_seq.equals("2")) { // 送物料任务 - // 避免没有找到位置 - if (ObjectUtil.isEmpty(point2Obj)) return; - 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", RegionIOEnum.IO_TYPE_IN.getCode()); - 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("weight_unit_id", RegionIOEnum.UNIT_ID_B.getCode()); - regionIoObj.put("bill_status", RegionIOEnum.BILL_STATUS_FINISH.getCode()); - regionIoObj.put("start_point_code", taskObj.getString("point_code1")); - regionIoObj.put("end_point_code", taskObj.getString("point_code3")); - regionIoObj.put("create_mode", RegionIOEnum.CREATE_MODE_ACS.getCode()); - 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); - if (!point_code2.equals("BZX01")) { // 半满到包装暂存区,记录库存 - //完成后入库 - point2Obj.put("instorage_time", DateUtil.now()); - point2Obj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - point2Obj.put("ivt_qty", requestObj.getString("qty")); - point2Obj.put("standing_time", workorderObj.getString("standing_time")); - point2Obj.put("material_id", workorderObj.getString("material_id")); - point2Obj.put("vehicle_type", workorderObj.getString("vehicle_type")); - point2Obj.put("vehicle_code", taskObj.getString("vehicle_code")); - point2Obj.put("group_id", taskObj.getString("group_id")); // 组盘标识 - point2Obj.put("is_full", requestObj.getString("is_full")); - point2Obj.put("point_status", PointEnum.POINT_STATUS_HAVE_MATERIAL.getCode()); - } - // 终点解锁 - point2Obj.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(point2Obj); - } - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - String point_code1 = form.getString("point_code1"); - String vehicle_code = form.getString("vehicle_code"); - String qty = form.getString("qty"); - String is_full = form.getString("is_full"); - String weight = form.getString("weight"); - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); - - //生产工单表【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_name("分拣入库") - .material_qty(qty) - .task_status(TaskStatusEnum.SURE_START.getCode()) - .point_code1(point_code1) - .acs_task_type("1") - .vehicle_code(vehicle_code) - .vehicle_type(workOrderObj.getString("vehicle_type")) - .workorder_id(workOrderObj.getLong("workorder_id")) - .material_id(workOrderObj.getLong("material_id")) - .handle_class(THIS_CLASS) - .group_id(form.getLong("group_id")) - .create_time(DateUtil.now()) - .request_param(form.toJSONString()) - .task_group_id(IdUtil.getLongId()) - .sort_seq(2) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - //创建好立即下发 - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @return - * @discription 确定下一点位 - * @author ldjun - * @created 2020年6月12日 下午6:01:06 - */ - @Override - @Transactional(rollbackFor = Exception.class) - 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); - JSONObject requestObj = taskObj.getJSONObject("request_param"); - if (requestObj.getString("is_full").equals("1")) { // 满拖去包装线,并且叫空木托盘 - // 更新包装线点位 - JSONArray jsonArray = new JSONArray(); - JSONObject data = new JSONObject(); - data.put("device_code", "BZX01"); - jsonArray.add(data); - // 更新点位 - PointUpdateUtil.updatePoint(jsonArray); - // 找点位 - JSONObject endPoint = pointTab.query("point_code = 'BZX01' AND" + - " point_status = '1' AND lock_type = '1'").uniqueResult(0); // 空位 - //判断当前点是否有未完成的任务 - JSONObject taskObj2 = taskTab.query("task_group_id = '" + taskObj.getString("task_group_id") + "' and sort_seq = '1'").uniqueResult(0); -// JSONObject param = new JSONObject(); -// if (ObjectUtil.isNotEmpty(taskObj2)){ -// param.put("point_code2", taskObj.getString("point_code1")); // 起点 -// SpringContextHolder.getBean(FjCallEmptyVehicleTask.class).createTask(param); -// } - // 满拖先生成叫半托,没有在呼叫空托盘的任务,在执行去到包装线 - SchTaskDto dto = null; - if (ObjectUtil.isEmpty(taskObj2)) { - dto = SchTaskDto.builder() - .task_id(IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("task_type") - .task_name("分拣呼叫空托盘") - .vehicle_type(taskObj.getString("vehicle_type")) // 与满拖的类型一致,因为工单未结束 - .material_qty(taskObj.getString("material_qty")) - .task_status(TaskStatusEnum.SURE_END.getCode()) - .point_code2(taskObj.getString("point_code1")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .sort_seq(1) - .task_group_id(taskObj.getLong("task_group_id")) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - } - // 先呼叫半托 - JSONObject halfTray = pointTab.query("region_code = 'BZZCQ' AND lock_type = '1' " + - "AND point_status = '2' AND is_used = '1' AND is_delete = '0'").uniqueResult(0); - // 获取任务 - String id = null; - if (ObjectUtil.isNotEmpty(dto)) { - id = String.valueOf(dto.getTask_id()); - } else { - id = taskObj2.getString("task_id"); - } - JSONObject taskEnt = taskTab.query("task_id = '" + id + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(halfTray)) { // 半托 - // 去搬运 - taskEnt.put("point_code1", halfTray.getString("point_code")); - taskEnt.put("update_time", DateUtil.now()); - taskEnt.put("group_id", halfTray.getString("group_id")); // 半托要把组盘标识记录起来 - taskEnt.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(taskEnt); - // 更新半托点位状态 - halfTray.put("task_id", taskObj.getString("task_id")); - halfTray.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(halfTray); - } else { - // 没有半托呼叫空木托盘 - // 获取所有的托盘堆叠位 - JSONArray pointCodes = WQL.getWO("QSCH_fjSendMaterial_01").addParam("flag", "2").process().getResultJSONArray(0); - // 更新点位 - PointUpdateUtil.updatePoint(pointCodes); - // 找到载具类型符合的覆膜机位置:真正的位置在device_code - JSONObject emptyTray = pointTab.query("region_code = 'RGCPQ' AND vehicle_type = '" + - taskObj.getString("vehicle_type") + "' AND point_status = '2' " + - "AND is_used = '1' AND is_delete = '0'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(emptyTray)) { - // 判断出口是否锁住 - JSONObject exitPoint = pointTab.query("point_code = '" + - emptyTray.getString("device_code") + "'" + - " AND lock_type = '1'").uniqueResult(0); - if (ObjectUtil.isEmpty(exitPoint)) return; // 出口点锁住就不能呼叫空盘 - // 向ACS申请传送一个空木托盘 - JSONArray jsons = new JSONArray(); - JSONObject datas = new JSONObject(); - datas.put("device_code", emptyTray.getString("point_code")); - jsons.add(datas); - WmsToAcsServiceImpl wmsToAcsService = SpringContextHolder.getBean(WmsToAcsServiceImpl.class); - wmsToAcsService.getTray(jsons); - // 去搬运 - taskEnt.put("point_code1", exitPoint.getString("point_code")); - taskEnt.put("update_time", DateUtil.now()); - taskEnt.put("remark", ""); - taskEnt.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(taskEnt); - // 更新空托盘点位状态 - exitPoint.put("task_id", taskObj.getString("task_id")); - exitPoint.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(exitPoint); - } else { - taskEnt.put("remark", "暂无空托盘"); - taskEnt.put("update_time", DateUtil.now()); - taskTab.update(taskEnt); - // 满拖搬运也不下发 - taskObj.put("remark", "暂无空托盘"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - return; - } - } - // 更新送料任务信息 - if (ObjectUtil.isEmpty(endPoint)) return; - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", ""); - 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", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(endPoint); - } else { - // 半满拖就去包装暂存区 - JSONObject param1 = new JSONObject(); - param1.put("flag", "1"); - param1.put("region_code", "BZZCQ"); - //1、查找困料货架是否有响应的载具类型和对应的物料 - JSONObject endPoint = WQL.getWO("QSCH_fjSendMaterial_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", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(endPoint); - } - } - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.CANCEL.getCode()); - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HnSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HnSendMaterialTask.java deleted file mode 100644 index 48649d9..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/HnSendMaterialTask.java +++ /dev/null @@ -1,341 +0,0 @@ -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.*; -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; - -/** - * @author: lyd - * @description: 混碾机送料 - * @Date: 2022/11/9 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class HnSendMaterialTask extends AbstractAcsTask { - - private final String THIS_CLASS = HnSendMaterialTask.class.getName(); - /** - * 添加任务进行下发 - * - * @return - */ - @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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @see org.nl.wms.sch.manage.UpdateTaskStatusEnum - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @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"); - WQLObject materialTab = WQLObject.getWQLObject("MD_ME_MaterialBase"); - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); //生产工单表【PDM_BD_WorkOrder】 - - String task_id = task.getString("task_id"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - - //任务取消 - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - // 取消删除任务 - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - String point_code2 = taskObj.getString("point_code2"); - if (ObjectUtil.isNotEmpty(point_code2)) { // 防止未找到终点而取消任务空指针 - JSONObject endPoint = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - endPoint.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(endPoint); - } - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().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, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - // 更改任务状态为完成 - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_optid", "22"); - taskObj.put("update_optname", "ACS系统"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - - String point_code2 = taskObj.getString("point_code2"); - - if (ObjectUtil.isEmpty(point_code2)) return; // 防止未找到终点而完成任务空指针 - - JSONObject point2Obj = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - JSONObject requestObj = taskObj.getJSONObject("request_param"); - // 工单标识 - String workorder_id = taskObj.getString("workorder_id"); - JSONObject workorderObj = workOrderTab.query("workorder_id = '" + workorder_id + "'").uniqueResult(0); - // 物料 - JSONObject materialObj = materialTab.query("material_id = '" + workorderObj.getString("material_id") + "'").uniqueResult(0); - if (ObjectUtil.isEmpty(materialObj)) throw new BadRequestException("物料不存在!"); - - // 区域出入表【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", RegionIOEnum.IO_TYPE_IN.getCode()); - 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("ivt_weight", requestObj.getString("qty")); - regionIoObj.put("weight_unit_id", RegionIOEnum.UNIT_ID_T.getCode()); - regionIoObj.put("bill_status", RegionIOEnum.BILL_STATUS_FINISH.getCode()); - regionIoObj.put("start_point_code", taskObj.getString("point_code1")); - regionIoObj.put("end_point_code", taskObj.getString("point_code2")); - regionIoObj.put("create_mode", RegionIOEnum.CREATE_MODE_ACS.getCode()); - regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - regionIoObj.put("create_id", "22"); - regionIoObj.put("create_name", "ACS系统"); - regionIoObj.put("create_time", DateUtil.now()); - regionIoTab.insert(regionIoObj); - - //完成后入库 - point2Obj.put("instorage_time", taskObj.getString("create_time")); // 入库时间为任务生成的时间 - point2Obj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - point2Obj.put("ivt_qty", requestObj.getString("qty")); - point2Obj.put("ivt_weight", requestObj.getString("weight")); - point2Obj.put("standing_time", materialObj.getString("standing_time")); - point2Obj.put("warn_time", materialObj.getString("warn_time")); - point2Obj.put("material_id", workorderObj.getString("material_id")); - point2Obj.put("vehicle_type", workorderObj.getString("is_new")); // 工单的新旧物料 - point2Obj.put("vehicle_code", taskObj.getString("vehicle_code")); - point2Obj.put("vehicle_qty", "1"); // 入库为1个载具 - point2Obj.put("is_full", requestObj.getString("is_full")); - - // 终点解锁 - point2Obj.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - point2Obj.put("point_status", PointEnum.POINT_STATUS_HAVE_MATERIAL.getCode()); - pointTab.update(point2Obj); - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - * 混碾机送料到困料货架 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - String point_code1 = form.getString("point_code1"); - String vehicle_code = form.getString("vehicle_code"); - String qty = form.getString("qty"); - String is_full = form.getString("is_full"); - String weight = form.getString("weight"); - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); - - //生产工单表【PDM_BD_WorkOrder】 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - //判断混碾机是否存在生产中的工单 - JSONObject workOrderObj = workOrderTab.query("point_code = '" + point_code1 + "' 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_name("混碾机满料") - .material_qty(qty) - .task_status(TaskStatusEnum.SURE_START.getCode()) - .point_code1(point_code1) - .vehicle_code(vehicle_code) - .vehicle_type(workOrderObj.getString("vehicle_type")) - .workorder_id(workOrderObj.getLong("workorder_id")) - .material_id(workOrderObj.getLong("material_id")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .request_param(form.toJSONString()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - //创建好立即下发 - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @return - * @discription 确定下一点位 - * @author ldjun - * @created 2020年6月12日 下午6:01:06 - */ - @Override - @Transactional(rollbackFor = Exception.class) - 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); - // 找生产改物料的液压机的工单 - JSONObject paramObj = new JSONObject(); - paramObj.put("flag", "1"); - paramObj.put("material_id", taskObj.getString("material_id")); - JSONArray workerOrders = WQL.getWO("QSCH_hnSendMaterial_01").addParamMap(paramObj).process().getResultJSONArray(0); - for (int j = 0; j < workerOrders.size(); j++) { // 根据符合的工单查找 - JSONObject workerOrder = workerOrders.getJSONObject(j); - // 判断仓库是否有该物料 - JSONObject param2 = new JSONObject(); - param2.put("flag", "2"); - param2.put("material_id", workerOrder.getString("material_id")); - param2.put("point_type", "1"); // 公用货架 - param2.put("point_status", PointEnum.POINT_STATUS_HAVE_MATERIAL.getCode()); // 有料 - JSONArray ivts = WQL.getWO("QSCH_hnSendMaterial_01").addParamMap(param2).process().getResultJSONArray(0); - if (ivts.size() > 0) continue; - // 判断是否有空位 - JSONObject param3 = new JSONObject(); - param3.put("flag", "2"); - param3.put("device_code", workerOrder.getString("device_code")); - param3.put("point_type", "2"); // 液压机旁边三个位置 - param3.put("point_status", PointEnum.POINT_STATUS_EMPTY_POSITION.getCode()); // 空位 - JSONObject endPoint = WQL.getWO("QSCH_hnSendMaterial_01").addParamMap(param3).process().uniqueResult(0); - if (ObjectUtil.isEmpty(endPoint)) continue; - - // 找到位置就可以直接搬 - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", ""); - taskObj.put("point_code2", endPoint.getString("point_code")); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(taskObj); - - // 点位上锁 - endPoint.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - endPoint.put("task_id", taskObj.getString("task_id")); - pointTab.update(endPoint); - return; - } - // 其他情况直接搬到困料货架上 - JSONObject param1 = new JSONObject(); - param1.put("flag", "3"); - param1.put("region_code", "KLHJ"); - // 查找困料货架 - JSONObject endPoint = WQL.getWO("QSCH_hnSendMaterial_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("remark", ""); - 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", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(endPoint); - } - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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,UpdateTaskStatusEnum.CANCEL.getCode()); - else { - throw new BadRequestException("未找到该任务或者任务已完成!"); - } - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SendMaterialTask.java deleted file mode 100644 index 314a234..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SendMaterialTask.java +++ /dev/null @@ -1,230 +0,0 @@ -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 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.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 java.util.ArrayList; -import java.util.List; - -/** - * @author: lyd - * @description: - * @Date: 2022/11/10 - */ -public class SendMaterialTask extends AbstractAcsTask { - private final String THIS_CLASS = this.getClass().getName(); - - /** - * 添加任务进行下发 - * - * @return - */ - @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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @Override - 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_optid", SecurityUtils.getCurrentUserId()); - taskObj.put("update_optname", SecurityUtils.getCurrentUsername()); - 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("workorder_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); - - //完成后入库 - point2Obj.put("instorage_time", DateUtil.now()); - point2Obj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - point2Obj.put("ivt_qty", requestObj.getString("qty")); - point2Obj.put("standing_time", workorderObj.getString("standing_time")); - point2Obj.put("material_id", workorderObj.getString("material_id")); - point2Obj.put("vehicle_type", workorderObj.getString("vehicle_type")); - point2Obj.put("vehicle_code", taskObj.getString("vehicle_code")); - point2Obj.put("is_full", requestObj.getString("is_full")); - - // 终点解锁 - point2Obj.put("lock_type", "1"); - point2Obj.put("point_status", "3"); - pointTab.update(point2Obj); - } - - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - */ - @Override - public String createTask(JSONObject form) { - String point_code1 = form.getString("point_code1"); - String vehicle_code = form.getString("vehicle_code"); - String qty = form.getString("qty"); - String is_full = form.getString("is_full"); - String weight = form.getString("weight"); - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); - - //生产工单表【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_name("混碾机满料") - .material_qty(qty) - .task_status(TaskStatusEnum.SURE_START.getCode()) - .point_code1(point_code1) - .vehicle_code(vehicle_code) - .vehicle_type(workOrderObj.getString("vehicle_type")) - .workorder_id(workOrderObj.getLong("workorder_id")) - .material_id(workOrderObj.getLong("material_id")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .request_param(form.toJSONString()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - //创建好立即下发 - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @Override - public void forceFinish(String task_id) { - - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(String task_id) { - - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SzSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SzSendMaterialTask.java deleted file mode 100644 index 31b2e6a..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/SzSendMaterialTask.java +++ /dev/null @@ -1,279 +0,0 @@ -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.*; -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; - -/** - * @author: lyd - * @description: 烧制满料入库 - * @Date: 2022/11/10 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class SzSendMaterialTask extends AbstractAcsTask { - private final String THIS_CLASS = SzSendMaterialTask.class.getName(); - /** - * 添加任务进行下发 - * - * @return - */ - @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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @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"); - WQLObject groupTab = WQLObject.getWQLObject("st_buss_vehiclegroup"); - - String task_id = task.getString("task_id"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - - //任务取消 - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - // 取消删除任务 - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - String point_code2 = taskObj.getString("point_code2"); - if (ObjectUtil.isNotEmpty(point_code2)) { - JSONObject endPoint = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - endPoint.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(endPoint); - } - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().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, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - String vehicle_code = taskObj.getString("vehicle_code"); - // 更改任务状态为完成 - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_optid", "22"); - taskObj.put("update_optname", "ACS系统"); - taskObj.put("update_time", DateUtil.now()); - taskTab.update(taskObj); - - String point_code2 = taskObj.getString("point_code2"); - if (ObjectUtil.isEmpty(point_code2)) return; - JSONObject point2Obj = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - JSONObject groupObj = groupTab.query("group_id = '" + taskObj.getString("group_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", RegionIOEnum.IO_TYPE_IN.getCode()); // 入库 - 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", groupObj.getString("material_uuid")); - regionIoObj.put("vehicle_code", vehicle_code); - regionIoObj.put("qty", groupObj.getString("qty")); - regionIoObj.put("weight_unit_id", RegionIOEnum.UNIT_ID_B.getCode()); - regionIoObj.put("bill_status", RegionIOEnum.BILL_STATUS_FINISH.getCode()); - regionIoObj.put("start_point_code", taskObj.getString("point_code1")); - regionIoObj.put("end_point_code", taskObj.getString("point_code2")); - regionIoObj.put("create_mode", RegionIOEnum.CREATE_MODE_ACS.getCode()); - regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - regionIoObj.put("create_id", "22"); - regionIoObj.put("create_name", "ACS系统"); - regionIoObj.put("create_time", DateUtil.now()); - regionIoTab.insert(regionIoObj); - - //完成后入库 - point2Obj.put("instorage_time", DateUtil.now()); - point2Obj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - point2Obj.put("ivt_qty", groupObj.getString("qty")); - point2Obj.put("material_id", groupObj.getString("material_uuid")); - point2Obj.put("vehicle_type", groupObj.getString("vehicle_type")); - point2Obj.put("vehicle_code", groupObj.getString("vehicle_code")); - point2Obj.put("vehicle_qty", "1"); // 入库为1个载具 - point2Obj.put("is_full", groupObj.getString("is_full")); - point2Obj.put("group_id", groupObj.getString("group_id")); - - // 终点解锁 - point2Obj.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - point2Obj.put("point_status", PointEnum.POINT_STATUS_HAVE_MATERIAL.getCode()); - pointTab.update(point2Obj); - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - * 压制机送料入窑缓存货架 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - String point_code1 = form.getString("point_code1"); - String vehicle_code = form.getString("vehicle_code"); - WQLObject groupTab = WQLObject.getWQLObject("st_buss_vehiclegroup"); - String qty = form.getString("qty"); - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); - - // 获取到组盘 - JSONObject groupObj = groupTab.query("vehicle_code = '" + vehicle_code + "'", "create_time desc").uniqueResult(0); - SchTaskDto dto = SchTaskDto.builder() - .task_id(IdUtil.getLongId()) - .task_code(CodeUtil.getNewCode("TASK_CODE")) - .task_type("task_type") - .task_name("烧制入库") - .acs_task_type("1") - .material_id(groupObj.getLong("material_uuid")) - .group_id(groupObj.getLong("group_id")) - .material_qty(qty) - .task_status(TaskStatusEnum.SURE_START.getCode()) - .point_code1(point_code1) - .vehicle_code(vehicle_code) - .vehicle_type(PointEnum.VEHICLE_TYPE_STEEL_TRAY.getCode()) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .request_param(form.toJSONString()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - //创建好立即下发 - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @return - * @discription 确定下一点位 - * @author ldjun - * @created 2020年6月12日 下午6:01:06 - */ - @Override - @Transactional(rollbackFor = Exception.class) - 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); - JSONObject param1 = new JSONObject(); - param1.put("flag", "1"); - param1.put("region_code", "CYZCQ"); - //1、查找出窑缓存区的空位 - JSONObject endPoint = WQL.getWO("QSCH_szSendMaterial_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("remark", ""); - 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", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(endPoint); - } - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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,"0"); - else { - throw new BadRequestException("未找到该任务或者任务已完成!"); - } - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YzjSendMaterialTask.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YzjSendMaterialTask.java deleted file mode 100644 index 13b9ce6..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/YzjSendMaterialTask.java +++ /dev/null @@ -1,313 +0,0 @@ -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.*; -import org.nl.wms.sch.tasks.AcsTaskDto; -import org.nl.wms.util.IdUtil; -import org.nl.wms.util.MapOf; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author: lyd - * @description: 压制机满料入库 - * @Date: 2022/11/10 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class YzjSendMaterialTask extends AbstractAcsTask { - private final String THIS_CLASS = YzjSendMaterialTask.class.getName(); - /** - * 添加任务进行下发 - * - * @return - */ - @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_code2")) - .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; - } - - /** - * @param task 代表一条任务对象 - * @param status 代表wcs任务完成状态: //0:acs,取消,:执行中,2:完成 - * @return - * @discription wcs请求wms任务完成状态反馈接口, 比如agv从a点往b点走。生成任务的时候绑定b的物料信息,任务完成的时候,清除a的物料信息 - * @author ldjun - * @created 2019年4月17日 下午8:51:50 - */ - @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"); - //生产工单表【PDM_BD_WorkOrder】 - WQLObject workOrderTab = WQLObject.getWQLObject("PDM_BD_WorkOrder"); - - String task_id = task.getString("task_id"); - JSONObject taskObj = taskTab.query("task_id = '" + task_id + "'").uniqueResult(0); - - //任务取消 - if (StrUtil.equals(status, UpdateTaskStatusEnum.CANCEL.getCode())) { - // 取消删除任务 - if (StrUtil.equals(taskObj.getString("task_status"), TaskStatusEnum.FINISHED.getCode())) { - throw new BadRequestException("已完成不能取消!"); - } - String point_code2 = taskObj.getString("point_code2"); - if (ObjectUtil.isNotEmpty(point_code2)) { - JSONObject endPoint = pointTab.query("point_code = '" + point_code2 + "'").uniqueResult(0); - endPoint.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - pointTab.update(endPoint); - } - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("remark", "已取消"); - taskTab.update(taskObj); - } - - if (UpdateTaskStatusEnum.EXECUTION.getCode().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, UpdateTaskStatusEnum.FORCEFINISH.getCode())) { - // 更改任务状态为完成 - taskObj.put("task_status", TaskStatusEnum.FINISHED.getCode()); - taskObj.put("update_optid", "22"); - taskObj.put("update_optname", "ACS系统"); - 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); - if (ObjectUtil.isEmpty(point2Obj)) return; - JSONObject requestObj = taskObj.getJSONObject("request_param"); - //工单标识 - String workorder_id = taskObj.getString("workorder_id"); - 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", RegionIOEnum.IO_TYPE_IN.getCode()); // 入库 - 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("ivt_weight", requestObj.getString("weight")); - regionIoObj.put("weight_unit_id", RegionIOEnum.UNIT_ID_B.getCode()); - regionIoObj.put("bill_status", RegionIOEnum.BILL_STATUS_FINISH.getCode()); - regionIoObj.put("start_point_code", taskObj.getString("point_code1")); - regionIoObj.put("end_point_code", taskObj.getString("point_code3")); - regionIoObj.put("create_mode", RegionIOEnum.CREATE_MODE_ACS.getCode()); - regionIoObj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - regionIoObj.put("create_id", "22"); - regionIoObj.put("create_name", "ACS系统"); - regionIoObj.put("create_time", DateUtil.now()); - regionIoTab.insert(regionIoObj); - - //完成后入库 - point2Obj.put("instorage_time", DateUtil.now()); - point2Obj.put("pcsn", DateUtil.format(DateUtil.parse(DateUtil.today()), "yyyyMMdd")); - point2Obj.put("ivt_qty", requestObj.getString("qty")); - point2Obj.put("ivt_weight", requestObj.getString("weight")); - point2Obj.put("standing_time", workorderObj.getString("standing_time")); - point2Obj.put("warn_time", workorderObj.getString("warn_time")); - point2Obj.put("material_id", workorderObj.getString("material_id")); - point2Obj.put("vehicle_type", workorderObj.getString("vehicle_type")); - point2Obj.put("vehicle_code", taskObj.getString("vehicle_code")); - point2Obj.put("vehicle_qty", "1"); // 入库为1个载具 - point2Obj.put("is_full", requestObj.getString("is_full")); -// point2Obj.put("group_id", taskObj.getString("group_id")); // 组盘标识 - // 解锁终点 - point2Obj.put("lock_type", PointEnum.LOCK_TYPE_FALSE.getCode()); - point2Obj.put("point_status", PointEnum.POINT_STATUS_HAVE_MATERIAL.getCode()); - pointTab.update(point2Obj); - } - } - - /** - * @param form 创建任务需要的参数 - * @return 返回任务标识 - * 压制机送料入窑缓存货架 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public String createTask(JSONObject form) { - String point_code1 = form.getString("point_code1"); - String vehicle_code = form.getString("vehicle_code"); - String qty = form.getString("qty"); - String is_full = form.getString("is_full"); - String weight = form.getString("weight"); - //任务表【SCH_BASE_Task】 - WQLObject taskTab = WQLObject.getWQLObject("SCH_BASE_Task"); - //判断当前点是否有未完成的任务 - JSONObject taskObj = taskTab.query("is_delete='0' and point_code1 = '" + point_code1 + "' and task_status <> '" + TaskStatusEnum.FINISHED.getCode() + "'").uniqueResult(0); - if (ObjectUtil.isNotEmpty(taskObj)) throw new BadRequestException("当前点位" + point_code1 + "存在未完成的任务"); - - //生产工单表【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_name("压制机满料") - .material_qty(qty) - .task_status(TaskStatusEnum.SURE_START.getCode()) - .point_code1(point_code1) - .vehicle_code(vehicle_code) - .group_id(form.getLong("group_id")) - .vehicle_type(PointEnum.VEHICLE_TYPE_STEEL_TRAY.getCode()) - .workorder_id(workOrderObj.getLong("workorder_id")) - .material_id(workOrderObj.getLong("material_id")) - .handle_class(THIS_CLASS) - .create_time(DateUtil.now()) - .request_param(form.toJSONString()) - .build(); - JSONObject json = JSONObject.parseObject(JSON.toJSONString(dto)); - taskTab.insert(json); - //创建好立即下发 - this.immediateNotifyAcs(); - return String.valueOf(dto.getTask_id()); - } - - /** - * @return - * @discription 确定下一点位 - * @author ldjun - * @created 2020年6月12日 下午6:01:06 - */ - @Override - @Transactional(rollbackFor = Exception.class) - 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 rywPoint = WQL.getWO("QSCH_yzSendMaterial_01").addParamMap(MapOf.of("flag", "1", - "point_code", "RYW")).process().uniqueResult(0); - if (ObjectUtil.isNotEmpty(rywPoint)) { - // 找到去入窑口 - taskObj.put("update_time", DateUtil.now()); - taskObj.put("remark", ""); - taskObj.put("point_code2", rywPoint.getString("point_code")); - taskObj.put("task_status", TaskStatusEnum.START_AND_POINT.getCode()); - taskTab.update(taskObj); - - //锁住终点 - rywPoint.put("task_id", taskObj.getString("task_id")); - rywPoint.put("lock_type", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(rywPoint); - continue; - } - // 否则就去货架查找 - JSONObject param1 = new JSONObject(); - param1.put("flag", "2"); - param1.put("region_code", "RYZCQ"); - param1.put("vehicle_type", "%" + vehicle_type + "%"); - //1、查找入窑暂存货架的空位 - JSONObject endPoint = WQL.getWO("QSCH_yzSendMaterial_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("remark", ""); - 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", PointEnum.LOCK_TYPE_TRUE.getCode()); - pointTab.update(endPoint); - } - } - } - - /** - * @param task_id 任务标识 - * @return - * @discription 强制结束完成任务 - * @author ldjun - * @created 2020年6月19日 上午10:34:58 - */ - @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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.FORCEFINISH.getCode()); - } - - /** - * 取消任务,货物搬回原点 - * - * @param task_id - */ - @Override - public void cancel(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.isEmpty(taskObj))throw new BadRequestException("未找到该任务或者任务已完成!"); - this.updateTaskStatus(taskObj, UpdateTaskStatusEnum.CANCEL.getCode()); - } -} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hnSendMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hnSendMaterial_01.wql deleted file mode 100644 index c5ed9e8..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_hnSendMaterial_01.wql +++ /dev/null @@ -1,105 +0,0 @@ -[交易说明] - 交易名: 混碾机送料 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 - -[IO定义] - ################################################# - ## 表字段对应输入参数 - ################################################# - 输入.flag TYPEAS s_string - 输入.region_code TYPEAS s_string - 输入.material_id TYPEAS s_string - 输入.vehicle_type TYPEAS s_string - 输入.device_code TYPEAS s_string - 输入.point_type TYPEAS s_string - 输入.point_status TYPEAS s_string - - -[临时表] - --这边列出来的临时表就会在运行期动态创建 - -[临时变量] - --所有中间过程变量均可在此处定义 - -[业务过程] - - ########################################## - # 1、输入输出检查 # - ########################################## - - - ########################################## - # 2、主过程前处理 # - ########################################## - - - ########################################## - # 3、业务主过程 # - ########################################## - IF 输入.flag = "1" - QUERY - SELECT - workorder.* - FROM - pdm_bd_workorder workorder - WHERE - workorder.order_status = '3' - AND workorder.is_delete = '0' - AND workorder.workorder_procedure = '2' - OPTION 输入.material_id <> "" - workorder.material_id = 输入.material_id - ENDOPTION - ENDSELECT - ENDQUERY - ENDIF - - IF 输入.flag = "2" - QUERY - SELECT - * - FROM - `sch_base_point` - WHERE - lock_type = '1' - AND region_code = 'KLHJ' - AND is_used = '1' - AND is_delete = '0' - OPTION 输入.material_id <> "" - material_id = 输入.material_id - ENDOPTION - OPTION 输入.point_type <> "" - point_type = 输入.point_type - ENDOPTION - OPTION 输入.point_status <> "" - point_status = 输入.point_status - ENDOPTION - ENDSELECT - ENDQUERY - ENDIF - - IF 输入.flag = "3" - QUERY - SELECT - 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_status = '1' - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - ORDER BY p.point_code - ENDSELECT - ENDQUERY - ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yzSendMaterial_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yzSendMaterial_01.wql deleted file mode 100644 index ec10333..0000000 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/tasks/sendMaterial/wql/QSCH_yzSendMaterial_01.wql +++ /dev/null @@ -1,81 +0,0 @@ -[交易说明] - 交易名: 压制机送料 - 所属模块: - 功能简述: - 版权所有: - 表引用: - 版本经历: - -[数据库] - --指定数据库,为空采用默认值,默认为db.properties中列出的第一个库 - -[IO定义] - ################################################# - ## 表字段对应输入参数 - ################################################# - 输入.flag TYPEAS s_string - 输入.region_code TYPEAS s_string - 输入.point_code TYPEAS s_string - 输入.material_id TYPEAS s_string - 输入.vehicle_type TYPEAS s_string - - -[临时表] - --这边列出来的临时表就会在运行期动态创建 - -[临时变量] - --所有中间过程变量均可在此处定义 - -[业务过程] - - ########################################## - # 1、输入输出检查 # - ########################################## - - - ########################################## - # 2、主过程前处理 # - ########################################## - - - ########################################## - # 3、业务主过程 # - ########################################## - IF 输入.flag = "1" - QUERY - SELECT - p.* - FROM - SCH_BASE_Point p - WHERE - lock_type = '1' - AND is_used = '1' - AND is_delete = '0' - AND point_status = '1' - OPTION 输入.point_code <> "" - p.point_code = 输入.point_code - ENDOPTION - ENDSELECT - ENDQUERY - ENDIF - IF 输入.flag = "2" - QUERY - SELECT - p.* - FROM - SCH_BASE_Point p - WHERE - lock_type = '1' - AND is_used = '1' - AND is_delete = '0' - AND point_status = '1' - OPTION 输入.vehicle_type <> "" - p.can_vehicle_type like 输入.vehicle_type - ENDOPTION - OPTION 输入.region_code <> "" - p.region_code = 输入.region_code - ENDOPTION - ORDER BY col_num,row_num,layer_num - ENDSELECT - ENDQUERY - ENDIF diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/util/PointUtils.java b/lms/nladmin-system/src/main/java/org/nl/wms/sch/util/PointUtils.java new file mode 100644 index 0000000..584937b --- /dev/null +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/util/PointUtils.java @@ -0,0 +1,15 @@ +package org.nl.wms.sch.util; + +/** + * @author zhangjiangwei + * @date 2023/04/04 15:41 + */ +public class PointUtils { + + /** + * 从ACS获取点位状态 + */ + public static void updatePointStatusFromACS() { + + } +} diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/QSCH_BASE_POINT.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/QSCH_BASE_POINT.wql index 4c07f81..9bf197c 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/QSCH_BASE_POINT.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/QSCH_BASE_POINT.wql @@ -49,16 +49,11 @@ IF 输入.flag = "1" PAGEQUERY SELECT - point.*, - d3.label as lock_type_name, - ma.material_name + point.* FROM sch_base_point point - LEFT JOIN SCH_BASE_Region region ON point.region_id = region.region_id - LEFT JOIN sys_dict_detail d3 ON point.lock_type = d3.value and d3.name='d_lock_type' - LEFT JOIN md_me_materialbase ma ON ma.material_id = point.material_id WHERE - point.is_delete = '0' + 1 = 1 OPTION 输入.region_id <> "" point.region_id = 输入.region_id ENDOPTION diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/QSCH_TASK_01.wql b/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/QSCH_TASK_01.wql index 729b8ca..a661003 100644 --- a/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/QSCH_TASK_01.wql +++ b/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/QSCH_TASK_01.wql @@ -72,7 +72,7 @@ task.create_time <= 输入.end_time ENDOPTION OPTION 输入.unFinish <> "" - task.task_status <> '07' + task.task_status <> '7' AND task_status <> '8' ENDOPTION OPTION 输入.task_status <> "" find_in_set( task.task_status, 输入.task_status) diff --git a/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/sch.xls b/lms/nladmin-system/src/main/java/org/nl/wms/sch/wql/sch.xls deleted file mode 100644 index 6efd92458bc899fb554a1ae44d57769239d3ae60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179712 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
  • 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%0Deu?A6>Ng7g=wA)brG89j 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%0DWo! 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 Je$^w2{}1lrW)A=W literal 296960 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

    {{ msg }}

    取消 - 确定 + 确定
    删除 diff --git a/lms/nladmin-ui/src/settings.js b/lms/nladmin-ui/src/settings.js index 860639a..209575a 100644 --- a/lms/nladmin-ui/src/settings.js +++ b/lms/nladmin-ui/src/settings.js @@ -40,7 +40,7 @@ module.exports = { /** * @description token key */ - TokenKey: 'NL-LMS-TOEKN', + TokenKey: 'NL-LMS-TOKEN', /** * @description 请求超时时间,毫秒(默认2分钟) */ diff --git a/lms/nladmin-ui/src/views/system/dept/index.vue b/lms/nladmin-ui/src/views/system/dept/index.vue index e5c87df..bf20d9e 100644 --- a/lms/nladmin-ui/src/views/system/dept/index.vue +++ b/lms/nladmin-ui/src/views/system/dept/index.vue @@ -81,7 +81,7 @@ diff --git a/lms/nladmin-ui/src/views/system/dict/dictDetail.vue b/lms/nladmin-ui/src/views/system/dict/dictDetail.vue index b62c9f7..1410765 100644 --- a/lms/nladmin-ui/src/views/system/dict/dictDetail.vue +++ b/lms/nladmin-ui/src/views/system/dict/dictDetail.vue @@ -56,7 +56,7 @@ diff --git a/lms/nladmin-ui/src/views/system/dict/index.vue b/lms/nladmin-ui/src/views/system/dict/index.vue index c205c56..a8b74c3 100644 --- a/lms/nladmin-ui/src/views/system/dict/index.vue +++ b/lms/nladmin-ui/src/views/system/dict/index.vue @@ -11,7 +11,7 @@ diff --git a/lms/nladmin-ui/src/views/system/grid/index.vue b/lms/nladmin-ui/src/views/system/grid/index.vue index 2593a07..00fd6e4 100644 --- a/lms/nladmin-ui/src/views/system/grid/index.vue +++ b/lms/nladmin-ui/src/views/system/grid/index.vue @@ -87,7 +87,7 @@ diff --git a/lms/nladmin-ui/src/views/system/logicflow/image/index.vue b/lms/nladmin-ui/src/views/system/logicflow/image/index.vue index 6c1eb64..02431a0 100644 --- a/lms/nladmin-ui/src/views/system/logicflow/image/index.vue +++ b/lms/nladmin-ui/src/views/system/logicflow/image/index.vue @@ -57,7 +57,7 @@ diff --git a/lms/nladmin-ui/src/views/system/logicflow/index.vue b/lms/nladmin-ui/src/views/system/logicflow/index.vue index 90c77e1..2204632 100644 --- a/lms/nladmin-ui/src/views/system/logicflow/index.vue +++ b/lms/nladmin-ui/src/views/system/logicflow/index.vue @@ -24,7 +24,7 @@ diff --git a/lms/nladmin-ui/src/views/system/menu/index.vue b/lms/nladmin-ui/src/views/system/menu/index.vue index f88c5c2..791ac9e 100644 --- a/lms/nladmin-ui/src/views/system/menu/index.vue +++ b/lms/nladmin-ui/src/views/system/menu/index.vue @@ -89,7 +89,7 @@ diff --git a/lms/nladmin-ui/src/views/system/param/index.vue b/lms/nladmin-ui/src/views/system/param/index.vue index dddbcab..6e92c65 100644 --- a/lms/nladmin-ui/src/views/system/param/index.vue +++ b/lms/nladmin-ui/src/views/system/param/index.vue @@ -27,7 +27,7 @@ diff --git a/lms/nladmin-ui/src/views/system/role/index.vue b/lms/nladmin-ui/src/views/system/role/index.vue index 7952854..0b802c4 100644 --- a/lms/nladmin-ui/src/views/system/role/index.vue +++ b/lms/nladmin-ui/src/views/system/role/index.vue @@ -58,7 +58,7 @@ diff --git a/lms/nladmin-ui/src/views/system/timing/index.vue b/lms/nladmin-ui/src/views/system/timing/index.vue index ca1474c..010ec4a 100644 --- a/lms/nladmin-ui/src/views/system/timing/index.vue +++ b/lms/nladmin-ui/src/views/system/timing/index.vue @@ -72,7 +72,7 @@ diff --git a/lms/nladmin-ui/src/views/system/user/index.vue b/lms/nladmin-ui/src/views/system/user/index.vue index 7f76c66..0e2a05d 100644 --- a/lms/nladmin-ui/src/views/system/user/index.vue +++ b/lms/nladmin-ui/src/views/system/user/index.vue @@ -129,7 +129,7 @@ diff --git a/lms/nladmin-ui/src/views/tools/codeGen/codeDetail.vue b/lms/nladmin-ui/src/views/tools/codeGen/codeDetail.vue index ea3a345..aec6166 100644 --- a/lms/nladmin-ui/src/views/tools/codeGen/codeDetail.vue +++ b/lms/nladmin-ui/src/views/tools/codeGen/codeDetail.vue @@ -75,7 +75,7 @@ diff --git a/lms/nladmin-ui/src/views/tools/codeGen/index.vue b/lms/nladmin-ui/src/views/tools/codeGen/index.vue index 6742313..3cb875b 100644 --- a/lms/nladmin-ui/src/views/tools/codeGen/index.vue +++ b/lms/nladmin-ui/src/views/tools/codeGen/index.vue @@ -11,7 +11,7 @@ diff --git a/lms/nladmin-ui/src/views/tools/storage/index.vue b/lms/nladmin-ui/src/views/tools/storage/index.vue index 4f82202..d99b67c 100644 --- a/lms/nladmin-ui/src/views/tools/storage/index.vue +++ b/lms/nladmin-ui/src/views/tools/storage/index.vue @@ -46,7 +46,7 @@ diff --git a/lms/nladmin-ui/src/views/wms/basedata/class/index.vue b/lms/nladmin-ui/src/views/wms/basedata/class/index.vue index 1fe5a33..fcc5820 100644 --- a/lms/nladmin-ui/src/views/wms/basedata/class/index.vue +++ b/lms/nladmin-ui/src/views/wms/basedata/class/index.vue @@ -81,7 +81,7 @@ diff --git a/lms/nladmin-ui/src/views/wms/basedata/customer/index.vue b/lms/nladmin-ui/src/views/wms/basedata/customer/index.vue index 74d9741..f2bf67a 100644 --- a/lms/nladmin-ui/src/views/wms/basedata/customer/index.vue +++ b/lms/nladmin-ui/src/views/wms/basedata/customer/index.vue @@ -110,7 +110,7 @@ diff --git a/lms/nladmin-ui/src/views/wms/basedata/material/index.vue b/lms/nladmin-ui/src/views/wms/basedata/material/index.vue index 3908729..2c02be4 100644 --- a/lms/nladmin-ui/src/views/wms/basedata/material/index.vue +++ b/lms/nladmin-ui/src/views/wms/basedata/material/index.vue @@ -2,39 +2,26 @@
    - - - - - 物料类别: - - - - - - - - 模糊查询: - - - +
    + + + + - - + +
    - + - + - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -140,32 +122,21 @@ style="width: 100%;" @selection-change="crud.selectionChangeHandler" > - - - - - - - - - - - - + + + + + + + + + + @@ -190,7 +161,7 @@ import rrOperation from '@crud/RR.operation' import crudOperation from '@crud/CRUD.operation' import udOperation from '@crud/UD.operation' import pagination from '@crud/Pagination' -import Treeselect, { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' +import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' import '@riophae/vue-treeselect/dist/vue-treeselect.css' import crudClassstandard from '@/api/wms/basedata/classstandard' import crudMdPbMeasureunit from '@/api/wms/basedata/mdPbMeasureunit' @@ -200,40 +171,26 @@ const defaultForm = { ass_unit_id: null, material_code: null, material_name: null, - material_spec: null, - material_model: null, - english_name: null, - base_unit_id: null, - approve_fileno: null, - print_no: null, - material_type_id: null, - len_unit_id: null, - length: null, - width: null, - height: null, - weight_unit_id: null, - gross_weight: null, - net_weight: null, - cubage_unit_id: null, - cubage: null, + standing_time: null, + threshold_time: null, + a: null, + b: null, + h: null, + w: null, + product_code: null, create_id: null, create_name: null, create_time: null, update_optid: null, update_optname: null, update_time: null, - is_used_time: null, - is_used: null, - is_delete: null, - ext_id: null, - material_height_type: null, - product_series: null + weight: null } export default { name: 'Materialbase', // 数据字典 dicts: ['is_used'], - components: { pagination, crudOperation, rrOperation, udOperation, Treeselect }, + components: { pagination, crudOperation, rrOperation, udOperation }, mixins: [presenter(), header(), form(defaultForm), crud()], cruds() { return CRUD({ @@ -255,73 +212,19 @@ export default { productSeries: [], permission: {}, rules: { - material_id: [ - { required: true, message: '不能为空', trigger: 'blur' } - ], material_code: [ { required: true, message: '物料编码不能为空', trigger: 'blur' } - ], - material_name: [ - { required: true, message: '物料名称不能为空', trigger: 'blur' } - ], - material_type_id: [ - { required: true, message: '物料分类不能为空', trigger: 'blur' } - ], - create_id: [ - { required: true, message: '不能为空', trigger: 'blur' } - ], - create_time: [ - { required: true, message: '不能为空', trigger: 'blur' } - ], - is_used: [ - { required: true, message: '是否启用不能为空', trigger: 'blur' } - ], - material_height_type: [ - { required: true, message: '不能为空', trigger: 'blur' } ] } } }, created() { - this.initClass1() - this.initClass2() - this.initClass3() }, methods: { // 钩子:在获取表格数据之前执行,false 则代表不获取数据 [CRUD.HOOK.beforeRefresh]() { return true }, - initClass1() { - const param = { - parent_class_code: '09' - } - crudClassstandard.getClassType(param).then(res => { - const data = res.content - this.buildTree(data) - this.classes1 = data - }) - }, - initClass2() { - const param = { - parent_class_code: '09' - } - crudClassstandard.getClassType(param).then(res => { - const data = res.content - this.buildTree(data) - this.classes2 = data - }) - }, - initClass3() { - const param = { - parent_class_code: '07' - } - crudClassstandard.getClassType(param).then(res => { - const data = res.content - this.buildTree(data) - this.classes3 = data - }) - }, [CRUD.HOOK.beforeToCU](crud, form) { crudMdPbMeasureunit.getUnit().then(res => { this.measure_unit = res.content @@ -344,10 +247,10 @@ export default { crudClassstandard.getClassSuperior(id).then(res => { const data = res.content that.buildTree(data) - if (type == '02') { + if (type === '02') { that.classes2 = data } - if (type == '03') { + if (type === '03') { that.classes3 = data } }) diff --git a/lms/nladmin-ui/src/views/wms/basedata/measure/index.vue b/lms/nladmin-ui/src/views/wms/basedata/measure/index.vue index 9f0838e..6622c32 100644 --- a/lms/nladmin-ui/src/views/wms/basedata/measure/index.vue +++ b/lms/nladmin-ui/src/views/wms/basedata/measure/index.vue @@ -36,7 +36,7 @@ diff --git a/lms/nladmin-ui/src/views/wms/basedata/supp/index.vue b/lms/nladmin-ui/src/views/wms/basedata/supp/index.vue index 487f0bd..a8760bf 100644 --- a/lms/nladmin-ui/src/views/wms/basedata/supp/index.vue +++ b/lms/nladmin-ui/src/views/wms/basedata/supp/index.vue @@ -120,7 +120,7 @@ diff --git a/lms/nladmin-ui/src/views/wms/basedata/vehicle/index.vue b/lms/nladmin-ui/src/views/wms/basedata/vehicle/index.vue index 51d0881..e197c92 100644 --- a/lms/nladmin-ui/src/views/wms/basedata/vehicle/index.vue +++ b/lms/nladmin-ui/src/views/wms/basedata/vehicle/index.vue @@ -11,6 +11,18 @@ label-width="80px" label-suffix=":" > + + + - - - + + style="width: 180px;" + @change="hand" + > + +
    - - - 打印 - - + - - - - - - - - + + + + - - - - - + + + + + + + + + + + + + + + + - - - - + + + + - - + + + + + - +
    @@ -126,32 +181,42 @@ import udOperation from '@crud/UD.operation' import pagination from '@crud/Pagination' import { getLodop } from '@/assets/js/lodop/LodopFuncs' -const defaultForm = { num: 1, vehicle_id: null, vehicle_code: null, vehicle_name: null, one_code: null, two_code: null, rfid_code: null, vehicle_type: null, vehicle_width: null, vehicle_long: null, vehicle_height: null, overstruct_type: null, occupystruct_qty: null, ext_id: null, create_id: null, create_name: null, create_time: null, update_optid: null, update_optname: null, update_time: null } +const defaultForm = { + vehicle_id: null, + vehicle_code: null, + vehicle_type: null, + vehicle_status: '0', + create_id: null, + create_name: null, + create_time: null, + update_optid: null, + update_optname: null, + update_time: null +} export default { name: 'Vehicle', - dicts:['vehicle_type'], + dicts: ['vehicle_type', 'vehicle_status'], components: { pagination, crudOperation, rrOperation, udOperation }, mixins: [presenter(), header(), form(defaultForm), crud()], cruds() { return CRUD({ - title: '载具维护', + title: '载具', url: 'api/vehicle', idField: 'vehicle_id', - sort: 'vehicle_id,desc', + sort: 'create_time,desc', crudMethod: { ...crudVehicle }, optShow: { add: true, edit: false, - del: false, + del: true, download: false, - reset: true + reset: false } }) }, data() { return { - permission: { - }, + permission: {}, rules: { vehicle_code: [ { required: true, message: '载具编码不能为空', trigger: 'blur' } @@ -159,13 +224,11 @@ export default { vehicle_type: [ { required: true, message: '载具类型不能为空', trigger: 'blur' } ], - overstruct_type: [ - { required: true, message: '载具超仓位类型不能为空', trigger: 'blur' } - ], - occupystruct_qty: [ - { required: true, message: '占仓位数不能为空', trigger: 'blur' } + vehicle_status: [ + { required: true, message: '载具状态不能为空', trigger: 'blur' } ] - }} + } + } }, methods: { // 钩子:在获取表格数据之前执行,false 则代表不获取数据 @@ -175,16 +238,6 @@ export default { hand() { this.crud.toQuery() }, - getVehicle(code) { - if (!code) { - this.crud.notify('请选择载具类型', CRUD.NOTIFICATION_TYPE.INFO) - this.form.vehicle_code = '' - return false - } - crudVehicle.getVehicle(code).then(res => { - this.form.vehicle_code = res.value - }) - }, addAndprint() { const data = this.form if (!this.form.vehicle_type) { @@ -210,26 +263,6 @@ export default { this.crud.toQuery() this.crud.notify('操作成功', CRUD.NOTIFICATION_TYPE.SUCCESS) }) - }, - print() { - const _selectData = this.$refs.table.selection - if (!_selectData || _selectData.length < 1) { - this.crud.notify('请选择一条记录', CRUD.NOTIFICATION_TYPE.INFO) - return - } - for (let i = 0; i < _selectData.length; i++) { - const code = _selectData[i].vehicle_code - const LODOP = getLodop() - LODOP.SET_SHOW_MODE('HIDE_DISBUTTIN_SETUP', 1)// 隐藏那些无效按钮 - // 打印纸张大小设置https://www.it610.com/article/2094844.html - LODOP.SET_PRINT_PAGESIZE(1, '50mm', '30mm', '') - // LODOP.ADD_PRINT_RECT('0mm', '0mm', '48mm', '28mm', 0, 1) - LODOP.ADD_PRINT_BARCODE('4.3mm', '8.2mm', '40mm', '20mm', '128Auto', code) - // LODOP.PREVIEW()// 预览 - LODOP.PRINT()// 打印 - this.crud.notify('打印成功', CRUD.NOTIFICATION_TYPE.SUCCESS) - this.crud.toQuery() - } } } } diff --git a/lms/nladmin-ui/src/views/wms/pdm/device/index.vue b/lms/nladmin-ui/src/views/wms/pdm/device/index.vue new file mode 100644 index 0000000..3562501 --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/pdm/device/index.vue @@ -0,0 +1,199 @@ + + + + + diff --git a/lms/nladmin-ui/src/views/wms/pdm/workerorder/index.vue b/lms/nladmin-ui/src/views/wms/pdm/workerorder/index.vue index 7165edc..692e83e 100644 --- a/lms/nladmin-ui/src/views/wms/pdm/workerorder/index.vue +++ b/lms/nladmin-ui/src/views/wms/pdm/workerorder/index.vue @@ -8,7 +8,7 @@ class="demo-form-inline" label-position="right" label-width="90px" - label-suffix=":" + label-suffix=":" > @@ -26,7 +26,7 @@ v-model="query.material" clearable size="small" - placeholder="物料编码、名称或规格" + placeholder="物料编码名称" style="width: 200px;" class="filter-item" /> @@ -53,23 +53,6 @@ /> - - - - - 开工 @@ -115,145 +98,113 @@ :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" - width="1200px" + width="600px" > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{ item.label }} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -278,34 +229,32 @@ {{ dict.label.pdm_workorder_status[scope.row.order_status] }} - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + @@ -369,21 +318,26 @@ const defaultForm = { syscompanyid: null, is_delete: null, material_name: null, - point_code: null, - point_name: null, + device_id: null, + device_code: null, is_canupdate_update: '1', material_spec: null, sale_id: null, is_new: '1', is_package: '1', warn_time: '0', - standing_time: '0' + standing_time: '0', + is_urgent: '0', + is_pri: '0', + ext_code: null, + qualified_qty: '0', + unqualified_qty: '0' } export default { name: 'Produceshiftorder', components: { pagination, crudOperation, rrOperation, udOperation, MaterDtl, ViewDialog, DeviceDialog }, mixins: [presenter(), header(), form(defaultForm), crud()], - dicts: ['pdm_workorder_status', 'priority_direction', 'is_used', 'is_or_not', 'material_type', 'vehicle_type', 'workorder_procedure'], + dicts: ['pdm_workorder_status', 'priority_direction', 'is_used', 'is_or_not', 'material_type', 'vehicle_type', 'workorder_procedure', 'true_or_false', 'wood_vehicle_type'], cruds() { return CRUD({ title: '工单', url: 'api/workorder', idField: 'workorder_id', sort: 'workorder_id,desc', @@ -442,6 +396,18 @@ export default { ], is_canupdate_update: [ { required: true, message: '不能为空', trigger: 'blur' } + ], + vehicle_type: [ + { required: true, message: '木托盘类型不能为空', trigger: 'blur' } + ], + device_code: [ + { required: true, message: '生产设备不能为空', trigger: 'blur' } + ], + is_urgent: [ + { required: true, message: '是否加急不能为空', trigger: 'blur' } + ], + is_pri: [ + { required: true, message: '是否优先包装不能为空', trigger: 'blur' } ] } } @@ -488,12 +454,10 @@ export default { setMaterValue(row) { this.form.material_id = row.material_id this.form.material_code = row.material_code - this.form.material_name = row.material_name - this.form.material_spec = row.material_spec }, tableChanged(row) { - this.form.point_code = row.point_code - this.form.point_name = row.point_name + this.form.device_code = row.device_code + this.form.device_id = row.device_id }, // 下发 submits(row) { diff --git a/lms/nladmin-ui/src/views/wms/pub/DeviceDialog.vue b/lms/nladmin-ui/src/views/wms/pub/DeviceDialog.vue index 645e334..b333e84 100644 --- a/lms/nladmin-ui/src/views/wms/pub/DeviceDialog.vue +++ b/lms/nladmin-ui/src/views/wms/pub/DeviceDialog.vue @@ -8,16 +8,24 @@ @close="close" @open="open" > - - - - - - - - - - + + + + + + - + - - - + + + + + + - + 取 消 确 定 @@ -58,20 +70,16 @@ import CRUD, { header, presenter } from '@crud/crud' import rrOperation from '@crud/RR.operation' import pagination from '@crud/Pagination' -import crudPoint from '@/api/wms/sch/point' +import crudDevice from '@/api/wms/pdm/device' +import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' +import crudClassstandard from '@/api/wms/basedata/classstandard' export default { name: 'EndPointDialog', + dicts: ['pdm_device_type'], components: { rrOperation, pagination }, cruds() { - return CRUD({ - title: '点位', url: 'api/point', crudMethod: { ...crudPoint }, - query: { - is_have_workder: '1' - }, - - optShow: {} - }) + return CRUD({ title: '设备', url: 'api/device', crudMethod: { ...crudDevice }, optShow: {}}) }, mixins: [presenter(), header()], props: { @@ -90,34 +98,26 @@ export default { }, data() { return { - formInline: { - search: '' - }, - tableRadio: '', - tableData: [], dialogVisible: false, - material: {} + classes: [], + tableRadio: null, + class_idStr: null, + checkrow: null, + rows: [] } }, watch: { dialogShow: { - handler(newValue, oldValue) { + handler(newValue) { this.dialogVisible = newValue } } }, methods: { - handleClose(done) { - this.$confirm('确认关闭?') - .then(_ => { - done() - }) - .catch(_ => { - }) + clickChange(item) { + this.tableRadio = item }, open() { - debugger - this.query.region_id = this.openParam this.crud.toQuery() }, close() { @@ -151,11 +151,23 @@ export default { onSelectAll() { this.$refs.table.clearSelection() }, - clickChange(item) { - this.tableRadio = item - }, hand(value) { this.crud.toQuery() + }, + loadClass({ action, parentNode, callback }) { + if (action === LOAD_CHILDREN_OPTIONS) { + crudClassstandard.getClass({ pid: parentNode.id }).then(res => { + parentNode.children = res.content.map(function(obj) { + if (obj.hasChildren) { + obj.children = null + } + return obj + }) + setTimeout(() => { + callback() + }, 100) + }) + } } } } @@ -173,7 +185,7 @@ export default { margin-left: auto; } -.el-table_body tr.current-row > td { +.el-table_body tr.current-row>td { background-color: #e9e500; } diff --git a/lms/nladmin-ui/src/views/wms/pub/MaterDialog.vue b/lms/nladmin-ui/src/views/wms/pub/MaterDialog.vue index 8427c24..97e87c6 100644 --- a/lms/nladmin-ui/src/views/wms/pub/MaterDialog.vue +++ b/lms/nladmin-ui/src/views/wms/pub/MaterDialog.vue @@ -15,21 +15,12 @@ label-width="80px" label-suffix=":" > - - - - + @@ -55,14 +46,15 @@ - - - - - - - - + + + + + + + + + @@ -79,13 +71,13 @@ import crudMaterialbase from '@/api/wms/basedata/materialbase' import CRUD, { header, presenter } from '@crud/crud' import rrOperation from '@crud/RR.operation' import pagination from '@crud/Pagination' -import Treeselect, { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' +import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect' import '@riophae/vue-treeselect/dist/vue-treeselect.css' import crudClassstandard from '@/api/wms/basedata/classstandard' export default { name: 'MaterDtl', - components: { rrOperation, pagination, Treeselect }, + components: { rrOperation, pagination }, cruds() { return CRUD({ title: '物料', url: 'api/Materialbase', crudMethod: { ...crudMaterialbase }, optShow: {}}) }, @@ -126,9 +118,6 @@ export default { clickChange(item) { this.tableRadio = item }, - seriesFormat(row) { - return this.dict.label.product_series[row.product_series] - }, open() { const param = { 'materOpt_code': this.materOptCode diff --git a/lms/nladmin-ui/src/views/wms/sch/point/index.vue b/lms/nladmin-ui/src/views/wms/sch/point/index.vue index 56a35e0..33d283e 100644 --- a/lms/nladmin-ui/src/views/wms/sch/point/index.vue +++ b/lms/nladmin-ui/src/views/wms/sch/point/index.vue @@ -10,7 +10,7 @@ label-width="90px" label-suffix=":" > - + - + @@ -47,6 +49,7 @@ > @@ -63,69 +66,30 @@ @change="hand" > - - - - - - - - - - - - - + > + + @@ -199,111 +163,124 @@ :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" - width="520px" + width="600px" > - - - + + + + + + - - - - - - - - - - - - - - - - - + - - + + + + - - + + + + - - - - - + + + + - - + + - - - - - + + + + - + @@ -317,34 +294,32 @@ @selection-change="crud.selectionChangeHandler" > - + + + + + + + + + + + - - - - - - - + - - - - - - - @@ -381,20 +355,19 @@ import udOperation from '@crud/UD.operation' import pagination from '@crud/Pagination' import ViewDialog from '@/views/wms/sch/point/ViewDialog' import MaterialDialog from '@/views/wms/sch/point/MaterialDialog' -import WorkOrderDialog from '@/views/wms/sch/point/WorkOrderDialog' const defaultForm = { point_id: null, point_code: null, point_name: null, point_type: null, - point_status: null, + point_status: '0', lock_type: '1', vehicle_code: null, source_id: null, remark: null, is_light: '0', - is_used: null, + is_used: '1', is_delete: null, create_id: null, create_name: null, @@ -405,8 +378,8 @@ const defaultForm = { } export default { name: 'Point', - dicts: ['vehicle_type', 'd_lock_type', 'SCH_TASK_TYPE_DTL', 'vehicle_type'], - components: { WorkOrderDialog, MaterialDialog, pagination, crudOperation, rrOperation, udOperation, ViewDialog }, + dicts: ['vehicle_type', 'lock_type', 'point_status', 'true_or_false'], + components: { MaterialDialog, pagination, crudOperation, rrOperation, udOperation, ViewDialog }, mixins: [presenter(), header(), form(defaultForm), crud()], cruds() { return CRUD({ @@ -415,7 +388,7 @@ export default { idField: 'point_id', optShow: { add: true, - edit: true, + edit: false, del: true, download: false, reset: true @@ -428,7 +401,6 @@ export default { return { syncLoading: false, materialDialog: false, - workOrderDialog: false, choose: '物料', invtypelist: [], pointStatusList: [], @@ -438,6 +410,7 @@ export default { options: [], regionList: [], permission: {}, + deviceList: [], rules: { point_code: [ { required: true, message: '点位编码不能为空', trigger: 'blur' } @@ -445,11 +418,14 @@ export default { point_name: [ { required: true, message: '点位名称不能为空', trigger: 'blur' } ], + point_status: [ + { required: true, message: '点位状态不能为空', trigger: 'blur' } + ], point_type: [ { required: true, message: '点位类型不能为空', trigger: 'blur' } ], region_id: [ - { required: true, message: '区域类型不能为空', trigger: 'blur' } + { required: true, message: '所属区域不能为空', trigger: 'blur' } ], lock_type: [ { required: true, message: '锁定类型不能为空', trigger: 'blur' } @@ -462,6 +438,9 @@ export default { crudPoint.getRegion().then(res => { this.regionList = res }) + crudPoint.getDevice().then(res => { + this.deviceList = res + }) }, methods: { // 钩子:在获取表格数据之前执行,false 则代表不获取数据 @@ -500,7 +479,6 @@ export default { }, getPointStatusAndTypeList(id, flag) { if (id) { - this.getPointStatusList(id, flag) this.getPointTypeList(id, flag) } if (flag === 1) { @@ -549,13 +527,6 @@ export default { this.$refs.viewDialog.setParentData(row) } }, - getMaterial() { - if (this.choose == '物料') { - this.materialDialog = true - } else { - this.workOrderDialog = true - } - }, tableChanged(row) { this.form.material_name = row.material_name this.form.material_id = row.material_id diff --git a/lms/nladmin-ui/src/views/wms/sch/region/index.vue b/lms/nladmin-ui/src/views/wms/sch/region/index.vue index f98d1a2..de3e284 100644 --- a/lms/nladmin-ui/src/views/wms/sch/region/index.vue +++ b/lms/nladmin-ui/src/views/wms/sch/region/index.vue @@ -4,16 +4,26 @@
    - - - + + + + + +
    @@ -23,27 +33,24 @@ :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" - width="550px" + width="500px" > - + - + - + - - - - + - + @@ -56,14 +63,12 @@ style="width: 100%;" @selection-change="crud.selectionChangeHandler" > - - + - - - + + + + diff --git a/lms/nladmin-ui/src/views/wms/st/cppoint/cppInventory.vue b/lms/nladmin-ui/src/views/wms/st/cppoint/cppInventory.vue new file mode 100644 index 0000000..0a84d50 --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/st/cppoint/cppInventory.vue @@ -0,0 +1,401 @@ + + + + + diff --git a/lms/nladmin-ui/src/views/wms/st/cppoint/cppOutRegion.vue b/lms/nladmin-ui/src/views/wms/st/cppoint/cppOutRegion.vue new file mode 100644 index 0000000..6f42bce --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/st/cppoint/cppOutRegion.vue @@ -0,0 +1,206 @@ + + + + + diff --git a/lms/nladmin-ui/src/views/wms/st/cppoint/index.vue b/lms/nladmin-ui/src/views/wms/st/cppoint/index.vue new file mode 100644 index 0000000..9c486f5 --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/st/cppoint/index.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/lms/nladmin-ui/src/views/wms/st/regionio.js b/lms/nladmin-ui/src/views/wms/st/regionio.js new file mode 100644 index 0000000..f9997c2 --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/st/regionio.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/regionio', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/regionio/', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/regionio', + method: 'put', + data + }) +} + +export function makeTask(data) { + return request({ + url: 'api/regionio/makeTask', + method: 'post', + data: data + }) +} + +export default { add, edit, del, makeTask } diff --git a/lms/nladmin-ui/src/views/wms/st/structivt.js b/lms/nladmin-ui/src/views/wms/st/structivt.js new file mode 100644 index 0000000..411cd72 --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/st/structivt.js @@ -0,0 +1,43 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/structivt', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/structivt/', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/structivt', + method: 'put', + data + }) +} + +export function outInventory(data) { + return request({ + url: 'api/structivt/outInventory', + method: 'post', + data: data + }) +} + +export function batchEdit(data) { + return request({ + url: 'api/structivt/batchEdit', + method: 'post', + data: data + }) +} + +export default { add, edit, del, outInventory, batchEdit } diff --git a/lms/nladmin-ui/src/views/wms/st/ysa/index.vue b/lms/nladmin-ui/src/views/wms/st/ysa/index.vue new file mode 100644 index 0000000..a0cbceb --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/st/ysa/index.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/lms/nladmin-ui/src/views/wms/st/ysa/inventory.vue b/lms/nladmin-ui/src/views/wms/st/ysa/inventory.vue new file mode 100644 index 0000000..21b176e --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/st/ysa/inventory.vue @@ -0,0 +1,412 @@ + + + + + diff --git a/lms/nladmin-ui/src/views/wms/st/ysa/ysqInRegion.vue b/lms/nladmin-ui/src/views/wms/st/ysa/ysqInRegion.vue new file mode 100644 index 0000000..1ce028b --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/st/ysa/ysqInRegion.vue @@ -0,0 +1,188 @@ + + + + + diff --git a/lms/nladmin-ui/src/views/wms/st/ysa/ysqOutRegion.vue b/lms/nladmin-ui/src/views/wms/st/ysa/ysqOutRegion.vue new file mode 100644 index 0000000..c71dbdd --- /dev/null +++ b/lms/nladmin-ui/src/views/wms/st/ysa/ysqOutRegion.vue @@ -0,0 +1,190 @@ + + + + +

    0x(SQNx`OI_k@TY5P)F+? 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 Xa~3IZP8;J>(I1o}aF6_d-tYec$squ2 diff --git a/lms/nladmin-system/src/main/resources/banner.txt b/lms/nladmin-system/src/main/resources/banner.txt index 8be4ead..d0dea47 100644 --- a/lms/nladmin-system/src/main/resources/banner.txt +++ b/lms/nladmin-system/src/main/resources/banner.txt @@ -1,8 +1,8 @@ - _ _ ___________ _ _____ _ ___________ _____ -| \ | | _ | ___ \ | | ___| | | ___| ___|_ _| -| \| | | | | |_/ / | | |__ | | | |__ | |_ | | -| . ` | | | | ___ \ | | __|| | | __|| _| | | -| |\ \ \_/ / |_/ / |____| |___| |____| |___| | | | -\_| \_/\___/\____/\_____/\____/\_____/\____/\_| \_/ + _ _ ____ ____ _ ______ _ _____ ______ _______ + | \ | |/ __ \| _ \| | | ____| | |_ _| ____|__ __| + | \| | | | | |_) | | | |__ | | | | | |__ | | + | . ` | | | | _ <| | | __| | | | | | __| | | + | |\ | |__| | |_) | |____| |____| |____ _| |_| | | | + |_| \_|\____/|____/|______|______|______|_____|_| |_| :: Spring Boot :: (v2.1.0.RELEASE) \ No newline at end of file diff --git a/lms/nladmin-system/src/main/resources/config/application-dev.yml b/lms/nladmin-system/src/main/resources/config/application-dev.yml index c177c95..84e511a 100644 --- a/lms/nladmin-system/src/main/resources/config/application-dev.yml +++ b/lms/nladmin-system/src/main/resources/config/application-dev.yml @@ -6,11 +6,9 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy - url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.81.252}:${DB_PORT:3306}/${DB_NAME:lnsh_lms2}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true -# url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:lnsh_lms2}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true + url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:lnsh_lms3}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useOldAliasMetadataBehavior=true username: ${DB_USER:root} - password: ${DB_PWD:Root.123456} - # password: ${DB_PWD:12356} + password: ${DB_PWD:123456} # 初始连接数 initial-size: 5 # 最小连接数 diff --git a/lms/nladmin-system/src/main/resources/config/application-prod.yml b/lms/nladmin-system/src/main/resources/config/application-prod.yml index 9159158..3a8b115 100644 --- a/lms/nladmin-system/src/main/resources/config/application-prod.yml +++ b/lms/nladmin-system/src/main/resources/config/application-prod.yml @@ -6,17 +6,19 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy - url: jdbc:log4jdbc:mysql://${DB_HOST:47.111.78.178}:${DB_PORT:3306}/${DB_NAME:ndxy3_lms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true + url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.4.220}:${DB_PORT:3306}/${DB_NAME:lms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useOldAliasMetadataBehavior=true username: ${DB_USER:root} - password: ${DB_PWD:P@ssw0rd} + password: ${DB_PWD:123456} # 初始连接数 initial-size: 5 # 最小连接数 min-idle: 15 # 最大连接数 - max-active: 60 + max-active: 30 + # 超时时间(以秒数为单位) + remove-abandoned-timeout: 180 # 获取连接超时时间 - max-wait: 5000 + max-wait: 3000 # 连接有效性检测时间 time-between-eviction-runs-millis: 60000 # 连接在池中最小生存的时间 @@ -36,11 +38,8 @@ spring: enabled: true stat-view-servlet: enabled: true - # 控制台管理用户名和密码 url-pattern: /druid/* reset-enable: false - login-username: admin - login-password: 123456 filter: stat: enabled: true @@ -51,23 +50,23 @@ spring: wall: config: multi-statement-allow: true - redis: - #数据库索引 - database: ${REDIS_DB:15} - host: ${REDIS_HOST:127.0.0.1} - port: ${REDIS_PORT:6379} - #连接超时时间 - timeout: 5000 - redisson: - config: | - threads: 4 - nettyThreads: 4 - singleServerConfig: - connectionMinimumIdleSize: 8 - connectionPoolSize: 8 - address: redis://127.0.0.1:6379 - idleConnectionTimeout: 10000 - timeout: 3000 +redis: + #数据库索引 + database: ${REDIS_DB:15} + host: ${REDIS_HOST:127.0.0.1} + port: ${REDIS_PORT:6379} + # password: ${REDIS_PWD:} + redisson: + config: | + threads: 4 + nettyThreads: 4 + singleServerConfig: + connectionMinimumIdleSize: 8 + connectionPoolSize: 8 + address: redis://127.0.0.1:6379 + idleConnectionTimeout: 10000 + timeout: 3000 + # 登录相关配置 login: # 登录缓存 @@ -86,7 +85,7 @@ login: heigth: 36 # 内容长度 length: 2 - # 字体名称,为空则使用默认字体,如遇到线上乱码,设置其他字体即可 + # 字体名称,为空则使用默认字体 font-name: # 字体大小 font-size: 25 @@ -98,36 +97,29 @@ jwt: token-start-with: Bearer # 必须使用最少88位的Base64对该令牌进行编码 base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI= - # 令牌过期时间 此处单位/毫秒 ,默认2小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html - token-validity-in-seconds: 7200000 + # 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html + token-validity-in-seconds: 14400000 # 在线用户key online-key: online-token- # 验证码 code-key: code-key- - # token 续期检查时间范围(默认30分钟,单位默认毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 + # token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 detect: 1800000 - # 续期时间范围,默认 1小时,这里单位毫秒 + # 续期时间范围,默认1小时,单位毫秒 renew: 3600000 +#是否允许生成代码,生产环境设置为false +generator: + enabled: true + +#是否开启 swagger-ui +swagger: + enabled: true + # IP 本地解析 ip: local-parsing: true -#是否允许生成代码,生产环境设置为false -generator: - enabled: false - -#如果生产环境要开启swagger,需要配置请求地址 -#springfox: -# documentation: -# swagger: -# v2: -# host: # 接口域名或外网ip - -#是否开启 swagger-ui -swagger: - enabled: false - # 文件存储路径 file: mac: @@ -144,7 +136,7 @@ file: avatarMaxSize: 5 logging: file: - path: /app/jar/logs + path: d:\log\wms config: classpath:logback-spring.xml # Sa-Token配置 @@ -168,5 +160,5 @@ sa-token: token-prefix: Bearer loki: - url: http://localhost:3100/loki/api/v1 + url: http://192.168.4.220:3100/loki/api/v1 systemName: lms diff --git a/lms/nladmin-system/src/main/resources/config/application.yml b/lms/nladmin-system/src/main/resources/config/application.yml index 7e3fbea..6f01423 100644 --- a/lms/nladmin-system/src/main/resources/config/application.yml +++ b/lms/nladmin-system/src/main/resources/config/application.yml @@ -19,6 +19,7 @@ spring: hibernate: dialect: org.hibernate.dialect.MySQL5InnoDBDialect enable_lazy_load_no_trans: true + show_sql: true task: pool: # 核心线程池大小 diff --git a/lms/nladmin-system/src/main/resources/logback-spring.xml b/lms/nladmin-system/src/main/resources/logback-spring.xml index 2e4c21c..12e497b 100644 --- a/lms/nladmin-system/src/main/resources/logback-spring.xml +++ b/lms/nladmin-system/src/main/resources/logback-spring.xml @@ -12,7 +12,7 @@ https://juejin.cn/post/6844903775631572999 nlAdmin + value="%black(%contextName-) %yellow(%d{yyyy-MM-dd HH:mm:ss.SSS}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %cyan(%msg%n)"/> diff --git a/lms/nladmin-system/src/test/java/org/nl/test/PointTest.java b/lms/nladmin-system/src/test/java/org/nl/test/PointTest.java new file mode 100644 index 0000000..0f70f58 --- /dev/null +++ b/lms/nladmin-system/src/test/java/org/nl/test/PointTest.java @@ -0,0 +1,41 @@ +package org.nl.test; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import com.alibaba.fastjson.JSONObject; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.nl.modules.wql.core.bean.WQLObject; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * @author zhangjiangwei + * @date 2023/03/02 16:54 + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class PointTest { + + @Test + public void test01() { + WQLObject point_table = WQLObject.getWQLObject("sch_base_point"); + + JSONObject point = new JSONObject(); + String now = DateUtil.now(); + for (int i = 0; i < 52; i++) { + point.put("point_id", IdUtil.getSnowflake().nextId()); + point.put("point_code", "CPHW" + String.format("%02d", i + 1)); + point.put("point_name", "成品货位" + (i + 1)); + point.put("region_id", 1643438902574452736L); + point.put("region_code", "CPHJ"); + point.put("region_name", "成品货架"); + point.put("point_type", "1"); + point.put("device_code", null); + point.put("create_id", 1L); + point.put("create_name", "管理员"); + point.put("create_time", now); + point_table.insert(point); + } + } +} diff --git a/lms/nladmin-system/src/test/java/org/nl/test/TempTest.java b/lms/nladmin-system/src/test/java/org/nl/test/TempTest.java new file mode 100644 index 0000000..09a6287 --- /dev/null +++ b/lms/nladmin-system/src/test/java/org/nl/test/TempTest.java @@ -0,0 +1,30 @@ +package org.nl.test; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.IdUtil; +import com.alibaba.fastjson.JSONObject; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.nl.modules.wql.core.bean.WQLObject; +import org.nl.wms.sch.manage.LockType; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.Set; + +/** + * @author zhangjiangwei + * @date 2023/03/06 17:49 + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class TempTest { + + @Test + public void test01() { + Set materialbase = WQLObject.getWQLObject("md_me_materialbase").query().uniqueResult(0).keySet(); + for (String s : materialbase) { + System.out.println(s); + } + } +} diff --git a/lms/nladmin-ui/src/api/wms/pdm/device.js b/lms/nladmin-ui/src/api/wms/pdm/device.js new file mode 100644 index 0000000..b901755 --- /dev/null +++ b/lms/nladmin-ui/src/api/wms/pdm/device.js @@ -0,0 +1,74 @@ +import request from '@/utils/request' + +export function add(data) { + return request({ + url: 'api/device', + method: 'post', + data + }) +} + +export function del(ids) { + return request({ + url: 'api/device/', + method: 'delete', + data: ids + }) +} + +export function edit(data) { + return request({ + url: 'api/device', + method: 'put', + data + }) +} + +export function getWorkprocedure() { + return request({ + url: 'api/device/getWorkprocedure', + method: 'get' + }) +} + +export function getItemByDevice(data) { + return request({ + url: 'api/device/getItemByDevice', + method: 'post', + data + }) +} + +export function savaDeviceItem(data) { + return request({ + url: 'api/device/savaDeviceItem', + method: 'post', + data + }) +} + +export function getItemByDeviceId(data) { + return request({ + url: 'api/device/getItemByDeviceId', + method: 'post', + data + }) +} + +export function copyAdd(data) { + return request({ + url: 'api/device/copyAdd', + method: 'post', + data + }) +} + +export function changeActive(data) { + return request({ + url: 'api/device/changeActive', + method: 'put', + data + }) +} + +export default { add, edit, del, getWorkprocedure, getItemByDeviceId, copyAdd, changeActive } diff --git a/lms/nladmin-ui/src/api/wms/sch/point.js b/lms/nladmin-ui/src/api/wms/sch/point.js index 7a78111..48523b2 100644 --- a/lms/nladmin-ui/src/api/wms/sch/point.js +++ b/lms/nladmin-ui/src/api/wms/sch/point.js @@ -68,4 +68,11 @@ export function changeLock(data) { }) } -export default { add, edit, del, changeActive, findPoints, getPoint, getRegion, changeUsed, changeLock } +export function getDevice() { + return request({ + url: 'api/point/getDevice', + method: 'post' + }) +} + +export default { add, edit, del, changeActive, findPoints, getPoint, getRegion, changeUsed, changeLock, getDevice } diff --git a/lms/nladmin-ui/src/components/Crud/UD.operation.vue b/lms/nladmin-ui/src/components/Crud/UD.operation.vue index 686247d..4a9d334 100644 --- a/lms/nladmin-ui/src/components/Crud/UD.operation.vue +++ b/lms/nladmin-ui/src/components/Crud/UD.operation.vue @@ -5,7 +5,7 @@