diff --git a/acs/nladmin-system/nlsso-server/src/main/java/org/nl/acs/enums/AcsDefineEnum.java b/acs/nladmin-system/nlsso-server/src/main/java/org/nl/acs/enums/AcsDefineEnum.java new file mode 100644 index 0000000..d336f18 --- /dev/null +++ b/acs/nladmin-system/nlsso-server/src/main/java/org/nl/acs/enums/AcsDefineEnum.java @@ -0,0 +1,67 @@ +package org.nl.acs.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; +import org.nl.acs.utils.MapOf; +import java.util.Map; + +/** + * acs状态枚举 + * + * @author gbx + * @since 2024-01-31 + */ +@AllArgsConstructor +@Getter +public enum AcsDefineEnum { + + //agv状态 1-关机2-运行中3-交通管制4-任务等待5-充电中6-故障中7-低电量 + AGV_STATUS(MapOf.of("关机", "1", "运行中", "2", "交通管制", "3", "任务等待", "4", "充电中", "5", "故障中", "6", "低电量", "7")), + + //RGV状态 1-空闲 2-工作中 3-手动 4-下线 + RGV_STATUS(MapOf.of("1","IDLE","2","WORK","3","UNAVAIL","4","OFFLINE")), + + //载具类型 + VEHICLE_TYPE(MapOf.of("普涂", "1", "连涂", "2")), + + //是否 + IS_USED(MapOf.of("启用", "1", "未启用", "0")); + + + private Map code; + + public String code(String desc) { + String code = this.getCode().get(desc); + if (StringUtils.isNotEmpty(code)) { + return code; + } + throw new RuntimeException(this.name() + "对应类型" + desc + "未定义"); + } + + public Long longCode(String desc) { + String code = this.getCode().get(desc); + if (StringUtils.isNotEmpty(code)) { + return Long.valueOf(code); + } + throw new RuntimeException(this.name() + "对应类型" + desc + "未定义"); + } + + public String check(String code) { + for (Map.Entry entry : this.getCode().entrySet()) { + if (entry.getValue().equals(code)) { + return entry.getValue(); + } + } + throw new RuntimeException(this.name() + "对应类型" + code + "未定义"); + } + + public String check1(String code) { + for (Map.Entry entry : this.getCode().entrySet()) { + if (entry.getValue().equals(code)) { + return entry.getKey(); + } + } + throw new RuntimeException(this.name() + "对应类型" + code + "未定义"); + } +} diff --git a/acs/nladmin-system/nlsso-server/src/main/java/org/nl/acs/utils/MapOf.java b/acs/nladmin-system/nlsso-server/src/main/java/org/nl/acs/utils/MapOf.java new file mode 100644 index 0000000..23097e3 --- /dev/null +++ b/acs/nladmin-system/nlsso-server/src/main/java/org/nl/acs/utils/MapOf.java @@ -0,0 +1,20 @@ +package org.nl.acs.utils; + + +import java.io.Serializable; +import java.util.HashMap; + +/* + * @author ZZQ + * @Date 2022/11/29 2:55 下午 + */ +public class MapOf implements Serializable { + + public static HashMap of(K... key) { + HashMap map = new HashMap<>(); + for (int i = 0; i < (key.length & ~1); i = i + 2) { + map.put(key[i], key[i + 1]); + } + return map; + } +} diff --git a/acs/nladmin-system/nlsso-server/src/main/java/org/nl/quartz/task/SyncDeviceStatus.java b/acs/nladmin-system/nlsso-server/src/main/java/org/nl/quartz/task/SyncDeviceStatus.java new file mode 100644 index 0000000..c2cff6e --- /dev/null +++ b/acs/nladmin-system/nlsso-server/src/main/java/org/nl/quartz/task/SyncDeviceStatus.java @@ -0,0 +1,289 @@ +package org.nl.quartz.task; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.nl.acs.agv.server.ZheDaAgvService; +import org.nl.acs.device.domain.Device; +import org.nl.acs.device_driver.basedriver.cw_site.CwSiteDeviceDriver; +import org.nl.acs.device_driver.basedriver.standard_autodoor.StandardAutodoorDeviceDriver; +import org.nl.acs.device_driver.basedriver.standard_inspect_site.StandardInspectSiteDeviceDriver; +import org.nl.acs.instruction.service.InstructionService; +import org.nl.acs.opc.DeviceAppService; +import org.nl.common.utils.RedisUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 自动同步设备状态 + */ +@Slf4j +@Component +public class SyncDeviceStatus { + + + @Autowired + ZheDaAgvService agvService; + + @Autowired + private RedisUtils redisUtils; + + @Resource + private DeviceAppService deviceAppService; + + @Resource + private InstructionService instructionService; + + public void run() throws Exception { + device(); + } + + + private void device() { + long startTime = System.currentTimeMillis(); + try { + //总数 + Integer a1_count = 0; + //正常运行 + Long a1_item1 = 0L; + //暂未生产 + Long a1_item2 = 0L; + //空闲设备 + Long a1_item3 = 0L; + //故障设备 + Long a1_item4 = 0L; + Integer a2_count = 0; + Long a2_item1 = 0L; + Long a2_item2 = 0L; + Long a2_item3 = 0L; + Long a2_item4 = 0L; + JSONArray tbxList1 = new JSONArray(); + JSONArray tbxList2 = new JSONArray(); + JSONArray ghsList1 = new JSONArray(); + JSONArray ghsList2 = new JSONArray(); + List siteList = new ArrayList<>(); + //JSONArray agvList = new JSONArray(); + log.info("自动线程开始查询agv设备状态"); + List deviceList = deviceAppService.findAllDevice(); + for (Device device : deviceList) { + if (device.getDeviceDriver() instanceof StandardInspectSiteDeviceDriver) { + if (StringUtils.isNotBlank(device.getOpc_server_id())) { + StandardInspectSiteDeviceDriver tbx = (StandardInspectSiteDeviceDriver) device.getDeviceDriver(); + JSONObject json = new JSONObject(); + json.put("device_code", tbx.getDeviceCode()); + if (tbx.getError() == 0) { + //0:脱机,1:故障,2:待机,3:运行中 + //0:无货,3:有货 + getDeviceMode(tbx.getMode(), json); + } else { + json.put("mode", "1"); + } + //区分车间 + if (tbx.getDeviceCode().replaceAll("[^0-9]", "").startsWith("0")) { + json.put("workshop_code", "A1"); + tbxList1.add(json); + } else { + json.put("workshop_code", "A2"); + tbxList2.add(json); + } + } + } else if (device.getDeviceDriver() instanceof StandardAutodoorDeviceDriver) { + if (StringUtils.isNotBlank(device.getOpc_server_id())) { + StandardAutodoorDeviceDriver ghs = (StandardAutodoorDeviceDriver) device.getDeviceDriver(); + JSONObject json = new JSONObject(); + json.put("device_code", ghs.getDeviceCode()); + if (ghs.getError() == 0) { + //0:脱机,1:故障,2:待机,3:运行中 + getDeviceMode(ghs.getMode(), json); + //json.put("mode", ghs.getMode() == 0 ? "0" : "3"); + } else { + json.put("mode", "1"); + } + if (Integer.parseInt(ghs.getDeviceCode().replaceAll("[^0-9]", "")) < 11) { + json.put("workshop_code", "A1"); + ghsList1.add(json); + } else { + json.put("workshop_code", "A2"); + ghsList2.add(json); + } + } + } else if (device.getDeviceDriver() instanceof CwSiteDeviceDriver) { + if (StringUtils.isNotBlank(device.getOpc_server_id())) { + CwSiteDeviceDriver site = (CwSiteDeviceDriver) device.getDeviceDriver(); + JSONObject json = new JSONObject(); + json.put("device_code", site.getDeviceCode()); + json.put("workshop_code", "A1"); + if (site.getError() == 0) { + //0:脱机,1:故障,2:待机,3:运行中 + getDeviceMode(site.getMode(), json); + //json.put("mode", site.getMode() == 0 ? "0" : "3"); + } else { + json.put("mode", "1"); + } + siteList.add(json); + } + } + // else if (device.getDeviceDriver() instanceof AgvNdcOneDeviceDriver) { + // AgvNdcOneDeviceDriver agvNdcOneDeviceDriver = (AgvNdcOneDeviceDriver) device.getDeviceDriver(); + // JSONObject json = new JSONObject(); + // json.put("device_code", device.getDevice_code()); + // json.put("device_name", device.getDevice_name()); + // json.put("device_status", agvNdcOneDeviceDriver.getStatus()); + // json.put("energyLevel", agvNdcOneDeviceDriver.getElectric_qty()); + // json.put("positionX", agvNdcOneDeviceDriver.getX()); + // json.put("positionY", agvNdcOneDeviceDriver.getY()); + // json.put("positionAngle", agvNdcOneDeviceDriver.getAngle()); + // agvList.add(json); + // } + } + List bpList = siteList.stream() + .filter(r -> r.getString("device_code").contains("BP")) + .collect(Collectors.toList()); + redisUtils.set("tbxList1", tbxList1); + redisUtils.set("tbxList2", tbxList2); + redisUtils.set("ghsList1", ghsList1); + redisUtils.set("ghsList2", ghsList2); + redisUtils.set("bpjList", bpList); + tbxList1.addAll(ghsList1); + tbxList1.addAll(bpList); + JSONArray a1 = new JSONArray(); + JSONArray a2 = new JSONArray(); + getDeviceCountAndPercentage(tbxList1, a1); + tbxList2.addAll(ghsList2); + getDeviceCountAndPercentage(tbxList2, a2); + redisUtils.set("deviceA1", a1); + redisUtils.set("deviceA2", a2); + //正极板缓存区出库对接位,正极板空架回收对接位 + List zjbKjHswList = siteList.stream() + .filter(r -> r.getString("device_code").contains("ZJBHCQCKDJW") || r.getString("device_code").contains("ZJBKJHSDJW")) + .collect(Collectors.toList()); + redisUtils.set("zjbKjHswList", zjbKjHswList); + //负极板空架对接位 + List fjbKjDjwList = siteList.stream() + .filter(r -> r.getString("device_code").contains("FJBKJDJW")) + .collect(Collectors.toList()); + redisUtils.set("fjbKjDjwList", fjbKjDjwList); + //正极板对接位 + List zjbDjwList = siteList.stream() + .filter(r -> r.getString("device_code").contains("ZJBDJW")) + .collect(Collectors.toList()); + redisUtils.set("zjbDjwList", zjbDjwList); + // if (ObjectUtil.isNotEmpty(agv)) { + // List deviceCodes = agv.stream() + // .map(r -> { + // String deviceCode = ((JSONObject) r).getString("device_code"); + // if (StringUtils.isNotBlank(deviceCode)) { + // return deviceCode.substring(deviceCode.length() - 1); + // } else { + // return null; + // } + // }) + // .filter(Objects::nonNull) + // .collect(Collectors.toList()); + // if (ObjectUtil.isNotEmpty(deviceCodes)) { + // List instructionList = instructionService.list(new LambdaQueryWrapper().in(InstructionMybatis::getCarno, deviceCodes).lt(InstructionMybatis::getInstruction_status, 2).eq(InstructionMybatis::getIs_delete, 0)); + // if (ObjectUtil.isNotEmpty(instructionList)) { + // Map taskCodeToTaskIdMap = instructionList.stream() + // .filter(instruction -> StringUtils.isNotBlank(instruction.getExt_task_id())) + // .collect(Collectors.toMap( + // InstructionMybatis::getInstruction_code, + // InstructionMybatis::getExt_task_id + // )); + // agv.forEach(r -> { + // JSONObject Item = (JSONObject) r; + // String taskId = taskCodeToTaskIdMap.get(Item.getString("task_code")); + // Item.put("task_id", ""); + // if (StringUtils.isNotBlank(taskId)) { + // Item.put("task_id", taskId); + // } + // }); + // } + // } + // + // } + //redisUtils.set("agvList", agvList); + log.trace("自动上报驱动状态,完毕耗时{}", System.currentTimeMillis() - startTime); + } catch (Exception e) { + //log.error("自动线程开始查询AGV设备,自动上报驱动状态失败{}{}", e, e.getMessage()); + } + } + + private static void getDeviceCountAndPercentage(JSONArray deviceList, JSONArray result) { + Integer a1_count; + Long a1_item3; + Long a1_item1; + Long a1_item2; + Long a1_item4; + //0:脱机,1:故障,2:待机,3:运行中 + a1_count = deviceList.size(); + JSONObject item1 = new JSONObject(); + item1.put("count", a1_count); + result.add(item1); + a1_item1 = deviceList.stream() + .map(JSONObject.class::cast) + .filter(r -> "3".equals(r.getString("mode"))) + .count(); + JSONObject item2 = new JSONObject(); + item2.put("count", a1_item1.toString()); + item2.put("name", "正常运行"); + // 计算百分比 + double a1Item1Percentage = (double) a1_item1 / a1_count * 100; + String a1Item1Percentages = new DecimalFormat("0.00").format(a1Item1Percentage) + "%"; + item2.put("percent", a1Item1Percentages); + result.add(item2); + a1_item2 = deviceList.stream() + .map(JSONObject.class::cast) + .filter(r -> "2".equals(r.getString("mode"))) + .count(); + JSONObject item3 = new JSONObject(); + item3.put("count", a1_item2.toString()); + item3.put("name", "暂未生产"); + // 计算百分比 + double a1Item2Percentage = (double) a1_item2 / a1_count * 100; + String a1Item2Percentages = new DecimalFormat("0.00").format(a1Item2Percentage) + "%"; + item3.put("percent", a1Item2Percentages); + result.add(item3); + a1_item3 = deviceList.stream() + .map(JSONObject.class::cast) + .filter(r -> "0".equals(r.getString("mode"))) + .count(); + JSONObject item4 = new JSONObject(); + item4.put("count", a1_item3.toString()); + item4.put("name", "空闲设备"); + // 计算百分比 + double a1Item3Percentage = (double) a1_item3 / a1_count * 100; + String a1Item3Percentages = new DecimalFormat("0.00").format(a1Item3Percentage) + "%"; + item4.put("percent", a1Item3Percentages); + result.add(item4); + a1_item4 = deviceList.stream() + .map(JSONObject.class::cast) + .filter(r -> "1".equals(r.getString("mode"))) + .count(); + JSONObject item5 = new JSONObject(); + item5.put("count", a1_item4.toString()); + item5.put("name", "故障设备"); + // 计算百分比 + double a1Item4Percentage = (double) a1_item4 / a1_count * 100; + String a1Item4Percentages = new DecimalFormat("0.00").format(a1Item4Percentage) + "%"; + item5.put("percent", a1Item4Percentages); + result.add(item5); + } + + private static void getDeviceMode(Integer mode, JSONObject json) { + if (mode == 0) { + json.put("mode", "0"); + } else if (mode == 2) { + json.put("mode", "2"); + } else { + json.put("mode", "3"); + } + } + +} diff --git a/acs/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml b/acs/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml index dfb2c9c..54066ad 100644 --- a/acs/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml +++ b/acs/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml @@ -7,10 +7,9 @@ spring: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy # url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.81.252}:${DB_PORT:3306}/${DB_NAME:stand_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true - url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:cw_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true + url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.10.10}:${DB_PORT:3306}/${DB_NAME:cw_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&useOldAliasMetadataBehavior=true username: ${DB_USER:root} -# password: ${DB_PWD:Root.123456} - password: ${DB_PWD:123456} + password: ${DB_PWD:123456789} # 初始连接数 initial-size: 5 # 最小连接数 @@ -71,7 +70,7 @@ spring: baseline-on-migrate: true redis: #数据库索引 - database: ${REDIS_DB:2} + database: ${REDIS_DB:5} host: ${REDIS_HOST:127.0.0.1} port: ${REDIS_PORT:6379} # password: ${REDIS_PWD:} @@ -169,7 +168,7 @@ sa-token: token-session-check-login: false alone-redis: # Redis数据库索引(默认为0) - database: 2 + database: 5 # Redis服务器地址 host: 127.0.0.1 # Redis服务器连接端口 diff --git a/lms/nladmin-system/nlsso-server/pom.xml b/lms/nladmin-system/nlsso-server/pom.xml index 0074b37..55766b3 100644 --- a/lms/nladmin-system/nlsso-server/pom.xml +++ b/lms/nladmin-system/nlsso-server/pom.xml @@ -98,6 +98,11 @@ sa-token-spring-boot-starter ${sa-token.version} + + org.dromara.dynamictp + dynamic-tp-spring-boot-starter-adapter-webserver + 1.1.7 + cn.dev33 sa-token-sso diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/AppRun.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/AppRun.java index f125113..feb2131 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/AppRun.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/AppRun.java @@ -4,6 +4,7 @@ import cn.dev33.satoken.annotation.SaIgnore; import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation; import com.alicp.jetcache.anno.config.EnableMethodCache; import io.swagger.annotations.Api; +import org.dromara.dynamictp.core.spring.EnableDynamicTp; import org.mybatis.spring.annotation.MapperScan; import org.nl.config.SpringContextHolder; import org.springframework.boot.SpringApplication; @@ -35,6 +36,7 @@ import org.springframework.web.bind.annotation.RestController; @EnableMethodCache(basePackages = "org.nl") @EnableCreateCacheAnnotation @MapperScan("org.nl.**.mapper") +@EnableDynamicTp public class AppRun { public static void main(String[] args) { diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/common/base/ErrorData.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/common/base/ErrorData.java new file mode 100644 index 0000000..eae3279 --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/common/base/ErrorData.java @@ -0,0 +1,14 @@ +package org.nl.common.base; + +import lombok.Data; + +/** + * 异常信息 + * + * @author gbx + * @since 2024-01-04 + */ +@Data +public class ErrorData { + private String error_info; +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/AsyncTaskExecutePool.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/AsyncTaskExecutePool.java index 0f7083a..0554590 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/AsyncTaskExecutePool.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/AsyncTaskExecutePool.java @@ -17,6 +17,7 @@ package org.nl.config.thread; import lombok.extern.slf4j.Slf4j; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -67,4 +68,35 @@ public class AsyncTaskExecutePool implements AsyncConfigurer { log.error("exception method:"+method.getName()); }; } + + + /** + * 线程池配置 + * @return java.util.concurrent.Executor + * @author gbx + * @since 2023-06-16 + */ + @Bean(name = "taskExecutor") + public ThreadPoolTaskExecutor threadPoolTaskExecutor() { + ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); + // 核心线程池大小 + threadPoolTaskExecutor.setCorePoolSize(config.getCorePoolSize()); + // 最大线程数 + threadPoolTaskExecutor.setMaxPoolSize(config.getMaxPoolSize()); + // 队列容量 + threadPoolTaskExecutor.setQueueCapacity(config.getQueueCapacity()); + // 活跃时间 + threadPoolTaskExecutor.setKeepAliveSeconds(config.getKeepAliveSeconds()); + // 主线程等待子线程执行时间 + threadPoolTaskExecutor.setAwaitTerminationSeconds(config.getAwaitTerminationSeconds()); + // threadPoolTaskExecutor.setAwaitTerminationSeconds(30); + // 线程名字前缀 + threadPoolTaskExecutor.setThreadNamePrefix("test-thread-"); + // RejectedExecutionHandler:当pool已经达到max-size的时候,如何处理新任务 + // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行 + threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + // 初始化 + threadPoolTaskExecutor.initialize(); + return threadPoolTaskExecutor; + } } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/AsyncTaskProperties.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/AsyncTaskProperties.java index 3a1541e..eab33d3 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/AsyncTaskProperties.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/AsyncTaskProperties.java @@ -36,4 +36,5 @@ public class AsyncTaskProperties { private int keepAliveSeconds; private int queueCapacity; + private int awaitTerminationSeconds; } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/ThreadPoolExecutorUtil.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/ThreadPoolExecutorUtil.java index 00c1bfe..279e9b3 100644 --- a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/ThreadPoolExecutorUtil.java +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/ThreadPoolExecutorUtil.java @@ -16,7 +16,12 @@ package org.nl.config.thread; +import org.dromara.dynamictp.core.support.DynamicTp; import org.nl.config.SpringContextHolder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; @@ -27,7 +32,10 @@ import java.util.concurrent.TimeUnit; * @author Zheng Jie * @date 2019年10月31日18:16:47 */ +@Configuration public class ThreadPoolExecutorUtil { + @Autowired + private AsyncTaskProperties asyncTaskProperties; public static ThreadPoolExecutor getPoll(){ AsyncTaskProperties properties = SpringContextHolder.getBean(AsyncTaskProperties.class); @@ -40,4 +48,18 @@ public class ThreadPoolExecutorUtil { new TheadFactoryName() ); } + + @Bean + @Primary + @DynamicTp("el-thread") + public ThreadPoolExecutor threadPoolExecutor() { + return new ThreadPoolExecutor( + asyncTaskProperties.getCorePoolSize(), + asyncTaskProperties.getMaxPoolSize(), + asyncTaskProperties.getKeepAliveSeconds(), + TimeUnit.SECONDS, + new ArrayBlockingQueue<>(asyncTaskProperties.getQueueCapacity()), + new TheadFactoryName() + ); + } } diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/AcsDefineEnum.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/AcsDefineEnum.java new file mode 100644 index 0000000..1c5d6ad --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/AcsDefineEnum.java @@ -0,0 +1,67 @@ +package org.nl.wms.cockpit; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; +import org.nl.config.MapOf; +import java.util.Map; + +/** + * acs状态枚举 + * + * @author gbx + * @since 2024-01-31 + */ +@AllArgsConstructor +@Getter +public enum AcsDefineEnum { + + //agv状态 1-关机2-运行中3-交通管制4-任务等待5-充电中6-故障中7-低电量 + AGV_STATUS(MapOf.of("关机", "1", "运行中", "2", "交通管制", "3", "任务等待", "4", "充电中", "5", "故障中", "6", "低电量", "7")), + + //RGV状态 1-空闲 2-工作中 3-手动 4-下线 + RGV_STATUS(MapOf.of("1","IDLE","2","WORK","3","UNAVAIL","4","OFFLINE")), + + //载具类型 + VEHICLE_TYPE(MapOf.of("普涂", "1", "连涂", "2")), + + //是否 + IS_USED(MapOf.of("启用", "1", "未启用", "0")); + + + private Map code; + + public String code(String desc) { + String code = this.getCode().get(desc); + if (StringUtils.isNotEmpty(code)) { + return code; + } + throw new RuntimeException(this.name() + "对应类型" + desc + "未定义"); + } + + public Long longCode(String desc) { + String code = this.getCode().get(desc); + if (StringUtils.isNotEmpty(code)) { + return Long.valueOf(code); + } + throw new RuntimeException(this.name() + "对应类型" + desc + "未定义"); + } + + public String check(String code) { + for (Map.Entry entry : this.getCode().entrySet()) { + if (entry.getValue().equals(code)) { + return entry.getValue(); + } + } + throw new RuntimeException(this.name() + "对应类型" + code + "未定义"); + } + + public String check1(String code) { + for (Map.Entry entry : this.getCode().entrySet()) { + if (entry.getValue().equals(code)) { + return entry.getKey(); + } + } + throw new RuntimeException(this.name() + "对应类型" + code + "未定义"); + } +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/controller/CockpitController.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/controller/CockpitController.java new file mode 100644 index 0000000..22a2c5a --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/controller/CockpitController.java @@ -0,0 +1,52 @@ +package org.nl.wms.cockpit.controller; + +import cn.dev33.satoken.annotation.SaIgnore; +import com.alibaba.fastjson.JSONObject; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.nl.common.logging.annotation.Log; +import org.nl.wms.cockpit.service.CockpitService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +/** + * @Author: gbx + * @Description: 天能数字孪生接口 + * @Date: 2024/10/18 + */ +@RestController +@Api(tags = "数字孪生") +@RequestMapping("/api/chaoWei") +@Slf4j +@SaIgnore +public class CockpitController { + + @Autowired + private CockpitService cockpitService; + + + @PostMapping("/allDeviceStatus") + @Log("秒级接口") + @ApiOperation("秒级接口") + public ResponseEntity allDeviceStatus() { + return new ResponseEntity<>(cockpitService.allDeviceStatus(), HttpStatus.OK); + } + + + + @PostMapping("/getHomeInfo") + @Log("获取首页总览信息") + @ApiOperation("获取首页总览信息") + public ResponseEntity getHomeInfo() { + return new ResponseEntity<>(cockpitService.getHomeInfo(), HttpStatus.OK); + } + + + + +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/CockpitService.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/CockpitService.java new file mode 100644 index 0000000..88e2ae0 --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/CockpitService.java @@ -0,0 +1,24 @@ +package org.nl.wms.cockpit.service; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @Author: gbx + * @Description: + * @Date: 2024/10/18 + */ +public interface CockpitService { + + + JSONObject allDeviceStatus(); + + + HashMap getHomeInfo(); + + + +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/DasDeviceFault.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/DasDeviceFault.java new file mode 100644 index 0000000..b3742b2 --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/DasDeviceFault.java @@ -0,0 +1,36 @@ +package org.nl.wms.cockpit.service.dao; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 设备故障表 + * + * @author gbx + * @since 2024-01-12 + */ + + +@Data +@TableName("das_device_fault") +public class DasDeviceFault implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(value = "data_id", type = IdType.NONE) + private String data_id; + + private String region_code; + + private String device_code; + + private String failure_time; + + private String failure_info; + + private String current_status; + +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/DayData.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/DayData.java new file mode 100644 index 0000000..a95db3c --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/DayData.java @@ -0,0 +1,14 @@ +package org.nl.wms.cockpit.service.dao; + +import lombok.Data; +import org.nl.common.base.ErrorData; + +/** + * @author gbx + * @since 2024-01-08 + */ +@Data +public class DayData extends ErrorData { + private String item_name; + private String item_qty; +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/PointInfo.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/PointInfo.java new file mode 100644 index 0000000..8359843 --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/PointInfo.java @@ -0,0 +1,21 @@ +package org.nl.wms.cockpit.service.dao; + +import io.swagger.models.auth.In; +import lombok.Builder; +import lombok.Data; +import org.nl.common.base.ErrorData; + +/** + * 点位 + * + * @author gbx + * @since 2024-01-11 + */ +@Data +public class PointInfo { + private String device_code; + private String workshop_code; + private String region_code; + private Integer move; + private Integer row_num; +} \ No newline at end of file diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/TargetAchievement.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/TargetAchievement.java new file mode 100644 index 0000000..f051d7d --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/TargetAchievement.java @@ -0,0 +1,40 @@ +package org.nl.wms.cockpit.service.dao; + +import lombok.Data; +import org.nl.common.base.ErrorData; + +import java.math.BigDecimal; + +/** + * 生产目标 + * + * @author gbx + * @since 2024-01-07 + */ + +@Data +public class TargetAchievement extends ErrorData { + //接口文档待修改 + private BigDecimal expected_production = BigDecimal.valueOf(0); + private BigDecimal actual_production= BigDecimal.valueOf(0);; + private Integer percentage =0; + private String await_curing = "1"; + private String curing = "1"; + private String complete = "1"; + private String material_name = "1"; + private String vehicle_type = "1"; + private String create_time = "1"; + private TbxTargetAchievement tbxTargetAchievement; + + @Data + public static class TbxTargetAchievement extends ErrorData { + //接口文档待修改 + private TargetAchievement lt_production; + private TargetAchievement pt_production; + + } + +} + + + diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/TaskInfo.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/TaskInfo.java new file mode 100644 index 0000000..08d3ca5 --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/dao/TaskInfo.java @@ -0,0 +1,27 @@ +package org.nl.wms.cockpit.service.dao; + +import lombok.Data; +import org.nl.common.base.ErrorData; + +/** + * 任务 + * + * @author gbx + * @since 2024-01-11 + */ +@Data +public class TaskInfo extends ErrorData { + private String car_no; + private String point_code; + private String point_code1; + private String point_code2; + private String material_name; + private String material_spec; + private String qty; + private String type; + private Integer task_status; + private String material_qty; + private String vehicle_type; + private String vehicle_code; + private String task_type; +} \ No newline at end of file diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/impl/CockpitServiceImpl.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/impl/CockpitServiceImpl.java new file mode 100644 index 0000000..a50db6b --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/impl/CockpitServiceImpl.java @@ -0,0 +1,638 @@ +package org.nl.wms.cockpit.service.impl; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.nl.common.utils.RedisUtils; +import org.nl.wms.cockpit.service.CockpitService; +import org.nl.wms.cockpit.service.dao.PointInfo; +import org.nl.wms.cockpit.service.dao.TaskInfo; +import org.nl.wms.cockpit.service.mapper.CockpitMapper; +import org.nl.wms.sch.point.service.dao.SchBasePoint; +import org.nl.wms.sch.point.service.impl.SchBasePointServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +/** + * @Author: gbx + * @Description: + * @Date: 2024/10/18 + */ +@Service +@Slf4j +@EnableScheduling +public class CockpitServiceImpl implements CockpitService { + + @Autowired + private CockpitMapper cockpitMapper; + + @Autowired + @Qualifier("threadPoolExecutor") + private ThreadPoolExecutor pool; + + + @Resource + private SchBasePointServiceImpl schBasePoint; + + @Autowired + private RedisUtils redisUtils; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd"); + LocalDate today = LocalDate.now(); + + /** + * 总览 + */ + @Override + public HashMap getHomeInfo() { + HashMap getHomeInfo = new HashMap<>(); + //设备运行状态 + JSONObject device_status = new JSONObject(); + //库存结构 + JSONObject zc_storage_info = new JSONObject(); + //状态信息 + CompletableFuture task1 = CompletableFuture.supplyAsync(() -> { + List> result = cockpitMapper.statusInfo(); + device_status.put("status_info", result); + return null; + }, pool); + task1.exceptionally((e) -> { + log.error("状态信息: {}", e.getMessage(), e); + device_status.put("status_info", null); + return null; + }); + //固化架信息 + CompletableFuture task2 = CompletableFuture.supplyAsync(() -> { + List> result = cockpitMapper.storageInfo(); + device_status.put("storage_info", result); + return null; + }, pool); + task2.exceptionally((e) -> { + log.error("固化架信息: {}", e.getMessage(), e); + device_status.put("storage_info", null); + return null; + }); + //暂存库库存结构 + CompletableFuture task3 = CompletableFuture.supplyAsync(() -> { + List> result = cockpitMapper.getZcMaterialmsg(); + zc_storage_info.put("material_info", result); + return null; + }, pool); + task3.exceptionally((e) -> { + log.error("暂存库库存结构: {}", e.getMessage(), e); + zc_storage_info.put("material_info", null); + return null; + }); + //库位使用占比 + CompletableFuture task4 = CompletableFuture.supplyAsync(() -> { + String result = cockpitMapper.percent(); + zc_storage_info.put("percent", result); + return null; + }, pool); + task4.exceptionally((e) -> { + log.error("库位使用占比: {}", e.getMessage(), e); + getHomeInfo.put("percent", null); + return null; + }); + //生产任务目标达成 + CompletableFuture task5 = CompletableFuture.supplyAsync(() -> { + JSONObject result = cockpitMapper.getProductTarget(); + getHomeInfo.put("target_achievement", result); + return null; + }, pool); + task5.exceptionally((e) -> { + log.error("获取生产任务目标达成: {}", e.getMessage(), e); + getHomeInfo.put("target_achievement", null); + return null; + }); + //生产汇总 + CompletableFuture task6 = CompletableFuture.supplyAsync(() -> { + JSONObject result = cockpitMapper.getProductionsummary(); + List> productionSummaryList = new ArrayList<>(); + for (String itemName : Arrays.asList("1", "2", "3")) { + Map item = new HashMap<>(); + item.put("item_name", itemName); + item.put("item_qty", "0"); + productionSummaryList.add(item); + } + if (ObjectUtil.isNotEmpty(result)) { + productionSummaryList.forEach(item -> { + String key = item.get("item_name").toString().toLowerCase(); + if (ObjectUtil.isNotEmpty(result.get(key))) { + item.put("item_qty", result.get(key).toString()); + } + }); + } + getHomeInfo.put("production_summary", productionSummaryList); + return null; + }, pool); + task6.exceptionally((e) -> { + log.error("生产汇总: {}", e.getMessage(), e); + getHomeInfo.put("production_summary", null); + return null; + }); + //今日生产任务 + CompletableFuture>> task7 = CompletableFuture.supplyAsync(() -> { + List> result = cockpitMapper.getTdWorkmsg(); + // List> today_work = new ArrayList<>(); + // if (ObjectUtil.isEmpty(result)) { + // //测试数据,上线后删除 + // Map item1 = new HashMap<>(); + // item1.put("workorder_code", "240918001"); + // item1.put("material_name", "TS_12Z中负"); + // item1.put("plan_qty", "100"); + // item1.put("real_qty", "0"); + // item1.put("point_name", "普涂线01"); + // item1.put("device_code", "LTX01"); + // item1.put("workorder_status", "生产中"); + // today_work.add(item1); + // } + getHomeInfo.put("today_work", result); + return null; + }, pool); + task7.exceptionally((e) -> { + log.error("今日生产任务: {}", e.getMessage(), e); + getHomeInfo.put("today_work", null); + return null; + }); + //固化一周生产 + CompletableFuture>> task8 = CompletableFuture.supplyAsync(() -> { + List> result = cockpitMapper.getGhsQty("7"); + List> gh_real_qty_default = new ArrayList<>(); + getWeekWorkStatistics(result, gh_real_qty_default, "GHS", 7); + getHomeInfo.put("ghs_produce", gh_real_qty_default); + return null; + }, pool); + task8.exceptionally((e) -> { + log.error("固化一周生产: {}", e.getMessage(), e); + getHomeInfo.put("ghs_produce", null); + return null; + }); + //涂板一周生产 + CompletableFuture>> task9 = CompletableFuture.supplyAsync(() -> { + List> result = cockpitMapper.getTxQty("7", "TBX"); + List> tb_real_qty_default = new ArrayList<>(); + getWeekWorkStatistics(result, tb_real_qty_default, "TBX", 7); + getHomeInfo.put("tbx_produce", tb_real_qty_default); + return null; + }, pool); + task9.exceptionally((e) -> { + log.error("涂板一周生产: {}", e.getMessage(), e); + getHomeInfo.put("tbx_produce", null); + return null; + }); + //实时故障告警 + CompletableFuture>> task10 = CompletableFuture.supplyAsync(() -> { + List> result = cockpitMapper.faultAlarm(); + //测试数据,上线后删除 + //faultAlarmDefault(result, "GHS01"); + getHomeInfo.put("fault_alarm", result); + return null; + }, pool); + task10.exceptionally((e) -> { + log.error("实时故障告警: {}", e.getMessage(), e); + getHomeInfo.put("fault_alarm", null); + return null; + }); + //近30日故障统计 + CompletableFuture task11 = CompletableFuture.supplyAsync(() -> { + JSONArray result = cockpitMapper.monthlyFaultStatistics(); + getHomeInfo.put("monthly_fault_statistics", result); + return null; + }, pool); + task11.exceptionally((e) -> { + log.error("近30日故障统计: {}", e.getMessage(), e); + getHomeInfo.put("monthly_fault_statistics", null); + return null; + }); + //设备报警前十 + CompletableFuture>> task12 = CompletableFuture.supplyAsync(() -> cockpitMapper.ghStatistics(), pool); + task12.thenAccept((result) -> { + getHomeInfo.put("gh_statistics", result); + }).exceptionally((e) -> { + log.error("设备报警前十: {}", e.getMessage(), e); + getHomeInfo.put("gh_statistics", null); + return null; + }); + CompletableFuture allQuery = CompletableFuture.allOf(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12); + CompletableFuture> future = allQuery.thenApply((result) -> getHomeInfo).exceptionally((e) -> { + log.error(e.getMessage(), e); + return null; + }); + future.join(); + getHomeInfo.put("device_status", device_status); + getHomeInfo.put("zc_storage_info", zc_storage_info); + return getHomeInfo; + } + + + /** + * 秒级接口 + */ + @Override + public JSONObject allDeviceStatus() { + JSONObject jsonObject = new JSONObject(); + //涂板线 + CompletableFuture>> task1 = CompletableFuture.supplyAsync(() -> { + // todo 初始化点位所在排信息 + // List list = schBasePoint.list(new LambdaQueryWrapper().eq(SchBasePoint::getIs_used, 1)); + // List list1 = list.stream().filter(r -> "HCQ1".equals(r.getRegion_code()) || "HCQ2".equals(r.getRegion_code()) || "HCQ3".equals(r.getRegion_code()) || "HCQ4".equals(r.getRegion_code()) || "HCQ5".equals(r.getRegion_code()) || "HCQ7".equals(r.getRegion_code())).collect(Collectors.toList()); + // for (SchBasePoint r : list1) { + // if (r.getRow_num() == 0) { + // LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper() + // .eq(SchBasePoint::getPoint_code, r.getPoint_code()); + // String pointId = r.getPoint_code().substring(5, 9); + // updateWrapper.set(SchBasePoint::getRow_num, Integer.parseInt(pointId)); + // schBasePoint.update(null, updateWrapper); + // } + // } + // todo 未对接的涂板线数据 + JSONObject tbx01 = new JSONObject(); + tbx01.put("mode", "0"); + tbx01.put("device_code", "TBX0001"); + tbx01.put("workshop_code", "A1"); + JSONObject tbx02 = new JSONObject(); + tbx02.put("mode", "0"); + tbx02.put("device_code", "TBX0002"); + tbx02.put("workshop_code", "A1"); + JSONArray tbx1 = (JSONArray) redisUtils.get("tbxList1"); + tbx1.add(tbx01); + tbx1.add(tbx02); + List tbxList1 = getSortedList(tbx1); + if (ObjectUtil.isNotEmpty(tbxList1)) { + jsonObject.put("1", tbxList1); + } else { + jsonObject.put("1", new JSONArray()); + } + JSONArray tbx2 = (JSONArray) redisUtils.get("tbxList2"); + List tbxList2 = getSortedList(tbx2); + if (ObjectUtil.isNotEmpty(tbxList2)) { + jsonObject.put("9", tbxList2); + } else { + jsonObject.put("9", new JSONArray()); + } + return null; + }, pool); + task1.exceptionally((e) -> { + log.error("读取涂板线设备缓存信息: {}", e.getMessage(), e); + return null; + }); + CompletableFuture>> task2 = CompletableFuture.supplyAsync(() -> { + JSONArray ghs1 = (JSONArray) redisUtils.get("ghsList1"); + List ghsList1 = getSortedList(ghs1); + JSONArray ghs2 = (JSONArray) redisUtils.get("ghsList2"); + List ghsList2 = getSortedList(ghs2); + if (ObjectUtil.isNotEmpty(ghsList1)) { + jsonObject.put("2", ghsList1); + } else { + jsonObject.put("2", new JSONArray()); + } + if (ObjectUtil.isNotEmpty(ghsList2)) { + jsonObject.put("11", ghsList2); + } else { + jsonObject.put("11", new JSONArray()); + } + return null; + }, pool); + task2.exceptionally((e) -> { + log.error("读取固化室设备缓存信息: {}", e.getMessage(), e); + return null; + }); + CompletableFuture>> task3 = CompletableFuture.supplyAsync(() -> { + JSONArray bpjList = (JSONArray) redisUtils.get("bpjList"); + List bpjList1 = getSortedList(bpjList); + if (ObjectUtil.isNotEmpty(bpjList1)) { + jsonObject.put("7", bpjList1); + } else { + jsonObject.put("7", new JSONArray()); + } + JSONArray deviceA1 = (JSONArray) redisUtils.get("deviceA1"); + JSONArray deviceA2 = (JSONArray) redisUtils.get("deviceA2"); + jsonObject.put("17", deviceA1); + jsonObject.put("19", deviceA2); + return null; + }, pool); + task3.exceptionally((e) -> { + log.error("读取包片机设备缓存信息: {}", e.getMessage(), e); + return null; + }); + CompletableFuture>> task4 = CompletableFuture.supplyAsync(() -> { + //正极板空架回收位 + JSONArray zjbKjHswList = (JSONArray) redisUtils.get("zjbKjHswList"); + List zjbKjHswList1 = getSortedList(zjbKjHswList); + //负极板空架回收位 + JSONArray fjbKjDjwList = (JSONArray) redisUtils.get("fjbKjDjwList"); + List fjbKjDjwList1 = getSortedList(fjbKjDjwList); + //正极板对接位 + JSONArray zjbDjwList = (JSONArray) redisUtils.get("zjbDjwList"); + List zjbDjwList1 = getSortedList(zjbDjwList); + if (ObjectUtil.isNotEmpty(zjbKjHswList1)) { + jsonObject.put("13", zjbKjHswList1); + } else { + jsonObject.put("13", new JSONArray()); + } + if (ObjectUtil.isNotEmpty(fjbKjDjwList1)) { + jsonObject.put("14", fjbKjDjwList1); + } else { + jsonObject.put("14", new JSONArray()); + } + if (ObjectUtil.isNotEmpty(zjbDjwList1)) { + jsonObject.put("15", zjbDjwList1); + } else { + jsonObject.put("15", new JSONArray()); + } + return null; + }, pool); + task4.exceptionally((e) -> { + log.error("读取包片机设备缓存信息: {}", e.getMessage(), e); + return null; + }); + CompletableFuture task5 = CompletableFuture.supplyAsync(() -> { + JSONArray jsonArray = cockpitMapper.getZCList(); + List pointInfoList = jsonArray.stream() + .map(r -> JSON.parseObject(r.toString(), PointInfo.class)) + .collect(Collectors.toList()); + //正极板空固化架缓存区A1 + List hcq6 = pointInfoList.stream().filter(r -> "HCQ6".equals(r.getRegion_code())).sorted(Comparator.comparing(PointInfo::getRow_num)).collect(Collectors.toList()); + AtomicReference> list1 = new AtomicReference<>(); + CompletableFuture>> task01 = CompletableFuture.supplyAsync(() -> { + //边负极板缓存区 + List hcq1 = pointInfoList.stream().filter(r -> "HCQ3".equals(r.getRegion_code())).collect(Collectors.toList()); + list1.set(getPointInfoList(hcq1)); + return null; + }, pool); + AtomicReference> list2 = new AtomicReference<>(); + CompletableFuture>> task02 = CompletableFuture.supplyAsync(() -> { + //边负极板缓存区 + //负极板缓存区 + List hcq2 = pointInfoList.stream().filter(r -> "HCQ2".equals(r.getRegion_code())).collect(Collectors.toList()); + list2.set(getPointInfoList(hcq2)); + return null; + }, pool); + AtomicReference> list3 = new AtomicReference<>(); + CompletableFuture>> task03 = CompletableFuture.supplyAsync(() -> { + //负极板空架缓存区 + List hcq3 = pointInfoList.stream().filter(r -> "HCQ1".equals(r.getRegion_code())).collect(Collectors.toList()); + list3.set(getPointInfoList(hcq3)); + return null; + }, pool); + AtomicReference> list4 = new AtomicReference<>(); + CompletableFuture>> task04 = CompletableFuture.supplyAsync(() -> { + //正极板缓存区 + List hcq4 = pointInfoList.stream().filter(r -> "HCQ4".equals(r.getRegion_code())).collect(Collectors.toList()); + list4.set(getPointInfoList(hcq4)); + return null; + }, pool); + AtomicReference> list5 = new AtomicReference<>(); + CompletableFuture>> task05 = CompletableFuture.supplyAsync(() -> { + //正极板空固化架缓存区 + List hcq5 = pointInfoList.stream().filter(r -> "HCQ5".equals(r.getRegion_code())).collect(Collectors.toList()); + list5.set(getPointInfoList(hcq5)); + return null; + }, pool); + AtomicReference> list7 = new AtomicReference<>(); + CompletableFuture>> task07 = CompletableFuture.supplyAsync(() -> { + //涂板线空固化架缓存区 + List hcq7 = pointInfoList.stream().filter(r -> "HCQ7".equals(r.getRegion_code())).collect(Collectors.toList()); + list7.set(getPointInfoList(hcq7)); + return null; + }, pool); + CompletableFuture allQuery = CompletableFuture.allOf(task01, task02, task03, task04, task05, task07); + CompletableFuture future = allQuery.thenApply((result) -> jsonObject).exceptionally((e) -> { + log.error(e.getMessage(), e); + return null; + }); + future.join(); + jsonObject.put("8", hcq6); + jsonObject.put("4", list1.get()); + jsonObject.put("5", list2.get()); + jsonObject.put("6", list3.get()); + jsonObject.put("12", list4.get()); + jsonObject.put("10", list5.get()); + jsonObject.put("3", list7.get()); + return null; + }, pool); + task5.exceptionally((e) -> { + log.error("库位详情{}", e.getMessage(), e); + return null; + }); + //今日生产任务 + CompletableFuture>> task6 = CompletableFuture.supplyAsync(() -> { + JSONArray a1 = new JSONArray(); + JSONArray a2 = new JSONArray(); + JSONObject tbx = new JSONObject(); + JSONObject ghs = new JSONObject(); + JSONObject tbx1 = new JSONObject(); + JSONObject ghs1 = new JSONObject(); + List result = cockpitMapper.getTodayTaskList(); + if (ObjectUtil.isNotEmpty(result)) { + Integer[] tbInProduction = {0, 0}; + Integer[] tbEndProduction = {0, 0}; + Integer[] ghInProduction = {0, 0}; + Integer[] ghEndProduction = {0, 0}; + //生产中的涂板任务 + List list1 = result.stream().filter(r -> r.getTask_status() < 5 && "MJXLTask".equals(r.getType())).collect(Collectors.toList()); + extracted(list1, tbInProduction); + //生产完成的涂板任务 + List list2 = result.stream().filter(r -> r.getTask_status() == 5 && "MJXLTask".equals(r.getType())).collect(Collectors.toList()); + extracted(list2, tbEndProduction); + //生产中的固化任务 + List list3 = result.stream().filter(r -> "GHSFMTask".equals(r.getType())).collect(Collectors.toList()); + extracted(list3, ghInProduction); + //生产完成的固化任务 + List list4 = result.stream().filter(r -> "GHSQHTask".equals(r.getType())).collect(Collectors.toList()); + extracted(list4, ghEndProduction); + tbx.put("device_code", "涂板"); + tbx.put("a", tbInProduction[0]); + tbx.put("b", tbEndProduction[0]); + a1.add(tbx); + tbx1.put("device_code", "涂板"); + tbx1.put("a", tbInProduction[1]); + tbx1.put("b", tbEndProduction[1]); + a2.add(tbx1); + ghs.put("device_code", "固化"); + ghs.put("a", ghInProduction[0]); + ghs.put("b", ghEndProduction[0]); + a1.add(ghs); + ghs1.put("device_code", "固化"); + ghs1.put("a", ghInProduction[1]); + ghs1.put("b", ghEndProduction[1]); + a2.add(ghs1); + } else { + tbx.put("device_code", "涂板"); + tbx.put("a", "0"); + tbx.put("b", 0); + a1.add(tbx); + ghs.put("device_code", "固化"); + ghs.put("a", "0"); + ghs.put("b", 0); + a1.add(ghs); + tbx1.put("device_code", "涂板"); + tbx1.put("a", "0"); + tbx1.put("b", 0); + a2.add(tbx1); + ghs1.put("device_code", "固化"); + ghs1.put("a", "0"); + ghs1.put("b", 0); + a2.add(ghs1); + } + jsonObject.put("16", a1); + jsonObject.put("18", a2); + return null; + }, pool); + task6.exceptionally((e) -> { + log.error("今日生产任务: {}", e.getMessage(), e); + return null; + }); + //设备统计 + // CompletableFuture>> task7 = CompletableFuture.supplyAsync(() -> { + // JSONArray a1 = new JSONArray(); + // JSONArray a2 = new JSONArray(); + // //测试数据,上线后删除 + // if (ObjectUtil.isEmpty(a1)) { + // JSONObject item1 = new JSONObject(); + // item1.put("count", "401"); + // a1.add(item1); + // JSONObject item2 = new JSONObject(); + // item2.put("count", "350"); + // item2.put("name", "正常运行"); + // item2.put("percent", "87.28%"); + // a1.add(item2); + // JSONObject item3 = new JSONObject(); + // item3.put("count", "29"); + // item3.put("name", "暂未生产"); + // item3.put("percent", "0.07%"); + // a1.add(item3); + // JSONObject item4 = new JSONObject(); + // item4.put("count", "21"); + // item4.put("name", "空闲设备"); + // item4.put("percent", "0.05%"); + // a1.add(item4); + // JSONObject item5 = new JSONObject(); + // item5.put("count", "1"); + // item5.put("name", "故障设备"); + // item5.put("percent", "0.02%"); + // a1.add(item5); + // JSONObject item01 = new JSONObject(); + // item01.put("count", "439"); + // a2.add(item01); + // JSONObject item02 = new JSONObject(); + // item02.put("count", "321"); + // item02.put("name", "正常运行"); + // item02.put("percent", "73.12%"); + // a2.add(item02); + // JSONObject item03 = new JSONObject(); + // item03.put("count", "51"); + // item03.put("name", "暂未生产"); + // item03.put("percent", "11.61%"); + // a2.add(item03); + // JSONObject item04 = new JSONObject(); + // item04.put("count", "60"); + // item04.put("name", "空闲设备"); + // item04.put("percent", "13.66%"); + // a2.add(item04); + // JSONObject item05 = new JSONObject(); + // item05.put("count", "7"); + // item05.put("name", "故障设备"); + // item05.put("percent", "0.01%"); + // a2.add(item05); + // } + // jsonObject.put("17", a1); + // jsonObject.put("19", a2); + // return null; + // }, pool); + // task7.exceptionally((e) -> { + // log.error("今日生产任务: {}", e.getMessage(), e); + // return null; + // }); + CompletableFuture allQuery = CompletableFuture.allOf(task1, task2, task3, task4, task5, task6); + CompletableFuture future = allQuery.thenApply((result) -> jsonObject).exceptionally((e) -> { + log.error(e.getMessage(), e); + return null; + }); + future.join(); + return jsonObject; + } + + private static void extracted(List list, Integer[] production) { + list.stream() + .peek(taskInfo -> { + if (StringUtils.isBlank(taskInfo.getPoint_code1()) && StringUtils.isNotBlank(taskInfo.getPoint_code2())) { + taskInfo.setPoint_code1(taskInfo.getPoint_code2()); + } + }) + .forEach(taskInfo -> { + int vehicleCount = taskInfo.getVehicle_code().split(",").length; + if ("A1".equals(taskInfo.getPoint_code1())) { + production[0] += vehicleCount; + } else { + production[1] += vehicleCount; + } + }); + } + + private static List getSortedList(JSONArray jsonArray) { + return jsonArray.stream() + .map(JSONObject.class::cast) + .sorted(Comparator.comparing(json -> json.getString("device_code"))) + .collect(Collectors.toList()); + } + + private static List getPointInfoList(List pointInfoList) { + Map> groupedByRowNum = pointInfoList.stream() + .collect(Collectors.groupingBy(PointInfo::getRow_num)); + List result = groupedByRowNum.entrySet().stream() + .map(r -> { + List groupList = r.getValue(); + PointInfo point = groupList.get(0); + if (groupList.stream().anyMatch(g -> g.getMove() == 3)) { + point.setMove(3); + } else { + point.setMove(0); + } + return point; + }).sorted(Comparator.comparing(PointInfo::getRow_num)) + .collect(Collectors.toList()); + return result; + } + + + private void getWeekWorkStatistics(List> gh_real_qty, List> tb_real_qty_default, String region_name, Integer days) { + for (int i = 0; i < days; i++) { + Map item = new HashMap<>(); + item.put("region_name", region_name); + item.put("total_qty", "0"); + item.put("date", today.minusDays(i).format(formatter)); + tb_real_qty_default.add(item); + } + Map ghRealQtyMap = gh_real_qty.stream() + .collect(Collectors.toMap( + item -> (String) item.get("date"), + item -> (BigDecimal) item.get("total_qty") + )); + tb_real_qty_default.forEach(tbItem -> { + String date = (String) tbItem.get("date"); + if (ghRealQtyMap.containsKey(date)) { + tbItem.put("total_qty", ghRealQtyMap.get(date)); + } + }); + } + + +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/mapper/CockpitMapper.java b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/mapper/CockpitMapper.java new file mode 100644 index 0000000..763aecf --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/mapper/CockpitMapper.java @@ -0,0 +1,151 @@ +package org.nl.wms.cockpit.service.mapper; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Param; +import org.nl.wms.cockpit.service.dao.DasDeviceFault; +import org.nl.wms.cockpit.service.dao.DayData; +import org.nl.wms.cockpit.service.dao.TargetAchievement; +import org.nl.wms.cockpit.service.dao.TaskInfo; +import org.nl.wms.sch.point.service.dao.SchBasePoint; + +import java.util.List; +import java.util.Map; + +/** + * @Author: gbx + * @Description: + * @Date: 2024/10/18 + */ +public interface CockpitMapper { + /** + * 获取最近n条工单数据 + * + * @param deviceCode + * @param number + * @return + */ + List getDeviceLimitOrders(@Param("deviceCode") String deviceCode, @Param("number") int number); + + + List getTemporaryStorage(); + + + List getTemporaryInTask(); + + + List getTemporaryOutTask(); + + + TargetAchievement getCompletionPercent(@Param("regionCode") String regionCode, @Param("vehicleType") String vehicleType, @Param("days") Integer days); + + + List getWorkOrders(@Param("regionCode") String regionCode, @Param("days") Integer days); + + List> getCurrentTasks(@Param("deviceCodes") List deviceCodes); + + JSONObject getCurrentTask(@Param("taskId") String taskId); + + List getGhActualProduction(@Param("days") Integer days); + + + List getTodayTaskList(); + + + JSONObject getFaultsForDevice(@Param("deviceCode") String deviceCode); + + + List getGhCuringSummary(); + + @Insert("INSERT INTO das_device_fault (data_id,region_code, device_code, failure_time, failure_info) " + + "VALUES (#{data_id},#{region_code}, #{device_code}, #{failure_time}, #{failure_info})") + int insertDeviceFault(DasDeviceFault deviceFault); + + + JSONObject getVehicleGroupInfo(String vehicleCode, String vehicleType); + + /** + * 固化室详情 + * + * @return + */ + JSONArray getGHSInteriorList(); + + + JSONArray getSSXInteriorList(); + + JSONArray getZCList(); + + JSONArray getKJList(); + + //目前是获取当天的错误数据 + JSONArray getError(); + + //获取生产中的工单数据 + JSONObject getProductTarget(); + + //获取暂存库库存信息 + List> getZcMaterialmsg(); + + //获取暂存库库存信息 + JSONObject getProductionsummary(); + + + //库位使用占比 + String percent(); + + //获取今日创建的每一条工单的信息 + List> getTdWorkmsg(); + + //7天涂板实际生产 + List> getTxQty(String days, String region); + + //7天固化室实际生产 + List> getGhsQty(String days); + + //获取连涂普涂月统计数 + List> getTbxMonthlyStatistics(); + + //查询所传设备当前生产的工单信息 + JSONObject getDeviceWorker(String devicecode); + + //根据所传的物料id获取物料名称 + String getMaterialName(String material_id); + + //根据所传设备得到该设备日产量 + JSONArray getProductionDay(String devicecode); + + //根据所传设备得到该设备班产量 + JSONArray getProductionTeam(@Param("deviceCode") String devicecode,@Param("dateType") Integer dateType); + + //根据所传设备得到该设备30天生产记录 + List> getProductionHistory(String devicecode); + //今日生产连涂生产 + JSONObject ltProduction(); + //今日生产普涂生产 + JSONObject ptProduction(); + //今日涂板任务 + JSONArray todayTbTask(); + //实时故障告警 + List> FaultTime(String region_code); + //进30日故障统计 + JSONArray FaultTotal(String region_code); + //固化汇总 + JSONArray curingSummary(); + //暂存库 + JSONObject temporaryStorage(); + //暂存区库存 + JSONArray inventory(); + //状态信息 + List> statusInfo(); + //固化架信息 + List> storageInfo(); + //实时故障告警 + List> faultAlarm(); + //进30日故障统计 + JSONArray monthlyFaultStatistics(); + //设备报警前十 + List> ghStatistics(); + //货位货位信息 + JSONArray taskInfo(); +} diff --git a/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/mapper/CockpitMapper.xml b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/mapper/CockpitMapper.xml new file mode 100644 index 0000000..87b6486 --- /dev/null +++ b/lms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/cockpit/service/mapper/CockpitMapper.xml @@ -0,0 +1,782 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lms/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml b/lms/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml index 0ef6ed3..2261c61 100644 --- a/lms/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml +++ b/lms/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml @@ -6,10 +6,10 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy - url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:cw_lms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true + url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.10.10}:${DB_PORT:3306}/${DB_NAME:cw_lms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true # url: jdbc:log4jdbc:mysql://${DB_HOST:47.111.78.178}:${DB_PORT:3306}/${DB_NAME:stand_lms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true username: ${DB_USER:root} - password: ${DB_PWD:123456} + password: ${DB_PWD:123456789} # password: ${DB_PWD:P@ssw0rd} # 初始连接数 initial-size: 5 @@ -54,7 +54,7 @@ spring: multi-statement-allow: true redis: #数据库索引 - database: ${REDIS_DB:2} + database: ${REDIS_DB:5} host: ${REDIS_HOST:127.0.0.1} port: ${REDIS_PORT:6379} password: ${REDIS_PWD:} @@ -152,7 +152,7 @@ sa-token: token-session-check-login: false alone-redis: # Redis数据库索引(默认为0) - database: 2 + database: 5 # Redis服务器地址 host: 127.0.0.1 # Redis服务器连接端口