diff --git a/src/main/java/com/heai/modules/production/config/TCPClient.java b/src/main/java/com/heai/modules/production/config/TCPClient.java new file mode 100644 index 0000000..7dad8d7 --- /dev/null +++ b/src/main/java/com/heai/modules/production/config/TCPClient.java @@ -0,0 +1,165 @@ +package com.heai.modules.production.config; + +import com.heai.modules.production.dao.TcpMapper; +import com.heai.modules.production.entity.ScaleTCPConfigData; +import com.heai.modules.production.entity.TcpData; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.List; +import java.util.Map; +import java.util.concurrent.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Slf4j +@Component +public class TCPClient { + + @Getter + private final Map socketMap = new ConcurrentHashMap<>(); + + @Autowired + private TcpMapper tcpMapper; + + private final ExecutorService executorService = Executors.newCachedThreadPool(); + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); // 定时任务线程池 + + private static final long CHECK_INTERVAL = 5; // 定时检测间隔(秒) + + public void start(List scaleTCPConfigData) { + startTCPClient(scaleTCPConfigData); + } + private void startTCPClient(List scaleTCPConfigData) { + if (!socketMap.isEmpty()){ + clearAllConnections(); + } + log.info("需要连接的设备数量: {}", scaleTCPConfigData.size()); + + for (ScaleTCPConfigData configData : scaleTCPConfigData) { + executorService.submit(() -> connectAndRead(configData)); + // 为每个设备配置一个定时任务,定期检测连接状态 这个业务 重连不能由后台去触发 + // scheduler.scheduleWithFixedDelay(() -> { + // checkConnection(configData); + // }, CHECK_INTERVAL, CHECK_INTERVAL, TimeUnit.SECONDS); + } + } + + private void connectAndRead(ScaleTCPConfigData configData) { + String serverAddress = configData.getIp(); + int port = configData.getPort(); + String key = serverAddress + ":" + port; + + BufferedReader in = null; + Socket socket = null; + + try { + socket = new Socket(); + InetSocketAddress socketAddress = new InetSocketAddress(serverAddress, port); + socket.connect(socketAddress, 30000); + + if (!socket.isConnected()) { + log.error("连接设备失败: IP: {}, Port: {}", configData.getIp(), configData.getPort()); + return; + } + in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + socketMap.put(key, socket); // 保存新连接 + log.info("连接设备成功, IP: {}, Port: {}", configData.getIp(), configData.getPort()); + + // 读取数据 + String responseLine; + while ((responseLine = in.readLine()) != null) { + if (StringUtils.hasText(responseLine)) { + // log.info("{}设备, IP: {}, Port: {}, 采集数据: {}", configData.getEquipmentNo(), configData.getIp(), configData.getPort(), responseLine); + // if (StringUtils.hasText(configData.getRegexp())) { + // log.info("正则表达式: {}", configData.getRegexp()); + // Pattern pattern = Pattern.compile(configData.getRegexp()); + // Matcher matcher = pattern.matcher(responseLine.trim()); + // if (matcher.find()) { + // saveData(configData, matcher.group(1)); + // } + // } else { + // saveData(configData, responseLine); + // } + + TcpData tcpData=new TcpData(); + tcpData.setIp(configData.getIp()); + tcpData.setPort(configData.getPort()); + tcpData.setType(configData.getType()); + tcpData.setValue(responseLine.trim()); + tcpData.setFlag(configData.getDataFlag()); + tcpMapper.saveTcpData(tcpData); + } + } + + } catch (IOException e) { + log.error("连接设备失败或读取数据时发生错误, IP: {}, Port: {}", configData.getIp(), configData.getPort(), e); + closeConnection(key); + } finally { + try { + if (in != null) { + in.close(); + } + if (socket != null && !socket.isClosed()) { + socket.close(); + } + socketMap.remove(key); + log.info("连接已关闭: {}", key); + } catch (IOException e) { + log.error("关闭连接失败: {}", key, e); + } + } + } + + + /** + * 清除所有连接 + */ + private void clearAllConnections() { + log.info("清除所有连接"); + for (String key : socketMap.keySet()) { + closeConnection(key); + } + } + + /** + * 关闭指定连接 + * @param key 连接的标识符 + */ + private void closeConnection(String key) { + try { + Socket socket = socketMap.get(key); + if (socket != null && !socket.isClosed()) { + socket.close(); + socketMap.remove(key); + log.info("连接已关闭: {}", key); + } + } catch (IOException e) { + log.error("关闭连接失败: {}", key, e); + } + } + + /** + * 定时检测连接状态 + * @param config 设备配置 + */ + public void checkConnection(ScaleTCPConfigData config) { + String key = config.getIp() + ":" + config.getPort(); + Socket socket = socketMap.get(key); + + if (socket == null || socket.isClosed() || !socket.isConnected()) { + log.warn("检测到连接断开,尝试重新连接: {}", key); + closeConnection(key); // 先关闭连接 + executorService.submit(() -> connectAndRead(config)); // 尝试重新连接 + } + } + +} diff --git a/src/main/java/com/heai/modules/production/dao/TcpMapper.java b/src/main/java/com/heai/modules/production/dao/TcpMapper.java new file mode 100644 index 0000000..5d0a600 --- /dev/null +++ b/src/main/java/com/heai/modules/production/dao/TcpMapper.java @@ -0,0 +1,18 @@ +package com.heai.modules.production.dao; + +import com.heai.modules.production.entity.ScaleTCPConfigData; +import com.heai.modules.production.entity.TcpData; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Repository; + +@Mapper +@Repository +public interface TcpMapper { + + void saveTcpData(TcpData data); + + ScaleTCPConfigData selectTCPMachine(String type); + + + +} diff --git a/src/main/java/com/heai/modules/production/entity/ScaleTCPConfigData.java b/src/main/java/com/heai/modules/production/entity/ScaleTCPConfigData.java new file mode 100644 index 0000000..6bb86d9 --- /dev/null +++ b/src/main/java/com/heai/modules/production/entity/ScaleTCPConfigData.java @@ -0,0 +1,52 @@ +package com.heai.modules.production.entity; + +import org.apache.ibatis.type.Alias; + +@Alias("ScaleTCPConfigData") +public class ScaleTCPConfigData { + private String ip; + private Integer port; + private String remark; + private String type; + private String dataFlag; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDataFlag() { + return dataFlag; + } + + public void setDataFlag(String dataFlag) { + this.dataFlag = dataFlag; + } +} diff --git a/src/main/java/com/heai/modules/production/entity/TcpData.java b/src/main/java/com/heai/modules/production/entity/TcpData.java new file mode 100644 index 0000000..6db57ad --- /dev/null +++ b/src/main/java/com/heai/modules/production/entity/TcpData.java @@ -0,0 +1,84 @@ +package com.heai.modules.production.entity; + +import java.util.Date; + +public class TcpData { + /** + * + */ + private String ip; + + /** + * + */ + private Integer port; + + /** + * + */ + private String type; + + /** + * + */ + private String value; + + /** + * + */ + private Date createDate; + + /** + * + */ + private String flag; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public String getFlag() { + return flag; + } + + public void setFlag(String flag) { + this.flag = flag; + } +} + diff --git a/src/main/java/com/heai/modules/production/service/impl/AbnormalServiceImpl.java b/src/main/java/com/heai/modules/production/service/impl/AbnormalServiceImpl.java index 92ccbc8..42e6f9e 100644 --- a/src/main/java/com/heai/modules/production/service/impl/AbnormalServiceImpl.java +++ b/src/main/java/com/heai/modules/production/service/impl/AbnormalServiceImpl.java @@ -1,5 +1,6 @@ package com.heai.modules.production.service.impl; +import com.heai.common.utils.DateUtil; import com.heai.common.utils.DateUtils; import com.heai.common.utils.R; import com.heai.common.utils.RandomUtil; @@ -7,9 +8,13 @@ import com.heai.modules.oss.dao.SysOssDao; import com.heai.modules.oss.entity.SysOssEntity; import com.heai.modules.oss.service.SysOssService; import com.heai.modules.production.dao.AbnormalMapper; +import com.heai.modules.production.dao.DailyPlanMapper; import com.heai.modules.production.entity.*; import com.heai.modules.production.service.AbnormalService; import com.heai.modules.sys.entity.SysUserEntity; +import com.heai.modules.taskmanage.dto.TaskDto; +import com.heai.modules.taskmanage.entity.TaskDetailEntity; +import com.heai.modules.taskmanage.service.TaskListService; import org.apache.shiro.SecurityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -20,12 +25,15 @@ import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.*; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; @Service public class AbnormalServiceImpl implements AbnormalService { + @Autowired + private DailyPlanMapper dailyPlanMapper; @Autowired private AbnormalMapper abnormalMapper; @Autowired @@ -35,6 +43,8 @@ public class AbnormalServiceImpl implements AbnormalService { @Value("${sys-file.file-path}") private String filePath; @Autowired + private TaskListService taskListService; + @Autowired private SysOssDao sysOssDao; @Override public List getAbnormalCodeList(){ @@ -52,6 +62,10 @@ public class AbnormalServiceImpl implements AbnormalService { @Override @Transactional public void saveAbnormalData( MultipartFile[] file,AbnormalFeedBackDataIn inData){ + List abList= abnormalMapper.getAbnormalCodeData(inData.getAbnormalCode()); + if(abList.size()==0){ + throw new RuntimeException("异常原因已经停用!"); + } abnormalMapper.saveAbnormalData(inData); Integer abId= inData.getId(); if(file.length>0){ @@ -61,6 +75,48 @@ public class AbnormalServiceImpl implements AbnormalService { data.setFolder("Abnormal"); abnormalService.uploadAbnormal(file,data); } + if("Y".equals(abList.get(0).getNeedFeedBackFlag())||inData.getSeqNo()<1){ + Date date= DateUtil.getDateToDate(new Date(),"yyyy-MM-dd"); + // TaskDto taskDto=abnormalMapper.getOriginator(); + TaskDto taskDto=new TaskDto(); + taskDto.setSite(inData.getSite()); + taskDto.setCreatedBy(inData.getFeedbackBy()); + taskDto.setCustomer(inData.getSeqNo().toString()); + taskDto.setProject("异常反馈"); + taskDto.setFinalStatus("未完成"); + taskDto.setRequiredCompletionDate(date); + taskDto.setStatus("未受理"); + taskDto.setTaskDescription( inData.getAbnormalRemark()); + taskDto.setTaskHeader(abList.get(0).getAbnormalDesc()); + taskDto.setTaskInitiator(taskDto.getCreatedBy()); + taskDto.setTaskStartDate(date); + taskDto.setType("abnormal"); + List taskDetails=abnormalMapper.getTasktSendUsers(taskDto); + if(taskDetails.size()==0){ + throw new RuntimeException("未维护异常反馈群发任务组!请联系管理员"); + } + taskDto.setTaskDetails(taskDetails); + taskListService.saveBatchTaskList(taskDto); + } + if(inData.getSeqNo()<1) { + SOScheduledRoutingOutData outData=new SOScheduledRoutingOutData(); + String transNo = dailyPlanMapper.getTransNo(); + outData.setTransNo(transNo); + outData.setSite(inData.getSite()); + outData.setToTypeFlag("异常反馈检验单"); + outData.setToTypeFlagDb("A"); + outData.setOperatorId(""); + outData.setsWorkCenterNo(""); + outData.setOrderNo(abList.get(0).getAbnormalDesc()); + //检验单加入暂停备注 + outData.setInspectRemark(inData.getAbnormalRemark()); + outData.setPartNo("异常反馈触发"); + outData.setQtyRequired(new BigDecimal(inData.getAbnormalQty())); + outData.setSeqNo(inData.getSeqNo()); + //硫化创建实验室检验单 + dailyPlanMapper.saveSOOpsTransferHeaderNew(outData); + dailyPlanMapper.saveSOOpsTransferDetailNew(outData); + } } @Override diff --git a/src/main/java/com/heai/modules/production/service/impl/DailyPlanServiceImpl.java b/src/main/java/com/heai/modules/production/service/impl/DailyPlanServiceImpl.java index 5284e78..9c0da2b 100644 --- a/src/main/java/com/heai/modules/production/service/impl/DailyPlanServiceImpl.java +++ b/src/main/java/com/heai/modules/production/service/impl/DailyPlanServiceImpl.java @@ -686,7 +686,7 @@ public class DailyPlanServiceImpl implements DailyPlanService { taskDto.setTaskHeader(inData.getPartNo() + inData.getPartDescription()); taskDto.setTaskInitiator(taskDto.getCreatedBy()); taskDto.setTaskStartDate(date); - taskDto.setType("abnormal"); + taskDto.setType("badReport"); List taskDetails = abnormalMapper.getTasktSendUsers(taskDto); if (taskDetails.size() == 0) { throw new RuntimeException("未维护异常反馈群发任务组!请联系管理员"); @@ -1516,7 +1516,7 @@ public class DailyPlanServiceImpl implements DailyPlanService { taskDto.setTaskHeader(checkUserSeqNo.get(0).getPartSpec()+" "+abList.get(0).getAbnormalDesc()); taskDto.setTaskInitiator(taskDto.getCreatedBy()); taskDto.setTaskStartDate(date); - taskDto.setType("badReport"); + taskDto.setType("abnormal"); List taskDetails=abnormalMapper.getTasktSendUsers(taskDto); if(taskDetails.size()==0){ throw new RuntimeException("未维护异常反馈群发任务组!请联系管理员"); diff --git a/src/main/resources/mapper/production/TcpMapper.xml b/src/main/resources/mapper/production/TcpMapper.xml new file mode 100644 index 0000000..d130830 --- /dev/null +++ b/src/main/resources/mapper/production/TcpMapper.xml @@ -0,0 +1,13 @@ + + + + + + insert into tcp_data (ip,port,[type],[value],create_date,flag) + values (#{ip},#{port},#{type},#{value},GetDate(),#{flag}) + + + \ No newline at end of file