From 5209aca9a9e25d088aa7f74490abe58f45c9b023 Mon Sep 17 00:00:00 2001 From: tuqiang <437016993@qq.com> Date: Mon, 29 Sep 2025 16:39:20 +0800 Subject: [PATCH] =?UTF-8?q?rev:=E7=A7=91=E5=86=B2=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/nl/acs/agv/QueryAGVStatus.java | 23 +- .../nl/acs/agv/rest/KeCongAgvController.java | 15 +- .../nl/acs/agv/server/KeCongAgvService.java | 8 +- .../agv/server/impl/KeCongAgvServiceImpl.java | 360 +++--- .../nl/acs/common/base/CommonFinalParam.java | 22 +- .../nl/acs/device/service/DeviceService.java | 8 + .../service/impl/DeviceServiceImpl.java | 8 + .../agv/ndctwo/AgvNdcTwoDeviceDriver.java | 33 +- .../acs/ext/wms/rest/WmsToAcsController.java | 1 + .../acs/ext/wms/service/AcsToWmsService.java | 4 +- .../wms/service/impl/AcsToWmsServiceImpl.java | 54 +- .../wms/service/impl/WmsToAcsServiceImpl.java | 261 +---- .../service/impl/InstructionServiceImpl.java | 17 +- .../controller/BmVehicleRfidController.java | 220 ++-- .../service/IbmVehicleRfidService.java | 116 +- .../impl/BmVehicleRfidServiceImpl.java | 1020 ++++++++--------- .../service/StorageCellService.java | 2 +- .../org/nl/acs/task/service/dto/TaskDto.java | 7 +- .../task/service/impl/TaskServiceImpl.java | 14 +- .../java/org/nl/acs/utils/StructUtil.java | 132 +-- .../service/quartz/task/AutoCreateInst.java | 60 +- .../resources/log/KeCongAgvServiceImpl.xml | 29 + .../src/main/resources/logback-spring.xml | 8 +- acs2/nladmin-ui/src/assets/images/ftdl.png | Bin 0 -> 39859 bytes acs2/nladmin-ui/src/assets/images/miri.png | Bin 0 -> 997991 bytes .../src/layout/components/Sidebar/Logo.vue | 6 +- .../acs/device/driver/agv/agv_ndc_one.vue | 103 ++ .../acs/device/driver/agv/agv_ndc_two.vue | 114 ++ 28 files changed, 1427 insertions(+), 1218 deletions(-) create mode 100644 acs2/nladmin-system/nlsso-server/src/main/resources/log/KeCongAgvServiceImpl.xml create mode 100644 acs2/nladmin-ui/src/assets/images/ftdl.png create mode 100644 acs2/nladmin-ui/src/assets/images/miri.png diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/QueryAGVStatus.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/QueryAGVStatus.java index ff43f3f..d1e3e43 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/QueryAGVStatus.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/QueryAGVStatus.java @@ -65,8 +65,8 @@ public class QueryAGVStatus { String body = result.body(); JSONObject json = JSONObject.parseObject(body); JSONObject taskStatus = json.getJSONObject("TaskStatus"); - String taskNo = taskStatus.getString("TaskNo"); - if ("true".equals(json.getString("Result")) && taskNo.equals(instruction.getInstruction_code())) { + String instructionCode = taskStatus.getString("TaskNo"); + if ("true".equals(json.getString("Result")) && instructionCode.equals(instruction.getInstruction_code())) { // 已创建=CREATED, // 待分配=TOBEDISPATCHED, // 正在执行=RUNNING, @@ -78,26 +78,16 @@ public class QueryAGVStatus { //执行中 String state = json.getString("Status"); String carNo = json.getString("VehicleNo"); - String instructionCode = json.getString("id"); if ("running".equals(state)) { - if ("1".equals(instruction.getInstruction_status())) { + TaskDto task = taskService.findById(instruction.getTask_id()); + if ("0".equals(instruction.getInstruction_status())&&"1".equals(task.getTask_status())) { instruction.setCarno(carNo); - TaskDto task = new TaskDto(); + instruction.setInstruction_status("1"); + instructionService.update(instruction); instructionService.update(instruction); task.setCarno(carNo); task.setTask_id(instruction.getTask_id()); - instructionService.update(instruction); taskService.update(task); -// if (StrUtil.isNotEmpty(instructionCode)) { -// Device carCode = deviceAppService.findDeviceByCode(instructionCode); -// XgAgvCarDeviceDriver xgAgvCarDeviceDriver; -// if (null != carCode) { -// if (carCode.getDeviceDriver() instanceof XgAgvCarDeviceDriver) { -// xgAgvCarDeviceDriver = (XgAgvCarDeviceDriver) carCode.getDeviceDriver(); -// xgAgvCarDeviceDriver.setTaskType(AgvActionTypeEnum.getStatus(instruction.getAgv_action_type())); -// } -// } -// } } } else if ("finish".equals(state)) { @@ -113,6 +103,7 @@ public class QueryAGVStatus { } else if ("paused".equals(state) || "aborted".equals(state) || "Error".equals(state)) { if (!"1".equals(instruction.getInstruction_status())) { instruction.setInstruction_status("1"); + //todo 备注异常信息 instructionService.update(instruction); } } diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/rest/KeCongAgvController.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/rest/KeCongAgvController.java index a804e07..cb0ce53 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/rest/KeCongAgvController.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/rest/KeCongAgvController.java @@ -22,16 +22,16 @@ public class KeCongAgvController { @PostMapping("/waitPointRequest") @Log("等待点请求") @SaIgnore - public ResponseEntity waitPointRequest(@RequestBody JSONObject requestParam) { + public ResponseEntity waitPointRequest(@RequestBody JSONObject requestParam) { return new ResponseEntity<>(keCongAgvService.agvWaitPointRequest(requestParam), HttpStatus.OK); } - @PostMapping("/requestResource") + @PostMapping("/applyIn") @Log("请求资源") @SaIgnore - public ResponseEntity requestResource(@RequestBody JSONObject requestParam) { - return new ResponseEntity<>(keCongAgvService.requestResource(requestParam), HttpStatus.OK); + public ResponseEntity applyIn(@RequestBody JSONObject requestParam) { + return new ResponseEntity<>(keCongAgvService.applyIn(requestParam), HttpStatus.OK); } @PostMapping("/releaseResource") @@ -41,4 +41,11 @@ public class KeCongAgvController { return new ResponseEntity<>(keCongAgvService.releaseResource(requestParam), HttpStatus.OK); } + @PostMapping("/requestAction") + @Log("AGV请求取放货") + @SaIgnore + public ResponseEntity requestAction(@RequestBody JSONObject requestParam) { + return new ResponseEntity<>(keCongAgvService.requestAction(requestParam), HttpStatus.OK); + } + } diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/KeCongAgvService.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/KeCongAgvService.java index 818b2c9..c53e80a 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/KeCongAgvService.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/KeCongAgvService.java @@ -7,6 +7,8 @@ import org.nl.acs.instruction.domain.Instruction; public interface KeCongAgvService { + public HttpResponse deleteTask(String instruction_code) throws Exception; + /** * 下发运单序列 * @@ -31,14 +33,16 @@ public interface KeCongAgvService { // */ // public HttpResponse queryKZAgvStatus(String vehicleCode); - AgvResponse agvWaitPointRequest(JSONObject requestParam); + JSONObject agvWaitPointRequest(JSONObject requestParam); // public AgvResponse updateKZAgvInst(JSONObject requestParam); - AgvResponse requestResource(JSONObject requestParam); + JSONObject applyIn(JSONObject requestParam); AgvResponse releaseResource(JSONObject requestParam); + JSONObject requestAction(JSONObject requestParam); + // HttpResponse getRobotInfo(String robotCode); /** diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/impl/KeCongAgvServiceImpl.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/impl/KeCongAgvServiceImpl.java index d5fbb81..5a7a3cb 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/impl/KeCongAgvServiceImpl.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/agv/server/impl/KeCongAgvServiceImpl.java @@ -4,8 +4,10 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.nl.acs.AcsConfig; @@ -13,15 +15,28 @@ import org.nl.acs.agv.server.KeCongAgvService; import org.nl.acs.agv.server.MagicAgvService; import org.nl.acs.agv.server.dao.AgvResponse; import org.nl.acs.common.base.CommonFinalParam; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device.service.impl.DeviceServiceImpl; +import org.nl.acs.ext.wms.service.AcsToWmsService; import org.nl.acs.instruction.domain.Instruction; import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.storage_cell.domain.StorageCell; +import org.nl.acs.storage_cell.service.mapper.StorageCellMapper; +import org.nl.acs.task.enums.ActionTypeEnum; +import org.nl.acs.task.enums.AgvActionTypeEnum; +import org.nl.acs.task.service.TaskService; +import org.nl.acs.task.service.dto.TaskDto; import org.nl.common.exception.BadRequestException; +import org.nl.config.SpringContextHolder; import org.nl.config.lucene.service.LuceneExecuteLogService; import org.nl.config.lucene.service.dto.LuceneLogDto; import org.nl.system.service.param.ISysParamService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; +import java.util.List; + @Slf4j @Service @RequiredArgsConstructor @@ -32,6 +47,52 @@ public class KeCongAgvServiceImpl implements KeCongAgvService { @Autowired private InstructionService instructionService; private final ISysParamService paramService; + @Autowired + private AcsToWmsService acsToWmsService; + @Autowired + private TaskService taskserver; + @Autowired + private StorageCellMapper storageCellMapper; + + @Override + public HttpResponse deleteTask(String instCode) throws Exception { + LuceneLogDto logDto = LuceneLogDto.builder() + .device_code("下发科聪任务") + .content(instCode) + .build(); + logDto.setLog_level(4); + luceneExecuteLogService.deviceExecuteLog(logDto); + log.info("删除科聪任务序列参数:{}", instCode); + if (StrUtil.equals(paramService.findByCode(AcsConfig.FORKAGV). + + getValue(), CommonFinalParam.ONE)) { + String agvurl = paramService.findByCode(AcsConfig.AGVURL).getValue(); + String agvport = paramService.findByCode(AcsConfig.AGVPORT).getValue(); + + agvurl = agvurl + ":" + agvport + "/api/fms/abortTask"; + + log.info(agvurl); + JSONObject ja = new JSONObject(); + ja.put("TaskNo", instCode); + HttpResponse result = HttpRequest.post(agvurl) + //表单内容 + .body(String.valueOf(ja)) + //超时,毫秒 + .timeout(20000) + .execute(); + LuceneLogDto logDto1 = LuceneLogDto.builder() + .device_code("删除科聪任务") + .content("指令号:" + instCode + ",删除科聪任务序列反馈参数:" + ja) + .build(); + logDto.setLog_level(4); + luceneExecuteLogService.deviceExecuteLog(logDto1); + log.info("指令号{},删除agv订单序列反馈:{}", instCode, result.body()); + + return result; + } else { + return null; + } + } @Override public HttpResponse addTask(Instruction inst) throws Exception { @@ -39,50 +100,24 @@ public class KeCongAgvServiceImpl implements KeCongAgvService { JSONArray arr = new JSONArray(); jo.put("TaskType", inst.getInstruction_type()); JSONObject json1 = new JSONObject(); - json1.put("Key", "TaskId"); + json1.put("Key", "TaskNo"); json1.put("Value", inst.getInstruction_code()); arr.add(json1); - JSONObject json2 = new JSONObject(); - json2.put("Key", "VehicleNo"); - json2.put("Value", "3"); - arr.add(json2); +// JSONObject json2 = new JSONObject(); +// json2.put("Key", "VehicleNo"); +// json2.put("Value", "3"); +// arr.add(json2); + DeviceService deviceService = SpringContextHolder.getBean(DeviceServiceImpl.class); + int startAddress = deviceService.queryAddressBydeviceCode(inst.getStart_point_code()); + int nextAddress = deviceService.queryAddressBydeviceCode(inst.getNext_point_code()); JSONObject json3 = new JSONObject(); - json3.put("Key", "point1"); - json3.put("Value", inst.getStart_device_code()); + json3.put("Key", "Point1"); + json3.put("Value", String.valueOf(startAddress)); arr.add(json3); JSONObject json4 = new JSONObject(); - json4.put("Key", "point2"); - json4.put("Value", inst.getNext_device_code()); + json4.put("Key", "Point2"); + json4.put("Value", String.valueOf(nextAddress)); arr.add(json4); - if ("任务1" .equals(inst.getInstruction_type())) { - JSONObject json5 = new JSONObject(); - json5.put("Key", "point3"); - json5.put("Value", inst.getStart_device_code2()); - arr.add(json5); - JSONObject json6 = new JSONObject(); - json6.put("Key", "point4"); - json6.put("Value", inst.getNext_device_code2()); - arr.add(json6); - } else if ("任务11" .equals(inst.getInstruction_type())) { - JSONObject json5 = new JSONObject(); - json5.put("Key", "isget"); - json5.put("Value", "0"); - arr.add(json5); - } else if ("任务12" .equals(inst.getInstruction_type())) { - JSONObject json6 = new JSONObject(); - json6.put("Key", "isput"); - json6.put("Value", "0"); - arr.add(json6); - } else if ("任务13" .equals(inst.getInstruction_type())) { - JSONObject json5 = new JSONObject(); - json5.put("Key", "isget"); - json5.put("Value", "0"); - arr.add(json5); - JSONObject json6 = new JSONObject(); - json6.put("Key", "isput"); - json6.put("Value", "0"); - arr.add(json6); - } jo.put("Params", arr); System.out.println(jo); LuceneLogDto logDto = LuceneLogDto.builder() @@ -173,108 +208,76 @@ public class KeCongAgvServiceImpl implements KeCongAgvService { // } @Override - public AgvResponse agvWaitPointRequest(JSONObject requestParam) { - System.out.println("请求kc参数:" + requestParam); - String taskId = requestParam.getString("TaskId"); + public JSONObject agvWaitPointRequest(JSONObject requestParam) { + log.info("科聪二次分配请求参数:" + requestParam); + String instNo = requestParam.getString("TaskNo"); + String vehicleNo = requestParam.getString("VehicleNo"); String type = requestParam.getString("type"); // 1 取货点等待 2 放货点等待 - Instruction inst = instructionService.findByCodeFromCache(taskId); + Instruction inst = instructionService.findByCodeFromCache(instNo); if (ObjectUtil.isEmpty(inst)) { throw new BadRequestException("请求失败,未找到指令!"); } - JSONObject jo = new JSONObject(); - JSONArray arr = new JSONArray(); - jo.put("TaskNo", taskId); - if ("任务11" .equals(inst.getInstruction_type())) { - //todo :需要跟上位申请新的点位 - JSONObject json1 = new JSONObject(); - json1.put("Name", "point1"); - json1.put("Value", "3"); - arr.add(json1); - } else if ("任务12" .equals(inst.getInstruction_type())) { - //todo :需要跟上位申请新的点位 - JSONObject json1 = new JSONObject(); - json1.put("Name", "point2"); - json1.put("Value", "4"); - arr.add(json1); - } else if ("任务13" .equals(inst.getInstruction_type())) { - if ("1" .equals(type)) { - //todo :需要跟上位申请新的点位 - JSONObject json1 = new JSONObject(); - json1.put("Name", "point1"); - json1.put("Value", "1"); - arr.add(json1); - } else if ("2" .equals(type)) { - //todo :需要跟上位申请新的点位 - JSONObject json1 = new JSONObject(); - json1.put("Name", "point2"); - json1.put("Value", "1"); - arr.add(json1); - } + if ("1".equals(type)) { + String newPointCode = applyNewPoint(vehicleNo, type, inst); + DeviceService deviceService = SpringContextHolder.getBean(DeviceServiceImpl.class); + int startAddress = deviceService.queryAddressBydeviceCode(newPointCode); + JSONObject ja = new JSONObject(); + ja.put("code", "200"); + ja.put("message", "操作成功"); + ja.put("point_code", String.valueOf(startAddress)); + log.info("科聪二次分配返回参数:" + ja); + return ja; } - if ("任务11" .equals(inst.getInstruction_type())) { - JSONObject json2 = new JSONObject(); - json2.put("Name", "isget"); - json2.put("Value", "1"); - arr.add(json2); - } else if ("任务12" .equals(inst.getInstruction_type())) { - JSONObject json2 = new JSONObject(); - json2.put("Name", "isput"); - json2.put("Value", "1"); - arr.add(json2); - } else if ("任务13" .equals(inst.getInstruction_type())) { - if ("1" .equals(type)) { - JSONObject json3 = new JSONObject(); - json3.put("Name", "isget"); - json3.put("Value", "1"); - arr.add(json3); - } else if ("2" .equals(type)) { - JSONObject json2 = new JSONObject(); - json2.put("Name", "isput"); - json2.put("Value", "1"); - arr.add(json2); - } + //如果是放货二次分配 + if ("2".equals(type)) { + String newPointCode = applyNewPoint(vehicleNo, type, inst); + DeviceService deviceService = SpringContextHolder.getBean(DeviceServiceImpl.class); + int nextAddress = deviceService.queryAddressBydeviceCode(newPointCode); + JSONObject ja = new JSONObject(); + ja.put("code", "200"); + ja.put("message", "操作成功"); + ja.put("point_code", String.valueOf(nextAddress)); + LuceneLogDto logDto = LuceneLogDto.builder() + .device_code(vehicleNo) + .content("放货二次分配,参数:" + inst.getTask_code() + "--" + ActionTypeEnum.getStatus(Integer.parseInt(inst.getInstruction_type()))) + .build(); + logDto.setLog_level(4); + return ja; } - jo.put("Params", arr); - String agvurl = paramService.findByCode(AcsConfig.AGVURL).getValue(); - String agvport = paramService.findByCode(AcsConfig.AGVPORT).getValue(); + throw new BadRequestException("请求失败,IN OUT 站点错误!"); + } - //更新任务参数 - agvurl = agvurl + ":" + agvport + "/api/fms/updateTaskParam"; - - log.info(agvurl); - HttpResponse result = HttpRequest.post(agvurl) - //表单内容 - .body(String.valueOf(jo)) - //超时,毫秒 - .timeout(20000) - .execute(); - LuceneLogDto logDto1 = LuceneLogDto.builder() - .device_code("下发科聪任务") - .content("任务号:" + inst.getTask_code() + ",指令号:" + inst.getInstruction_code() + ",下发科聪任务序列反馈参数:" + jo) + private String applyNewPoint(String vehicleNo, String type, Instruction inst) { + JSONObject param = new JSONObject(); + param.put("taskCode", inst.getTask_code()); + param.put("actionType", inst.getInstruction_type()); + param.put("type", type); + LuceneLogDto logDto = LuceneLogDto.builder() + .device_code(vehicleNo) + .content("二次分配请求wms,参数:" + inst.getTask_code() + "--" + ActionTypeEnum.getStatus(Integer.parseInt(inst.getInstruction_type()))) .build(); - logDto1.setLog_level(4); - luceneExecuteLogService.deviceExecuteLog(logDto1); - log.info("任务号:{},指令号{},状态{},下发agv订单序列反馈:{}", inst.getTask_code(), inst.getInstruction_code(), result.getStatus(), result.body()); - JSONObject jsonObject = null; - if (ObjectUtil.isNotEmpty(result)) { - String body = result.body(); - jsonObject = JSONObject.parseObject(body); - if (ObjectUtil.isNotNull(jsonObject) && "true" .equals(jsonObject.getString("Result"))) { - AgvResponse agvResponse = new AgvResponse(); - agvResponse.setResult("true"); - agvResponse.setErrMsg(""); - return agvResponse; - } else { - AgvResponse agvResponse = new AgvResponse(); - agvResponse.setResult("false"); - agvResponse.setErrMsg(""); - return agvResponse; - } + logDto.setLog_level(4); + luceneExecuteLogService.deviceExecuteLog(logDto); + String response = acsToWmsService.secondaryAllocationPoint(param); + JSONObject jo = JSON.parseObject(response); + if (jo.getInteger("status") == 200) { + LuceneLogDto logDto2 = LuceneLogDto.builder() + .device_code(vehicleNo) + .content("二次分配请求lms,参数,接口返回:" + jo) + .build(); + logDto2.setLog_level(4); + //二次分配更新点位 + updataTask(inst, jo.getString("data")); + return jo.getString("data"); } else { - AgvResponse agvResponse = new AgvResponse(); - agvResponse.setResult("false"); - agvResponse.setErrMsg(""); - return agvResponse; + LuceneLogDto logDto2 = LuceneLogDto.builder() + .device_code(vehicleNo) + .content("二次分配请求lms,返回参数:" + jo) + .build(); + logDto2.setLog_level(4); + luceneExecuteLogService.deviceExecuteLog(logDto2); + log.info("科聪二次分配请求lms失败,返回参数:" + jo); + throw new BadRequestException("二次分配请求lms返回失败" + jo); } } @@ -291,12 +294,76 @@ public class KeCongAgvServiceImpl implements KeCongAgvService { // } @Override - public AgvResponse requestResource(JSONObject requestParam) { - //todo: 延迟十秒 - AgvResponse agvResponse = new AgvResponse(); - agvResponse.setResult("true"); - agvResponse.setErrMsg("请求失败"); - return agvResponse; + public JSONObject applyIn(JSONObject requestParam) { + String resourceID = requestParam.getString("point_code"); + String vehicleNo = requestParam.getString("VehicleNo"); + if (resourceID.equals("659") || resourceID.equals("17")) { + log.info("科聪申请离开请求参数:" + requestParam); + LuceneLogDto logDto2 = LuceneLogDto.builder() + .device_code(vehicleNo) + .content("agv申请进入请求离开成功") + .build(); + logDto2.setLog_level(4); + JSONObject json = new JSONObject(); + json.put("code", "200"); + json.put("message", "操作成功"); + return json; + } + log.info("科聪申请进入请求参数:" + requestParam); + List storageCells = storageCellMapper.selectList(new LambdaQueryWrapper().eq(StorageCell::getAddress, resourceID).orderByDesc(StorageCell::getUpdate_time)); + StorageCell storageCell = storageCells.get(0); + String storage_code = storageCell.getStorage_code(); + JSONObject ja = new JSONObject(); + ja.put("point_code", storage_code); + String response = acsToWmsService.applyIn(ja); + + JSONObject jo = JSON.parseObject(response); + if (jo.getInteger("status") == 200) { + log.info("agv申请进入请求lms成功,参数,接口返回:" + jo); + LuceneLogDto logDto2 = LuceneLogDto.builder() + .device_code(vehicleNo) + .content("agv申请进入请求lms成功,参数,接口返回:" + jo) + .build(); + logDto2.setLog_level(4); + JSONObject json = new JSONObject(); + json.put("code", "200"); + json.put("message", "操作成功"); + log.info("科聪申请进入下发返回参数:" + json); + return json; + } else { + log.info("agv申请进入请求lms失败,参数,接口返回:" + jo); + LuceneLogDto logDto2 = LuceneLogDto.builder() + .device_code(vehicleNo) + .content("agv申请进入请求lms失败,返回参数:" + jo) + .build(); + logDto2.setLog_level(4); + luceneExecuteLogService.deviceExecuteLog(logDto2); + JSONObject json = new JSONObject(); + json.put("code", "400"); + json.put("message", "申请进入失败,接口返回:" + jo); + log.info("科聪申请进入下发返回参数:" + json); + return json; + } + } + + private void updataTask(Instruction instructionDto, String newPoint) { + + TaskDto taskUpdate = new TaskDto(); + if (AgvActionTypeEnum.IN_STOCK.getCode().equals(instructionDto.getAgv_action_type())) { + instructionDto.setStart_point_code(newPoint); + taskUpdate.setStart_point_code(newPoint); + instructionDto.setStart_device_code(newPoint); + taskUpdate.setStart_device_code(newPoint); + } + if (AgvActionTypeEnum.OUT_STOCK.getCode().equals(instructionDto.getAgv_action_type())) { + instructionDto.setNext_point_code(newPoint); + taskUpdate.setNext_point_code(newPoint); + instructionDto.setNext_device_code(newPoint); + taskUpdate.setNext_device_code(newPoint); + } + taskUpdate.setTask_id(instructionDto.getTask_id()); + instructionService.update(instructionDto); + taskserver.update(taskUpdate); } @Override @@ -307,6 +374,25 @@ public class KeCongAgvServiceImpl implements KeCongAgvService { return agvResponse; } + @Override + public JSONObject requestAction(JSONObject requestParam) { + String taskNo = requestParam.getString("TaskNo"); + Instruction instruction = instructionService.findByCode(taskNo); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("task_code", instruction.getTask_code()); + LuceneLogDto logDto1 = LuceneLogDto.builder() + .device_code(taskNo) + .content("取货完成反馈:" + jsonObject.toJSONString() + ";指令号:" + taskNo) + .build(); + logDto1.setLog_level(4); + luceneExecuteLogService.deviceExecuteLog(logDto1); + acsToWmsService.actionFinishRequest2(jsonObject); + JSONObject jo = new JSONObject(); + jo.put("code", "200"); + jo.put("message", "请求成功"); + return jo; + } + // @Override // public HttpResponse getRobotInfo(String robotCode) { // if (StrUtil.equals(paramService.findByCode(AcsConfig.FORKAGV).getValue(), "1")) { diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/common/base/CommonFinalParam.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/common/base/CommonFinalParam.java index ba3609b..853b847 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/common/base/CommonFinalParam.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/common/base/CommonFinalParam.java @@ -55,13 +55,21 @@ public class CommonFinalParam { /** * 申请任务type类型 */ - public static final String TYPE_ONE = "1"; - public static final String TYPE_TWO = "2"; - public static final String TYPE_THREE = "3"; - public static final String TYPE_FOUR = "4"; - public static final String TYPE_FIVE = "5"; - public static final String TYPE_SIX = "6"; - public static final String TYPE_SEVEN = "7"; +// public static final String TYPE_ONE = "1"; +// public static final String TYPE_TWO = "2"; +// public static final String TYPE_THREE = "3"; +// public static final String TYPE_FOUR = "4"; +// public static final String TYPE_FIVE = "5"; +// public static final String TYPE_SIX = "6"; +// public static final String TYPE_SEVEN = "7"; + + /** + * 申请任务type类型 + */ + public static final String TYPE_ONE = "ONE"; + public static final String TYPE_TWO = "TWO"; + public static final String TYPE_THREE = "THREE"; + public static final String TYPE_FOUR = "FOUR"; diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device/service/DeviceService.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device/service/DeviceService.java index 7582b73..6c919ed 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device/service/DeviceService.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device/service/DeviceService.java @@ -132,6 +132,14 @@ public interface DeviceService extends CommonService { */ DeviceDto findByCode(String code); + /** + * 根据站点号查询 + * + * @param code code + * @return Device + */ + DeviceDto findByAgvCode(String code); + /** * 创建 * diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device/service/impl/DeviceServiceImpl.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device/service/impl/DeviceServiceImpl.java index 9fc61f9..e7ca314 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device/service/impl/DeviceServiceImpl.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device/service/impl/DeviceServiceImpl.java @@ -273,6 +273,14 @@ public class DeviceServiceImpl extends CommonServiceImpl i return ConvertUtil.convert(device, DeviceDto.class); } + @Override + public DeviceDto findByAgvCode(String code) { + Device device = new LambdaQueryChainWrapper<>(deviceMapper) + .eq(Device::getAddress, code) + .one(); + return ConvertUtil.convert(device, DeviceDto.class); + } + @Override @Transactional(rollbackFor = Exception.class) public void create(DeviceDto dto) { diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device_driver/agv/ndctwo/AgvNdcTwoDeviceDriver.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device_driver/agv/ndctwo/AgvNdcTwoDeviceDriver.java index 494b51b..9c0a094 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device_driver/agv/ndctwo/AgvNdcTwoDeviceDriver.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/device_driver/agv/ndctwo/AgvNdcTwoDeviceDriver.java @@ -16,6 +16,7 @@ import org.nl.acs.device.service.DeviceService; import org.nl.acs.device_driver.DeviceDriver; import org.nl.acs.device_driver.FeedLmsRealFailed; import org.nl.acs.device_driver.agv.utils.TwoAgvPhase; +import org.nl.acs.device_driver.conveyor.belt_conveyor.BeltConveyorDeviceDriver; import org.nl.acs.device_driver.conveyor.standard_inspect_site.StandardInspectSiteDeviceDriver; import org.nl.acs.device_driver.conveyor.standard_ordinary_site.StandardOrdinarySiteDeviceDriver; import org.nl.acs.device_driver.driver.AbstractDeviceDriver; @@ -165,8 +166,6 @@ public class AgvNdcTwoDeviceDriver extends AbstractDeviceDriver implements Devic //普通站点 StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver; - //标准-光电检测 - StandardInspectSiteDeviceDriver standardInspectSiteDeviceDriver; if (phase == 0x02) { @@ -483,11 +482,11 @@ public class AgvNdcTwoDeviceDriver extends AbstractDeviceDriver implements Devic //当前上报的车号 String now_car = String.valueOf(this.agvaddr); //如果配置的车号是诺宝车号 - if(now_car.equals(is_atuo_car)){ + if (now_car.equals(is_atuo_car)) { //是否开启自动充电 String is_atuo_electric = ISysParamService.findByCode(AcsConfig.IS_ATUO_ELECTRIC).getValue(); log.info("接收agv上报信息,is_atuo_electric:" + is_atuo_electric); - if("1".equals(is_atuo_electric)){ + if ("1".equals(is_atuo_electric)) { String electric_begin = ISysParamService.findByCode(AcsConfig.ELECTRIC_BEGIN).getValue(); String[] begins = electric_begin.split(":"); String electric_end = ISysParamService.findByCode(AcsConfig.ELECTRIC_END).getValue(); @@ -499,27 +498,27 @@ public class AgvNdcTwoDeviceDriver extends AbstractDeviceDriver implements Devic LocalTime now = LocalTime.now(); // 判断当前时间是否在时间段内 boolean isInRange = !now.isBefore(startTime) && !now.isAfter(endTime); - int electric = 0 ; + int electric = 0; //早上8-22点 - if(isInRange){ + if (isInRange) { electric = Integer.parseInt(ISysParamService.findByCode(AcsConfig.ELECTRIC).getValue()); - }else{ + } else { electric = Integer.parseInt(ISysParamService.findByCode(AcsConfig.ELECTRIC2).getValue()); } - if (electric_qty>0 && electric_qty < electric) { - log.info("当前车辆{}电量为{}低于{},开始判断是否需要充电!", this.agvaddr, electric_qty,electric); + if (electric_qty > 0 && electric_qty < electric) { + log.info("当前车辆{}电量为{}低于{},开始判断是否需要充电!", this.agvaddr, electric_qty, electric); //判断是否已下发充电任务 - Dict dict1 = dictService.getDictByName3("station",String.valueOf(this.agvaddr),null); - if(ObjectUtil.isNotEmpty(dict1)){ - log.info("当前车辆{}已分配充电桩{},退出后续判断",this.agvaddr,dict1.getPara1()); - }else{ + Dict dict1 = dictService.getDictByName3("station", String.valueOf(this.agvaddr), null); + if (ObjectUtil.isNotEmpty(dict1)) { + log.info("当前车辆{}已分配充电桩{},退出后续判断", this.agvaddr, dict1.getPara1()); + } else { //未下发,判断是否有空闲充电桩 Dict dict = dictService.getDictByName2("station"); - if(ObjectUtil.isNotEmpty(dict)){ + if (ObjectUtil.isNotEmpty(dict)) { ndcAgvService.charge(String.valueOf(this.agvaddr)); - isCharge =true; - }else{ - log.info("当前车辆{}电量为{}低于{},但无空闲充电桩!", this.agvaddr, electric_qty,electric); + isCharge = true; + } else { + log.info("当前车辆{}电量为{}低于{},但无空闲充电桩!", this.agvaddr, electric_qty, electric); } } } diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/rest/WmsToAcsController.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/rest/WmsToAcsController.java index 5775403..749e24f 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/rest/WmsToAcsController.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/rest/WmsToAcsController.java @@ -32,6 +32,7 @@ import java.util.List; @RequiredArgsConstructor @RequestMapping("/api/wms") @Slf4j +@SaIgnore public class WmsToAcsController { private final WmsToAcsService wmstoacsService; diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java index b7b4c41..4cd231e 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/AcsToWmsService.java @@ -127,7 +127,7 @@ public interface AcsToWmsService { * @param arr * @return */ - HttpResponse feedTaskStatus(JSONArray arr); + HttpResponse feedTaskStatus(JSONObject arr); /** * ACS向WMS反馈任务状态 @@ -225,4 +225,6 @@ public interface AcsToWmsService { * @return */ ManipulatorApplyPointResponse manipulatorApplyPointRequest(ManipulatorApplyPointRequest param); + + String applyIn(JSONObject ja); } diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java index 4a7af9e..c74579e 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/impl/AcsToWmsServiceImpl.java @@ -326,20 +326,11 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { @Override - public HttpResponse feedTaskStatus(JSONArray data) { + public HttpResponse feedTaskStatus(JSONObject data) { //feedTaskStatus try { MDC.put(log_file_type, log_type); String wmsurl = paramService.findByCode(AcsConfig.WMSURL).getValue(); - - String task_code = ""; - for (int i = 0; i < data.size(); i++) { - JSONObject json = (JSONObject) data.get(i); - task_code = json.getString("task_code"); - } - TaskDto taskDto = taskService.findByCode(task_code); - String vehicle_code = taskDto.getVehicle_code(); - HttpResponse result2 = null; log.info("feedbackTaskStatusToWms-----请求参数{}", data.toString()); @@ -347,7 +338,6 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { String methods_url = addressDto.getMethods_url(); try { result2 = HttpRequest.post(wmsurl + methods_url) - .addInterceptor(tLogHutoolhttpInterceptor) .header(Header.USER_AGENT, "Hutool http") .header("Authorization", token).body(String.valueOf(data)) .execute(); @@ -744,6 +734,48 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { } } + @Override + public String applyIn(JSONObject param) { + try { + MDC.put(log_file_type, log_type); + log.info("applyIn-----agv申请进入输入参数{}", param); + String wmsurl = paramService.findByCode(AcsConfig.WMSURL).getValue(); + AddressDto addressDto = addressService.findByCode("applyIn"); + String url = wmsurl + addressDto.getMethods_url(); + HttpResponse result2 = null; + try { + result2 = HttpRequest.post(url) + .addInterceptor(tLogHutoolhttpInterceptor) + .header(Header.USER_AGENT, "Hutool http") + .header("Authorization", token) + .body(String.valueOf(param)) + .execute(); + } catch (Exception e) { + String msg = e.getMessage(); + log.info("applyIn-----输出参数{}", msg); + //网络不通 + } + if (ObjectUtil.isEmpty(result2)) { + log.info("applyIn-----输出参数{}", "返回结果为空"); + return null; + } + String type = ""; + if (result2.getStatus() == 200) { + type = "info"; + } else { + type = "error"; + } + log.info("secondaryAllocationPoint-----输出参数{}", result2.body()); + LuceneLogDto luceneLogDto = new LuceneLogDto(4, "applyIn", String.valueOf(result2.getStatus()), + JSON.toJSONString(param), String.valueOf(result2.body()), "agv申请进入"); + luceneLogService.interfaceExecuteLog(luceneLogDto); + return result2.body(); + + } finally { + MDC.remove(log_file_type); + } + } + @Override public String forceMove(JSONObject param) { diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java index 3b3e93c..b6f5fa1 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java @@ -1,5 +1,6 @@ package org.nl.acs.ext.wms.service.impl; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -12,7 +13,10 @@ import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.nl.acs.common.base.CommonFinalParam; import org.nl.acs.device.domain.Device; +import org.nl.acs.device.service.DeviceService; +import org.nl.acs.device.service.impl.DeviceServiceImpl; import org.nl.acs.device_driver.agv.ndctwo.AgvNdcTwoDeviceDriver; import org.nl.acs.device_driver.conveyor.belt_conveyor.BeltConveyorDeviceDriver; import org.nl.acs.device_driver.conveyor.standard_ordinary_site.StandardOrdinarySiteDeviceDriver; @@ -74,91 +78,41 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { .build(); logDto.setLog_level(4); luceneExecuteLogService.deviceExecuteLog(logDto); - JSONArray datas = JSONArray.parseArray(param); + JSONObject req = JSONObject.parseObject(param); + org.nl.acs.ext.wms.data.WmstoAcsData.createTask.CreateTaskRequest tasks = JSON.toJavaObject(req, org.nl.acs.ext.wms.data.WmstoAcsData.createTask.CreateTaskRequest.class); CreateTaskResponse response = new CreateTaskResponse(); -// ParamService paramService = SpringContextHolder.getBean(ParamService.class); - ISysParamService paramService = SpringContextHolder.getBean(ISysParamService.class); -// String cancelTaskCheck = paramService.findByCode(AcsConfig.ISALLOWTASK).getValue(); JSONArray errArr = new JSONArray(); -// if (StrUtil.equals(cancelTaskCheck, "0")) { -// response.setStatus(400); -// response.setMessage("ACS系统需要更新,请稍等"); -// response.setErrArr(datas); -// return response; -// } - for (int i = 0; i < datas.size(); i++) { - String data = datas.get(i).toString(); - CreateTaskRequest request = JsonUtl.format(data, CreateTaskRequest.class); - String paper_array = request.getPaper_array(); - String ext_task_id = request.getExt_task_id(); - String task_code = request.getTask_code(); - String start_device_code = request.getStart_device_code(); - String start_device_code2 = request.getStart_device_code2(); - String next_device_code = request.getNext_device_code(); - String next_device_code2 = request.getNext_device_code2(); - String put_device_code = request.getPut_device_code(); - String priority = request.getPriority(); - String vehicle_code = request.getVehicle_code(); - String vehicle_code2 = request.getVehicle_code2(); - String vehicle_type = request.getVehicle_type(); - String route_plan_code = request.getRoute_plan_code(); - String task_type = request.getTask_type(); - String class_type = request.getClass_type(); - String truss_type = request.getTruss_type(); - Integer agv_action_type = request.getAgv_action_type(); - String empty_site = request.getEmpty_site(); - String is_bushing = request.getIs_bushing(); - String is_pulling = request.getIs_pulling(); - String size = request.getSize(); - String version = request.getVersion(); - String bushing_num = request.getBushing_num(); - String storage_task_type = request.getDtl_type(); - String agv_system_type = request.getAgv_system_type(); - String remark = request.getRemark(); - double oven_time = 0.00d; - if (StrUtil.isNotEmpty(request.getOven_time())) { - oven_time = Double.parseDouble(request.getOven_time()); - } - String temperature = request.getTemperature(); - String start_height = request.getStart_height(); - String next_height = request.getNext_height(); - String params2 = request.getParams2(); - Map params = request.getParams(); + for (int i = 0; i < tasks.getList().size(); i++) { + TaskDto task = tasks.getList().get(i); + String ext_task_uuid = task.getExt_task_uuid(); + String task_code = task.getTask_code(); + String start_point_code = task.getStart_device_code(); + String next_point_code = task.getNext_device_code(); + String priority = task.getPriority(); + String vehicle_code = task.getVehicle_code(); + String vehicle_type = task.getVehicle_type(); + String route_plan_code = task.getRoute_plan_code(); + String task_type = task.getTask_type(); + String remark = task.getRemark(); + String params = task.getParams(); + Integer agv_action_type = task.getAgv_action_type(); - String start_point_code = ""; - String start_point_code2 = ""; - String next_point_code = ""; - String next_point_code2 = ""; - String put_point_code = ""; + String put_device_code = task.getPut_device_code(); + String agv_system_type = task.getAgv_system_type(); + + String start_device_code2 = task.getStart_device_code2(); + String next_device_code2 = task.getNext_device_code2(); + String start_device_code = ""; + String next_device_code = ""; if (StrUtil.isEmpty(task_code)) { JSONObject json = new JSONObject(); json.put("task_code", task_code); - json.put("ext_task_id", ext_task_id); + json.put("ext_task_id", ext_task_uuid); json.put("message", "任务号不能为空"); errArr.add(json); continue; } - if (StrUtil.isEmpty(start_device_code)) { - JSONObject json = new JSONObject(); - json.put("task_code", task_code); - json.put("ext_task_id", ext_task_id); - json.put("message", "起点不能为空"); - errArr.add(json); - continue; - } - if (StrUtil.isEmpty(next_device_code)) { - JSONObject json = new JSONObject(); - json.put("task_code", task_code); - json.put("ext_task_id", ext_task_id); - json.put("message", "终点不能为空"); - errArr.add(json); - continue; - } - if (StrUtil.equals(task_type, "8")) { - next_device_code = request.getPut_device_code(); - put_device_code = request.getNext_device_code(); - } StorageCell start_storageCell = new LambdaQueryChainWrapper<>(storageCellMapper) .eq(StorageCell::getStorage_code, start_device_code) @@ -166,15 +120,6 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { StorageCell next_storageCell = new LambdaQueryChainWrapper<>(storageCellMapper) .eq(StorageCell::getStorage_code, next_device_code) .one(); - StorageCell start2_storageCell = new LambdaQueryChainWrapper<>(storageCellMapper) - .eq(StorageCell::getStorage_code, start_device_code2) - .one(); - StorageCell next2_storageCell = new LambdaQueryChainWrapper<>(storageCellMapper) - .eq(StorageCell::getStorage_code, next_device_code2) - .one(); - StorageCell put_storageCell = new LambdaQueryChainWrapper<>(storageCellMapper) - .eq(StorageCell::getStorage_code, put_device_code) - .one(); JSONObject start_device_json = (JSONObject) JSONObject.toJSON(start_storageCell); if (!ObjectUtil.isEmpty(start_device_json)) { @@ -184,18 +129,6 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { if (!ObjectUtil.isEmpty(next_device_json)) { next_point_code = (String) next_device_json.get("parent_storage_code") == null ? next_point_code : (String) next_device_json.get("storage_code"); } - JSONObject start_device_json2 = (JSONObject) JSONObject.toJSON(start2_storageCell); - if (!ObjectUtil.isEmpty(start_device_json2)) { - start_point_code2 = (String) start_device_json2.get("parent_storage_code") == null ? start_device_code2 : (String) start_device_json2.get("storage_code"); - } - JSONObject next_device_json2 = (JSONObject) JSONObject.toJSON(next2_storageCell); - if (!ObjectUtil.isEmpty(next_device_json2)) { - next_point_code2 = (String) next_device_json2.get("parent_storage_code") == null ? next_device_code2 : (String) next_device_json2.get("storage_code"); - } - JSONObject put_device_json = (JSONObject) JSONObject.toJSON(put_storageCell); - if (!ObjectUtil.isEmpty(put_device_json)) { - put_point_code = (String) put_device_json.get("parent_storage_code") == null ? put_device_code : (String) put_device_json.get("storage_code"); - } if (StrUtil.isNotEmpty(start_point_code) && start_point_code.indexOf("-") > 0) { String str[] = start_point_code.split("-"); start_device_code = str[0]; @@ -210,47 +143,16 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { next_device_code = next_point_code; } - if (StrUtil.isNotEmpty(start_point_code2) && start_point_code2.indexOf("-") > 0) { - String str[] = start_point_code2.split("-"); - start_device_code2 = str[0]; - } else { - start_device_code2 = start_point_code2; - } - - if (StrUtil.isNotEmpty(next_point_code2) && next_point_code2.indexOf("-") > 0) { - String str[] = next_point_code2.split("-"); - next_device_code2 = str[0]; - } else { - next_device_code2 = next_point_code2; - } - - if (StrUtil.isNotEmpty(put_point_code) && put_point_code.indexOf("-") > 0) { - String str[] = put_point_code.split("-"); - put_device_code = str[0]; - } else { - put_device_code = put_point_code; - } - if (StrUtil.isEmpty(route_plan_code)) { route_plan_code = "normal"; } - if (StrUtil.equals(task_type, "5")) { - if (taskserver.querySameDeviceReadyTask(start_device_code, next_device_code, "0") > 1) { - JSONObject json = new JSONObject(); - json.put("task_code", task_code); - json.put("ext_task_id", ext_task_id); - json.put("message", "已存在相同的起点:" + start_device_code + "终点:" + next_device_code + "未执行的输送任务"); - errArr.add(json); - continue; - } - } TaskDto taskDto = taskserver.findByCodeFromCache(task_code); if (taskDto != null) { JSONObject json = new JSONObject(); json.put("task_code", task_code); - json.put("ext_task_id", ext_task_id); + json.put("ext_task_id", ext_task_uuid); json.put("message", "存在相同的任务号:" + task_code); errArr.add(json); continue; @@ -260,7 +162,7 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { if (vehicle_dto != null) { JSONObject json = new JSONObject(); json.put("task_code", task_code); - json.put("ext_task_id", ext_task_id); + json.put("ext_task_id", ext_task_uuid); json.put("message", "已存在任务编号为" + vehicle_dto.getTask_code() + "托盘号:" + vehicle_code); errArr.add(json); continue; @@ -279,93 +181,57 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { if (StrUtil.isEmpty(start_point_code)) { JSONObject json = new JSONObject(); json.put("task_code", task_code); - json.put("ext_task_id", ext_task_id); - json.put("message", request.getStart_device_code() + " 该设备号未找到对应点位"); + json.put("ext_task_id", ext_task_uuid); + json.put("message", task.getStart_device_code() + " 该设备号未找到对应点位"); errArr.add(json); continue; } if (StrUtil.isEmpty(next_point_code)) { JSONObject json = new JSONObject(); json.put("task_code", task_code); - json.put("ext_task_id", ext_task_id); - json.put("message", request.getNext_device_code() + " 该设备号未找到对应点位"); + json.put("ext_task_id", ext_task_uuid); + json.put("message", task.getNext_device_code() + " 该设备号未找到对应点位"); errArr.add(json); continue; } JSONObject jo = new JSONObject(); - jo.put("task_id", IdUtil.simpleUUID()); jo.put("task_code", task_code); + jo.put("ext_task_id", ext_task_uuid); jo.put("start_point_code", start_point_code); jo.put("next_point_code", next_point_code); - jo.put("start_point_code2", start_point_code2); - jo.put("next_point_code2", next_point_code2); - jo.put("put_point_code", put_point_code); - jo.put("start_parent_code", start_point_code); - jo.put("next_parent_code", next_point_code); jo.put("start_device_code", start_device_code); jo.put("next_device_code", next_device_code); + jo.put("start_point_code2", start_device_code2); + jo.put("next_point_code2", next_device_code2); jo.put("start_device_code2", start_device_code2); jo.put("next_device_code2", next_device_code2); - jo.put("put_device_code", put_device_code); - jo.put("agv_action_type", agv_action_type); jo.put("priority", priority); jo.put("vehicle_code", vehicle_code); - jo.put("vehicle_code2", vehicle_code2); jo.put("vehicle_type", vehicle_type); - jo.put("storage_task_type", storage_task_type); - jo.put("agv_system_type", agv_system_type); - jo.put("start_height", start_height); - jo.put("next_height", next_height); - jo.put("oven_time", (int) Math.ceil(oven_time)); jo.put("remark", remark); jo.put("params", params); - jo.put("params2", params2); + jo.put("agv_system_type", agv_system_type); + jo.put("agv_action_type", agv_action_type); jo.put("task_type", StrUtil.isEmpty(task_type) ? 1 : Integer.parseInt(task_type)); - jo.put("class_type", class_type); - jo.put("route_plan_code", route_plan_code); - jo.put("paper_array", JSONUtil.toJsonStr(paper_array)); - jo.put("truss_type", JSONUtil.toJsonStr(truss_type)); - jo.put("empty_site", JSONUtil.toJsonStr(empty_site)); - jo.put("is_bushing", JSONUtil.toJsonStr(is_bushing)); - jo.put("is_pulling", JSONUtil.toJsonStr(is_pulling)); - jo.put("size", JSONUtil.toJsonStr(size)); - jo.put("version", JSONUtil.toJsonStr(version)); - jo.put("bushing_num", JSONUtil.toJsonStr(bushing_num)); - if (!StrUtil.isEmpty(ext_task_id)) { - jo.put("ext_task_id", ext_task_id); - } + jo.put("put_device_code", put_device_code); TaskDto task_dto = jo.toJavaObject(TaskDto.class); try { - if (ObjectUtil.isNotEmpty(request.getInteraction_json())) { - task_dto.setInteractionJson(request.getInteraction_json()); - } +// if (ObjectUtil.isNotEmpty(task.getInteraction_json())) { +// task_dto.setInteractionJson(task.getInteraction_json()); +// } taskserver.create(task_dto); } catch (Exception e) { // e.printStackTrace(); JSONObject json = new JSONObject(); json.put("task_code", task_code); - json.put("ext_task_id", ext_task_id); + json.put("ext_task_id", ext_task_uuid); json.put("message", e.getMessage()); errArr.add(json); continue; } - if ("RK1002".equals(task_dto.getStart_device_code())){ - Device device = deviceAppService.findDeviceByCode("RK1003"); - BeltConveyorDeviceDriver beltConveyorDeviceDriver1; - if (device.getDeviceDriver() instanceof BeltConveyorDeviceDriver) { - beltConveyorDeviceDriver1 = (BeltConveyorDeviceDriver) device.getDeviceDriver(); - List list1 = new ArrayList(); - Map map = new HashMap(); - map.put("code", "to_command"); - map.put("value", "55"); - list1.add(map); - beltConveyorDeviceDriver1.writing(list1); - } - - } } if (ObjectUtil.isEmpty(errArr)) { response.setStatus(200); @@ -500,34 +366,26 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { } @Override - public PutActionResponse putAction(String jsonObject) throws Exception { - log.info("WMS下发点位信号--------------:输入参数" + jsonObject); - String date = new Date().toString(); + public PutActionResponse putAction(String whereJson) throws Exception { + log.info("WMS下发点位信号--------------:输入参数" + whereJson); + DeviceService deviceService = SpringContextHolder.getBean(DeviceServiceImpl.class); LuceneLogDto logDto = LuceneLogDto.builder() .device_code("WMS下发点位信号") - .content("WMS下发点位信号-----输入参数:" + jsonObject) + .content("WMS下发点位信号-----输入参数:" + whereJson) .build(); logDto.setLog_level(4); luceneExecuteLogService.deviceExecuteLog(logDto); - JSONArray datas = JSONArray.parseArray(jsonObject); PutActionResponse response = new PutActionResponse(); - JSONArray errArr = new JSONArray(); - for (int i = 0; i < datas.size(); i++) { - String data = datas.get(i).toString(); - PutActionRequest request = JsonUtl.format(data, PutActionRequest.class); - String device_code = request.getDevice_code(); - String code = request.getCode(); - String value = request.getValue(); - Device device = deviceAppService.findDeviceByCode(device_code); - if (ObjectUtil.isEmpty(device)) { - throw new Exception("未找到对应设备:" + device_code); - } - BeltConveyorDeviceDriver beltConveyorDeviceDriver; - if (device.getDeviceDriver() instanceof BeltConveyorDeviceDriver) { - beltConveyorDeviceDriver = (BeltConveyorDeviceDriver) device.getDeviceDriver(); - beltConveyorDeviceDriver.writing(code, value); - } - } + JSONObject jsonObject = JSONObject.parseObject(whereJson); + + String device_code = jsonObject.getString("point_code"); + //1-进入; 0-离开 + String option = jsonObject.getString("option"); + Device device = deviceAppService.findDeviceByCode(device_code); + device.setAddress(option); + device.setUpdate_time(DateUtil.now()); + device.setUpdate_by("WMS"); + deviceService.updateById(device); response.setStatus(200); response.setMessage("success"); LuceneLogDto logDto1 = LuceneLogDto.builder() @@ -541,7 +399,6 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { } - @Override public Map getTubeMes(String jsonObject) throws Exception { log.info("下发管芯信息--------------:输入参数" + jsonObject); @@ -582,8 +439,6 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { JSONArray datas = JSONArray.parseArray(jsonObject); - - //标准版输送线 BeltConveyorDeviceDriver beltConveyorDeviceDriver; diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/instruction/service/impl/InstructionServiceImpl.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/instruction/service/impl/InstructionServiceImpl.java index c7014e7..64b6a62 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/instruction/service/impl/InstructionServiceImpl.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/instruction/service/impl/InstructionServiceImpl.java @@ -459,13 +459,7 @@ public class InstructionServiceImpl extends CommonServiceImpl" + dto.getNext_device_code() + "路由不通"); } -// if (StrUtil.equals(shortPathsList.get(0).getType(), CommonFinalParam.ONE)) { -// throw new BadRequestException(dto.getStart_device_code() + "->" + dto.getNext_device_code() + "路由类型不是agv类型"); -// } - if (StrUtil.equals(paramService.findByCode(AcsConfig.AGVTYPE).getValue(), "2")) { - NDCAgvService ndcAgvService = SpringContextHolder.getBean(NDCAgvService.class); - ndcAgvService.sendAgvInstToNDC(task.getAgv_system_type(), dto); - } + if (StrUtil.equals(paramService.findByCode(AcsConfig.AGVTYPE).getValue(), "5")) { HttpResponse response = keCongAgvService.addTask(dto); JSONObject jsonObject = null; @@ -476,7 +470,9 @@ public class InstructionServiceImpl extends CommonServiceImpl" + dto.getNext_device_code() + "任务下发科聪调度失败!"); } } } catch (Exception e) { @@ -1171,7 +1167,12 @@ public class InstructionServiceImpl extends CommonServiceImpl query(@RequestParam Map whereJson, PageQuery page) { - //写入标签 - //bmVehicleRfidService.writeEpc("1"); - return new ResponseEntity<>(TableDataInfo.build(bmVehicleRfidService.query(whereJson, page)), HttpStatus.OK); - } - - - - - /** - * 条件查询 - * - * @param params 查询条件 - */ - @PostMapping("/selectList") - //@SaCheckPermission("@el.check(BmVehicleRfid:list") - public ResponseEntity selectList(@RequestBody BmVehicleRfidParam params) { - return new ResponseEntity<>(bmVehicleRfidService.selectList(params), HttpStatus.OK); - } - - - /** - * 新增数据 - * - * @param params 实体对象 - * @return 新增结果 - */ - @PostMapping - //@SaCheckPermission("@el.check(BmVehicleRfid:add") - public ResponseEntity create(@RequestBody BmVehicleRfidParam params) { - bmVehicleRfidService.create(params); - return new ResponseEntity<>(HttpStatus.OK); - } - - /** - * 连接测试 - * @return 结果 - */ - @PostMapping("/open") - //@SaCheckPermission("@el.check(BmVehicleRfid:add") - public ResponseEntity connectRfid(@RequestBody BmVehicleRfidParam params) { - bmVehicleRfidService.connectRfid(params); - return new ResponseEntity<>(HttpStatus.OK); - } - - - /** - * 修改数据 - * - * @param params 实体对象 - * @return 修改结果 - */ - @PutMapping - //@SaCheckPermission("@el.check(BmVehicleRfid:edit')") - public ResponseEntity update(@RequestBody BmVehicleRfidParam params) { - bmVehicleRfidService.update(params); - return new ResponseEntity<>(HttpStatus.OK); - } - - - /** - * 删除数据 - * - * @param ids 多个主键Id - * @return 删除结果 - */ - //@SaCheckPermission("@el.check(BmVehicleRfid:del')") - @DeleteMapping - public ResponseEntity delete(@RequestBody Set ids) { - bmVehicleRfidService.deleteAll(ids); - return new ResponseEntity<>(HttpStatus.OK); - } -} +//package org.nl.acs.rfid_manage.controller; +// +//import cn.dev33.satoken.annotation.SaIgnore; +//import lombok.RequiredArgsConstructor; +//import lombok.extern.slf4j.Slf4j; +//import org.nl.acs.rfid_manage.service.IbmVehicleRfidService; +//import org.nl.acs.rfid_manage.service.dto.BmVehicleRfidParam; +//import org.nl.common.base.TableDataInfo; +//import org.nl.common.domain.query.PageQuery; +//import org.springframework.http.HttpStatus; +//import org.springframework.http.ResponseEntity; +//import org.springframework.web.bind.annotation.*; +// +//import javax.annotation.Resource; +//import java.util.Map; +//import java.util.Set; +// +// +//@RestController +//@RequiredArgsConstructor +//@RequestMapping("/api/rfid") +//@Slf4j +//@SaIgnore +//public class BmVehicleRfidController { +// +// @Resource +// private IbmVehicleRfidService bmVehicleRfidService; +// +// +// /** +// * 分页查询 +// * +// * @param whereJson 查询条件 +// * @param page 分页参数 +// */ +// @GetMapping +// //@SaCheckPermission("@el.check(BmVehicleRfid:list") +// public ResponseEntity query(@RequestParam Map whereJson, PageQuery page) { +// //写入标签 +// //bmVehicleRfidService.writeEpc("1"); +// return new ResponseEntity<>(TableDataInfo.build(bmVehicleRfidService.query(whereJson, page)), HttpStatus.OK); +// } +// +// +// +// +// /** +// * 条件查询 +// * +// * @param params 查询条件 +// */ +// @PostMapping("/selectList") +// //@SaCheckPermission("@el.check(BmVehicleRfid:list") +// public ResponseEntity selectList(@RequestBody BmVehicleRfidParam params) { +// return new ResponseEntity<>(bmVehicleRfidService.selectList(params), HttpStatus.OK); +// } +// +// +// /** +// * 新增数据 +// * +// * @param params 实体对象 +// * @return 新增结果 +// */ +// @PostMapping +// //@SaCheckPermission("@el.check(BmVehicleRfid:add") +// public ResponseEntity create(@RequestBody BmVehicleRfidParam params) { +// bmVehicleRfidService.create(params); +// return new ResponseEntity<>(HttpStatus.OK); +// } +// +// /** +// * 连接测试 +// * @return 结果 +// */ +// @PostMapping("/open") +// //@SaCheckPermission("@el.check(BmVehicleRfid:add") +// public ResponseEntity connectRfid(@RequestBody BmVehicleRfidParam params) { +// bmVehicleRfidService.connectRfid(params); +// return new ResponseEntity<>(HttpStatus.OK); +// } +// +// +// /** +// * 修改数据 +// * +// * @param params 实体对象 +// * @return 修改结果 +// */ +// @PutMapping +// //@SaCheckPermission("@el.check(BmVehicleRfid:edit')") +// public ResponseEntity update(@RequestBody BmVehicleRfidParam params) { +// bmVehicleRfidService.update(params); +// return new ResponseEntity<>(HttpStatus.OK); +// } +// +// +// /** +// * 删除数据 +// * +// * @param ids 多个主键Id +// * @return 删除结果 +// */ +// //@SaCheckPermission("@el.check(BmVehicleRfid:del')") +// @DeleteMapping +// public ResponseEntity delete(@RequestBody Set ids) { +// bmVehicleRfidService.deleteAll(ids); +// return new ResponseEntity<>(HttpStatus.OK); +// } +//} diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/rfid_manage/service/IbmVehicleRfidService.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/rfid_manage/service/IbmVehicleRfidService.java index a07bf42..65935f7 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/rfid_manage/service/IbmVehicleRfidService.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/rfid_manage/service/IbmVehicleRfidService.java @@ -1,58 +1,58 @@ -package org.nl.acs.rfid_manage.service; - -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.service.IService; -import org.nl.acs.rfid_manage.service.dao.BmVehicleRfid; -import org.nl.acs.rfid_manage.service.dto.BmVehicleRfidParam; -import org.nl.common.domain.query.PageQuery; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -public interface IbmVehicleRfidService extends IService { - - /** - * 分页查询 - * - * @param whereJson 查询条件 - * @return IPage - */ - IPage query(Map whereJson, PageQuery page); - - /** - * 条件查询 - * - * @param params 查询条件 - * @return List - */ - List selectList(BmVehicleRfidParam params); - - - /** - * 创建 - * - * @param params 对象实体 - */ - void create(BmVehicleRfidParam params); - - - /** - * 编辑 - * - * @param params 对象实体 - */ - void update(BmVehicleRfidParam params); - - /** - * 多选删除 - * - * @param ids / - */ - void deleteAll(Set ids); - - - void connectRfid(BmVehicleRfidParam params); - - void writeEpc(String id); -} +//package org.nl.acs.rfid_manage.service; +// +//import com.baomidou.mybatisplus.core.metadata.IPage; +//import com.baomidou.mybatisplus.extension.service.IService; +//import org.nl.acs.rfid_manage.service.dao.BmVehicleRfid; +//import org.nl.acs.rfid_manage.service.dto.BmVehicleRfidParam; +//import org.nl.common.domain.query.PageQuery; +// +//import java.util.List; +//import java.util.Map; +//import java.util.Set; +// +//public interface IbmVehicleRfidService extends IService { +// +// /** +// * 分页查询 +// * +// * @param whereJson 查询条件 +// * @return IPage +// */ +// IPage query(Map whereJson, PageQuery page); +// +// /** +// * 条件查询 +// * +// * @param params 查询条件 +// * @return List +// */ +// List selectList(BmVehicleRfidParam params); +// +// +// /** +// * 创建 +// * +// * @param params 对象实体 +// */ +// void create(BmVehicleRfidParam params); +// +// +// /** +// * 编辑 +// * +// * @param params 对象实体 +// */ +// void update(BmVehicleRfidParam params); +// +// /** +// * 多选删除 +// * +// * @param ids / +// */ +// void deleteAll(Set ids); +// +// +// void connectRfid(BmVehicleRfidParam params); +// +// void writeEpc(String id); +//} diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/rfid_manage/service/impl/BmVehicleRfidServiceImpl.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/rfid_manage/service/impl/BmVehicleRfidServiceImpl.java index 88ffc39..0c908d7 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/rfid_manage/service/impl/BmVehicleRfidServiceImpl.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/rfid_manage/service/impl/BmVehicleRfidServiceImpl.java @@ -1,512 +1,512 @@ -package org.nl.acs.rfid_manage.service.impl; - -import cn.hutool.core.date.DateTime; -import cn.hutool.core.date.DateUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.gg.reader.api.dal.GClient; -import com.gg.reader.api.dal.HandlerTagEpcLog; -import com.gg.reader.api.dal.HandlerTcpDisconnected; -import com.gg.reader.api.protocol.gx.*; -import org.apache.commons.lang3.StringUtils; -import org.nl.acs.rfid_manage.service.IbmVehicleRfidService; -import org.nl.acs.rfid_manage.service.dao.BmVehicleRfid; -import org.nl.acs.rfid_manage.service.dao.mapper.BmVehicleRfidMapper; -import org.nl.acs.rfid_manage.service.dto.BmVehicleRfidParam; -import org.nl.acs.rfid_manage.service.dto.EpcRecord; -import org.nl.acs.utils.StructUtil; -import org.nl.common.domain.query.PageQuery; -import org.springframework.beans.BeanUtils; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; -import java.time.Duration; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -@Service("bmVehicleRfidService") -public class BmVehicleRfidServiceImpl extends ServiceImpl implements IbmVehicleRfidService { - - @Resource - private BmVehicleRfidMapper bmVehicleRfidMapper; - // EPC 缓存:设备ID -> 天线号 -> EPC记录对象(包含EPC值 + 时间戳) - - private static final ConcurrentHashMap> epcCache = new ConcurrentHashMap<>(); - - //rfid读写器列表 - private static final ConcurrentHashMap clientMap = new ConcurrentHashMap<>(); - - // 缓存过期时间,单位:毫秒(例如5分钟) - private static final long EXPIRE_MILLIS = 5 * 60 * 1000; - - @Override - public void connectRfid(BmVehicleRfidParam params) { - //reconnectAllDisconnectedClients(); - List clientList = this.list(new QueryWrapper().eq("is_used", '1')); - for (BmVehicleRfid r : clientList) { - String deviceId = r.getId(); - GClient client = clientMap.get(deviceId); - String port = StringUtils.isNotBlank(params.getPort()) ? params.getPort() : r.getPort(); - String ip = r.getIp() + ":" + port; - // 打开连接命令 "1" 为开启所有设备连接,"0" 为关闭所有设备连接 - if ("1".equals(params.getIsOpen())) { - // 如果客户端连接对象不存在或未打开,创建新连接 - if (client == null) { - client = new GClient(); - if (client.openTcp(ip, 2000)) { - addClient(deviceId, client); - client.setSendHeartBeat(true); - stopEpc(deviceId); - // 发送扫码启动命令 - MsgBaseInventoryEpc msgBaseInventoryEpc = new MsgBaseInventoryEpc(); - msgBaseInventoryEpc.setAntennaEnable(EnumG.AntennaNo_1); // 默认1号天线 - msgBaseInventoryEpc.setInventoryMode(EnumG.InventoryMode_Inventory); - client.sendSynMsg(msgBaseInventoryEpc); - if (msgBaseInventoryEpc.getRtCode() == 0x00) { - System.out.println("设备[" + ip + "] 开始扫码任务成功"); - } else { - System.err.println("设备[" + ip + "] 扫码配置失败: " + msgBaseInventoryEpc.getRtMsg()); - } - //写入数据 -// MsgBaseWriteEpc msg = new MsgBaseWriteEpc(); -// msg.setAntennaEnable(EnumG.AntennaNo_1); -// //字起始地址 第0个为CRC,不可写 -// msg.setStart(1);//word -// //写EPC,数据默认为 hex 432 -// msg.setArea(EnumG.WriteArea_Epc); -// String sWriteHexData = "888"; // 写入数据 (16进制) -// System.out.println("Write hex " + sWriteHexData); -// int iWordLen = StructUtil.getValueLen(sWriteHexData); -// // PC值为EPC区域的长度标识(前5个bit标记长度),参考文档说明 -// sWriteHexData = StructUtil.getPc(iWordLen) + StructUtil.padLeft(sWriteHexData.toUpperCase(), 4 * iWordLen, '0'); // PC值+数据内容 -// msg.setHexWriteData(sWriteHexData); -// // 若需要写入带特殊编码数据,请自行进行编码并使用 "BwriteData" 属性。 -// // msg.setBwriteData(HexUtils.hexString2Bytes(sWriteHexData)); -// client.sendSynMsg(msg); -// if (0 == msg.getRtCode()) { -// System.out.println("写入:" + sWriteHexData + "成功!"); +//package org.nl.acs.rfid_manage.service.impl; +// +//import cn.hutool.core.date.DateTime; +//import cn.hutool.core.date.DateUtil; +//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +//import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +//import com.baomidou.mybatisplus.core.metadata.IPage; +//import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +//import com.gg.reader.api.dal.GClient; +//import com.gg.reader.api.dal.HandlerTagEpcLog; +//import com.gg.reader.api.dal.HandlerTcpDisconnected; +//import com.gg.reader.api.protocol.gx.*; +//import org.apache.commons.lang3.StringUtils; +//import org.nl.acs.rfid_manage.service.IbmVehicleRfidService; +//import org.nl.acs.rfid_manage.service.dao.BmVehicleRfid; +//import org.nl.acs.rfid_manage.service.dao.mapper.BmVehicleRfidMapper; +//import org.nl.acs.rfid_manage.service.dto.BmVehicleRfidParam; +//import org.nl.acs.rfid_manage.service.dto.EpcRecord; +//import org.nl.acs.utils.StructUtil; +//import org.nl.common.domain.query.PageQuery; +//import org.springframework.beans.BeanUtils; +//import org.springframework.stereotype.Service; +// +//import javax.annotation.Resource; +//import java.time.Duration; +//import java.time.LocalDateTime; +//import java.time.format.DateTimeFormatter; +//import java.util.List; +//import java.util.Map; +//import java.util.Set; +//import java.util.concurrent.ConcurrentHashMap; +// +//@Service("bmVehicleRfidService") +//public class BmVehicleRfidServiceImpl extends ServiceImpl implements IbmVehicleRfidService { +// +// @Resource +// private BmVehicleRfidMapper bmVehicleRfidMapper; +// // EPC 缓存:设备ID -> 天线号 -> EPC记录对象(包含EPC值 + 时间戳) +// +// private static final ConcurrentHashMap> epcCache = new ConcurrentHashMap<>(); +// +// //rfid读写器列表 +// private static final ConcurrentHashMap clientMap = new ConcurrentHashMap<>(); +// +// // 缓存过期时间,单位:毫秒(例如5分钟) +// private static final long EXPIRE_MILLIS = 5 * 60 * 1000; +// +// @Override +// public void connectRfid(BmVehicleRfidParam params) { +// //reconnectAllDisconnectedClients(); +// List clientList = this.list(new QueryWrapper().eq("is_used", '1')); +// for (BmVehicleRfid r : clientList) { +// String deviceId = r.getId(); +// GClient client = clientMap.get(deviceId); +// String port = StringUtils.isNotBlank(params.getPort()) ? params.getPort() : r.getPort(); +// String ip = r.getIp() + ":" + port; +// // 打开连接命令 "1" 为开启所有设备连接,"0" 为关闭所有设备连接 +// if ("1".equals(params.getIsOpen())) { +// // 如果客户端连接对象不存在或未打开,创建新连接 +// if (client == null) { +// client = new GClient(); +// if (client.openTcp(ip, 2000)) { +// addClient(deviceId, client); +// client.setSendHeartBeat(true); +// stopEpc(deviceId); +// // 发送扫码启动命令 +// MsgBaseInventoryEpc msgBaseInventoryEpc = new MsgBaseInventoryEpc(); +// msgBaseInventoryEpc.setAntennaEnable(EnumG.AntennaNo_1); // 默认1号天线 +// msgBaseInventoryEpc.setInventoryMode(EnumG.InventoryMode_Inventory); +// client.sendSynMsg(msgBaseInventoryEpc); +// if (msgBaseInventoryEpc.getRtCode() == 0x00) { +// System.out.println("设备[" + ip + "] 开始扫码任务成功"); // } else { -// System.out.println("写入:" + sWriteHexData + "失败!"); +// System.err.println("设备[" + ip + "] 扫码配置失败: " + msgBaseInventoryEpc.getRtMsg()); // } - - // 订阅标签事件 - subscribeHandler(client, deviceId); - MsgAppGetBaseVersion msgAppGetBaseVersion = new MsgAppGetBaseVersion(); - //获取版本号 - client.sendSynMsg(msgAppGetBaseVersion); - if (0x00 == msgAppGetBaseVersion.getRtCode()) { - System.out.println("msgAppGetBaseVersion[OK]."); - } else { - System.out.println(msgAppGetBaseVersion.getRtMsg()); - } - //获取设备信息 - MsgAppGetReaderInfo msgAppGetReaderInfo = new MsgAppGetReaderInfo(); - client.sendSynMsg(msgAppGetReaderInfo); - if (0x00 == msgAppGetReaderInfo.getRtCode()) { - System.out.println("msgAppGetReaderInfo[OK]."); - } else { - System.out.println(msgAppGetReaderInfo.getRtMsg()); - } - BmVehicleRfid updated = new BmVehicleRfid(); - updated.setId(deviceId); - updated.setStart_time(DateUtil.now()); - updated.setStatus(1); - updated.setLog(DateUtil.now() + ":设备:" + r.getDevice_code() + "连接服务器成功!"); - this.updateById(updated); - } else { - System.err.println("设备[" + ip + "] TCP连接失败"); - BmVehicleRfid updated = new BmVehicleRfid(); - updated.setId(deviceId); - updated.setRfid(null); - updated.setLog(DateUtil.now() + ":设备:" + r.getDevice_code() + "连接服务器失败!"); - updated.setStatus(0); - this.updateById(updated); - continue; - } - } - // 检查连接有效性(通过版本获取判断) - if (!checkConnection(client)) { - System.err.println("设备[" + ip + "] 连接无效,关闭重试"); - removeClient(deviceId); - } - } else if ("0".equals(params.getIsOpen())) { - // 关闭连接 - if (client != null) { - // MsgBaseStop stopMsg = new MsgBaseStop(); - // client.sendSynMsg(stopMsg); - // if (stopMsg.getRtCode() == 0x00) { - // System.out.println("设备[" + ip + "] 停止扫码任务成功"); - // } else { - // System.err.println("设备[" + ip + "] 停止扫码失败: " + stopMsg.getRtMsg()); - // } - // client.close(); - // removeClient(deviceId); - disconnectAllClients(); - System.out.println("设备[" + ip + "] 已断开连接"); - BmVehicleRfid updated = new BmVehicleRfid(); - updated.setId(deviceId); - updated.setRfid(null); - updated.setLog(DateUtil.now() + ":设备:" + r.getDevice_code() + "已与服务器断开连接!"); - updated.setStart_time(null); - updated.setStatus(0); - this.updateById(updated); - } else { - BmVehicleRfid updated = new BmVehicleRfid(); - updated.setId(deviceId); - updated.setLog(DateUtil.now() + ":设备:" + r.getDevice_code() + "未连接,无需断开"); - updated.setStart_time(null); - updated.setStatus(0); - this.updateById(updated); - System.out.println("设备[" + ip + "] 未连接,无需断开"); - } - } - } - } - - @Override - public void writeEpc(String id) { - GClient client = getClient("1"); - if (client != null) { - MsgBaseWriteEpc msg = new MsgBaseWriteEpc(); - stopEpc(id); - msg.setAntennaEnable(EnumG.AntennaNo_1); - //字起始地址 第0个为CRC,不可写 - msg.setStart(1);//word - //写EPC,数据默认为 hex 432 - msg.setArea(EnumG.WriteArea_Epc); - String sWriteHexData = "666"; // 写入数据 (16进制) - System.out.println("Write hex " + sWriteHexData); - int iWordLen = StructUtil.getValueLen(sWriteHexData); - // PC值为EPC区域的长度标识(前5个bit标记长度),参考文档说明 - sWriteHexData = StructUtil.getPc(iWordLen) + StructUtil.padLeft(sWriteHexData.toUpperCase(), 4 * iWordLen, '0'); // PC值+数据内容 - msg.setHexWriteData(sWriteHexData); - // 若需要写入带特殊编码数据,请自行进行编码并使用 "BwriteData" 属性。 - // msg.setBwriteData(HexUtils.hexString2Bytes(sWriteHexData)); - client.sendSynMsg(msg); - if (0 == msg.getRtCode()) { - System.out.println("写入:" + sWriteHexData + "成功!"); - } else { - System.out.println("写入:" + sWriteHexData + "失败!"); - } - } - } - - public void stopEpc(String id) { - GClient client = getClient("1"); - if (client != null) { - MsgBaseStop msgBaseStop = new MsgBaseStop(); - client.sendSynMsg(msgBaseStop); - if (0 == msgBaseStop.getRtCode()) { - System.out.println("停止成功!"); - } else { - System.out.println("停止失败!"); - } - } - } - - /** - * 判断设备是否已连接(通过获取版本信息判断) - */ - private boolean checkConnection(GClient client) { - try { - MsgAppGetBaseVersion versionMsg = new MsgAppGetBaseVersion(); - client.sendSynMsg(versionMsg); - return versionMsg.getRtCode() == 0x00; - } catch (Exception e) { - return false; - } - } - - /** - * 定时器执行断线重连 - */ - public void reconnectAllDisconnectedClients() { - List clientList = this.list(new QueryWrapper().eq("is_used", '1')); - for (BmVehicleRfid r : clientList) { - String ip = r.getIp() + ":" + r.getPort(); - System.out.println("设备[" + ip + "] 连接异常,开始重连..."); - if (tryReconnect(r.getId(), ip)) { - System.out.println("设备[" + ip + "] 重连成功"); - } else { - System.err.println("设备[" + ip + "] 重连失败"); - } - } - } - - public boolean tryReconnect(String deviceId, String ip) { - final int MAX_RETRY = 3; - final int WAIT_MS = 500; - for (int i = 1; i <= MAX_RETRY; i++) { - System.out.println("设备[" + ip + "] 第" + i + "次重连尝试..."); - GClient oldClient = clientMap.remove(deviceId); - if (oldClient != null) { - try { - oldClient.close(); - } catch (Exception ignored) { - } - } - GClient newClient = new GClient(); - if (newClient.openTcp(ip, 2000)) { - addClient(deviceId, newClient); - subscribeHandler(newClient, deviceId); - newClient.setSendHeartBeat(true); - if (checkConnection(newClient)) { - System.out.println("设备[" + ip + "] 重连成功"); - return true; - } else { - try { - newClient.close(); - } catch (Exception ignored) { - } - } - } - try { - Thread.sleep(WAIT_MS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return false; - } - } - return false; - } - - - public static GClient getClient(String deviceId) { - return clientMap.get(deviceId); - } - - public static void disconnectAllClients() { - for (String deviceId : clientMap.keySet()) { - removeClient(deviceId); - } - } - - - public static void addClient(String deviceId, GClient client) { - clientMap.put(deviceId, client); - } - - - public static void removeClient(String deviceId) { - GClient client = clientMap.remove(deviceId); - if (client != null) { - client.close(); - // try { - // MsgBaseStop stopMsg = new MsgBaseStop(); - // client.sendSynMsg(stopMsg); - // if (stopMsg.getRtCode() == 0x00) { - // System.out.println("停止扫码任务成功: " + deviceId); - // } else { - // System.err.println("停止扫码失败: " + stopMsg.getRtMsg()); - // } - // } catch (Exception e) { - // System.err.println("停止扫码任务异常: " + e.getMessage()); - // } finally { - // client.close(); - // System.out.println("已断开设备连接: " + deviceId); - // } - } - } - - - /** - * 上报RFID信息 - */ - private void subscribeHandler(GClient client, String id) { - //上报标签信息 - client.onTagEpcLog = new HandlerTagEpcLog() { - @Override - public void log(String s, LogBaseEpcInfo logBaseEpcInfo) { - if (logBaseEpcInfo != null && logBaseEpcInfo.getResult() == 0) { - String epc = logBaseEpcInfo.getEpc(); - handleEpc(epc, id, "1"); - } - } - }; - //断开连接通知 - client.onDisconnected = new HandlerTcpDisconnected() { - @Override - public void log(String s) { - System.out.println("command log output5:onDisconnected:" + "connect" + s + "close.........."); - client.close();//释放当前连接资源 - BmVehicleRfid updated = new BmVehicleRfid(); - updated.setId(id); - updated.setRfid(null); - // updated.setLog(DateUtil.now() + ":设备:" + r.getDevice_code() + "已与服务器断开连接!"); - updated.setStart_time(null); - updated.setStatus(0); - //todo 更新断开状态 - // this.updateById(updated); - } - }; - - } - - /** - * 主处理方法:如果 EPC 不同或过期,则更新数据库 - */ - private void handleEpc(String epc, String deviceId, String antenna) { - if (epc == null) { - return; - } - ConcurrentHashMap antennaMap = epcCache.get(deviceId); - EpcRecord record = antennaMap != null ? antennaMap.get(antenna) : null; - boolean isSame = record != null && epc.equals(record.epc) - && System.currentTimeMillis() - record.timestamp < EXPIRE_MILLIS; - - if (isSame) { - System.out.println(epc + "与上次标签值相同,不上报,跳过...."); - return; // EPC 相同且未过期,跳过 - } - epcCache.computeIfAbsent(deviceId, k -> new ConcurrentHashMap<>()) - .put(antenna, new EpcRecord(epc, System.currentTimeMillis())); - BmVehicleRfid currentDevice = this.getById(deviceId); - if (currentDevice != null && !epc.equals(currentDevice.getRfid())) { - BmVehicleRfid updated = new BmVehicleRfid(); - updated.setId(deviceId); - updated.setRfid(epc); - updated.setLog(DateUtil.now() + ":设备:" + currentDevice.getDevice_code() + "读取RFID值:" + epc + "成功!"); - this.updateById(updated); - System.out.println("读取RFID值:" + epc + "成功!"); - } - } - - - /** - * 定期清理过期 EPC 缓存(建议由定时任务调用) - */ - private void clearExpiredCache() { - long now = System.currentTimeMillis(); - for (Map.Entry> deviceEntry : epcCache.entrySet()) { - ConcurrentHashMap antennaMap = deviceEntry.getValue(); - for (Map.Entry antennaEntry : antennaMap.entrySet()) { - if (now - antennaEntry.getValue().timestamp >= EXPIRE_MILLIS) { - antennaMap.remove(antennaEntry.getKey()); - } - } - if (antennaMap.isEmpty()) { - epcCache.remove(deviceEntry.getKey()); - } - } - } - - - /** - * 查询数据分页 - * - * @param whereJson 查询条件 - * @param page 分页参数 - */ - @Override - public IPage query(Map whereJson, PageQuery page) { - IPage resultPage = new Page<>(page.getPage(), page.getSize()); - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); - IPage list = bmVehicleRfidMapper.selectPage(resultPage, queryWrapper); - list.getRecords().forEach(r -> { - if (r.getStart_time() != null) { - LocalDateTime createTime = LocalDateTime.parse(r.getStart_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); - LocalDateTime updateTime = DateTime.now().toLocalDateTime(); - // 计算时间间隔 - Duration duration = Duration.between(createTime, updateTime); - if (duration.toMinutes() > 0) { - r.setOnline_time(duration.toMinutes() + "分钟"); - } else { - r.setOnline_time(duration.getSeconds() + "秒钟"); - } - } - }); - return list; - } - - - /** - * 根据条件查询 - * - * @param params 查询条件 - */ - @Override - public List selectList(BmVehicleRfidParam params) { - return bmVehicleRfidMapper.selectList(new QueryWrapper() - .lambda() - //.eq(ObjectUtil.isNotEmpty(params), BmVehicleRfid::getId, params.getFuzzy()) - //.or() - //.eq(ObjectUtil.isNotEmpty(params), BmVehicleRfid::getDjid, params.getFuzzy()) - ); - } - - - /** - * 创建 - * - * @param params 对象实体 - */ - @Override - public void create(BmVehicleRfidParam params) { - bmVehicleRfidMapper.insert(getBasicInfo(params, true)); - } - - - /** - * 编辑 - * - * @param params 对象实体 - */ - @Override - public void update(BmVehicleRfidParam params) { - // BmVehicleRfid dto = bmVehicleRfidMapper.selectById(params.getId()); - // if (dto == null) { - // throw new BadRequestException("不存在该数据!"); - // } - bmVehicleRfidMapper.updateById(getBasicInfo(params, false)); - } - - - /** - * 多选删除 - * - * @param ids 多个Id主键 - */ - @Override - public void deleteAll(Set ids) { - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - updateWrapper.set("is_delete", "1") - //.set("update_optid", SecurityUtils.getCurrentUserId()) - //.set("update_optname", SecurityUtils.getCurrentNickName()) - //.set("update_time", DateUtil.now()) - .in("id", ids); - bmVehicleRfidMapper.update(null, updateWrapper); - //bmVehicleRfidMapper.deleteBatchIds(ids); - } - - - /** - * 获取实体基础信息 - * - * @param params 对象实体 - * @param isCreate 是否创建 - */ - private BmVehicleRfid getBasicInfo(BmVehicleRfidParam params, boolean isCreate) { - // if (isCreate) { - // params.setId(IdUtil.getStringId()); - // params.setCreate_id(Long.valueOf(SecurityUtils.getCurrentUserId())); - // params.setCreate_name(SecurityUtils.getCurrentNickName()); - // params.setCreate_time(DateUtil.now()); - // params.setIs_delete(IOSEnum.IS_NOTANDYES.code("否")); - // } - // params.setUpdate_optid(Long.valueOf(SecurityUtils.getCurrentUserId())); - // params.setUpdate_optname(SecurityUtils.getCurrentNickName()); - // params.setUpdate_time(DateUtil.now()); - BmVehicleRfid bmVehicleRfid = new BmVehicleRfid(); - BeanUtils.copyProperties(params, bmVehicleRfid); - return bmVehicleRfid; - } - -} +// //写入数据 +//// MsgBaseWriteEpc msg = new MsgBaseWriteEpc(); +//// msg.setAntennaEnable(EnumG.AntennaNo_1); +//// //字起始地址 第0个为CRC,不可写 +//// msg.setStart(1);//word +//// //写EPC,数据默认为 hex 432 +//// msg.setArea(EnumG.WriteArea_Epc); +//// String sWriteHexData = "888"; // 写入数据 (16进制) +//// System.out.println("Write hex " + sWriteHexData); +//// int iWordLen = StructUtil.getValueLen(sWriteHexData); +//// // PC值为EPC区域的长度标识(前5个bit标记长度),参考文档说明 +//// sWriteHexData = StructUtil.getPc(iWordLen) + StructUtil.padLeft(sWriteHexData.toUpperCase(), 4 * iWordLen, '0'); // PC值+数据内容 +//// msg.setHexWriteData(sWriteHexData); +//// // 若需要写入带特殊编码数据,请自行进行编码并使用 "BwriteData" 属性。 +//// // msg.setBwriteData(HexUtils.hexString2Bytes(sWriteHexData)); +//// client.sendSynMsg(msg); +//// if (0 == msg.getRtCode()) { +//// System.out.println("写入:" + sWriteHexData + "成功!"); +//// } else { +//// System.out.println("写入:" + sWriteHexData + "失败!"); +//// } +// +// // 订阅标签事件 +// subscribeHandler(client, deviceId); +// MsgAppGetBaseVersion msgAppGetBaseVersion = new MsgAppGetBaseVersion(); +// //获取版本号 +// client.sendSynMsg(msgAppGetBaseVersion); +// if (0x00 == msgAppGetBaseVersion.getRtCode()) { +// System.out.println("msgAppGetBaseVersion[OK]."); +// } else { +// System.out.println(msgAppGetBaseVersion.getRtMsg()); +// } +// //获取设备信息 +// MsgAppGetReaderInfo msgAppGetReaderInfo = new MsgAppGetReaderInfo(); +// client.sendSynMsg(msgAppGetReaderInfo); +// if (0x00 == msgAppGetReaderInfo.getRtCode()) { +// System.out.println("msgAppGetReaderInfo[OK]."); +// } else { +// System.out.println(msgAppGetReaderInfo.getRtMsg()); +// } +// BmVehicleRfid updated = new BmVehicleRfid(); +// updated.setId(deviceId); +// updated.setStart_time(DateUtil.now()); +// updated.setStatus(1); +// updated.setLog(DateUtil.now() + ":设备:" + r.getDevice_code() + "连接服务器成功!"); +// this.updateById(updated); +// } else { +// System.err.println("设备[" + ip + "] TCP连接失败"); +// BmVehicleRfid updated = new BmVehicleRfid(); +// updated.setId(deviceId); +// updated.setRfid(null); +// updated.setLog(DateUtil.now() + ":设备:" + r.getDevice_code() + "连接服务器失败!"); +// updated.setStatus(0); +// this.updateById(updated); +// continue; +// } +// } +// // 检查连接有效性(通过版本获取判断) +// if (!checkConnection(client)) { +// System.err.println("设备[" + ip + "] 连接无效,关闭重试"); +// removeClient(deviceId); +// } +// } else if ("0".equals(params.getIsOpen())) { +// // 关闭连接 +// if (client != null) { +// // MsgBaseStop stopMsg = new MsgBaseStop(); +// // client.sendSynMsg(stopMsg); +// // if (stopMsg.getRtCode() == 0x00) { +// // System.out.println("设备[" + ip + "] 停止扫码任务成功"); +// // } else { +// // System.err.println("设备[" + ip + "] 停止扫码失败: " + stopMsg.getRtMsg()); +// // } +// // client.close(); +// // removeClient(deviceId); +// disconnectAllClients(); +// System.out.println("设备[" + ip + "] 已断开连接"); +// BmVehicleRfid updated = new BmVehicleRfid(); +// updated.setId(deviceId); +// updated.setRfid(null); +// updated.setLog(DateUtil.now() + ":设备:" + r.getDevice_code() + "已与服务器断开连接!"); +// updated.setStart_time(null); +// updated.setStatus(0); +// this.updateById(updated); +// } else { +// BmVehicleRfid updated = new BmVehicleRfid(); +// updated.setId(deviceId); +// updated.setLog(DateUtil.now() + ":设备:" + r.getDevice_code() + "未连接,无需断开"); +// updated.setStart_time(null); +// updated.setStatus(0); +// this.updateById(updated); +// System.out.println("设备[" + ip + "] 未连接,无需断开"); +// } +// } +// } +// } +// +// @Override +// public void writeEpc(String id) { +// GClient client = getClient("1"); +// if (client != null) { +// MsgBaseWriteEpc msg = new MsgBaseWriteEpc(); +// stopEpc(id); +// msg.setAntennaEnable(EnumG.AntennaNo_1); +// //字起始地址 第0个为CRC,不可写 +// msg.setStart(1);//word +// //写EPC,数据默认为 hex 432 +// msg.setArea(EnumG.WriteArea_Epc); +// String sWriteHexData = "666"; // 写入数据 (16进制) +// System.out.println("Write hex " + sWriteHexData); +// int iWordLen = StructUtil.getValueLen(sWriteHexData); +// // PC值为EPC区域的长度标识(前5个bit标记长度),参考文档说明 +// sWriteHexData = StructUtil.getPc(iWordLen) + StructUtil.padLeft(sWriteHexData.toUpperCase(), 4 * iWordLen, '0'); // PC值+数据内容 +// msg.setHexWriteData(sWriteHexData); +// // 若需要写入带特殊编码数据,请自行进行编码并使用 "BwriteData" 属性。 +// // msg.setBwriteData(HexUtils.hexString2Bytes(sWriteHexData)); +// client.sendSynMsg(msg); +// if (0 == msg.getRtCode()) { +// System.out.println("写入:" + sWriteHexData + "成功!"); +// } else { +// System.out.println("写入:" + sWriteHexData + "失败!"); +// } +// } +// } +// +// public void stopEpc(String id) { +// GClient client = getClient("1"); +// if (client != null) { +// MsgBaseStop msgBaseStop = new MsgBaseStop(); +// client.sendSynMsg(msgBaseStop); +// if (0 == msgBaseStop.getRtCode()) { +// System.out.println("停止成功!"); +// } else { +// System.out.println("停止失败!"); +// } +// } +// } +// +// /** +// * 判断设备是否已连接(通过获取版本信息判断) +// */ +// private boolean checkConnection(GClient client) { +// try { +// MsgAppGetBaseVersion versionMsg = new MsgAppGetBaseVersion(); +// client.sendSynMsg(versionMsg); +// return versionMsg.getRtCode() == 0x00; +// } catch (Exception e) { +// return false; +// } +// } +// +// /** +// * 定时器执行断线重连 +// */ +// public void reconnectAllDisconnectedClients() { +// List clientList = this.list(new QueryWrapper().eq("is_used", '1')); +// for (BmVehicleRfid r : clientList) { +// String ip = r.getIp() + ":" + r.getPort(); +// System.out.println("设备[" + ip + "] 连接异常,开始重连..."); +// if (tryReconnect(r.getId(), ip)) { +// System.out.println("设备[" + ip + "] 重连成功"); +// } else { +// System.err.println("设备[" + ip + "] 重连失败"); +// } +// } +// } +// +// public boolean tryReconnect(String deviceId, String ip) { +// final int MAX_RETRY = 3; +// final int WAIT_MS = 500; +// for (int i = 1; i <= MAX_RETRY; i++) { +// System.out.println("设备[" + ip + "] 第" + i + "次重连尝试..."); +// GClient oldClient = clientMap.remove(deviceId); +// if (oldClient != null) { +// try { +// oldClient.close(); +// } catch (Exception ignored) { +// } +// } +// GClient newClient = new GClient(); +// if (newClient.openTcp(ip, 2000)) { +// addClient(deviceId, newClient); +// subscribeHandler(newClient, deviceId); +// newClient.setSendHeartBeat(true); +// if (checkConnection(newClient)) { +// System.out.println("设备[" + ip + "] 重连成功"); +// return true; +// } else { +// try { +// newClient.close(); +// } catch (Exception ignored) { +// } +// } +// } +// try { +// Thread.sleep(WAIT_MS); +// } catch (InterruptedException e) { +// Thread.currentThread().interrupt(); +// return false; +// } +// } +// return false; +// } +// +// +// public static GClient getClient(String deviceId) { +// return clientMap.get(deviceId); +// } +// +// public static void disconnectAllClients() { +// for (String deviceId : clientMap.keySet()) { +// removeClient(deviceId); +// } +// } +// +// +// public static void addClient(String deviceId, GClient client) { +// clientMap.put(deviceId, client); +// } +// +// +// public static void removeClient(String deviceId) { +// GClient client = clientMap.remove(deviceId); +// if (client != null) { +// client.close(); +// // try { +// // MsgBaseStop stopMsg = new MsgBaseStop(); +// // client.sendSynMsg(stopMsg); +// // if (stopMsg.getRtCode() == 0x00) { +// // System.out.println("停止扫码任务成功: " + deviceId); +// // } else { +// // System.err.println("停止扫码失败: " + stopMsg.getRtMsg()); +// // } +// // } catch (Exception e) { +// // System.err.println("停止扫码任务异常: " + e.getMessage()); +// // } finally { +// // client.close(); +// // System.out.println("已断开设备连接: " + deviceId); +// // } +// } +// } +// +// +// /** +// * 上报RFID信息 +// */ +// private void subscribeHandler(GClient client, String id) { +// //上报标签信息 +// client.onTagEpcLog = new HandlerTagEpcLog() { +// @Override +// public void log(String s, LogBaseEpcInfo logBaseEpcInfo) { +// if (logBaseEpcInfo != null && logBaseEpcInfo.getResult() == 0) { +// String epc = logBaseEpcInfo.getEpc(); +// handleEpc(epc, id, "1"); +// } +// } +// }; +// //断开连接通知 +// client.onDisconnected = new HandlerTcpDisconnected() { +// @Override +// public void log(String s) { +// System.out.println("command log output5:onDisconnected:" + "connect" + s + "close.........."); +// client.close();//释放当前连接资源 +// BmVehicleRfid updated = new BmVehicleRfid(); +// updated.setId(id); +// updated.setRfid(null); +// // updated.setLog(DateUtil.now() + ":设备:" + r.getDevice_code() + "已与服务器断开连接!"); +// updated.setStart_time(null); +// updated.setStatus(0); +// //todo 更新断开状态 +// // this.updateById(updated); +// } +// }; +// +// } +// +// /** +// * 主处理方法:如果 EPC 不同或过期,则更新数据库 +// */ +// private void handleEpc(String epc, String deviceId, String antenna) { +// if (epc == null) { +// return; +// } +// ConcurrentHashMap antennaMap = epcCache.get(deviceId); +// EpcRecord record = antennaMap != null ? antennaMap.get(antenna) : null; +// boolean isSame = record != null && epc.equals(record.epc) +// && System.currentTimeMillis() - record.timestamp < EXPIRE_MILLIS; +// +// if (isSame) { +// System.out.println(epc + "与上次标签值相同,不上报,跳过...."); +// return; // EPC 相同且未过期,跳过 +// } +// epcCache.computeIfAbsent(deviceId, k -> new ConcurrentHashMap<>()) +// .put(antenna, new EpcRecord(epc, System.currentTimeMillis())); +// BmVehicleRfid currentDevice = this.getById(deviceId); +// if (currentDevice != null && !epc.equals(currentDevice.getRfid())) { +// BmVehicleRfid updated = new BmVehicleRfid(); +// updated.setId(deviceId); +// updated.setRfid(epc); +// updated.setLog(DateUtil.now() + ":设备:" + currentDevice.getDevice_code() + "读取RFID值:" + epc + "成功!"); +// this.updateById(updated); +// System.out.println("读取RFID值:" + epc + "成功!"); +// } +// } +// +// +// /** +// * 定期清理过期 EPC 缓存(建议由定时任务调用) +// */ +// private void clearExpiredCache() { +// long now = System.currentTimeMillis(); +// for (Map.Entry> deviceEntry : epcCache.entrySet()) { +// ConcurrentHashMap antennaMap = deviceEntry.getValue(); +// for (Map.Entry antennaEntry : antennaMap.entrySet()) { +// if (now - antennaEntry.getValue().timestamp >= EXPIRE_MILLIS) { +// antennaMap.remove(antennaEntry.getKey()); +// } +// } +// if (antennaMap.isEmpty()) { +// epcCache.remove(deviceEntry.getKey()); +// } +// } +// } +// +// +// /** +// * 查询数据分页 +// * +// * @param whereJson 查询条件 +// * @param page 分页参数 +// */ +// @Override +// public IPage query(Map whereJson, PageQuery page) { +// IPage resultPage = new Page<>(page.getPage(), page.getSize()); +// LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); +// IPage list = bmVehicleRfidMapper.selectPage(resultPage, queryWrapper); +// list.getRecords().forEach(r -> { +// if (r.getStart_time() != null) { +// LocalDateTime createTime = LocalDateTime.parse(r.getStart_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); +// LocalDateTime updateTime = DateTime.now().toLocalDateTime(); +// // 计算时间间隔 +// Duration duration = Duration.between(createTime, updateTime); +// if (duration.toMinutes() > 0) { +// r.setOnline_time(duration.toMinutes() + "分钟"); +// } else { +// r.setOnline_time(duration.getSeconds() + "秒钟"); +// } +// } +// }); +// return list; +// } +// +// +// /** +// * 根据条件查询 +// * +// * @param params 查询条件 +// */ +// @Override +// public List selectList(BmVehicleRfidParam params) { +// return bmVehicleRfidMapper.selectList(new QueryWrapper() +// .lambda() +// //.eq(ObjectUtil.isNotEmpty(params), BmVehicleRfid::getId, params.getFuzzy()) +// //.or() +// //.eq(ObjectUtil.isNotEmpty(params), BmVehicleRfid::getDjid, params.getFuzzy()) +// ); +// } +// +// +// /** +// * 创建 +// * +// * @param params 对象实体 +// */ +// @Override +// public void create(BmVehicleRfidParam params) { +// bmVehicleRfidMapper.insert(getBasicInfo(params, true)); +// } +// +// +// /** +// * 编辑 +// * +// * @param params 对象实体 +// */ +// @Override +// public void update(BmVehicleRfidParam params) { +// // BmVehicleRfid dto = bmVehicleRfidMapper.selectById(params.getId()); +// // if (dto == null) { +// // throw new BadRequestException("不存在该数据!"); +// // } +// bmVehicleRfidMapper.updateById(getBasicInfo(params, false)); +// } +// +// +// /** +// * 多选删除 +// * +// * @param ids 多个Id主键 +// */ +// @Override +// public void deleteAll(Set ids) { +// UpdateWrapper updateWrapper = new UpdateWrapper<>(); +// updateWrapper.set("is_delete", "1") +// //.set("update_optid", SecurityUtils.getCurrentUserId()) +// //.set("update_optname", SecurityUtils.getCurrentNickName()) +// //.set("update_time", DateUtil.now()) +// .in("id", ids); +// bmVehicleRfidMapper.update(null, updateWrapper); +// //bmVehicleRfidMapper.deleteBatchIds(ids); +// } +// +// +// /** +// * 获取实体基础信息 +// * +// * @param params 对象实体 +// * @param isCreate 是否创建 +// */ +// private BmVehicleRfid getBasicInfo(BmVehicleRfidParam params, boolean isCreate) { +// // if (isCreate) { +// // params.setId(IdUtil.getStringId()); +// // params.setCreate_id(Long.valueOf(SecurityUtils.getCurrentUserId())); +// // params.setCreate_name(SecurityUtils.getCurrentNickName()); +// // params.setCreate_time(DateUtil.now()); +// // params.setIs_delete(IOSEnum.IS_NOTANDYES.code("否")); +// // } +// // params.setUpdate_optid(Long.valueOf(SecurityUtils.getCurrentUserId())); +// // params.setUpdate_optname(SecurityUtils.getCurrentNickName()); +// // params.setUpdate_time(DateUtil.now()); +// BmVehicleRfid bmVehicleRfid = new BmVehicleRfid(); +// BeanUtils.copyProperties(params, bmVehicleRfid); +// return bmVehicleRfid; +// } +// +//} diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/storage_cell/service/StorageCellService.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/storage_cell/service/StorageCellService.java index 3db5ca3..8bbbbd6 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/storage_cell/service/StorageCellService.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/storage_cell/service/StorageCellService.java @@ -117,7 +117,7 @@ public interface StorageCellService extends CommonService { * @param code code * @return StorageCell */ -// StorageCellDto findByCode(String code); + StorageCellDto findByCode(String code); /** * 根据地址查询 diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/task/service/dto/TaskDto.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/task/service/dto/TaskDto.java index 8a77885..1688dec 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/task/service/dto/TaskDto.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/task/service/dto/TaskDto.java @@ -348,7 +348,7 @@ public class TaskDto implements Serializable { /** * 扩展属性 */ - String params2; + String params; /** * 是否拔轴 0/1 @@ -361,6 +361,11 @@ public class TaskDto implements Serializable { */ private Integer agv_action_type; + /** + * 外部系统标识 + */ + private String ext_task_uuid; + /** * 任务类型 * 9 子卷下线行架任务 diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java index 1ae68be..3a2d1ce 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java @@ -910,10 +910,6 @@ public class TaskServiceImpl extends CommonServiceImpl impleme if (!TaskStatusEnum.FINISHED.getIndex().equals(updateTask.getTask_status())) { //反馈上位系统任务状态 this.feedWmsTaskStatus(entity); - //关闭仙工运单序列 - if (StrUtil.equals(task.getTask_type(), TaskTypeEnum.Standard_AGV_Task.getCode()) && (StrUtil.equals(task.getAgv_system_type(), AgvSystemTypeEnum.One_NDC_System_Type.getCode()) || StrUtil.equals(task.getAgv_system_type(), AgvSystemTypeEnum.XG_System_Type.getCode()))) { - this.markComplete(entity); - } } } @@ -1804,17 +1800,17 @@ public class TaskServiceImpl extends CommonServiceImpl impleme if (ObjectUtil.isNotEmpty(entity.getCarno())) { feed_jo.put("car_no", entity.getCarno()); } - JSONArray ja = new JSONArray(); - ja.add(feed_jo); +// JSONArray ja = new JSONArray(); +// ja.add(feed_jo); //TODO 有需要根据上位系统反馈的信息再做进一步处理 - CompletableFuture.runAsync(() -> { - acstowmsService.feedTaskStatus(ja); +// CompletableFuture.runAsync(() -> { // 异步更新任务状态 try { + acstowmsService.feedTaskStatus(feed_jo); } catch (Exception e) { e.printStackTrace(); } - }); +// }); } } diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/utils/StructUtil.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/utils/StructUtil.java index 6aa2d45..bb836d4 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/utils/StructUtil.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/acs/utils/StructUtil.java @@ -1,66 +1,66 @@ -package org.nl.acs.utils; - -import com.gg.reader.api.utils.BitBuffer; -import com.gg.reader.api.utils.HexUtils; - -public class StructUtil { - - public static String getZdPoint(int row,String source_code) { - if (row == 2 || row == 3) { - return source_code; - } - int blockRow = row == 1 ? 2 : 3; - String replace = source_code.replaceFirst("L0" + row, "L0%s"); - return String.format(replace, blockRow); - } - - public static String getDeepPoint(int row,String source_code) { - if (row == 1 || row == 4) { - return source_code; - } - int blockRow = row == 2 ? 1 : 4; - String replace = source_code.replaceFirst("L0" + row, "L0%s"); - return String.format(replace, blockRow); - } - - public static String getPc(int pcLen) { - int iPc = pcLen << 11; - BitBuffer buffer = BitBuffer.allocateDynamic(); - buffer.put(iPc); - buffer.position(16); - byte[] bTmp = new byte[2]; - buffer.get(bTmp); - return HexUtils.bytes2HexString(bTmp); - } - - public static String getGbPc(int pcLen) { - int iPc = pcLen << 8; - BitBuffer buffer = BitBuffer.allocateDynamic(); - buffer.put(iPc); - buffer.position(16); - byte[] bTmp = new byte[2]; - buffer.get(bTmp); - return HexUtils.bytes2HexString(bTmp); - } - - //写入数据不足4位后面补'0' AA00 - public static String padLeft(String src, int len, char ch) { - int diff = len - src.length(); - if (diff <= 0) { - return src; - } - - char[] chars = new char[len]; - System.arraycopy(src.toCharArray(), 0, chars, 0, src.length()); - for (int i = src.length(); i < len; i++) { - chars[i] = ch; - } - return new String(chars); - } - - public static int getValueLen(String data) { - data = data.trim(); - return data.length() % 4 == 0 ? data.length() / 4 - : (data.length() / 4) + 1; - } -} +//package org.nl.acs.utils; +// +//import com.gg.reader.api.utils.BitBuffer; +//import com.gg.reader.api.utils.HexUtils; +// +//public class StructUtil { +// +// public static String getZdPoint(int row,String source_code) { +// if (row == 2 || row == 3) { +// return source_code; +// } +// int blockRow = row == 1 ? 2 : 3; +// String replace = source_code.replaceFirst("L0" + row, "L0%s"); +// return String.format(replace, blockRow); +// } +// +// public static String getDeepPoint(int row,String source_code) { +// if (row == 1 || row == 4) { +// return source_code; +// } +// int blockRow = row == 2 ? 1 : 4; +// String replace = source_code.replaceFirst("L0" + row, "L0%s"); +// return String.format(replace, blockRow); +// } +// +// public static String getPc(int pcLen) { +// int iPc = pcLen << 11; +// BitBuffer buffer = BitBuffer.allocateDynamic(); +// buffer.put(iPc); +// buffer.position(16); +// byte[] bTmp = new byte[2]; +// buffer.get(bTmp); +// return HexUtils.bytes2HexString(bTmp); +// } +// +// public static String getGbPc(int pcLen) { +// int iPc = pcLen << 8; +// BitBuffer buffer = BitBuffer.allocateDynamic(); +// buffer.put(iPc); +// buffer.position(16); +// byte[] bTmp = new byte[2]; +// buffer.get(bTmp); +// return HexUtils.bytes2HexString(bTmp); +// } +// +// //写入数据不足4位后面补'0' AA00 +// public static String padLeft(String src, int len, char ch) { +// int diff = len - src.length(); +// if (diff <= 0) { +// return src; +// } +// +// char[] chars = new char[len]; +// System.arraycopy(src.toCharArray(), 0, chars, 0, src.length()); +// for (int i = src.length(); i < len; i++) { +// chars[i] = ch; +// } +// return new String(chars); +// } +// +// public static int getValueLen(String data) { +// data = data.trim(); +// return data.length() % 4 == 0 ? data.length() / 4 +// : (data.length() / 4) + 1; +// } +//} diff --git a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/quartz/task/AutoCreateInst.java b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/quartz/task/AutoCreateInst.java index 4bac297..4a59141 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/quartz/task/AutoCreateInst.java +++ b/acs2/nladmin-system/nlsso-server/src/main/java/org/nl/system/service/quartz/task/AutoCreateInst.java @@ -57,18 +57,11 @@ public class AutoCreateInst { List list = taskserver.queryAllByStatus("0"); for (int i = 0; i < list.size(); i++) { TaskDto acsTask = list.get(i); - if (StrUtil.equals(acsTask.getTask_type(), TaskTypeEnum.AGV_Task.getIndex()) && !StrUtil.startWith(acsTask.getTask_code(), "-")) { - continue; - } - if (StrUtil.equals(acsTask.getTask_type(), TaskTypeEnum.Truss_Task.getIndex()) && !StrUtil.startWith(acsTask.getTask_code(), "-")) { - continue; - } String taskid = acsTask.getTask_id(); String taskcode = acsTask.getTask_code(); String task_type = acsTask.getTask_type(); String vehiclecode = acsTask.getVehicle_code(); String vehiclecode2 = acsTask.getVehicle_code2(); - String storage_task_type = acsTask.getStorage_task_type(); String priority = acsTask.getPriority(); String is_send = acsTask.getIs_send(); @@ -101,16 +94,16 @@ public class AutoCreateInst { } //校验路由关系 -// List shortPathsList = routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code); -// if (ObjectUtils.isEmpty(shortPathsList)) { -// acsTask.setRemark("路由不通无法生成指令"); -// taskserver.updateByCodeFromCache(acsTask); -// continue; -// } -// -// if (!StrUtil.equals(shortPathsList.get(0).getType(), CommonFinalParam.ONE)) { -// continue; -// } + List shortPathsList = routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code); + if (ObjectUtils.isEmpty(shortPathsList)) { + acsTask.setRemark("路由不通无法生成指令"); + taskserver.updateByCodeFromCache(acsTask); + continue; + } + + if (!StrUtil.equals(shortPathsList.get(0).getType(), CommonFinalParam.ONE)) { + continue; + } // RouteLineDto routeLineDto = shortPathsList.get(0); // String path = routeLineDto.getPath(); @@ -147,9 +140,6 @@ public class AutoCreateInst { Instruction instdto = new Instruction(); instdto.setInstruction_type(task_type); instdto.setInstruction_id(IdUtil.simpleUUID()); - if (acsTask.getAgv_system_type().equals(AgvSystemTypeEnum.One_NDC_System_Type.getIndex())){ - instdto.setInstruction_code(CodeUtil.getNewCode("INSTRUCT_NO")); - } instdto.setRoute_plan_code(route_plan_code); instdto.setRemark(acsTask.getRemark()); instdto.setMaterial(acsTask.getMaterial()); @@ -182,34 +172,6 @@ public class AutoCreateInst { instdto.setStart_height(start_height); instdto.setNext_height(next_height); instdto.setAgv_action_type(agvActionType); - //判断agv系统 - //1、1楼叉车系统 - //2、2楼1区域AGV系统 - //3、2楼2区域AGV系统 -已废弃 - if (StrUtil.equals(agv_system_type, CommonFinalParam.TWO)) { - // task_type - //1、生箔; Itype=1:取空,取满,放空,放满; - //2、分切 Itype=3取满、取空、放满、放空; - //3、普通任务 Itype=2:取货、放货; - //4、叉车任务 - //5、输送任务 - //6、行架 - //7、立库 - if (StrUtil.equals(task_type, CommonFinalParam.ONE)) { - instdto.setAgv_inst_type(CommonFinalParam.ONE); - } else if (StrUtil.equals(task_type, "3")) { - instdto.setAgv_inst_type("2"); - } else if (StrUtil.equals(task_type, "2")) { - instdto.setAgv_inst_type("3"); - } else if (StrUtil.equals(task_type, "8")) { - instdto.setAgv_inst_type("2"); - } else { - log.info("未找到对应的AGV指令类型,任务号:" + acsTask.getTask_code() + ",task_type:" + acsTask.getTask_type()); - continue; - } - } else { - instdto.setAgv_inst_type("4"); - } try { instructionService.create(instdto); } catch (Exception e) { @@ -225,8 +187,6 @@ public class AutoCreateInst { } //创建指令后修改任务状态 acsTask.setTask_status(TaskStatusEnum.BUSY.getIndex()); - acsTask.setUpdate_time(DateUtil.now()); - acsTask.setRemark(" "); taskserver.update(acsTask); } diff --git a/acs2/nladmin-system/nlsso-server/src/main/resources/log/KeCongAgvServiceImpl.xml b/acs2/nladmin-system/nlsso-server/src/main/resources/log/KeCongAgvServiceImpl.xml new file mode 100644 index 0000000..4d7405a --- /dev/null +++ b/acs2/nladmin-system/nlsso-server/src/main/resources/log/KeCongAgvServiceImpl.xml @@ -0,0 +1,29 @@ + + + + + + + + + ${LOG_HOME}/科聪agv请求/%d{yyyy-MM-dd}.%i.log + + 15 + + 50MB + + 2GB + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + ${log.charset} + + + + + + + + + diff --git a/acs2/nladmin-system/nlsso-server/src/main/resources/logback-spring.xml b/acs2/nladmin-system/nlsso-server/src/main/resources/logback-spring.xml index 427aaa5..ce996be 100644 --- a/acs2/nladmin-system/nlsso-server/src/main/resources/logback-spring.xml +++ b/acs2/nladmin-system/nlsso-server/src/main/resources/logback-spring.xml @@ -68,11 +68,11 @@ https://juejin.cn/post/6844903775631572999 - - + + - + diff --git a/acs2/nladmin-ui/src/assets/images/ftdl.png b/acs2/nladmin-ui/src/assets/images/ftdl.png new file mode 100644 index 0000000000000000000000000000000000000000..d065d63a242662be6dd2b195ecc4254e5e1ba1c7 GIT binary patch literal 39859 zcmV)PK()V#P)AgD~R$OTn}dQA+^ zqaq}A7z%?rJ0J%v`s-NiV!4B(=Wynn>vvyz?X}slS?(4WUVo>Rrg1atsa~0MA$Huh zHqGu>u{?FPO}0CKybl3=ae#9Y4QjaSOWr-kN}E-2wg@2 zAs`0DfC7{N2oMhn0D}~ShrdRESg#F1ICy}-00bBw%L1te2_!(pgDP;$JzJzEQ2+zM zf_#V#1Aqen5TF2tCkP-eHwXv;(9i~?N8cO(FQaF~Pz**%a6pVw!@+Af1<$~6_PtlG zfcF4Kx2E9~nA=PNR0ARhlmGz)unXE(iYurB2%a;ANRSf-fPxzfNSsCqFp$70R0x1i zhchiCq;o)k1W@>AkD=rPU<;Bf00mnjx0R$(4PXK*2StDzPEP=N zkOMm~!S>NzMQ0tIF4j9(>tJOSi_4+i9rXJwAR-l+s9wkT7+Ni~>bU%JWD$}SSp*Zq zC@2F`9*Ku$7%d1nq=3?Z0W<(0cqj!5Ab{aFE(c%&^l(nXXvImKAdG+_5em2fmq3&S zLVyA^=VCP(V>O(^;u*I-e|+K8{L!QR!$Itk5#tKstTlXHg@|ut1@~g0U8nqa) zfhbTk1c?v^5h{cTh!M17fJGw!$_tzW#8p*cT~e><$P6WuL?8qbAvl8DST+NS?FIsQ zs7(Ms53R(89P}-;LCm8I7(&Qj1Sg;n5NrruF_;w)1Z-ghEI>f;upZt7V_?{V9N-}= zltPprzFT!{qc+BhoB#smjTIF4Q|gL%_@XLvA1ucivGyB=DjHqSXki5$fFd}}x?A;9 zqcbvMT~(H>RFu|aWM74?1FMnlBMhp38pQwwm<_W&@{kNLoI-&(a1aV)Xv0B_1nfVQ zs-RFZ9EQFK4A=;agAhtB9yWD`LGTw9k_#*X=f!D?7%^~h!kvPTMZxRg_ZQw%tiXZb z%?9Q@v>h$(N5s60mh&R22^W{(5*@t(Dg?lXP?j9WPymMj-_LtlY7_yL!+H;IA6(;BX8v>7y&FtT| z>tol}5A4U4m%};`FgEVUVqBF3>CQp0Iwl{9@b z;;`WYFq|G4Lj}0bfCW)KD}kPZ22zh`C=)a^n+^yJVext>7Z*)%aBu-h6T}0X2L;U< zU?*Ho4G;!4L@@(_5Y&cR9J+WI>86h|WMsxKndnQbqI~!n(1wb&fEj+&q3j~oV2j}8 z zcV2t)g(u%X{BEslXX1$zEj>0dbK~Xv@3|ER_Cje0kfa4-3ljkmKn`G3i~y9@iw}m# zP%!YM7~&uTvDh%jAa*0`rvPK1+0usssy5=a5a1a^(7FRGC}>~~NIXO!0I?$$NQK}4 zkIJH|5CBrp27y6@A|T741sZ_20IL*Gd9SF)nFLR$5Cu>Pl<kQAb;66FAFp*_gs=5ID6Amc>YQrZlDfo?C3k5{MLmavttSo^Dnm}PAbvHDU3}HY)G&~_N1Yi#e zqZ3IXX@D6)Ff-MuXC=@8VgcEqI9P-dp@J>2e8HYMd-BMUbH`8iRy*X7>c~Xt?DpML zTjnMX?8eqjXl76filGctf}tr79+G2qQTnUYnug6#2uP5|sHHF(+E^c0k0LP$00-L0 zMtVk3V6YA;zyTl>9u-O-#XI+bxdK>$U=>P)3SQuVp2hq^c>D0-!*8BhU2r4_V)J4u zZtmZAX!EsKW6y3(jUhHrF*pWbJ;2Ze0#N3V3f)x<`Y;5oU>%%*H7Eh`Px)CRw5SjB z7qnqSH6x3VH9^rZL0Bp{hJsB{qTRt-7hVt?(g^hkd4W=+^4PW+ktvi3(9Zc(DKk`v z902&y8Uz2mfdBAZxx}_#I_Rf$K`{V(kjMIR_eVc`>xYjvI|IGCM(e!Gu5`{Em~{Mlb_ zYi6see7}9pHsi~0yY>3}?#H34kxqg$U?g6`sNew3`*tjiVFM6QmP-$P_lXC-?p7A- z%#2_;2(f@kNP7lQ>L3K;nJ;>U2uj>^TFcwrM8)eaENAJpzxeq>U;0&yjX7u;Mz_wv z7FaruV@C&PPyghh?@~Sp{Q{LUL1`#)EG}@A=H5o*js4eOx8u`y;_54qMN(DN8uw5| zuV;!x%qeqXw@Z7A5WM$2mc#uSx8sB#FjR)_#8`HB;X6T7sVz?~eARYx>c;fLl zfB2AHI6Wp62S`+Nt!X>G>&{>M4c@vnFgOCL9=Jr&M_#s{e&M}Go?LtXxbEi!R~dmO z?|scAb(K0#ZSU0F^ufDt-+I^WzBNIU(~gV-4@D&M0k(YL_kZ7?JI9NQ%@7(&lXpHK zC{-Xh1pxvDp)gd+DzFiy0;{1vLBVqf6qeKYi~sRI@{Zj|8X)BeUUP+DkSFc+7ykNh zidWtqbH3YN$#p2F8ofcjtFhJ8#;^OGFJaHl<+6;kNiz)E!wB<2@WcH1MOWgZVLo73 z0Qm=ooqk${Y`j&3GGT?PM5l}AUpV>bk5*rQU9YW9h}4-C!v#NZu43jSj*_^u-quyD_sFhDD=K?pz$Xs852n!FK)EwR>-pFH{6_aEt< zI58Du#w2A~s#tHk>4r`B-HDm$9GOMZlxS##26+`yRf`l#i#HD+f9%<v!Iwuef~NWEOE3$beWyg?Hj4V#0xI8@1WXo_%HM z&6mrnec9HjRX=$92al}JuiX0czm(keX{Z>QN2YtU9HCx|1#m7mBoG%>Rhsu(Y!X{4 zc*_v-DzNcLEddxr)^kvSM~a&Q$g>2~U5^LF^kC9F44u}L&5(GXz{Red7miyMQg;y7! ze`!|iR4wkTx0fp4AK!G#Z{5jro1jNYCJ4~(;@sKC|I42jXXe$y+Ju)nv-e?8SqKC0 z?Kas?W@2Vu`(W_u-+ueWXP^1Zzxv(8`Dl73QhETdgdrZ*?n-Mmkng*Ot!i2U!9%=Z zp&(8?1yBg&8Bl>Zu$D*#CgBn0mG|r@NOyU$zIn4s8(;_mzy>~Y6*}F8SKi29d}DHI zD#^PQRmS$XUz}^t*XOpuI(Vlcj6mQpERP9q*y*48`_G3xUBvP~vg&>#$md~Fk^%&P zPh1WL*4j&d|Iqv2|A9JpZZ2Tl7;Q@mHUMCiWr-qHg^&-*w3ZI*3Qj~2ShI?>rZ|K^ z#KHuk0PzqXtPehL&}`x~i6T(t%Cd4rsRB1^wQip0^F39|wnZlQ{@jz#=5M@r?Z5lq z;523?C}zV}v;rbWFnS{=dCAQV=S%&;AO7L`dOuAfIEQodgNGje{(t_zW?h*K)|*u| zsiMK4-;dOxU-&s3+*W3j-ldI@!SZlEOso_Kwtciaoge*V@tId^UKeq4+wcE=`ZJ%N zy5-u-Z#?kq>(3W!{qd+V##wFmq0}Nt(*%ft)FT#FqTm=#Bht0ig>x@GlWC4c)-Nn= z8k>>AJ^jS9+mdFM*3oRCw1_nb0tZk99>D5IX(~Y;7tX!)^ix@I;>#q}y|R~Pao%kw z!N)}vi!&MWd|ivW~FOY8Cjb!B}v3em9838r4yUQO8L?hxh@7%COUuo#5-@kv48h2%xxx3 z-MoxVgffinxs2aAwR-G$BlLCEiIvpr(fs){6U|0*(;QkYa3q9&OrFQ@=ZjLiFc$Yhk!tRDR}&+(jD6Xy@(u@A&r)AiA`&2uye03*I<7i~cYg9y z>Api?hIrA65%TUzs?Gc(KYs7wN3Tp9?(DfSrD~ejR+ct5$0sRSTWeFKCJ!A*#+nvl zpvey-I)G)Eu~HBc!bS%1pFaph7ZcqZVZA3*KrW650$)~rg}@{z3sfbZd;ZnG_={7| zJe_shlN@5PETxBc>?#kE_NA>Nr4*q4 z-GBIlRz3D>>zr5X5C7nquYGmzcw_C%2V?cb7CoEijmgOsYd2qZP~H47Tl!2*!vO`V zQi_PeFer09QP|wfYbsr_EX4C8Y zBxd#~*CgalWeOSy`NFrq>X#SE`&dU=T&oH<7}#2^dEx9rBS~vp=TJ|4IpEkRu$SOb zd00cxEC?c3_6YUdcGclOH3j`9I-^YA3`C)G#bG~ zl`>1#FB4|3xN`c&>!B3}-R8s?&YXGb&;E4jjW@^2D(d%DSsI0)IcHk)cEy(+!?uy4 znVnmkcL>`y%|=1W)%A&by|UFa&p%gh*2eemSBh8}SioYcHMM;7T~n<~zE;ap3Rb*7 zbNckbJMID$;>-ok8m3nwRY;BTODnwIdHj$5co)c?JwIEk_1o*AmeQ6jhyL~NV0H=< zt#xtrNK?17^w2}EJ@}2*dT*LlR9M^Zvteo^=LYRlz4g#aT@o+$x`V1p(nLbYyZwx4 zwpK4LEH$I}?BTcO4(vfK1`E1vL~8!Yr+f1Ysw$&ccU;~f-%WTRmF?w5kY=$h2fiwr z^*WPo_lm%AK~c_nz+5mF97>k9G23tbWNq6nXck2dJ_037Snt02mA^_Cm&XU?7{T`X ztw!A=_@anPucK(W%J+QyCe&Mzibz=TMR-$yjOq)r5e|K{#QjeP@H{FyglC-4r6^KlS&5%DLev5gg6idQUVoVJd_X(Jq9IU0n1O7LM}ch z85v<6IB{e=voM1&EJzYLhE?#4z$5Yi0ZO2RQ%dJgoGj0uooF>NGYKN40ueii8!D7h z%tDb;OdvqJXvlLjOOO8e?T3F{F0OPY)4exbd3yd7r?sl>dqo#s9sbF4*W7SJy6+Gc zS1~(*2CSkLz+*6pDvBJsi>DV()TfhfGr|3zMB1qGVA7QI^!}@En~z^r`O3nZC$Bia ziq;lLRcl2K2xW-J8Bn0ycbCGc$b0o zZy`Gvh+FFSYv~v~_Zhz4D0Ce?K^71kR=cl%?Qc#z`}7<%q|>ny*4gbURgQ*;DdX9>&qzmQKMA?!P&?dI4Bbzf9M6?-6@dG5(~AN^tft#`IgOm^Dssm*iUF}>&t8BgOw+YW5s zyyL)LBEE3u?8>pztEbNDmHu?r%q&*VoE>k}&mVnjdFcc7z2-Gv{w>4_VunJ8ec4PI zt{X=k;|3gjJ>@FdHaT9NU-aI4>)4Bynk6!gte~t=aYe={2zgLNuw`OQ)`atjOaKr9 z#KQ)>@z(OYM>bcMgVmbJsG_npQ)>@;%r0Vk^4RcQ{GxwFxroy2T1?MZS+#t8x&M=Ux(d(w`n zVrD_&S&OhB{3A^y7l|~N{J!yu1VZo>9P{uPD98r)Xvh>Iff8W^ZF^N|7oKZ}qQ9@- z#%;F%ktT;IwGbgCiYr$o%CJyXlu;7v2wn%l*>f-c{lhrFG&8fQulh5;`NiI&-+S}r zS2s;H-D;Uc@%-CI=#T#N>fin{uDAhK;GIih6e$Q{Aj?bhufNhOJ3KZ%d)XG$1?+T^ zLIBFJ?ckv+K6YX4RlB%?*IvTjCTdAO=-0D`N`TcR#0(SG55M~S-+dGPRkB6B*2+0K z-x=I}$JLEnZ#n;!znHXs_1Mu@k>9g#8!o>B;@}n7z&j8_028ATPhNY&XIyO36zrg! z*SShH203z9Jo41}x8GZ9uM)9_@=1Mi=bnSV@HsRRMC5|kW8)}2ge%s1W(KWEND13N z@mF6t^4Mc@Q9Mb;mL8hcnf#{N%kKEZ+}*ch&rZ}bD4r#Cz!q3qIR5lAZ+`3h^C!#R)GO>6xz!PH=uYB)& zdv3fLx8IH6`n__pS%U?79V{;g*Lm`pcYpNM z;ydp*@@k^hs%7!wnG?IVZ+hv6Kb+jPYujf&4aFe3<2QaSoL}I|B8uU1Pzd#m9pTK{ ziw``wvUt9gG*n1d2BoBpz1Q75b=Q3`DYOAG$O9EnI?Z}+8cfB#KH3PjK24#5pwdelwuP4u(t@r!mS}A1^s1h3-F?0YNGY1`rHcI1x5R|}# z|BtJae_RcuKoG|8+dRV!>*^bB&5&xX0*1Z=iBnZ?d#knL!}*tA%&Xp25ZrPTYKazC zdQUnDfYN$YYYqZ|`rrSTe@m5p;g9~b`|kVoKy8=b_Ah?P-1+hGEt?*H_PL@6jaoB- zj-8KtgN0XLtLN)cC@?ja7-Y()C^Hcv{lWJi?yj#48s<~~@{4-gbZ(T=i3rNFZvxl) z?%n5}EsX6a)u#JyK@yUPsJli%0N~uI_rLPz&pq&0<+1l?h$A*gnt9S_PfT9+>3j4i zZkce!(ureLcO`ExkuRpNyaI6z-V9?gD00jtv(}pGEj70tJ9lBncI?>1`?q1o7VO-D zO|#4I96NI2SfxU#s9@cT;?{vf(_i`$4(!I>J-lxhwr|0fIqck_wr>x$%to=cIbMC~ z?XP_;?&Wn)Wv58%jdsAYQrG{&=QrPWE3Up8wI+xyl!_WK8OA0iF1up3KDNHPTC8{A zeXNu%3uaziSWIg5*()xC(LqU{Y&22dx@GR^AN_cyHR*dr%>~=bRoQlldzx%st&pxDeAd<4*06qO*zH;`7CwFK) ztGUc`Gd1&Wdu{6G>u>$Nf1Q5vPP8VV>);Hgj;MxO7Vq7^^|H%*E35OT&doL&X3)(< zA`=&R_1=*aSAXJmBy|MA>>6V&^W}u@jrOV$;@R&pp4ex~S49Fs)X$ ztTzta^(p4FLskDYeRiO-c{HYfn_(t);shaYvC}tgdGDV075<3-9R*PftEP(|yLbx720<^$LFhK~SBPnd3;b~b4(*OV< z07*naR8wOH?e&$j=Vv2>9lOAQt4ai=G(#A|0#*t{>JR?I|I~f#CvSf3@3uv?{$OA> zO&|F8{{~rv>DjtTkH34o>hv?Ps)|iXdivPAXD%E+`Tkq^(WCKNJJpd=2|5K9Ru6ym z!S3=>KU6pW4_`*44IB1`i^6Dv_lS}cKlm4q{qd9X$T*n_u~>*Z%r% zx<}sIu`+kW*g{qppkx1p6rvy=kv4uApL8U^D;H8)uIk%OYa&64by`G&Q^R?t37vue?j@T|&>6 zNu07GjuOR0&b{|1e_XzIbW$Z%cfb@`6|ZZ3&AmUf^|!x_E!z+$l`>v6pz1(U*wCqb z7H8?)_PIDc_STzKud{n@^PtmVLA_p^UtBu4cMoQ#s!)nfJb5!d6&LP2Wz)U)L#Kezo{|do zg;$>c>j!pg-STB`aUp7CN0!$nueti;zxS_j^%aQXPS3{i1Skck5WUoH*J>GB&DmXh z?ZV=z_uj4hGK=*fucEB6((dcPGdJ7}9l@|ql3-G&BB+>E0*PT6;1iGksK2tLz17aM z(mt(iyXuh;ppbd<|$nm5hv z`_gZ&9zVUfxX6?%4h&P2k|1tfe-lKIX~&~F)R1>^NtN!Snfno~hepnVjN%1vh)k&9 zJjx2sy>$4&Zx@H(-=5V~aGHq&u>)CQVWSgek}3=%Z6X96#DrjiR}unIAPgU#aq)Q= z)&&SckRb_z;2BoK4lA4l0F0nTw1^T>A}mAnickPiU?(OF%3jQBEX!Q4Tspttte?p0 z*gB`;I5x^b6bRl^S&~*D*66Rl_04Z?4U*;+z&G4|FIrPb31xBUbH8qu{h4Q;DHku; zFj(o9+qTq?cTdad<)shKTzKSZpN&s%-o9(wTywm&WmRVMR9TO4>H@ZCBoQn_H2P}@ z9_#blCexMGb-Om-{l3$G0FDT?Xjr8vkOjaZ_aNnU z6lx95;@-UW&M0kE+#0%Zaa^lKU4WpYH0B}iC0O!;caB_mlc0v7O1DfMgUt1RT3#=CQXyn7eQ%`ZvEu0*Is?|@4s`tv&!US=W0UjGv_~e{Ha}+ zUlyxCkuBkZ(1Bn5%`-2)g=5Eg&~Byi(#qP*)Y$WnJ-YLrTQN0(EXBzqPkrxO6V;%> zp6hB^s(w^!?b~(v7k&|(AZRQP5GN?;!grt8wA9-@)#$WWO69u=p*4HOeLsW!`=E60 zqvlu>Igk%4?`nK%uH(xjbfXjzmc(FnZ0A7alTY{ny$~;z<-+uo2#5q)X zNRlF@PNJ{5{bn56x95f%PMtk9aNQbWW25m-b?U^Tf8&5nzxsf-V9(5Y2C$4PPg z%u8SU<_+Uxxb||=6nx1#W5v$7Cx&fWH~#j!l~+}csdy}nvZ~#4!8Wsot~YxwZyT$(ZoTCJpMU2lR@RZuSRETPN@EV&-9||q3n(x_0Sc)tD+O|S z$<}5%G9pZzd!G;bpn%e&kyN47oG6$8s8GQ(^0I&QeQI|mqokW#DDITGuQhgFb2TO= z&}@Raav+VGAyOkUF9}q{7yxmy=k9w>zyDtM-D5KxGxPewh1q)R+{>@+%1cbt2YEM2 zCnz-_f7dVn%1{2&pY#X08}v-9%^;5!mtKD0tJnYge}n$|*=L`Y#S0C%Feth-D4WfG zoZkP%FCtEJ>(W@Go}rgxW$DCgFHdRJUs|-?{*G8GbYe?PJD&=kQRAvBqn|vkS2|P|E7#K0=bz8Zn!0 zuiZV?IsTn*@0n?0$7aa~Xe9z;bPb{bXgvQ);=B{r&(v~O;`%)<2EaNPs2Ewm-Jiby z`a`E*fBEzyj~##cwb{^=cBiJ(W+N8wy8VT|FKf*jVg$IPFK&5F&Mm3BiE5_s2!#&T z=CNhlX~EVh>0ap9YU3S_D*#+cEUxffS7L11&uqKnOJ7iX_F(&7n5?fj0FAhbK?n8O zUHh(Ge*JA@vuNEPfBwZizp>x4GZ26bv>GRxZi)d1r zbPyJP@EC5t5lQsISHHG3m>RT@iOs}{)wkXEg?Qf;Ws*3K9H6C(%;WT{ZPSssta&t& zmOEFD)u(2!yaBUw;7FXMVXk;=WE5G20Hpv84T@mo+Ml`qdoRA=f=l6&qTFI=ZTalE zH(#3i>|KyLk!B!)!j54H7A}KD z(R=RO56);dh3k7SIzb0F-TVpEr%`KQ_wJdUyQ_r@CF)3jsiUU#5F-6t~$5j+lO5TU6Bo|o4oK)S)gxHw0 z10hlgDR0XV4Y7?tV8GEvNdhbsARH(FEC>)*0g3gVO+V2k(I5Rr$%|z9z zQaTl{Cn&^ev1wDy?%cigvdd>behUumM=L|C2}&yBVPkm!g9u|SRUadYk;Aah7nUHF z0gu4Y1Q;20x_USd8$lC-_6h_UF?Kx=gdiYK>=~817!LBr?g%`hZzEvPt2&)T#4$r_ zr^srW+&+h99a%K$*t|&CR0wbaKWgV8z$ip%bNh~dTsN=-sk}JYO2c$kSDW4|tph;J zAPesf{@O2{I(oQo^SH3oA55CmmG;fAejRDFt3D24MYa5`tBQVeD&EET0ykd`Jf-89ITuly!t|R z$Hz-lfYx9YYsiq3=i$Q!@BW`P7yoU`r{IY>sM2c{)Fm|puR{P-yCjMej-t}%<)ENoeS`>1KBPg{$pm3X z4h#q>VhNTIXw(IM=`jEx2?UUY;eV8H+MB({SRt{_NHkA>OU)riJ-Z@v7o zeftjX#pWHDoItY%PO-uwl)5UW54|G53>|Mwt3 zFesKgooQv1GCE3fpak#TwF_~Cji!3K$ljEohRt~t!wb9&_tTl%vE^MYRb_)AFDNS) zlwMlA&~yO`3J?wNt*)ntrf&QBpL_WK{6Ne6h^pJ&I^ot}S2o}!H$HHvA)=@B_MCcpO`}aU8Y_u1M6A<7DfKt(@hm@2c z5CfZLTH`IdG#_iK#Cejyw6ea2JV&dgfCw1&tC~wV>i-S1dP!3)Bq+-YfGr^Y>{HL# z#kC-$mG;7IYt{B9ZoV2>>Pe~bbo|a+!nYn+zp#+RsV_@iGwsgm>kmKr@f&Z9V>6I4 z9ya6>0>J8GAKpKInc0XEVh0SWs-8pu!fHEhsKJpV@BQGh#{5!EM_!ywmESxzzHiqD zWsxhb#3>0N4}gSNG`w~~p4h2SDR}lm0bs405u2#!hxU5tv~^XuvS-`9dTHtv>Lwm2 zRLVIMQUo0;<6Rv7NzDHfM*tKwShHt6WIg-gwn2zREuCL{>j#hDeElbq*=?{DkN|){ z_jHC2+3>MgfZ6PspzX}NdB&wduyTn1x`JP(aH z0gQLI3Wh;&%0Kv(J8$JOd2m}HO?-L)$s9G)V_=<=v zoF@cD-CiG61sUzaL_j1P1#Lenlac&W6Fb~t<|1=u*bW>B;^7?DR}TO9>1mx-o%OWd zsH=F{*=--Y5_3~vW@ryqGvjmDA3FBkhgoW4M#_`iQu#bI!@=(eG!~WwC zgg;ti9kUo~D~XJ*MR0%xS0x7O#P@z&zI|*rM_J4jagnlY9^3lszcjV`5Onn6iVt0k zz$5ZM5r#B8<-h^Nuo1+-S_}qQUBk)ar=EG@=o8O0DvF#-AVIU|;K;ELT1tkngi#CT zfBVRQqQJ%vNyrQde#A{e3blN8;r(y@?Y`gpA4eOuL<$si?tNU#q;fSj-GyZYD1-oC zc^}beO9BN3Wk?l(oS1>QvM>p13^)jSY?jss(^+%whHGcO_^We`1phB*?-^{_b)AWQ zYwf*Hy5WU>uXCfjfkuuDUuvN)R-QL8i}HqBmy82ngl?kMj%pmBX#%7@7;9H*?X_$ALrcrUW1T?)~Q?frTb3Y zYws1l^?gNwpdbeoh{t5m|HFUx%-{TIb66f-T*7tNL)5c%CWlQSfU^;WfIWh;ozX)W zh9Fjm7WGhlW=)J0`Isxgdt~W5bvgfC8!78_DUjXDju2RNR@`L}!%$=s*w!3D9Eqn; zs-~emDC{nkLYqUHHUPnb6cAR89HQ}H7F9JOrYY#O91?2b!Q)W%IyuV8`~UHO{_XRx zZ*30`rm2oc7*})Mj)Cv=<}PgSq*on1_NC8Zc>&Hbn<#J$X9<%A(9JHgs<2AnP!pFf zv;dAh9izLZx#wGHD@FneKm|%wO=LtuoL*z&xwd=^)1c^Wx4+rX?v16(2*E%Ks!>ls zs7^mReEp3R3yYfy5veBQbfI_0r#}G$lr^Q!S0m#mH-G9Q&-~z9<<__-T*tCk6y?Tt z`NPxM)mLX}3XKrc5EsNIWpJgNu+wZ*`zK~f>Lc<|wk`yM&GQ!i)Ta%TrwHnco& zxcbydpabM>qZjQd4JrcyRgeGytY882xR$~?PzqC^JBOo3k6(R!|E=#m|FypuzOky+ zL{*5y#VRlBv<{`Sm6?sAzvrEWlVFV)7Z}>KHk!(URD==5J5SF(^3bWfKT7Yr6ILp? zlr7VI*ITZG^wM0`x3MuKL`JN&@}kXP5rGGUl1Qn*fgCyuum!|G4dxc+mk#tgeQUCi z6jhHL?gGssO!@a-$>o{?|WLCB&N#NmHg35pxyS+JI)f7pChl-l0RvlQ@}ljf>;b20eM~D6T#M1w1hE8Cf`s8?HNY@_4_<3u{9) zcHYl>edWO)V|^1UVDjn>w+~YJ3P;40{WVRT0NeF8P+>H>^qud|Z)_hoxr=c!nGoB+ zJdgluU@ejqX)0+Nk~AcVxI|o{iA9pYC9nxh3S(iduuVICq&d>G4aTz^*Ik!??z0Cz z`e7VBxW%X;hLK84t4SIKY6XelUA;Fq zh$sQ!gSXv0v?eHAB)dJqb1%V50k|a5jF1AZzqnD_2wG@a~r2iv*P!9y?y%tF)GGaDKtmC zc=lD46KDj2AVeTG3!dQsSHVsc(KLjq0`FJPo=bwy0P6!qfpgyQzJmuFN*u5fAU-I} z2pU`$Npk2DAHVU#AJ{3&q9_XEw2V=(?fnfO|0q6r4~#91i*PL!XG0xpEi5k`JL;7j zTlHdsumlGgzxX0TfCwWh5FIrH$4D?y4egxgZNuO9)}?ZFH3O;l%q(m?On+%VI^DP5 z#D)!&2w<8zPC9iNnoagldCBy@lp?w=KKVQDH_3A2I>zK6nvA=u>*rn#KYaorfWrj7VS@41&qLbZ^^gDp$|O<5 zAx=NI@zm3YU~*rDP@6mjz>)f{fEPGug0aDfP!S@vD>}`h8g1#86+)15brqut2(g#> z`CggjBU@muzwr5A$ZxuCR5))?kS#otpjO$4WpVHFWt0iQph{zv1)qvfBp3}wV;aJe zx&sq`e5~@!OL+J(R8_$Qu$_C)?SsGm;hYg)dWTRy_j2;l_a$?#LI|)8a-w};3T<3{ z1GBFKpe`piOxW4w`K8xml(M!VfSH}Gz_q{-hN$|@iaqjN2_>9l8Im-~*f$HMMg&3h zHnFy;s2k|Cd5EE?$C!*qFTPg2zG_^bi%!+=nv=(n*emU)AZ@A~Xc1R?;(3||r3zMJ zFp%b1w)(BFQq^@?NgX1m`SQN2f8|SnsL331 z5l}$dWIP#^S|D9KdQ@CWY08r^qB@Rw2x~9Da@8Go!gN$>WCg+01U3+$CU21#NG!*& z8O9afd@F1Xa-vEIY?Tq%=5zfP<2(xyXoi4$=Lewg)ZEt8oJL{LWq$mDAEk8&b(J~C zqv3qkxwyHu{?ZGN{*RCBJ9>=Y+_qIrI_XF%o#(u)_OI{cWC~--s?M|A27mskr?2_I z`*0}n8XGz|^}^|uh4T$>R0tr81e`*!wf4r39&p2*RAfBZmVU?e^Lp$<9S^5H3~NY5 zDHo{=#;G;|9MH~i5y8WI#2Qd?0_IMhgQ2l3Ic?aE04~_kiDSjd!|`+~Rh@z%@F1JG zX-br*(b(Vh9w~^c7}7+nkvK4f;6w(a(Nd>hkHc{5t>f39dgZ={uDS6#96JUJ#;rHX z{$=U*CzUTEo%x#|;rv^uqmdE_P2EL-P=O*Ww}cywL(82m&vh{wbq*g0DHf-sUv1r5Nc9s(Wc7A3KmCTv%E1lY>$&?Q9+_%Y_MJ+xI(j!HeyhqZ6k9o#4z*|K`8>uOIx%Z$9(Y-+ksQzxUX0{a2fR`2V09kgF>h zra%X9!IJ>hr2DCRs7S|URSnCm=&f07<#udCZR(n0{Za()S-nfV=A}C{V@zh-(xfH7Y!9xirG#J17XMc$**s4kp z38xhs#ifH7|tS3qtVT+wZZ}`Z$iA3JI!M^QgJuO#S5e1cGgR|aL5f3 znmKzQ0Sj0fy2{jGXJbf!WsY%(P-8g84<8x6c>dJ#Q6YD+9Dm>opF`#%GgBV_VeM34 zY1jE_xk?&da9C><05N(!d+hlBtF9XPDri`opQFim@a7v^=U&54pFpS)JVl=`rmSkLCr^U=Bf4up_X%xJlY#p*|_ex%-J+e^9mSn93yfale$8vG}aVKu4}(t zhB3CvusWF(ovw&@^~NFf{?e0A1Hp4V>vNYbJ^d%& zSo_BR2S4dBF~kBr>vTLuFU4YSe*a?LDLBHHQHyTu6ww4m%~ZXccTg2MMh=lRvNU~o zwLxu=%=dbW`_yn%j&ozGwT+F(pF~xGm|^ofKK+^eT7e_1AoEi3j zISZ%LKwPIeFtLyXfMB85HIM{8^Aq?AFTC{7*Z(w`1j}Y+GG4y%#^Rojqt_Wg1I(2M z^iA*a%pJq5K*wzs+OUx(oo7=VIdb5J>+Iq}$)*lb%DM{pf0g;;oM(+>)HG7&m}G|EW#wE*zJJc(c}HQK8~#8!2+WYsGw<<0!&M9 z&tPf@!D8dw{g|Nevf#y%g`X+WsM zW>t<8JLsmPPNqpJNmk~`u;Yf^q{`FI{QkM+W7xM`_4;+1PGYDyip0#v=N~zZm6g6} zU=q+6{sB2%C6rZZ5TS~Tn%akefWuiX;~gk7R9UxZN#X(4Hj)KShReQjlJt(xp;oEYsa%+;}e_KC-_y@L>VB7`HyKm4UH zyeZ|-QZ2sA=JX$b9p_(1QRQUkmKNja=Z)`-Js-!DFU^Ek;KxBb_fRNUwif2-&sF@ zzQ52vx3OCGJ0JVCFQZ$)rP3rAub3l&r)|j1IzLS+^PZ|TxK;%Li92%l-3vG0vMyM! ze1CD@Qh#2zhZmlH_MzYZ{c!qW_!=6qvx$orX=l);_g*`9;jh2<><@oXUcA^LGx1?F z_zfR+*xvQ!uOi7%6atR$+|V>bpfK93ngrrm(W^}tv}uSv<*})cEz`~r0fQ}$9sR)P zf9cHXO6Yde`Ng`fcoJm^5Xvg4YFt{u_5hn(*xbO+e)i1wzkB}C z)3zD~jokwWM`T{OcbN0IbP}^zCsLV)kCbH==76TpM}0t4j%20g7-KxPxKyoeV|%C&L&i%~0FG#}5B616 z4u?Yt%A91Kd6yMFB1U?bF9~eQ#7rlRR z5f@gVYAtu6vG?guUiaK{E2n?5b@AfCZ0^NJf7CAmUIQ!U7DKY=oEwf+A@1xIb^^bQv4Wj5?YK5Cs`bhUdQbH^t7tsDUF@HFLet z&*p#QEAPAQW*CRsLK#ND0f-QT(19|-7S6u#SO4?>gz>1)cI(1QS}b(Dy!NA?9KGk$ zFf|f_b*;kRm23v+N>KmQBifb8}F} zYJaEa>D@Z7M%YF+N+#MyXRcYvB8SbD0oT=1Run}cllrhpwztZi@893Q<#tO*Mq4YL zBD?u_enUoETRZDJgRLUQvyVL5%eyB&{W)BF3V8<3x%**Hg`eC}XRdlnR5RYGd5`fepbtx3UR9|7*mxhK? zl?dnFxbPqU<4X_zFbi=klTE@cpSkDcum1`XM$z*^R*f~FD_-Y+e$%~Qr-@O9Wkf<& zEd0VR-t^Yyv)}y7*H$+&sk>Q*Iv#S)Y;3&o@PjYj|3DO&EYZxFpmuxY2iv)hS!>hn zC0VjMsz(|Q-g5hmzww*s&vC*5#{07GlJ-iCKulZznr6G28UjP0AQcxuO*WMTL|}ck*=HYl?j;J}SXkJ1 z>Cz>&Fpfeske$JPYZsgy4>x3A=h<_wyyvdZe)yB0$L)8(8O_o$V4GyW0xHegZq45! z{LoCS!~j|Vd<2X^2sn5C)hD0W=O~ExsxhFlMSAP?c+bsX2TEbnMmQ8Kpa21E1^})L z9Q6klhObYSUD~rLsWQyknV0b5Ib3@zuYk!xdcR7D_^_gus!gUO0MSw0dc4 zGM;z2pOkZ1X3FyXqmSOYvuUlOHVGtRdEwSy{B$ohZ#?$of|od{U%LOHowea@U;HJ! z@4Y}>+sH^dR-vL6lifs;B{2)P-`SBrSgtgGbGY-f3tI>7o39Mmz47PYk3W9l+A6Cg zB;D>c*WHT1sZ1AGg8);30Gm0mB9hox;f0r8`SU+N|NS4hYSf+2*D2oe@sHm8)h}Xc z4r0JYEA6E18givUTtjqrISy|+Ite<(Z!18?t_&yp=k{Iwxi6Sub@BfDX=|-tBx@Th zoo-gHt%^|Bx+F=Y!p^0UAC>!TZ)tuGo&LEu&W_gB;@rFzd4BZpd%pMuTy+%;ha{QDx}wz>7#3*GH%G#CsyVqyNkjW-_o7ysRn`DNJj zT@PhxGg{F?2oX?))`%6t7?1quv9JB{*6NzAM@t$yWF!V`Z`fK<%=h6(hyi!L_r$)1 zx~yJ#{7H@)tMa+WPrtc+>8{~g_nwdLWA@_}6g_V#LLyjZdVs3ff3Sb#s`%FWXk+`x z{Qk2K{p9S!r+dA*{>7bSJU)16-}&)ov2Y02-VAccJ2NhYRy+#9z#;})?f9pj{Nexo zwbdt{KGp9{B&>#b@~#iw@Y}zQgZqb@>)nIL05MFY2vxNCw26aeY2>CuIncEKgVX~U zIk%IfnMSoSSW~lYWxhnf0TRJkgUAthYnZ?y((m?EBVBdm_&@vI1D*7t|MaI3f?hvK z6ZRDcu?iZGV~k6d(q2D9dhx9b(lMNOIZwwfT|RZgZU6N5aPm4JAS;G`lDfo^Vmw5V za+CI@MvM9=+y)|Ks1T zPR@?XF^arMv$CvQFWpJzci25G&rZcFb+lbXb(ZYogA0x_+~v_yg@t_;VS2KbcmLIs)a*^@Wi_|*lZ zT>x_~qLTsyla72WlGFe^0X(odc>QaC`r>!)zoXZgTUx%9(Itv?IXJS=N588sf7{f5 znLo7~kV=GjC;`bXC0ImcctRC1*S$C#E`gT!FS%hAHV45Ho_*HV90h7!Vi8~rPF;K5 zKlz=*cRuy4um6cw6JJeMUw!%q|L**akKT9fr|xmL+y<}|ivneY6y%zIl*GX%H+=Dz z@BhO;D&{-Oi7R(@j&%yRxjE0M3wv%dUYnb{^%I{&F&C4(B#?yxs1oBRSw=uW@Obmh zm;demwSDIKxVo{NCaW>kFyILFgsa%>6f`N)g zYZ+l1Yyd$uE)N}iz0-w_MUqv8U3 zlkd6V+3$b%%p;F1rCF?F66-lK;CP)5kt`_>=eI@DVr% zYe2r|*q{akU4}%|h762BjWL6)i73Z#uC&=CB^4FIN?nc%gIGgj1E5Xz>Z|NYNm#Nl zT_D2d_|QEcf6oVA`d9z!@Z}fZdi^z>l)WUejzT^0!RI|5jy7zbEbL!epNzd=-?0OFkL;Ds_F-0hy-`6g#Ah zv2On0hi+|WvA1t)<04ER$zBNh>Cb%;rjKF8MFOtDM!~!*xeNxZ)))@pEQ2?^!?bWk?@vW1;_7!q4L6JJVYu{KQHPvZqFsxUe{FxP`-NO5E;1HN1 z2?(r6qjCg+1M$cqkS3u<9Kt0)-pqj=Mm-9aQtUsDT44z`A~)4|kfupTT|Gu(0L8}R z&pi2!uhTP6>@!I!S_kj)Y+P2yPMt(7VQr(5Tu(;5qC0WA~Tz&RM^Z=fe54!GZ*u|hxl6Rx}PT!Yy9j5YhfC-?SRxWAxUucscxtH%gYBI z`R=#RKJ(Nc;=x8UVrq_^rdsl zE=!VRlW^?4cf9{AU&hV101-(Srhz#&4Bs+Mx!c*0pYn}bf-o6CKnm|cj56A#L;K(R z{)JIxtEy9E8S&!D69@`lq0@om>B6bI0b!Hax2Ea!fiw8P`)}UAbnQL&-2WGURjpnc zZf*{$DhZL;70$SBcbh17y2bMTTW`McnvZ@AH{As1VmUJ1{#43ZVk;xhU;}T#P7wl3 zgAy{dwg3J9fF~dCK63i( zv(K(yy0|_b6{*cSDG`mTdN3NqG%F4tJ#q65cYNeyc+dM$%t_v1V_KV#2(Td~o{9(U z&D}9D8qD8xV}9`J?kM)u3Do#;y|gdOau7;zMBP)yU?7QGJaOFmL1+IyJ3p6LTX%AE z^eS+Q;Gt#;^^81qWCT#KHJM2j(Sy_c)b;y5vfc@?+TJ$Co)McJs zL4If287CNf9ZV>SAU0W5B~gZeSzx0W1uLuN25W3oAOTc?jS>@C0*WF*EeLIa#h0ZJ zr$vHLX&DpBnmqsFt=HX~{L03By86hE&b|8bV!wmHDePclh^!-%3WZ}JO;bXE!X-%y z!(f`_L=%{XK0C1%fk8kNGR8v!Pzo|)s7-@S1CvE$M2J->&%aJuO$qm6TPKHlh(`$6 z+I;hS-@pIQ{@kywU4P_g9&ql}bKUOJtsnWwfzN&lw_S&fr}Z*HH39Ue|K}f^{*ymD z5zTTPJEL+jFUEC6ON-Cf<2!!!A07T@{}ie7LY!nqQdEMqZ9Mz@h0{Mi`@|E&)eAz3 zZhmpNGk^5h-Jk!$;=P~1!UCLwb%D8_4)vLen`yOm+k3KCQCL+i)XWO;P4a1H2dPEy zu&&jb?Q}p;YyF;X8#6sb1ghy$ng9-BR1hO#KvcZ>#^CkWb}nAnSz8-#ZBdL#lJ39i zs{N;~!>MbLWv~V|fpvjUPr@PUKq_K+2D4#sKQ z9Vk&05TZsx;+^*2_~2y)bqGM9rY92%oq_Q+I}c-k4p1nt?Q!W677|2{#K8xMVtEN{ zVNArV{=eG<6oD;|#5I}#(V<54SX}`T(hOu!2Y5lZhkmbwZS>gQeQ%vYJbV%>yuS9_ z|MD;8nKS!*#ae@7#S{sRv2ZCrSL{N3+7_b1=zjDre?Zr5CM^5)MOARF3qw^FOK2aU5Haz%@1e*4<^MK68L6vCs;Oa2cvpe@aaNmFW=J3+WHAk*a2jg@1{qU(D-Jc!V zf9Sn8pLpM`?$mKC6hK6hy!Rs??3_Qp_3R6@zGa+h&YM*^*jah+C+7fOpFcvm}GoVJ! zxhc1aHWaJ7-KlRsVnfn4s;WHenzo0Ip`x~^fe43I91#lCK+;dqxe79ZY07s5<3iBV zOYmA`NlQN2JfNNN~b#kJU*2xBW7qcwMIe+*&y@BzH|QuyBes~6YT-&oteu%V+`qYz*?Y@_0Z?8r^m9=hem z<9B@$M~;Im#wF4$S>6xg)wS(~rMVeU-psgJ;&ct4QeBw0!M9w8zt;B4C`qo`^GUw1Ow(!3E75#rxfD<*K)d8DrU?u$L_Z?|!4E zC<{W6ayaS}k!SU{*3HV!!jKvILjjRE9^0nS zSjV>L)eOZ5h-GCZX3XV?f_^@C__KF^{$5;qZSdGne*DnswX^35To^Ol8BEqUFTU{7 zcx&V2RYwwz7uUCnEHQcN>-w#=Elsog?|*pbFTR(jdCwKAZ(cgOe0U^ft&+_5PTqXe zi4VTl-El3BA3~CX^L7==IuIV0qckg)mgX>ZSJx zuA)!Lioh`HNyu|cKUa35Mua5n+4F4wVb2i(ScimR)W?!LdD$xmZdPsYpmwf}O+pPz0>fay5Hg;^ zA2kSBgCs$kBoLV<=ch*zfe5VqTTMqqRhu{{KnXC2i5M>9jKm_zOcRtSyQ;AtjY(5I ziXdlq2jAPSLxBp$!dQS{9m6pJAU7KZjaFr?sw%0wGTIDkc?GzxYs*IUvi53BPeF(R z1F$R%wE#mb)Ibd>83PLgGHIH3f?td}SCw2!RPEaC+2>w9`@~Z>-u@nwcCGlxb_^YZ zdt`C#^#`xHZZvpteS62$!+jZG0-OZ_TicKP={H6%pEXfO-QQ>3O7I01=z5<6~2okc)^M8{+Sm0;L} zP>O^kN#Fp)vMP-U?y7~}kxzf>i=W1*9G$;#{`nU#zWi#rzLiATJbUiEY8Z@zOM6Kg z%Q`Xn()_`^Gk0OMb!i;B{dBmmt4HQ1R~@_I`Wp`%If|>U!dwrQVF-?txI%~$qA0`W zrjvFOK*p0%k$0(qplQR>AnhZ!t>r0H+IIkuRP3~_1q6tyh?hvnD+C7@jCU|WYlkGy zm70dW_7P8q9}&c0Ml?gZ%dFa%F$sVuUR0S`i7HD069rkg1lBrk{(stlCT%n_%Rw58 zI8CWgTch!i8bYuWTct=Pi3Y)Pu#^PwI|i&eRYrK*fUYJ!v5pPMMr9BMKqE!dTB9fv zHP~N46{1Uxw2EnM1FaZ{z`j%4tZiC`W3Y)0sGE60P+EXVU==|?1Qo;}ibxa?1TaKK zLGYNr3WR5mwB z?x@GkqXJD}_3%|Ee)jY$A*FSioJu38@=`miut-|1L+lZ-;{R@XQNXG2s491JQ( z3iOhE-{$scWmpbI$#{eqU<1U%GEA#%X%#M_;{n0Q!d5y;DK$;s8l2sxB*h@(B9FbZluJuGb zREZ)%JYs_4%HX%sazZExTcfH9RozVuDImmwQ8U+U0+~%`2F~WzHjt=h0ynk?DUo(- z+o>{K@lTjJPdM4 zng_Z#uI42|8`zBjiL$AIR24hh^OJhfCL?DT6{sd{nJI?p>H=0YvUw_y7;T^OU1*0) zr&k3UGCT&6HnIc_^R#V_JA3R62P%M~4-v#*L=glkOHlxua|$xx*fh+xOSAksO{WKP;EcOXHyc!XSswvy z>T0(|oY5|t+^#i^53z^k$))M+hnXG$0S<;?+Vg2w^gWDC)Q~YVSat;%nxeN%8J?ID z1AxOc!=J)XL^qj(@Dv#QF0%H(<(@Jb>!t~WCi4q!SiE*WGp$+hyV^e~TJaD?!Fe+K z{odqzn`M}aOGP_%nxws*B%Blo4e<`hpjoJQr)+9JN=XtL%HmSU4C%JJ|?OmFsNxnTQy{b4n){yUCUa2D;J+{)Z`=x5VY=H&f z4C-`!PE*hWBL7k4PewO(0a58d0 ziFyJ~QF~OS+1y%C@`GVQi46h~XfTvQBH6)UlPLfIAOJ~3K~!eC5wJ;orNeqYO=xoq zWKh>l*jTQwc9W#Mw2~HVtrZ`wbs(}vE}s->3bLG%mQIPPW+1n>535GIw|!bBg$fdZ zY73U3Y4AY1eV>3p8)l`JtGLOy5@6sigO|--m~~`N?SF4?Ow*~|l25al_5!@!+1=e? z6F2Xvb?@?9Hk9~#yL5$#W!H`_8#0%Dnbi^ZW~632qG@9s&-(eK)kSSCO?daBri}zV z>+zpX5zW;Z{Qd8H9_wXfA@96RBaC;mXS4e+4C1EHYxm5;ElJkpRf;{q6WVY`u^aa^ zC3!K#n6~f;p@FnpZTVF=0+yknDOnM`fQ^AOu;WQt@~A?}H!u)V0@QJb|-tfcMDy zNK7EIupZLo-!L;TEX)#fC$z=Nmf>u5*xb(Z1i4+5=laEnVq^xP=ki&H0%QDcPrsM z9ek~+>a>=H*86Neq>R8Eh<(Fm2V~P6wG!IC^kyximQKwGY=oWagNkXjJ9sA4w`b_+ zw3MX8jS0HFcJ)qatlcZo%YWSa$ftbujVe%_RrlKa%k7%~wy`_y!EJY=?LZGxcD>6^ zewzPlsE1&4e=(GjDOcd-5vYykN^^RrDz0B4w#0rYyy z5ENPZPBZ=AyD_XyyG6CRk)??dt*deLfhlp;CP}AGla-y#wc(&M*TYgDSu!%VMr@iu zGmFTmfYQglRX(r;9}sG=AWcyNd9uT{1Oi1?=~-7SXA~<`6*kuEjZIgM-F7*7VdcmF z`rm9;iLr%)Kf*4&_8LrHGYyj@cML-filK2KGXBS zC5f(Y^;UP%7-NT{h3Vvmm|S8pwE>!riM@RjgvNh?(>7jIgV@wy_EuJApP%j_Oe=uR z9&{#P1dVN)O%2q5&5UrbF#^*7VznPWr_g+oB zd=A+wU3l3_zW0dJKgra(+ErOw&q=3Jr1A1YG+Ugm@w_L{H`9IUUO(B)bRXX-zW(`$ zUiM5Ev$;dxe&*Pnm9A+2Ge>>;oObaMyFblF5dk%|%`@Ce3b(Jf6=imxof?pF28y<< z+-%dfAE&=A3KT57k;%D*jr zKT*lCuA}Vlb}hKHHg>bX1lTqm-`t%@5FpPrNxEIzHT9sJl+`F5mAy_r9*^ftvOh~T zhAk5U(}-0?78VyRLWwCN#5AEL(`+4R`1xB-ya*VPL<37?a4T{kt<_DlRAw5BHxDWC z3;~f?111EPnSsR?3eV{b*r^<~#bbrt0q{=s=;>BBZK$(NnE=(d*=h490;wuMB2)gE zCJ4Da3otV;282}@I860(4~X>Ep!AD2tx&tnQ&SE z#*DsrI=Btgn7to(yFD7cTv#AZi)sueB*Y0{?jO%6ks|;yYV+3Ordhga33Ylz-nBH6 z%T7Rlj`#mE#-^sa6Wd%s8z4=;$CUL&X;+!#viMzU;$x9LXylbzTww22`t+fG|eWnarUnB z_D#9RkRq{5hYq|3jnJUNhC&sFgRynR{QP{GxY1xVs%lgLRsbQUE?ba8XhiZNV%3h8 zG9nPt9HQ_wggJFN6d?c+lOgIFKH#U%zH#3p!axNn z(WTuqE$8Q4FbKrV#!z6jBn*NFmX`b7xgMLWtQDm(&?p#h`*JcQ!xh)cu`q`7%p{uI z^vEIm@*n>jQZd3t#R?n2l#-?08u5bIQZ+H{3h~L?DbSjcql`VSuW%%Y5hlP0HIFbd z6dV~!(j+E$dQh49+oZai3X+CQf)z%H8)pBzr&biB5GPAO_uI}muTcbe$BsK!1NN|BjiXf>0Da$gYkhP3N%a$}@ z*)#T!p~nt~WB$m$JTYNA?3f78jAVK!Tbsp^OonD4}HqS402#!6!aYV+W1dS!Ub zi%kg0#Qhq3#{jX2Q@F$KDIu}Uhd2P6UIv@=175#1NGz;8|DaTi!l;shA>DPpzW`9S z$#u1w#F99@^dnG^GASD&R!+n%8zm6bs8|svi4_cC>($vY(VivV+_?Td?=C3?vc@hQ zs#m7~lES+qCysOG5}{48FkJSEriwAfI?ifAzuzAWhZt9w5=;Yc;W8+rZctC475W4t z2nlsS@+kT!`*XgKs={;+nouyBS{{G&*>6Ac{J;CFboPbK)~xgjW5oB%DXVdeD3HJ* zIoRoF)cUMy(nQd2EgB1AW4NZ&0v3`R!OpndnWfgJwh275S#C4bbvsz=*&w-L57T(t zL^VmoAiwc?`~m(gf$T*)kJ?X+pEz$RjVguAFN5xQ#R{_~+Ek-7VNvjEp5+9!vDP0Y&N#eP6!R8A7fqD?;! zjQMgi;zcPrt9S{3v^I5+WF=T(RwBJzC?I7g#zmKir(Pnf6?9*d7{LHgmta)7?M4Y$ zY%5OWGJb0zxj{N#TPG*pT}g?dMq?s07Tp^sWz+GjsSsd9ge9^zR%(kxY*KEM^{Lww z(A|W^jyxyur^Vb+A_+DL$^1Lcor*f|>OR5lSXC04?>L5(-GWY7FEjI9e(^bIm=Rfm zk$Hg-0JJ+Zxbu9G?u{(Uu4;r_^hQZZ6LoGc!Xh+>zmWpqea{!7%GyNilUNa};-u4i zMM{avVk^ciqGNBk>-u}&gyn%Vhl=YVKn=-QoFQziqbO4fEMVrQn&vKdSr%s%$<(NS z>@UB1?w>y6?aH{0Q$**S2XhP#i9F4yibx*F*_+6r)d^JCAn0npUlOYEZc|U#XpAwA z#w%h=nCsS8+v)Vu_>%28vc%+CZEI}>(#wlbhoLV5o0_eY2#pW}B!VPx0O!oevtFJL zj5nIbD#@m#GK)3UB#pM>toM$oPO*Vh*5SHq?dF~UGCy;aS%s8A^POA3An7pri~Kgx zq7?jtjXGs!1~YRMY9o?(GKMrk!Enw62^vF2MnlV@X3*c_*o3r^E%9WglbRXgO~cxe z^%vxwB@tB3ED>zxO!G3aD80hstY}dO*c69$OJ)IFx_-a*1$-T*fkW%2>H%vx6~0AC z4mNn+@e)(L8YvTv4tuk)^_eTn-RUgPOOEmiT)c95@6kEl!>E?lj$;!Y z&0>3GX=OIrWw3F!LLfz<@Dcrl#F%>2mXVv?o%0*nayE-OyIEc7pcgVTO#wi+7gzx+ zge5X!fGm3BSBgw^o5Fl$w8)f5gQeJpJW^@B0oN(iOq98*sxr2#S&v0kb*G;0gz3u0 zI>U^|LZX>9F$C^*?H9>DFsYD|Qm6Ez3w@C*`=I-qCMm%t?%vm;$S+C? zh-FIE^oTE*otXsK0VGqC9f~V0L0Tv~>*^_PJnfEbOrCr0cyAfwQO=+=X{w2{DA;m@ zWrOD{ABs|(EH=Te9wERIX$Q=o7b8H+)Xm3qbusbtEMY{ zi)>s^S67CURtRuSC@C%#o>0M5u+r95nGeS?!e&Sc3$-%Y-W^&peRqB~>h*f2?B}ha zkOG?~NfjC`SeEli-{acr?Vx>`d8r?GJ%kCA+61s;%Dp$DDMlic&eyRv+9rvHsdQEe zscl%23E(!?)ovN!0qPKMV@(wI()xg+AEn$D2PJ{vuZ*Vm23(D z6BD8ihJ%Ktf>~8hf( z{kB&!BQR}pqE5Lqo@Q0is%KG}^ER6V7nv2RFp&-5jj_FQMNQ6XqF6T5*fav~7=TkT zx?d6(FR;RY+-C~jPLiQZR=S(aCxzm z5s=ytnpQ;wNxt#pGWMTp@|8xm~kXYdocRQ()1k(Y6m4uNb6EUfSNZW3l z;NX>e25bi)$@>_ZW7nOz@Z5#H$#js6w+2XHF)WVRDCdb-$w@M=sDA#EO4!T3sr@tt zV5Aqr9SjS5yEmJTLx^gJy*~S1tgA_A8iT$8EO|I6Wojb;Q(!a$EM?wijww+jM4`l% za<(v8VTw%Z$+>FO4qbWbIEJeS%?w|)Ip<;sU9>MEP1}kg=edRoq|s=MX)PpafchjW z`3hM@-B51E(zcv-wXU^Y9W49kT%=5>jc8*#rBJo0ILy8-gvyvoS>OldQo+V)Z^XeH;R=k}hBefTop%-4Iy zw`iLvP?ILXSCk^xmFCy2pLzYgaQRjCc@k$G0oum8t_?umf>6bTJQG72T{7HQ7etvY z4~E|xjdPzjv*~ibrvRL@)-Gk{!q&w?5yh6|4Y4uCn=T_c1VSY-o2)<}a5R)n_NtwF zROQ)t*7ODgbqzUytVF4kort8iZTl7)VoaGaOlE9(oRhZ*$<8LzJX*k#s3TF=$WhEb&qNqaKR80oT ze9ssng=mbitJv>XWar=F;2Y2n#|$i(K>_UyCr-@P*GEVd!Swn@yJUn|Er~J0%BgYF zU=J^mbucS~Y${h<+fcVBZMn9*4LZ*{Ewa-muYt)xHVHF>x(16f*xT!Fn0Q;~CSAG| zw=V?_)70kIo}#=AlNiMHT+xr4IDJidgRk_O`XfgvWCdc7iHN<+?~!+RIo|L z6HzUc)bxs;Il1|s|Lz~|Zf$+-cmFtys%&@STg9|WE}U3eml(JXO&e{3F{V#eFrP^~ zpb1a~5g3h01GSN|mGu*M+*5%j)g)jNF;cY5hPbc1LWYbPr+U&(iIG`kaIga^t>I@c zwbhIaoGQ1$fC}-PIO*S9>A1We7QbwyX#p8kv#N(J8zQK#>p`!-fJGB2GGQCg8a~(5 zG0$3xMV{HRHyZ7f>UzexR-7U**q{@=DnciebBOgAK@N6G(bx!S70Racz98PMs+q{i z+i$z!H+~)9<=_6lcAj{8^4z73WvjC~Q!UEODA#S(gg_RBbMp;|kr+ZOB)njZ{5xU^ z7&TRHO_^D&5Ae1({OGmE;0z!LU5~RHo-+^&VQ_@s!&UQn%-ZQc``^YFcdDxGojh^l zuY3rvxe1P7%+!12Wr9lv3b>rm&12kp> zrf5weCK$T$t#{RfJULg_!8Quz)_|3I0a@fMA`u_Y3=fJ)HF23OitG!Y`m}9nDYDUE zQ=%(S16jhHH}>Fr5J5Aym(rznHuYRP8&ooo_c@irl-Z+iem!1u8c#p{WSC90DUYq~ zDwE9(sA3X{>e==BdG7ZndrA?!>*WQ2R#FV1Eb_FuZi*b$6h#3L)Iu53 z`FsZ>;~O}>ip&P(Ue;H*xrz`d0X8KtuvFm4jo=D( zrDd;frLC)Ru(<6;Y^)*Ws2oxWHt?x6)|0vFKJRlU5`~zJZL4NB8Rtt&r>?o?nTuOV zC@6@?fZN2gR+pxNi9^$0#ULBx(l(bY?>2jen5l%p-0FV!l;3k5dn#-8ek$!N9Zp7 zN512q+qTk?0f7`g!3l)s-MB+xQG-D>C@)syabfcl#|CSwlbB{z*aJnT{`z|UBe!8_ zrqhcrtd~*OYO+e=z10xIbXv0MTQeGsFP%HLT=uMV9XoWqKwVAe;6cX^!OQ}=5F?j) z4}j?nz`)Y-V#;BT%e-PJpofmT;cEE2<%`vHMnMZ-XN;af&gxx4=0KF9B}0@VK_Sov z*2DQkX{KQigA+cHFYT!|)}e3_#Kx#66Bw?5>mVh1)qTG3+1_N#5xrigl+CM~o2TFW zrq^6|EuavAb0EgFMpod|DX8McGe7n-Ki%Irf_et25hfV+APMKrP5%1PXTJ03=+YKa zkivD7f3FBB{XQdTswyQ(DMmr-D0sjtcE|tnpZpKYF_dvnQtkSKwY%;*^7sDUsatOP zqkr)){rOAvPF>Yee6fDh4Y$7UzH9D&JtQ_wO-+@2L7ddusM>~L=nzh?gmS5uYKc|6 zc<~})!p;ayqqCOCtKr>@m9W&XZMqo-L0iKnoEl}c@#(KKn$5C-fESf>gh zga~ix>iRq@Oq3p*EX(#rd%oWX;Zm5L{_%IA$S_=*56)T(6|e;}*ua|p&pv<{Apva# zN-&C;(8S{T^Or`uJ?D)vk+rHC;zP_%vLegOteW`3G#uHxRvTCWiQC!hPujtBXSv8P zeed~Mlb!m-U&Gey$alB(yJv^uY_W8%+Mc%Qn*ZnnXw#BVmc-|IijB=_9A~!7LnUBy zn0z(X@e*?i#txXi{G0!D+v0`UZ1cp)uv4+mc31+zD0Hv7^~lNR9{b+%^7;j7uKkI( zy!lst5l=qdBkyKy#x59XI$lYE7eq$4Uz7p%Fg@17+0+VcPuL9Lmr*4Q`Y;T3Sld7{ z*qZ?b1b~GB`UAKO(qJ$^Q$rQUHmbInyTv}Jc^@%#U@^8If_38YYQP3{Ot~eOWspcw zpeB*KQQ<811rD#CNt;AfnYrUs%zZZ6-oYn69m;H) zxhW8w_2pn(&m`%QGdHfk=?zU?ef5t%e$-}JRp%0&N2;f`saDvWed=tl*DDiECwuCs z=W~sRI?04%GLjOLIu(ORsiSBtqLi~xRH;PL$WRYqs2(MsqG{@++V+A(VYG@?Y=RXr zETGhhgo#P5O;*h-O0|BU5yZFATXvbHM$C3S4bAn(j=b~UcjDR`p8d?{KKtb_-}|<= z-14JuK@ zjfc7SF=TDXl8l~t;n>p9rB0q^zMd-w8UOBBT#R&BYmgFR#O|(aUHGH_^S5uk=0q5c zcDK(TU0Y_x-gvj4FG=tV`1wItMGkizh8dkbo5z&9)SSO~{&#wIG@pu;+!j)9X$ zaPvJlbH+UK%wYB0Lytap%ZJ~N@%Z%JZ+Y^Y-;P$7P9590<8?^!>4zWIx;8!wsTIdU zZ~~*^B12*4Q?!RTSB=U>(JNgMTdlWe&px*`wtQs$*lSMTY&NgQGtYkg&pto<-i4p~ z!26dr*1q!fFF$jBm(D)F!nPTYa?3d+)w97Mf79maol9E`S{P2^b$Dh^hEjQUkFSkg=Yz*s!GbK9c+~FawV+p;s9!4S3cG{f({9kOf ztvcVcJ!*{=C`sjH>QiF{kSyAA$5=IW*;b|v(<%=k2V)$^Uwn9~cH)ZF*W7$fz5 z8#>mje$FFvzO5^b$q>gjWQFE=zO%DKy|OGz_P$Nh5gGS-JrO~aIIH`4rn3kp0TRI$ z*k+&?&0`7h>#BqUgKh!bCiULNX?ntA;$MW7%kQc_Y_{>>*^O?;z zzp?(z=R=V5pZWCB`|i8#9q)MZufDZw(_7wp50-|waPE7Euyb*z&xRo^;-ni@ zfC`F;z<329@XMPJwstOM)?3a3xd>W6a_sioZ(n=gdoY=O<&&R&@WBUH^K$9+ugB)b z@az*0eeE0N_T=c=F*aG8Ol;{4cyDW4i>yP%E6tCvS3|||Los%j(+@TbNf?wc$A01i z|G}63&A%~Q+c&MRHkZzurrPWmdy`$s^T;o+@bS05S`iz>k*VuurRYmtFFRk)+S0LY zlod)+w&*w7SP?=N!)hvx$X-=7s09Hf+sLtvE14aQoBoldx4ip3SXlw28IQ8n70^}o zd82SqT@YtsvV0c8BsOu7)t2sl*L_Fsz6*u}s~BI0*dGi`ua6x0i6cMtkABtEb>A>+ zYpf87Ubyh(kNwHy(Wd}5#u(yA>Wf^09Q@o+0@$dsfHftf@WNn=UhnoFeQU3(Lte#L z_mbz6r}Wr53b*;LH}`i&%`7PwrSr4G(&jpxZ`dguDU67Ns91_NN<7rFtt62fI0`IH zn$Rq7l(Ay@+UsBY&Ug0T`X;Olny0>( z9Y6AxpZ*ENfIcwbYu|k5tzkB7=~&rsCu3@68-rr|*=Ha7=GR9lW(uRSm>>kFeS)LI z+@Py$9Ui#tSY9|W;=rSlupa;b8#PHpK~#|Q28Qs!J9`g(`P^5ww$K=sj5V>U(ZKE1 z^LYgd<1N|P%t%w-gucrrq4i0l%DxV59uXO>0Vxw|^-L~Bq=uz2=ruMeT8YzPdGy`^ z_!^dSwwjTeEK6zf%(M9Rw{X)9Z~gl}{hbg0lkF#;`2W7~5cVd6o36kA zrys!S>+r<6$3Ok0<$zd^DR-?Auj0~N#H?`u*d?;kv3(ultZ$ksTB;yp#G7xtuK(Wq zQT8Fou0M0v`Z25wF&o1}+Fa51eq# zDTv_gbC}Ig^fBH;p1~+)Q|#_aOqLDBM2c=q^F>M|f0xdAM9>r#um#{SBT6s=4-06( zUH9De?8QHS;o{!TZbq!hL}ie>dhbAi7B(8*$VOp!)Ga;iL)RD<16p;}usU}7w zvbh1oY8)u{5}Ahj4TAG4M^|rt$6Imh^=cBa^MMp;QcX;;cGZ2JK}DXA_omY}xT4I8 zJUCAwK6m!Hho3lW%W`ivW78>?^DXaq>+SEoza8y;><>S7ED~?+3^U(bDn^q_DFqwD z=JLwy;w2(;Y<+`AyG_${D)I+3Qh`J!WpatUQLkMv-qauc@IUsknJ&rhXy>F^x#r9r z_x#d_aKq+D|J&bO(J;F(omSBfR^ySCANvQtuzBVdqsh)Wb9kXp!Re4-W(C_k8(o+V zS#n#{61;UqpxIva+_#^&=1)Jn^1&Zpe)~IL|J|+6eCpHh{LqJb@4gRpz*oNU;P3sx zb+*_YPnI{9Vw%{?1J0UQIx-SrmcsynyP2QTmbopZW98{mI8A1(wv$eYJC`&%B(OdS|vV97w1;x}3{A%GAve zAFhJ;l0E&(1VOH>-@fX)pjq%Y0>&V50#SlDxuR|HwtKHXd-mZ!{RG;$xwO{ojB@YI zJ}X0qdQwu-E5-`uL#T6NnZ?_mbGp7YY-bYVQ&xc2(-XqSCfgUMK3T8YNSq}KY2F~RbL5evV)Q>_h`M|G8~-7yT~2fbpe z4W=kL>2_UH=CzSSecDFjvQ2x{v~Em_W-rjxxOE%R>=b(!j@Gf=3rFj=XWYnt57(_h zcT1}3?>=^%2cGiX(esZ@&YGnU!tau)q4gxSM$@v-L#vGh%8j;%2wYj1r&x7E1ZZfp zHd0VES&(Fezy7(;zkWDeec$^|{q)cL*xTQJ;z#aAsPSii`i1}FxAUAQ+NJ`44&mBa zO=N{2BwjEGp(~y#^FlxFK&D_32iqSt5(AD=X4RM!vbJrj<~aEmb|)8|+S%EC=;6Iq*!aFTDO4on$q+cisAR}9AXr5_iFlnX|LZ1+6<*?-0s~RY|%Uo`pEWK{$absF2spo5ZY2t+q*&*g6Z#Lalcx z)B%C4DU)VXg*|>Ef9);!`#+0bmdF6Mh4F-8Zw-NQ)q8c|ND+B%2K~zNSlgwO$M5{W z`|dn>3dA5rR-lcY9GSGjCywZJyt=vhYybIg3~i1G)Kf?`r`_$9c>etP&wlaAuYF^* zHz}Mohdeh3+BOqOftj;%$@iAB;Q$0^;7|>Ootl8m!0ss_RIu%O*{fT@XdCML{c>$B zvnGK8Y4nz19hAjrKnh5tZ0V5LHzBAMHktJ$w^0xfBMD--@bq(k{5!w*^Vi(Kcinm7 znrm7z-}&>;KmF0)4`-iQAFk}BIGRmriG80HzAv#=2#86=rv=cxJ9Z9?7ZBpT5GR>4 z*KYQ#$#w)mDNx<$nQJGWQe{L@Yk{Ic2rpfCmr44VT1h&X-2&A;$-kEf43 z@!+4ISza2AwlYKqPK3-DYkebe)>iOVNfIm2(Ypw%3ZR^@9}mtsjOFtFMIxlSPcA@` zST3`?D+>|8M%YHNY@Ky*5=9cFBuSAj?p{1`^k|r-X=2-3+L|>h*PXcb*Z&ig8N7+G zfYE&}N#Lquaw4O$5?tIZ5V;+haCEuAb;oeWtpLM0kVQhGqZT-x5}lXw^C5Acr_Qgn@p)ZK|na+O~|aH*Jo!f~XC6loE#+>ew^h z2%{wwOS21Y5r(T-Zoy;aLLH`x(l6l+3W%IwMi2o6@w-cIBS6x2r+1C zO7_+ukt8|vEq(s!XMEY~FAdn*pxA9Ivgofaz2WtDuHAn>e2#t}&pdtZ;YT*#^k%!Z zao>kOjL&}VE1&+_N3g-}QIt@|g};lSZ!II4JW(aR74!>|ku zC>*5#ZBb8|qSvKGogtxK4BA${>mML>Fy z*wNvPUal6PKr&{ARNBmPi>kssciqOXRRc3G=AXj zbSCLoQo~CMPFJ|P0NQywzy_k=2q&<*kT5k!N+5`Lpb(^KLF9}QsltIBxh&=M-QCHk zm%rvGAGr2se+DNvUW6JaV`n&F2fAhU~?uD;@>`$`2dfj9aYm{zlbg?%m&xW>aQ%__l#G)xR zqQZs`{tzYNX_DkKElQ*;TC*b!q@LRLJ^%Hu43(mZ&UmDv^1iv@Xaqj+KmPZ4>O95~ zLNJ6frq^8$aOf3H=3=N35m&1ar?qPnzQ zZSQ(EDh%yZWC0K>x={b%pO;lxHQD*6o`3xJKaqXvFX)*|rOiXHm_n0xO;7|0W%iE$ z^yjg8Z2D(k{_8J&sSQ(WG{!)Ju= zh30mrU%;|YC(23-J;g<-Z%!!CEnWbyQ75o*P6`~8LE;#VIO}57a+`ANym2WdX(cF4 z$UIwB;rNl;-uKRv54;E0om6&vk_z&j!_SL}`$VQ!JGLhUhs05eEKiA2D-40mdTm(B z23${_vNb-XR8>ts(Iy$Fz}qaeMN_-bwA0D*+Hx8T3#r!cWhD};d*VnQ*%sT^D)0UE(GLmnX#k#S6Lh)hI= z2!dA9VcPQ`U^?10S*}K3``XuD^D{q*d+vg>&l7plL*pOk|KD+nYEEjXeBhU zg1jJ!Hc#F6b06gQzYAV#b~CsMs|7La9CbwK09OLIt3P9dpiq$<8dGdz%ibHyLsv?u zGZGKgShFgTxY)FNTd4O??GBboo>bh1rOY{ro5PhL0lBxLfYd6Lr`8+sY-Z`;b7M~6 z>SRpJLbEJ>!~0_u;rt9vk_)(u4PfUhNwIF(+8h?Ki|sGdX6WL$ zJM^-yrp*fi`wZTl2NJ5L$+OJDPeWC>62#&QZ-Cd{y0N^(M~^@I)vrw+f2yrU1`q)$ zn}z&&BvOh(7AjC$$Sb_a-Iequdmk%|Dyt|2Dk4!iB@rP3Nvo=W8dAe4q6L}$60NQe zHc#FC%fF1*orX#*mL@PGGy@C-_VUa>0LH$4)K#CcK`(2jNgYH1Zz;ERY(t9Hd1f$6 z2*DcTN<$i_`z4kCf3a?%^VxzA)Gc%odPz7ldpdI z#F35V=PtD4aWU)@SR{p{PMxz}4^yF1!V9|>H&31#KrTFg?$O`-gZ^hffA-w@i(6YN zl1nJ8@l4dzG1dKoceYf{dZ1ibA4@Nd3n6O)wABHbTdC!C}-)R zJf9RK;pa!2qw=8e5+qUtimHY42N)EN$&pPe13|mOynqOV*aQbWABJ zsTc!6SAUjH15;>!RfqQZ{f68=wCAM)g@>dDx%?j&A&|LJ&qrYh!z>#$O_60wZWs_5 z&U(`{(@Y&sonHT`YgX4zJWQV$Kk~?UGSLu9YZ-B|yiSOx6X{~XoGt!}!2XrrDJOvn ziBUlkJ68u_=X~oWke{&|Lz}Ev+1wmncjHaJ_8V9ppy!aA7Oda_yoGU{HtfrlKmzURI|NU6d9&v{tvU#_*ocptRI#5#U6W&=`rPt9D2cVMRzGERBVr zQ=~ZfVXk-z?ntkFx+*qm{y1(q|NfVDtB}j2>qP;Me zUh1L`;Vz>)+%qjC3Qoj{jF3%a7U_W)6@$PUoJOm`Xl&U}eLt}8v)b{^Op^p4#A+B<*jUHKb+1g?a& zFbqR2ID$Lafxk>IKIherxFWXS=TZ9ietlV96q4UHJ#mEW{m2 zSYT8-iJPPVX&^f6`aw_zrY7|Ae1wMFD*9^{~PT zWT6t>m70vQs4kAvWQ8&jC&(g{5Nt|aF5LMx%@ueAmy!1SqSu`a^`Y)h$Ah$g?S2Zu zFm-a6LP$`kLgkS9l-R#t`#QN;oYY2P=tYli7b-JbQOf|F!?6?ik$Z36SU>ZlZ~oH9 z|G3?{AbaCg!qKJvpx>iO)3z}=BVM4Su}lM*4NM4})t^FF&ogpOjBNDA-BIwM}l zNJ0abygyfkJu<^PZoTvVcMk7;12)!RoWcPtUq)Ht?k+pO6q^eLAN-X7|Y*S20Mkz@QiI{z^S=qSk)NOZcyzOnc z`*s{#L+)xeRW|_)WZl6Y7x=`5tK*8P%Kh!o8h_P@egM)g_P*@%borm;CAl3bfl?LWrJ8 z4GDq4%pjpo%MT!9nGFCYogc#;SXxQxz;k1)pww-^Oau@t?aR_K=0j;j>gEBHl8y5k z?-hkHA_BA9mk%`P#6R~Vi34MV6qSPl#=#e4xhBOaOM>OaO6f{WGGBK1v@fo{kHf3l zLufF(3VR7I^0JWo%YAV}*dr*Tmyjte0gBMoKonNs6NDuIGsd0+fMLtofyEmVAs7*o z?tXJOkQ|8@5NPfa4V8psH9CdYj{LOy9%-(tOB4(Th7c!0r|!6bOdcYa?j$ReU`0%V z6EO;#x*khM4$qM|G9q(e7}X+O(WkhgEJQ?C&ZsJNKOl$GW=3Qtz%~F7jTiwUiij+T zVa#&W8KxejNC{Rtb*9t*vdhG+5bOJ8|OV@P?auue}AY zxdqGXFb>8db@Rz4Gq&T$Z08DGm+SLbB=E`z=+LKEbRr4%^o=(j<}MxDUaVUCqTBub zR$J`m5JE2?UywHnV+HY7$ab@bBXH( zmz?cNhsj=UFU|8kf+z5cTPjz{r#ehcZfZ)tN4<_$$U47i>blT)}d9h1&mMqepknOHI0Ai zamswi_pfrWK@|tF+AvEE9=(Y?O*>t+xFLmVN1l400000NkvXXu0mjfhzIH& literal 0 HcmV?d00001 diff --git a/acs2/nladmin-ui/src/assets/images/miri.png b/acs2/nladmin-ui/src/assets/images/miri.png new file mode 100644 index 0000000000000000000000000000000000000000..fca2d587730625c891ad9ef36ca952e4941fdeec GIT binary patch literal 997991 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⪻{{h@78l6XV2@3paAIQ@YPB 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 + + diff --git a/acs2/nladmin-ui/src/views/acs/device/driver/agv/agv_ndc_two.vue b/acs2/nladmin-ui/src/views/acs/device/driver/agv/agv_ndc_two.vue index e69de29..867afad 100644 --- a/acs2/nladmin-ui/src/views/acs/device/driver/agv/agv_ndc_two.vue +++ b/acs2/nladmin-ui/src/views/acs/device/driver/agv/agv_ndc_two.vue @@ -0,0 +1,114 @@ + + + + +