| src/main/java/com/zy/asrs/controller/AppVersionController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/asrs/task/handler/AgvHandler.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/common/constant/ApiInterfaceConstant.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/common/properties/AgvProperties.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/zy/common/web/RouterController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/resources/application-dev.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/resources/application-prod.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/zy/asrs/controller/AppVersionController.java
@@ -12,6 +12,10 @@ import com.zy.asrs.entity.AppVersion; import com.zy.asrs.service.AppVersionService; import com.zy.common.web.BaseController; import com.zy.system.entity.Permission; import com.zy.system.entity.RolePermission; import com.zy.system.service.PermissionService; import com.zy.system.service.RolePermissionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.util.ClassUtils; @@ -22,10 +26,15 @@ import java.io.*; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; @RestController public class AppVersionController extends BaseController { @Autowired private PermissionService permissionService; @Autowired private RolePermissionService rolePermissionService; @Autowired private AppVersionService appVersionService; @@ -57,6 +66,7 @@ public R checkUpdate(@PathVariable("version") String version, @PathVariable("type") Integer type) { EntityWrapper<AppVersion> wrapper = new EntityWrapper<>(); wrapper.eq("type", type); AppVersion appVersion = appVersionService.selectOne(wrapper); if (Cools.isEmpty(appVersion)) { return R.ok("已是最新版本"); @@ -220,4 +230,23 @@ response.setStatus(404); } } @RequestMapping("/menu/pda/auth") @ManagerAuth public R menuPda(){ Long userId = getUserId(); List<RolePermission> rolePermissions; if (userId == 9527L) { rolePermissions = rolePermissionService.selectList(new EntityWrapper<>()); } else { Long roleId = getUser().getRoleId(); rolePermissions = rolePermissionService.selectList(new EntityWrapper<RolePermission>().eq("role_id", roleId)); } if (Cools.isEmpty(rolePermissions)) { return R.ok(); } List<Long> collect = rolePermissions.stream().map(RolePermission::getPermissionId).distinct().collect(Collectors.toList()); List<Permission> permissions = permissionService.selectBatchIds(collect); return R.ok().add(permissions); } } src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java
@@ -23,6 +23,7 @@ import com.zy.common.model.DetlDto; import com.zy.common.model.MesCombParam; import com.zy.common.model.enums.WorkNoType; import com.zy.common.properties.AgvProperties; import com.zy.common.service.CommonService; import com.zy.common.utils.HttpHandler; import lombok.extern.slf4j.Slf4j; @@ -122,6 +123,9 @@ @Resource private BasDevpMapper basDevpMapper; @Resource private AgvProperties agvProperties; @Override public R inLocCallAgv(CallAgvParam param,Long userId) { int type = param.getType(); @@ -159,23 +163,33 @@ locCacheService.updateById(locCache); break; case 3: // 判断条码在wms不存在,是空托盘 // 已组托 // 判断是否为空托入库:检查条码在wms中不存在,确认为空托盘 log.info("开始判断是否为空托入库,条码:{}", barcode); // 检查是否已组托 int waitPakInCount = waitPakinService.selectCount(new EntityWrapper<WaitPakin>().eq("zpallet", barcode)); if (waitPakInCount != 0) { log.warn("条码组托档已存在,不是空托盘:{}", barcode); throw new CoolException("条码组托档已存在:" + barcode); } // 有任务 // 检查是否有任务 int wrkMastCount = wrkMastService.selectCount(new EntityWrapper<WrkMast>().eq("barcode", barcode)); if (wrkMastCount != 0) { log.warn("条码任务档已存在,不是空托盘:{}", barcode); throw new CoolException("条码任务档已存在:" + barcode); } // 有库存 // 检查是否有库存 int locDetlCount = locDetlService.selectCount(new EntityWrapper<LocDetl>().eq("zpallet", barcode)); if (locDetlCount != 0) { log.warn("条码库存已存在,不是空托盘:{}", barcode); throw new CoolException("条码库存已存在:" + barcode); } // 通过所有检查,确认为空托盘,设置为空托入库 ioType = 10; log.info("确认为空托盘,设置为空托入库,条码:{},ioType:{}", barcode, ioType); break; default: throw new CoolException("入库类型错误,type:" + type); @@ -186,15 +200,47 @@ throw new CoolException(barcode+ ":条码存在agv搬运任务!"); } // 根据whs_type选择站点和机器人组 Long whsType = locCache.getWhsType(); List<String> targetStations; String robotGroup; if (whsType != null && whsType.equals(agvProperties.getWhsTypeMapping().getInboundArea())) { // whs_type = 1: 入库区,使用东侧站点和Group-001 targetStations = agvProperties.getEastStations(); robotGroup = agvProperties.getRobotGroupEast(); log.info("库位whs_type={},使用入库区配置(东侧站点和Group-001)", whsType); } else if (whsType != null && whsType.equals(agvProperties.getWhsTypeMapping().getCacheArea())) { // whs_type = 2: 缓存区,使用西侧站点和Group-002 targetStations = agvProperties.getWestStations(); robotGroup = agvProperties.getRobotGroupWest(); log.info("库位whs_type={},使用缓存区配置(西侧站点和Group-002)", whsType); } else { // whs_type为空或其他值,根据type判断(兼容旧逻辑) if (type == 1) { targetStations = agvProperties.getEastStations(); robotGroup = agvProperties.getRobotGroupEast(); } else { targetStations = agvProperties.getWestStations(); robotGroup = agvProperties.getRobotGroupWest(); } log.warn("库位whs_type={}未配置或不在映射范围内,使用type={}的默认逻辑", whsType, type); } // 将站点字符串列表转换为整数列表 List<Integer> siteIntList = targetStations.stream() .map(Integer::parseInt) .collect(Collectors.toList()); // 判断能入站点 List<Integer> sites = basDevpMapper.selectList( new EntityWrapper<BasDevp>() .eq("canining", "Y") .in("dev_no", type == 1 ? Arrays.asList(1003, 1005, 1007) : Arrays.asList(1044, 1046, 1048)) .in("dev_no", siteIntList) ).stream().map(BasDevp::getDevNo).collect(Collectors.toList()); if (sites.isEmpty()) { throw new CoolException("没有能入站点,type:" + type); throw new CoolException("没有能入站点,whs_type:" + whsType + ",type:" + type); } // 获取没有出库任务的站点 @@ -228,10 +274,12 @@ .setTaskType("agv") .setIoPri(10D) .setStaNo(String.valueOf(endSite)) .setSourceStaNo(sourceSite) // 设置源站点 .setInvWh(robotGroup) // 根据whs_type设置机器人组 .setFullPlt(ioType != 10 ? "N" : "Y")// 满板:Y .setPicking("N") // 拣料 .setExitMk("N")// 退出 .setSourceLocNo(sourceSite) .setSourceLocNo(locCache.getLocNo()) // 设置源库位编号,用于AGV fromBin .setEmptyMk(ioType == 10 ? "Y" : "N")// 空板 .setBarcode(barcode)// 托盘码 .setLinkMis("N") src/main/java/com/zy/asrs/service/impl/OpenServiceImpl.java
@@ -61,7 +61,7 @@ @Override @Transactional(rollbackFor = Exception.class) public R agvCallback(AgvCallbackDto param) { log.debug("agvCallback param:{}", param); log.debug("agv回调 param:{}", param); // 优先使用taskId,如果没有则使用id(向后兼容) String taskId = Cools.isEmpty(param.getTaskId()) ? param.getId() : param.getTaskId(); if (Cools.isEmpty(taskId)) { src/main/java/com/zy/asrs/task/handler/AgvHandler.java
@@ -12,17 +12,19 @@ import com.zy.asrs.service.TaskLogService; import com.zy.asrs.service.TaskService; import com.zy.common.constant.ApiInterfaceConstant; import com.zy.common.properties.AgvProperties; import com.zy.common.utils.HttpHandler; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** @@ -49,15 +51,15 @@ @Resource private BasStationMapper basStationMapper; @Value("${Agv.sendTask}") private boolean agvSendTask; @Resource private AgvProperties agvProperties; /** * 呼叫agv搬运 */ public void callAgv(List<Task> taskList) { if (!agvSendTask) { if (!agvProperties.isSendTask()) { return; } @@ -99,6 +101,7 @@ success = true; task.setWrkSts(8L); taskService.updateById(task); log.info(namespace + "呼叫agv搬运请求参数:{}", body); log.info(namespace + "呼叫agv搬运成功:{}", task.getId()); } else { log.error(namespace + "呼叫agv搬运失败!!!url:{};request:{};response:{}", url, body, response); @@ -131,19 +134,34 @@ JSONObject object = new JSONObject(); // taskId使用任务ID,格式:T + 任务ID object.put("taskId", "T" + task.getId()); object.put("fromBin", task.getSourceStaNo()); // fromBin使用源库位编号(sourceLocNo),如果为空则使用源站点编号(sourceStaNo)作为备选 String fromBin = task.getSourceLocNo(); if (fromBin == null || fromBin.isEmpty()) { fromBin = task.getSourceStaNo(); } if (fromBin == null || fromBin.isEmpty() || "0".equals(fromBin)) { log.warn("任务{}的源库位和源站点都为空,使用默认值", task.getId()); fromBin = "0"; } object.put("fromBin", fromBin); // toBin使用目标站点编号 object.put("toBin", task.getStaNo()); // robotGroup从invWh字段获取,如果没有则使用默认值 // robotGroup从invWh字段获取,如果没有则根据站点编号判断 String robotGroup = task.getInvWh(); if (robotGroup == null || robotGroup.isEmpty()) { robotGroup = "Group-001"; // 默认机器人组 robotGroup = determineRobotGroupByStation(task.getStaNo()); } object.put("robotGroup", robotGroup); // kind根据任务类型映射 String kind = ""; switch (nameSpace) { case "入库": kind = "实托入库"; // 判断是否为空托入库:ioType=10 或 emptyMk="Y" if (task.getIoType() == 10 || "Y".equals(task.getEmptyMk())) { kind = "空托入库"; } else { kind = "实托入库"; } break; case "出库": kind = "实托出库"; @@ -156,6 +174,31 @@ } object.put("kind", kind); return object.toJSONString(); } /** * 根据站点编号判断机器人组 * @param staNo 站点编号 * @return 机器人组名称 */ private String determineRobotGroupByStation(String staNo) { if (staNo == null || staNo.isEmpty()) { return agvProperties.getRobotGroupEast(); // 默认使用东侧机器人组 } // 从配置中获取站点列表 Set<String> eastStations = new HashSet<>(agvProperties.getEastStations()); Set<String> westStations = new HashSet<>(agvProperties.getWestStations()); // 判断站点属于哪一侧 if (eastStations.contains(staNo)) { return agvProperties.getRobotGroupEast(); // 东侧机器人 } else if (westStations.contains(staNo)) { return agvProperties.getRobotGroupWest(); // 西侧机器人 } else { log.warn("站点编号不在配置列表中,使用默认机器人组:{}", staNo); return agvProperties.getRobotGroupEast(); // 默认使用东侧机器人组 } } /** @@ -231,7 +274,7 @@ * @return 是否成功 */ public boolean cancelAgvTask(Task task) { if (!agvSendTask) { if (!agvProperties.isSendTask()) { return false; } src/main/java/com/zy/common/constant/ApiInterfaceConstant.java
@@ -33,7 +33,7 @@ */ // public static final String AGV_IP = "http://192.168.99.130:80"; // 测试地址 public static final String AGV_IP = "http://127.0.0.1:8080/yhfzwms/open/asrs"; public static final String AGV_IP = "http://10.10.10.200:8080/agv"; /** * 仙工M4 - 创建任务(货物转运、实托入库,实托出库) src/main/java/com/zy/common/properties/AgvProperties.java
New file @@ -0,0 +1,102 @@ package com.zy.common.properties; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; import java.util.List; /** * AGV配置属性 * * @author system */ @Data @Configuration @ConfigurationProperties(prefix = "agv") public class AgvProperties { /** * 是否发送任务 */ private boolean sendTask = false; /** * 东侧配置 */ private RobotGroupConfig east = new RobotGroupConfig(); /** * 西侧配置 */ private RobotGroupConfig west = new RobotGroupConfig(); /** * whs_type映射配置 * 1: 入库区(东侧),2: 缓存区(西侧) */ private WhsTypeMapping whsTypeMapping = new WhsTypeMapping(); /** * whs_type映射配置内部类 */ @Data public static class WhsTypeMapping { /** * 入库区对应的whs_type值(默认1) */ private Long inboundArea = 1L; /** * 缓存区对应的whs_type值(默认2) */ private Long cacheArea = 2L; } /** * 机器人组配置内部类 */ @Data public static class RobotGroupConfig { /** * 机器人组编号 */ private String robotGroup = ""; /** * 站点列表 */ private List<String> stations = new ArrayList<>(); } /** * 获取东侧站点列表(兼容旧代码) */ public List<String> getEastStations() { return east != null ? east.getStations() : new ArrayList<>(); } /** * 获取西侧站点列表(兼容旧代码) */ public List<String> getWestStations() { return west != null ? west.getStations() : new ArrayList<>(); } /** * 获取东侧机器人组编号(兼容旧代码) */ public String getRobotGroupEast() { return east != null && east.getRobotGroup() != null && !east.getRobotGroup().isEmpty() ? east.getRobotGroup() : "Group-001"; } /** * 获取西侧机器人组编号(兼容旧代码) */ public String getRobotGroupWest() { return west != null && west.getRobotGroup() != null && !west.getRobotGroup().isEmpty() ? west.getRobotGroup() : "Group-002"; } } src/main/java/com/zy/common/web/RouterController.java
@@ -51,4 +51,13 @@ } } @RequestMapping("/rfid") public void rfid(HttpServletResponse response) { try { response.sendRedirect(contextPath + "/views/rfid.html"); } catch (Exception ex) { ex.printStackTrace(); } } } src/main/resources/application-dev.yml
@@ -68,6 +68,28 @@ Agv: sendTask: false # 东侧配置 east: robotGroup: "Group-001" stations: - "1001" - "1003" - "1005" - "1007" # 西侧配置 west: robotGroup: "Group-002" stations: - "1042" - "1044" - "1046" - "1048" # whs_type映射配置 whsTypeMapping: # 入库区whs_type值(对应东侧) inboundArea: 1 # 缓存区whs_type值(对应西侧) cacheArea: 2 # 越库配置 cross-dock: src/main/resources/application-prod.yml
@@ -66,6 +66,31 @@ # 右深库位排号 doubleLocsRight: 4,8,12,16,20,24,28,32 Agv: sendTask: false # 东侧配置 east: robotGroup: "Group-001" stations: - "1001" - "1003" - "1005" - "1007" # 西侧配置 west: robotGroup: "Group-002" stations: - "1042" - "1044" - "1046" - "1048" # whs_type映射配置 whsTypeMapping: # 入库区whs_type值(对应东侧) inboundArea: 1 # 缓存区whs_type值(对应西侧) cacheArea: 2 # 越库配置 cross-dock: # 越库入库单类型ID @@ -74,4 +99,3 @@ outbound-doc-type-id: 36 # 虚拟库位编号 virtual-location-no: VIRTUAL