src/main/java/com/zy/asrs/controller/DigitalTwinController.java
New file @@ -0,0 +1,967 @@ package com.zy.asrs.controller; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.R; import com.fasterxml.jackson.databind.ObjectMapper; import com.zy.asrs.entity.LocChartPie; import com.zy.asrs.entity.LocDetl; import com.zy.asrs.entity.LocMast; import com.zy.asrs.entity.digitaltwin.*; import com.zy.asrs.mapper.LocDetlMapper; import com.zy.asrs.mapper.ReportQueryMapper; import com.zy.asrs.service.DigitalTwinService; import com.zy.common.utils.HttpHandler; import com.zy.common.web.BaseController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.core.type.TypeReference; import javax.annotation.Resource; import java.io.IOException; import java.text.ParseException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @RequestMapping("/digitalTwin") @RestController public class DigitalTwinController extends BaseController { @Value("${digitalTwins.jgUrl}") private String JG_URL; @Value("${digitalTwins.djUrl}") private String DJ_URL; @Value("${digitalTwins.ljqUrl}") private String LJQ_URL; @Resource private DigitalTwinService digitalTwinService; @Autowired ReportQueryMapper reportQueryMapper; @Autowired private LocDetlMapper locDetlMapper; /** * 数据总览 * * @param areaId 库区编码 * @return */ @RequestMapping(value = "/overview") // @ManagerAuth public R overview(@RequestParam(required = false) String areaId) throws IOException { Map<String, Object> map = new HashMap<>(); if (areaId != null) { map.put("areaId", areaId); } HttpHandler.Builder builder = new HttpHandler.Builder() .setPath("/digitalTwin/overview") .setParams(map); ObjectMapper objectMapper = new ObjectMapper(); if (areaId != null) { switch (areaId) { case "A": { String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 Map<String, Object> data = (Map<String, Object>) result.get("data"); return R.ok(data); } case "B": { String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resB, Map.class); // 如果只需要data部分 Map<String, Object> data = (Map<String, Object>) result.get("data"); return R.ok(data); } case "C": { String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resC, Map.class); // 如果只需要data部分 Map<String, Object> data = (Map<String, Object>) result.get("data"); return R.ok(data); } case "D": { return R.ok(digitalTwinService.overview(areaId)); } default: Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.overview(areaId); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } else { Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.overview(areaId); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } /** * 近期订单(默认7天) * * @param areaId 库区编码 * @param startDate 格式:yyyyMMdd,20251022 * @param endDate 格式:yyyyMMdd,20251027 * @return */ @RequestMapping(value = "/recentOrder") // @ManagerAuth public R recentOrder(@RequestParam(required = false) String areaId, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) throws IOException { Map<String, Object> map = new HashMap<>(); if (areaId != null) { map.put("areaId", areaId); } if (startDate != null) { map.put("startDate", startDate); } if (endDate != null) { map.put("endDate", endDate); } HttpHandler.Builder builder = new HttpHandler.Builder() .setPath("/digitalTwin/recentOrder") .setParams(map); ObjectMapper objectMapper = new ObjectMapper(); if (areaId != null) { switch (areaId) { case "A": { String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "B": { String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resB, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "C": { String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resC, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "D": { return R.ok(digitalTwinService.order(startDate, endDate)); } default: Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.order(startDate, endDate); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } else { Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.order(startDate, endDate); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } /** * 近期剩余库位(默认7天) * * @param areaId 库区编码 * @param startDate 格式:yyyyMMdd,20251022 * @param endDate 格式:yyyyMMdd,20251027 * @return */ @RequestMapping(value = "/recentIdleLoc") // @ManagerAuth public R recentIdleLoc(@RequestParam(required = false) String areaId, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) throws IOException { Map<String, Object> map = new HashMap<>(); if (areaId != null) { map.put("areaId", areaId); } if (startDate != null) { map.put("startDate", startDate); } if (endDate != null) { map.put("endDate", endDate); } HttpHandler.Builder builder = new HttpHandler.Builder() .setPath("/digitalTwin/recentIdleLoc") .setParams(map); ObjectMapper objectMapper = new ObjectMapper(); if (areaId != null) { switch (areaId) { case "A": { String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "B": { String resA = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "C": { String resA = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "D": { return R.ok(digitalTwinService.recentLoc(areaId, startDate, endDate)); } default: Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.recentLoc(areaId, startDate, endDate); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } else { Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.recentLoc(areaId, startDate, endDate); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } /** * 近期出入库(默认7天) * * @param areaId 库区编码 * @param startDate 格式:yyyyMMdd,20251022 * @param endDate 格式:yyyyMMdd,20251027 * @return */ @RequestMapping(value = "/recentInAndOutBound") // @ManagerAuth public R recentInAndOutBound(@RequestParam(required = false) String areaId, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) throws ParseException, IOException { Map<String, Object> map = new HashMap<>(); if (areaId != null) { map.put("areaId", areaId); } if (startDate != null) { map.put("startDate", startDate); } if (endDate != null) { map.put("endDate", endDate); } HttpHandler.Builder builder = new HttpHandler.Builder() .setPath("/digitalTwin/recentInAndOutBound") .setParams(map); ObjectMapper objectMapper = new ObjectMapper(); if (areaId != null) { switch (areaId) { case "A": { String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "B": { String resA = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "C": { String resA = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "D": { return R.ok(digitalTwinService.inAndOutBound(areaId, startDate, endDate)); } default: Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.inAndOutBound(areaId, startDate, endDate); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } else { // 如果没有提供areaId,默认调用本地服务 Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.inAndOutBound(areaId, startDate, endDate); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } /** * 近期呆滞品(默认超30天) * * @param areaId 库区编码 * @param overDayNum 呆滞品天数,默认30天 * @return */ @RequestMapping(value = "/recentDetainMat") // @ManagerAuth public R recentDetainMat(@RequestParam(required = false) String areaId, @RequestParam(required = false) Integer overDayNum, @RequestParam(required = false) Integer pageIndex, @RequestParam(required = false) Integer pageSize, @RequestParam(required = false) String condition) throws IOException { Map<String, Object> map = new HashMap<>(); if (areaId != null) { map.put("areaId", areaId); } if (overDayNum != null) { map.put("overDayNum", overDayNum); } if (pageIndex != null) { map.put("pageIndex", pageIndex); } if (pageSize != null) { map.put("pageSize", pageSize); } if (condition != null) { map.put("condition", condition); } HttpHandler.Builder builder = new HttpHandler.Builder() .setPath("/digitalTwin/recentDetainMat") .setParams(map); ObjectMapper objectMapper = new ObjectMapper(); if (areaId != null) { switch (areaId) { case "A": { String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "B": { String resA = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "C": { String resA = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "D": { return R.ok(digitalTwinService.recentDetainMat(areaId, overDayNum, pageIndex, pageSize, condition)); } default: Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.recentDetainMat(areaId, overDayNum, pageIndex, pageSize, condition); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } else { // 如果没有提供areaId,默认调用本地服务 Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.recentDetainMat(areaId, overDayNum, pageIndex, pageSize, condition); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } /** * 设备运行信息 * * @param areaId * @return */ @RequestMapping(value = "/equipment") // @ManagerAuth public R equipment(@RequestParam(required = false) String areaId) throws IOException { Map<String, Object> map = new HashMap<>(); map.put("areaId", areaId); HttpHandler.Builder builder = new HttpHandler.Builder() .setPath("/digitalTwin/equipment") .setParams(map); ObjectMapper objectMapper = new ObjectMapper(); if (areaId != null){ switch (areaId) { case "A": { String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); return R.ok(result.get("data")); } case "B": { String resA = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); return R.ok(result.get("data")); } case "C": { String resA = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); return R.ok(result.get("data")); } case "D": { return R.ok(digitalTwinService.equipment(areaId)); } default: Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.equipment(areaId); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } }else { Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.equipment(areaId); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } /** * 库位和库存详情 * * @param areaId * @return */ @RequestMapping(value = "/warehouseDetail") // @ManagerAuth public R warehouseDetail(@RequestParam(required = false) String areaId) throws IOException { Map<String, Object> map = new HashMap<>(); if (areaId != null) { map.put("areaId", areaId); } HttpHandler.Builder builder = new HttpHandler.Builder() .setPath("/digitalTwin/warehouseDetail") .setParams(map); ObjectMapper objectMapper = new ObjectMapper(); if (areaId != null) { switch (areaId) { case "A": { String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "B": { builder.setPath("/digitalTwin/warehouseDetail"); String resA = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "C": { String resA = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> result = objectMapper.readValue(resA, Map.class); // 如果只需要data部分 List data = (List) result.get("data"); return R.ok(data); } case "D": { return R.ok(digitalTwinService.warehouseDetail(areaId)); } default: Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.warehouseDetail(areaId); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } else { // 如果没有提供areaId,默认调用本地服务 Map<String, Object> mergedResult = new HashMap<>(); Map<String, Object> mergedData = new HashMap<>(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } Object resultD = digitalTwinService.warehouseDetail(areaId); if (resultD != null) { mergedData.put("D", resultD); } return R.ok(mergedData); } } /** * 查询所有库位状态和物料-二机床信息化数字孪生用 */ @RequestMapping(value = "/getAllLocations") public R getAllLocations() throws IOException { Map<String, Object> mergedData = new HashMap<>(); HttpHandler.Builder builder = new HttpHandler.Builder() .setPath("/digitalTwin/getAllLocations"); ObjectMapper objectMapper = new ObjectMapper(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } mergedData.put("D",digitalTwinService.getAllLocations()); return R.ok(mergedData); } /** * 查询所有库的库位状态总数量 */ @RequestMapping(value = "/getLocalInfo") public R getLocalInfo() throws IOException { Map<String, Object> mergedData = new HashMap<>(); HttpHandler.Builder builder = new HttpHandler.Builder() .setPath("/digitalTwin/getLocalInfo"); ObjectMapper objectMapper = new ObjectMapper(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); mergedData.put("A", resultA); String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); mergedData.put("B", resultB); String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); mergedData.put("C", resultC); Map<String, Object> locInfo = digitalTwinService.getLocInfo(); mergedData.put("D", locInfo); return R.ok(mergedData); } /** * 查询所有库的库存明细 */ @RequestMapping(value = "/getLocalDetal") public R getLocalDetal() throws IOException { Map<String, Object> mergedData = new HashMap<>(); HttpHandler.Builder builder = new HttpHandler.Builder() .setPath("/digitalTwin/getLocalDetal"); ObjectMapper objectMapper = new ObjectMapper(); String resA = builder.setUri(JG_URL).build().doGet(); Map<String, Object> resultA = objectMapper.readValue(resA, Map.class); if (resultA.get("data") != null) { mergedData.put("A", resultA.get("data")); } String resB = builder.setUri(DJ_URL).build().doGet(); Map<String, Object> resultB = objectMapper.readValue(resB, Map.class); if (resultB.get("data") != null) { mergedData.put("B", resultB.get("data")); } String resC = builder.setUri(LJQ_URL).build().doGet(); Map<String, Object> resultC = objectMapper.readValue(resC, Map.class); if (resultC.get("data") != null) { mergedData.put("C", resultC.get("data")); } List<Map<String, Object>> detalList = digitalTwinService.getLocalDetal(); mergedData.put("D", detalList); return R.ok(mergedData); } } src/main/java/com/zy/asrs/entity/LocCount.java
New file @@ -0,0 +1,41 @@ package com.zy.asrs.entity; import com.baomidou.mybatisplus.annotations.TableField; import com.baomidou.mybatisplus.annotations.TableName; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @TableName("asr_loc_count") public class LocCount { private static final long serialVersionUID = 1L; /** * 日期 */ @ApiModelProperty(value= "日期,格式:20250101") @TableField("date") private Integer date; /** * 库区号 */ @ApiModelProperty(value= "库区号") @TableField("area_id") private String areaId; /** * 库位数量 */ @ApiModelProperty(value= "库位数量") @TableField("loc_num") private Integer locNum; /** * 剩余库位数量 */ @ApiModelProperty(value= "剩余库位数量") @TableField("remain_num") private Integer remainNum; } src/main/java/com/zy/asrs/entity/digitaltwin/AllLocationsVo.java
New file @@ -0,0 +1,36 @@ package com.zy.asrs.entity.digitaltwin; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.ArrayList; import java.util.List; /** * @author pang.jiabao * @description 查询所有库位状态和物料-二机床信息化数字孪生用 * @createDate 2026/1/26 11:13 */ @Data public class AllLocationsVo { // 库位号 private String locNo; // 库位状态,O空库位(英文不是数字);F 在库;D 空板;P 出库中;R 出库预约;S 入库预约;其他 其他; private String locSts; private List<LocDetl> locDetls = new ArrayList<>(); @Data public static class LocDetl { @ApiModelProperty(value = "商品编号") private String matnr; @ApiModelProperty(value = "商品名称") private String maktx; private Double anfme; } } src/main/java/com/zy/asrs/entity/digitaltwin/DtDetainMatVo.java
New file @@ -0,0 +1,27 @@ package com.zy.asrs.entity.digitaltwin; import lombok.Builder; import lombok.Data; // 数字孪生:呆滞品信息 @Data public class DtDetainMatVo { // 归属库区ID private String belongAreaId; // 归属库区名称 private String belongAreaName; // 物料ID private String matId; // 物料名称 private String matName; // 所属库位ID private String lokId; // 所属库位名称 private String lokName; // 呆滞时间,计算单位:分钟 private Integer detainTime; // 入库时间,格式:2025-10-11T11:15:16,预留 private String inBoundTime; } src/main/java/com/zy/asrs/entity/digitaltwin/DtEquipmentDocVo.java
New file @@ -0,0 +1,36 @@ package com.zy.asrs.entity.digitaltwin; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; // 数字孪生:设备监控(对接文档) @Data public class DtEquipmentDocVo { // 设备类型:1 堆垛机;2 输送线 private Integer equipmentType; // 堆垛机号 private Integer crnNo; // 任务号 private String taskNo; // 列 private Integer bay1; // 层 @JsonProperty("Lev1") private Integer lev1; // 垂直速度,单位:M/min private Integer verticalSpeed; // 水平速度,单位:M/min private Integer horizontalSpeed; // 电压,单位:v private Integer voltage; // 设备状态:1 正常;2 待机;3 故障; private Integer status; // 操作方式:1 自动;2 半自动;3 手动; private Integer operateMethod; // 输送线号 private Integer devpNo; // 有物 @JsonProperty("Loading") private String loading; } src/main/java/com/zy/asrs/entity/digitaltwin/DtEquipmentVo.java
New file @@ -0,0 +1,35 @@ package com.zy.asrs.entity.digitaltwin; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @AllArgsConstructor @NoArgsConstructor public class DtEquipmentVo { // 设备ID private String equipmentId; // 设备名称 private String equipmentName; // 设备类型:1 堆垛机;2 CTU;3 AGV; private Integer equipmentType; // 所属库ID private String belongAreaId; // 所属库名 private String belongAreaName; // 垂直速度,单位:M/min private Integer verticalSpeed; // 水平速度,单位:M/min private Integer horizontalSpeed; // 电压,单位:v private Integer voltage; // 设备状态:1 正常;2 待机;3 故障; private Integer status; // 操作方式:1 自动;2 半自动;3 手动; private Integer operateMethod; } src/main/java/com/zy/asrs/entity/digitaltwin/DtInAndOutBoundVo.java
New file @@ -0,0 +1,17 @@ package com.zy.asrs.entity.digitaltwin; import lombok.Builder; import lombok.Data; // 数字孪生:按天出入库数量 @Data @Builder public class DtInAndOutBoundVo { // 日期 private String boundDate; // 入库数量 private Integer inBoundNum; // 出库数量 private Integer outBoundNum; } src/main/java/com/zy/asrs/entity/digitaltwin/DtLocDetailVo.java
New file @@ -0,0 +1,30 @@ package com.zy.asrs.entity.digitaltwin; import com.zy.asrs.entity.LocDetl; import com.zy.asrs.entity.LocMast; import lombok.Data; @Data public class DtLocDetailVo { // 库位号 private String locNo; // 库位状态,O空库位(英文不是数字);F 在库;D 空板;P 出库中;R 出库预约;S 入库预约;其他 其他; private String locSts; // 库区id private Long areaId; // 库区名称 private String areaName; // 排 private Integer row1; // 列 private Integer bay1; // 层 private Integer lev1; // 库位信息 private LocMast locMast; // 库存信息 private LocDetl locDetl; } src/main/java/com/zy/asrs/entity/digitaltwin/DtLocVo.java
New file @@ -0,0 +1,15 @@ package com.zy.asrs.entity.digitaltwin; import lombok.Builder; import lombok.Data; // 数字孪生:按天剩余库位数量 @Data @Builder public class DtLocVo { // 日期 private String locDate; // 库位剩余数量 private Integer idleNum; } src/main/java/com/zy/asrs/entity/digitaltwin/DtOrderVo.java
New file @@ -0,0 +1,19 @@ package com.zy.asrs.entity.digitaltwin; import lombok.Builder; import lombok.Data; import java.time.LocalDate; import java.time.ZoneId; import java.util.Date; // 数字孪生:按天订单数量 @Data @Builder // DtOrderVo.java public class DtOrderVo { private String orderDate; // 或 LocalDate private Integer orderNum; } src/main/java/com/zy/asrs/entity/digitaltwin/DtOverviewVo.java
New file @@ -0,0 +1,24 @@ package com.zy.asrs.entity.digitaltwin; import lombok.Builder; import lombok.Data; // 数字孪生:按天出库、入库数量 @Data @Builder public class DtOverviewVo { // 总库位 private Integer totalLoc; // 已用库位 private Integer useLoc; // 剩余库位 private Integer idleLoc; // 今日出库 private Integer todayOutbound; // 今日入库 private Integer todayWarehousing; // 剩余库存 private Integer remainingStock; } src/main/java/com/zy/asrs/entity/digitaltwin/LocPicDto.java
New file @@ -0,0 +1,13 @@ package com.zy.asrs.entity.digitaltwin; import lombok.Data; import java.util.List; @Data public class LocPicDto { private String locNo; private List<String> pics; } src/main/java/com/zy/asrs/mapper/DigitalTwinMapper.java
New file @@ -0,0 +1,27 @@ package com.zy.asrs.mapper; import com.zy.asrs.entity.digitaltwin.DtDetainMatVo; import com.zy.asrs.entity.digitaltwin.DtInAndOutBoundVo; import com.zy.asrs.entity.digitaltwin.DtOrderVo; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.Date; import java.util.List; @Mapper @Repository public interface DigitalTwinMapper { List<Double> overview(@Param("areaId")String areaId); List<DtOrderVo> recentOrder(@Param("startTime")Date startTime, @Param("endTime")Date endTime); List<DtInAndOutBoundVo> recentInBound(@Param("areaId")String areaId, @Param("startTime") Date startTime, @Param("endTime")Date endTime); List<DtInAndOutBoundVo> recentOutBound(@Param("areaId")String areaId, @Param("startTime") Date startTime, @Param("endTime")Date endTime); List<DtDetainMatVo> recentDetainMat(@Param("areaId")String areaId, @Param("startTime")Date startTime, @Param("pageIndex")Integer pageIndex, @Param("pageSize")Integer pageSize); } src/main/java/com/zy/asrs/mapper/LocCountMapper.java
New file @@ -0,0 +1,24 @@ package com.zy.asrs.mapper; import com.baomidou.mybatisplus.mapper.BaseMapper; import com.zy.asrs.entity.LocCount; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.List; @Mapper @Repository public interface LocCountMapper extends BaseMapper<LocCount> { List<LocCount> getByAreaAndDate(@Param("areaId")String areaId, @Param("startDate")int startDate, @Param("endDate")int endDate); List<LocCount> getByDate(@Param("startDate")int startDate, @Param("endDate")int endDate); Integer insertOrUpdate(@Param("model")LocCount model); List<LocCount> totalLoc(); List<LocCount> useLoc(); } src/main/java/com/zy/asrs/service/DigitalTwinService.java
New file @@ -0,0 +1,83 @@ package com.zy.asrs.service; import com.zy.asrs.entity.digitaltwin.*; import java.util.List; import java.util.Map; public interface DigitalTwinService { /** * 总览:总库位、已用库位、剩余库位、今日出库、今日入库、剩余库位 * * @param areaId * @return */ DtOverviewVo overview(String areaId); /** * 近期订单,默认7天 * * @param startDate * @param endDate * @return */ List<DtOrderVo> order(String startDate, String endDate); /** * 近期出库、入库数量,默认7天 * * @param areaId * @param startDate * @param endDate * @return */ List<DtInAndOutBoundVo> inAndOutBound(String areaId, String startDate, String endDate); /** * 近期近期呆滞品信息,默认超过30天为呆滞品 * * @param areaId * @param overDayNum * @param pageIndex * @param pageSize * @param condition 搜索条件 * @return */ List<DtDetainMatVo> recentDetainMat(String areaId, Integer overDayNum, Integer pageIndex, Integer pageSize, String condition); /** * 查询库存和库位详细信息 * * @param areaId * @return */ List<DtLocDetailVo> warehouseDetail(String areaId); /** * 近期剩余库位数量,默认7天 * * @param areaId * @param startDate * @param endDate * @return */ List<DtLocVo> recentLoc(String areaId, String startDate, String endDate); /** * 定期统计剩余库存 * */ void locNumCount(); List<DtEquipmentDocVo> equipment(String areaId); /** * 查询所有库位状态和物料-二机床信息化数字孪生用 */ List<AllLocationsVo> getAllLocations(); List<Map<String, Object>> getLocalDetal(); Map<String, Object> getLocInfo(); } src/main/java/com/zy/asrs/service/impl/DigitalTwinServiceImpl.java
New file @@ -0,0 +1,482 @@ package com.zy.asrs.service.impl; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.zy.asrs.entity.BasCrnp; import com.zy.asrs.entity.BasDevp; import com.zy.asrs.entity.LocCount; import com.zy.asrs.entity.LocDetl; import com.zy.asrs.entity.LocMast; import com.zy.asrs.entity.digitaltwin.*; import com.zy.asrs.mapper.DigitalTwinMapper; import com.zy.asrs.mapper.LocCountMapper; import com.zy.asrs.mapper.LocDetlMapper; import com.zy.asrs.mapper.LocMastMapper; import com.zy.asrs.service.BasCrnpService; import com.zy.asrs.service.BasDevpService; import com.zy.asrs.service.DigitalTwinService; import com.zy.asrs.service.LocDetlService; import com.zy.asrs.service.LocMastService; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; @Service public class DigitalTwinServiceImpl implements DigitalTwinService { @Resource private DigitalTwinMapper digitalTwinMapper; @Resource private LocCountMapper locCountMapper; @Resource private LocMastMapper locMastMapper; @Resource private LocDetlMapper locDetlMapper; @Resource private LocMastService locMastService; /** * 总览:总库位、已用库位、剩余库位、今日出库、今日入库、剩余库位 * * @param areaId * @return */ public DtOverviewVo overview(String areaId) { List<Double> dbOverview = digitalTwinMapper.overview(areaId); if (dbOverview != null && !dbOverview.isEmpty()){ DtOverviewVo dtOverviewVo = DtOverviewVo.builder() .totalLoc((int)Math.round(dbOverview.get(0))) .useLoc((int)Math.round(dbOverview.get(1))) .remainingStock((int)Math.round(dbOverview.get(2))) .todayWarehousing((int)Math.round(dbOverview.get(3))) .todayOutbound((int)Math.round(dbOverview.get(4))) .build(); dtOverviewVo.setIdleLoc(dtOverviewVo.getTotalLoc() - dtOverviewVo.getUseLoc()); return dtOverviewVo; } return DtOverviewVo.builder().build(); } /** * 近期订单,默认7天 * * @param startDate * @param endDate * @return */ public List<DtOrderVo> order(String startDate, String endDate) { Date startTime = new Date(); Date endTime = new Date(); if (startDate == null || endDate == null || startDate.isEmpty() || endDate.isEmpty()){ Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(now); calendar.add(Calendar.DAY_OF_MONTH, -7); startTime = calendar.getTime(); endTime = now; } else { SimpleDateFormat sdf; try { // 尝试解析yyyyMMdd格式 if (startDate.length() == 8 && endDate.length() == 8) { sdf = new SimpleDateFormat("yyyyMMdd"); startTime = sdf.parse(startDate); endTime = sdf.parse(endDate); // 设置结束时间为当天的23:59:59.999 Calendar calendar = Calendar.getInstance(); calendar.setTime(endTime); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); endTime = calendar.getTime(); } else { // 尝试解析yyyy-MM-dd HH:mm:ss.SSS格式 sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); startTime = sdf.parse(startDate); endTime = sdf.parse(endDate); } } catch (ParseException e) { e.printStackTrace(); // 解析失败时使用默认的7天时间范围 Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(now); calendar.add(Calendar.DAY_OF_MONTH, -7); startTime = calendar.getTime(); endTime = now; } } List<DtOrderVo> dbOrder = digitalTwinMapper.recentOrder(startTime, endTime); // 空日期补全 for (DtOrderVo dtOrderVo : dbOrder) { dtOrderVo.setOrderDate(dtOrderVo.getOrderDate()); } return dbOrder; } /** * 近期出库、入库数量,默认7天 * * @param areaId * @param startDate * @param endDate * @return */ public List<DtInAndOutBoundVo> inAndOutBound(String areaId, String startDate, String endDate) { Date startTime = new Date(); Date endTime = new Date(); if (startDate == null || endDate == null || startDate.isEmpty() || endDate.isEmpty()){ Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(now); calendar.add(Calendar.DAY_OF_MONTH, -7); startTime = calendar.getTime(); endTime = now; } else { SimpleDateFormat sdf; try { // 尝试解析yyyyMMdd格式 if (startDate.length() == 8 && endDate.length() == 8) { sdf = new SimpleDateFormat("yyyyMMdd"); startTime = sdf.parse(startDate); endTime = sdf.parse(endDate); // 设置结束时间为当天的23:59:59.999 Calendar calendar = Calendar.getInstance(); calendar.setTime(endTime); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); endTime = calendar.getTime(); } else { // 尝试解析yyyy-MM-dd HH:mm:ss.SSS格式 sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); startTime = sdf.parse(startDate); endTime = sdf.parse(endDate); } } catch (ParseException e) { e.printStackTrace(); // 解析失败时使用默认的7天时间范围 Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(now); calendar.add(Calendar.DAY_OF_MONTH, -7); startTime = calendar.getTime(); endTime = now; } } List<DtInAndOutBoundVo> dtInBoundVos = digitalTwinMapper.recentInBound(areaId, startTime, endTime); List<DtInAndOutBoundVo> dtOutBoundVos = digitalTwinMapper.recentOutBound(areaId, startTime, endTime); // 格式整理 List<DtInAndOutBoundVo> dtInAndOutBoundVos = new ArrayList<>(dtInBoundVos); dtInAndOutBoundVos.addAll(dtOutBoundVos); return dtInAndOutBoundVos; } /** * 近期近期呆滞品信息,默认超过30天为呆滞品 * * @param areaId * @param overDayNum * @param pageIndex * @param pageSize * @param condition 搜索条件 * @return */ public List<DtDetainMatVo> recentDetainMat(String areaId, Integer overDayNum, Integer pageIndex, Integer pageSize, String condition) { overDayNum = overDayNum == null ? 30 : overDayNum; pageIndex = pageIndex == null ? 1 : pageIndex; pageSize = pageSize == null ? 1000000 : pageSize; Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(now); calendar.add(Calendar.DAY_OF_MONTH, -overDayNum); Date start = calendar.getTime(); /* SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String startTime = sdf.format(start);*/ List<DtDetainMatVo> dbDetainMats = digitalTwinMapper.recentDetainMat(areaId, start, pageIndex, pageSize); return dbDetainMats; } /** * 查询库存和库位详细信息 * * @param areaId * @return */ public List<DtLocDetailVo> warehouseDetail(String areaId) { List<LocMast> locMastList = locMastService.selectList(new EntityWrapper<>()); return locMastList.stream() .map(loc -> { DtLocDetailVo vo = new DtLocDetailVo(); BeanUtils.copyProperties(loc, vo); vo.setLocMast(loc); LocDetl query = new LocDetl(); query.setLocNo(loc.getLocNo()); LocDetl locDetl = locDetlMapper.selectOne(query); vo.setLocDetl(locDetl); return vo; }) .collect(Collectors.toList()); } /** * 近期剩余库位数量,默认7天 * * @param areaId * @param startDate * @param endDate * @return */ public List<DtLocVo> recentLoc(String areaId, String startDate, String endDate) { List<DtLocVo> locVos = new ArrayList<>(); if (startDate == null || endDate == null || startDate.isEmpty() || endDate.isEmpty()){ Date now = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(now); calendar.add(Calendar.DAY_OF_MONTH, -7); Date start = calendar.getTime(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); endDate = sdf.format(now); startDate = sdf.format(start); } List<LocCount> locCounts; if (areaId != null && !areaId.isEmpty()) { locCounts = locCountMapper.getByAreaAndDate(areaId, Integer.parseInt(startDate), Integer.parseInt(endDate)); } else { locCounts = locCountMapper.getByDate(Integer.parseInt(startDate), Integer.parseInt(endDate)); } for (LocCount locCount : locCounts) { String date = locCount.getDate().toString(); String locDate = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8); DtLocVo dtLocVo = DtLocVo.builder() .locDate(locDate) .idleNum(locCount.getRemainNum()) .build(); locVos.add(dtLocVo); } return locVos; } /** * 定期统计剩余库存 * */ @Transactional public void locNumCount() { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); String date = sdf.format(new Date()); List<LocCount> totalLoc = locCountMapper.totalLoc(); List<LocCount> useLoc = locCountMapper.useLoc(); LocCount locCount1 = new LocCount(); locCount1.setDate(Integer.valueOf(date)); locCount1.setLocNum(totalLoc.get(0).getLocNum()); locCount1.setRemainNum(locCount1.getLocNum() - useLoc.get(0).getLocNum()); locCountMapper.insertOrUpdate(locCount1); } @Resource private BasCrnpService basCrnpService; @Resource private BasDevpService basDevpService; @Override public List<DtEquipmentDocVo> equipment(String areaId) { List<DtEquipmentDocVo> equipmentVos = new ArrayList<>(); List<BasCrnp> crnps = basCrnpService.selectList(new EntityWrapper<>()); for (BasCrnp crnp : crnps) { DtEquipmentDocVo vo = new DtEquipmentDocVo(); vo.setEquipmentType(1); vo.setCrnNo(crnp.getCrnNo()); Integer wrkNo = crnp.getWrkNo(); vo.setTaskNo(wrkNo == null ? null : String.valueOf(wrkNo)); String locNo = !Cools.isEmpty(crnp.getToLocno()) ? crnp.getToLocno() : crnp.getFrmLocno(); if (!Cools.isEmpty(locNo)) { LocMast locMast = locMastService.selectById(locNo); if (locMast != null) { vo.setBay1(locMast.getBay1()); vo.setLev1(locMast.getLev1()); } } vo.setVerticalSpeed(parseInteger(crnp.getCtlHp())); vo.setHorizontalSpeed(parseInteger(crnp.getCtlRest())); vo.setVoltage(220); vo.setStatus(crnp.getCrnErr() != null && crnp.getCrnErr() == 0 ? 1 : 3); vo.setOperateMethod(crnp.getCrnSts() != null && crnp.getCrnSts() == 3 ? 1 : 3); equipmentVos.add(vo); } List<BasDevp> devps = basDevpService.selectList(new EntityWrapper<>()); for (BasDevp devp : devps) { DtEquipmentDocVo vo = new DtEquipmentDocVo(); vo.setEquipmentType(2); vo.setDevpNo(devp.getDevNo()); Integer wrkNo = devp.getWrkNo(); Integer wrkNo1 = devp.getWrkNo1(); Integer task = wrkNo != null ? wrkNo : wrkNo1; vo.setTaskNo(task == null ? null : String.valueOf(task)); vo.setLoading(devp.getLoading()); equipmentVos.add(vo); } return equipmentVos; } private Integer parseInteger(String value) { if (Cools.isEmpty(value)) { return 0; } try { return Integer.valueOf(value); } catch (NumberFormatException ex) { return 0; } } // region 数字孪生 // 数字孪生整合 // 机器状态整合 // endregion // region 立库调度 // 堆垛机存取 // 输送线拍照、称重 // endregion @Resource private LocDetlService locDetlService; @Override public List<AllLocationsVo> getAllLocations() { List<AllLocationsVo> allLocationsVos = new ArrayList<>(); List<LocMast> locMastList = locMastService.selectList(new EntityWrapper<>()); locMastList.forEach(locMast -> { AllLocationsVo allLocationsVo = new AllLocationsVo(); allLocationsVo.setLocNo(locMast.getLocNo()); String locSts = locMast.getLocSts(); allLocationsVo.setLocSts(locSts); // 有库存 if (locSts.equals("F") || locSts.equals("P") || locSts.equals("Q") || locSts.equals("R")) { List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no", locMast.getLocNo())); if (!locDetls.isEmpty()) { List<AllLocationsVo.LocDetl> locDetlList = locDetls.stream().map(locDetl -> { AllLocationsVo.LocDetl locDetl1 = new AllLocationsVo.LocDetl(); BeanUtils.copyProperties(locDetl, locDetl1); return locDetl1; } ).collect(Collectors.toList()); allLocationsVo.setLocDetls(locDetlList); } } allLocationsVos.add(allLocationsVo); }); return allLocationsVos; } public List<Map<String, Object>> getLocalDetal() { List<LocDetl> locDetls = locDetlMapper.selectList(new EntityWrapper<>()); List<Map<String, Object>> result = new ArrayList<>(); for (LocDetl locDetl : locDetls) { Map<String, Object> item = new HashMap<>(); item.put("zpallet", locDetl.getZpallet()); item.put("anfme", locDetl.getAnfme()); item.put("matnr", locDetl.getMatnr()); item.put("maktx", locDetl.getMaktx()); result.add(item); } return result; } public Map<String, Object> getLocInfo() { List<LocMast> LocMasts = locMastMapper.selectList(new EntityWrapper<>()); Map<String, Object> result = new HashMap<>(); // 初始化计数器 int emptyLocCount = 0; int fullZpalletCount = 0; int emptyZpalletCount = 0; int pickOutCount = 0; int pickInCount = 0; int outboundCount = 0; int inboundCount = 0; int disableCount = 0; int mergeCount = 0; // 统计每种状态的库位数量 for (LocMast locMast : LocMasts) { String locSts = locMast.getLocSts(); if (locSts.equals("O")) { emptyLocCount++; } else if (locSts.equals("F")) { fullZpalletCount++; } else if (locSts.equals("D")) { emptyZpalletCount++; } else if (locSts.equals("P")) { pickOutCount++; } else if (locSts.equals("Q")) { pickInCount++; } else if (locSts.equals("R")) { outboundCount++; } else if (locSts.equals("S")) { inboundCount++; } else if (locSts.equals("X")) { disableCount++; } else if (locSts.equals("Y")) { mergeCount++; } } // 将统计结果放入Map中 result.put("EmptyLoc", emptyLocCount); result.put("FullZpallet", fullZpalletCount); result.put("EmptyZpallet", emptyZpalletCount); result.put("PickOut", pickOutCount); result.put("PickIn", pickInCount); result.put("Outbound", outboundCount); result.put("Inbound", inboundCount); result.put("Disable", disableCount); result.put("Merge", mergeCount); return result; } } src/main/resources/application.yml
@@ -53,6 +53,11 @@ api-key: app-mP0O6aY5WpbfaHs7BNnjVkli model: deepseek-ai/DeepSeek-V3.2 digitalTwins: jgUrl: http://172.26.11.88:8089/jgwms djUrl: http://172.26.11.88:8088/djwms ljqUrl: http://172.26.11.80:8083/ljqwms # 下位机配置 wcs-slave: # 双深 src/main/resources/mapper/LocCountMapper.xml
New file @@ -0,0 +1,50 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.asrs.mapper.LocCountMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.zy.asrs.entity.LocCount"> <result column="date" property="date" /> <result column="area_id" property="areaId" /> <result column="loc_num" property="locNum" /> <result column="remain_num" property="remainNum" /> </resultMap> <select id="getByAreaAndDate" resultType="com.zy.asrs.entity.LocCount"> SELECT * FROM asr_loc_count WHERE area_id = #{areaId} AND date BETWEEN #{startDate} AND #{endDate} </select> <select id="getByDate" resultType="com.zy.asrs.entity.LocCount"> SELECT date, SUM(ISNULL(loc_num, 0)) AS loc_num, SUM(ISNULL(remain_num, 0)) AS remain_num FROM asr_loc_count WHERE date BETWEEN #{startDate} AND #{endDate} GROUP BY date </select> <insert id="insertOrUpdate" parameterType="com.zy.asrs.entity.LocCount"> IF EXISTS (SELECT 1 FROM asr_loc_count WHERE date = #{model.date}) BEGIN UPDATE asr_loc_count SET loc_num = #{model.locNum}, remain_num = #{model.remainNum} WHERE date = #{model.date} END ELSE BEGIN INSERT INTO asr_loc_count(date, area_id, loc_num, remain_num) VALUES (#{model.date}, #{model.areaId}, #{model.locNum}, #{model.remainNum}) END </insert> <select id="totalLoc" resultType="com.zy.asrs.entity.LocCount"> SELECT area_id, COUNT(*) AS loc_num FROM asr_loc_mast WHERE loc_sts != 'Z' GROUP BY area_id </select> <select id="useLoc" resultType="com.zy.asrs.entity.LocCount"> SELECT area_id, COUNT(*) AS loc_num FROM asr_loc_mast WHERE loc_sts = 'F' or loc_sts = 'P' or loc_sts = 'Q' or loc_sts = 'R' or loc_sts = 'S' or loc_sts = 'X' GROUP BY area_id </select> </mapper> src/main/resources/mapper/ViewDigitalTwinMapper.xml
New file @@ -0,0 +1,105 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.asrs.mapper.DigitalTwinMapper"> <resultMap id="dtOrderMap" type="com.zy.asrs.entity.digitaltwin.DtOrderVo"> <constructor> <arg column="orderDate" javaType="java.util.Date"/> <arg column="orderNum" javaType="java.lang.Integer"/> </constructor> </resultMap> <!--总览:总库位、已用库位、今日库存、今日出库、今日入库--> <select id="overview" resultType="Double"> SELECT COUNT(*) FROM asr_loc_mast WHERE loc_sts != 'Z' <!-- <if test="areaId != null">--> <!-- and area_id = #{areaId}--> <!-- </if>--> UNION ALL SELECT COUNT(*) FROM asr_loc_mast WHERE loc_sts = 'F' or loc_sts = 'P' or loc_sts = 'Q' or loc_sts = 'R' or loc_sts = 'S' or loc_sts = 'X' <!-- <if test="areaId != null">--> <!-- and area_id = #{areaId}--> <!-- </if>--> UNION ALL SELECT ISNULL(SUM(anfme), 0) FROM asr_loc_detl <!-- <if test="areaId != null">--> <!-- WHERE area_id = #{areaId}--> <!-- </if>--> UNION ALL SELECT ISNULL(SUM(anfme), 0) FROM asr_wrkin_view WHERE CONVERT(VARCHAR, io_time, 23) = CONVERT(VARCHAR, GETDATE(), 23) <!-- <if test="areaId != null">--> <!-- and area_id = #{areaId}--> <!-- </if>--> UNION ALL SELECT ISNULL(SUM(anfme), 0) FROM asr_wrkout_view WHERE CONVERT(VARCHAR, io_time, 23) = CONVERT(VARCHAR, GETDATE(), 23) <!-- <if test="areaId != null">--> <!-- and area_id = #{areaId}--> <!-- </if>--> </select> <select id="recentOrder" resultType="com.zy.asrs.entity.digitaltwin.DtOrderVo"> SELECT FORMAT(orderDate, 'yyyy-MM-dd') as orderDate, COUNT(*) as orderNum FROM ( SELECT CAST(order_time AS DATE) as orderDate FROM man_order_pakin WHERE order_time BETWEEN #{startTime} AND #{endTime} UNION ALL SELECT CAST(order_time AS DATE) as orderDate FROM man_order_pakout WHERE order_time BETWEEN #{startTime} AND #{endTime} ) combined GROUP BY orderDate ORDER BY orderDate </select> <select id="recentInBound" resultType="com.zy.asrs.entity.digitaltwin.DtInAndOutBoundVo"> SELECT CONVERT(VARCHAR, io_time, 23) AS boundDate, SUM(anfme) AS inBoundNum FROM asr_wrkin_view WHERE io_time BETWEEN #{startTime} AND #{endTime} <!-- <if test="areaId != null">--> <!-- and area_id = #{areaId}--> <!-- </if>--> GROUP BY CONVERT(VARCHAR, io_time, 23) </select> <select id="recentOutBound" resultType="com.zy.asrs.entity.digitaltwin.DtInAndOutBoundVo"> SELECT CONVERT(VARCHAR, io_time, 23) AS boundDate, SUM(anfme) AS outBoundNum FROM asr_wrkout_view WHERE io_time BETWEEN #{startTime} AND #{endTime} <!-- <if test="areaId != null">--> <!-- and area_id = #{areaId}--> <!-- </if>--> GROUP BY CONVERT(VARCHAR, io_time, 23) </select> <select id="recentDetainMat" resultType="com.zy.asrs.entity.digitaltwin.DtDetainMatVo"> SELECT * FROM ( SELECT ROW_NUMBER() OVER(ORDER BY t.inBoundTime DESC) AS rownum, t.* FROM ( SELECT matnr AS matId, maktx AS matName, loc_no AS lokId, '' AS lokName, DATEDIFF(MINUTE, appe_time, GETDATE()) AS detainTime, CONVERT(VARCHAR, appe_time, 126) AS inBoundTime FROM asr_loc_detl WHERE appe_time <= #{startTime} ) t ) a WHERE a.rownum BETWEEN ((#{pageIndex}-1)*#{pageSize}+1) AND (#{pageIndex}*#{pageSize}) </select> </mapper>