package org.jeecg.modules.iot.service.impl; import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.jeecg.common.api.vo.Result; import org.jeecg.modules.iot.depository.DbConfig; import org.jeecg.modules.iot.depository.InfluxdbTest; import org.jeecg.modules.iot.depository.MysqlDataWriter; import org.jeecg.modules.iot.entity.Equipment; import org.jeecg.modules.iot.entity.ParameterGroup; import org.jeecg.modules.iot.entity.ServerDeploy; import org.jeecg.modules.iot.entity.xmlEntity.*; import org.jeecg.modules.iot.entity.xmlEntity.script.FunctionEntity; import org.jeecg.modules.iot.entity.xmlEntity.script.Functions; import org.jeecg.modules.iot.mapper.EquipmentMapper; import org.jeecg.modules.iot.service.IEquipmentService; import org.jeecg.modules.iot.service.IParameterGroupService; import org.jeecg.modules.iot.service.IServerDeployService; import org.jeecg.modules.iot.util.HttpClientUtil; import org.jeecg.modules.iot.util.JaxbUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.sql.DataSource; import java.sql.*; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.Date; import java.util.stream.Collectors; /** * @Description: 设备 * @Author: cuikaidong * @Date: 2024-12-23 * @Version: V1.0 */ @Service public class EquipmentServiceImpl extends ServiceImpl implements IEquipmentService { @Autowired private IParameterGroupService parameterGroupService; @Autowired private IServerDeployService serverDeployService; @Autowired private DataSource dataSource; @Value("${drive}") private String drive; @Override public List findProjectCode() { Config entity = (Config) JaxbUtil.xmlToBean(drive, Config.class); return entity.getSystemTypeList(); } @Override public Object[] queryEquipmentSubscribeList(String id) { Object[] strings = new Object[0]; List equipmentList = new LambdaQueryChainWrapper<>(baseMapper) .eq(Equipment::getServerId, id).list(); if (CollectionUtil.isNotEmpty(equipmentList)) { Object[] objects = new Object[equipmentList.size()]; for (int i = 0; i < equipmentList.size(); i++) { objects[i] = equipmentList.get(i).getReadTopic(); } return objects; } return strings; } @Override public List findControlSystems(String type) { Config entity = (Config) JaxbUtil.xmlToBean(drive, Config.class); List controlSystemList = entity.getControlSystemList(); return controlSystemList.stream().filter(c -> c.getType().equals(type)).collect(Collectors.toList()); } @Override public List findByteOrder() { Config entity = (Config) JaxbUtil.xmlToBean(drive, Config.class); return entity.getByteOrderList(); } @Override public List findSystemDataTypeList() { Config entity = (Config) JaxbUtil.xmlToBean(drive, Config.class); return entity.getSystemDataTypeList(); } @Override public List findParameterById(String id) { ParameterGroup parameterGroup = parameterGroupService.getById(id); Equipment equipment = this.baseMapper.selectById(parameterGroup.getEquipmentId()); Config entity = (Config) JaxbUtil.xmlToBean(drive, Config.class); List controlSystemList = entity.getControlSystemList(); List list1 = controlSystemList.stream().filter(c -> c.getType().equals(equipment.getEqptType()) && c.getName().equals(equipment.getControlSystem())).collect(Collectors.toList()); List controlSystem = list1.get(0).protocolList; List list2 = controlSystem.stream().filter(c -> c.getName().equals(equipment.getProtocol())).collect(Collectors.toList()); List driveTypeList = list2.get(0).driveTypeList; List list3 = driveTypeList.stream().filter(c -> c.getName().equals(equipment.getDriveType())).collect(Collectors.toList()); return list3.get(0).registerInfoList.get(0).defaultParameterList.get(0).parameterList; } @Override public List findParameterCustomizeById(String id) { ParameterGroup parameterGroup = parameterGroupService.getById(id); Equipment equipment = this.baseMapper.selectById(parameterGroup.getEquipmentId()); Config entity = (Config) JaxbUtil.xmlToBean(drive, Config.class); List controlSystemList = entity.getControlSystemList(); List list1 = controlSystemList.stream().filter(c -> c.getType().equals(equipment.getEqptType()) && c.getName().equals(equipment.getControlSystem())).collect(Collectors.toList()); List controlSystem = list1.get(0).protocolList; List list2 = controlSystem.stream().filter(c -> c.getName().equals(equipment.getProtocol())).collect(Collectors.toList()); List driveTypeList = list2.get(0).driveTypeList; List list3 = driveTypeList.stream().filter(c -> c.getName().equals(equipment.getDriveType())).collect(Collectors.toList()); return list3.get(0).registerInfoList.get(0).registerTypeList.get(0).parameterList; } @Override public List findDataTypeById(String id) { ParameterGroup parameterGroup = parameterGroupService.getById(id); Equipment equipment = this.baseMapper.selectById(parameterGroup.getEquipmentId()); Config entity = (Config) JaxbUtil.xmlToBean(drive, Config.class); List controlSystemList = entity.getControlSystemList(); List list1 = controlSystemList.stream().filter(c -> c.getType().equals(equipment.getEqptType()) && c.getName().equals(equipment.getControlSystem())).collect(Collectors.toList()); List controlSystem = list1.get(0).protocolList; List list2 = controlSystem.stream().filter(c -> c.getName().equals(equipment.getProtocol())).collect(Collectors.toList()); List driveTypeList = list2.get(0).driveTypeList; List list3 = driveTypeList.stream().filter(c -> c.getName().equals(equipment.getDriveType())).collect(Collectors.toList()); return list3.get(0).registerInfoList.get(0).dataTypeList.get(0).parameterList; } @Override public List findEquipmentByServerId(String id) { return new LambdaQueryChainWrapper<>(baseMapper).eq(Equipment::getServerId, id).list(); } @Override public Boolean findEquipmentByName(Equipment equipment, Integer type) { List equipmentList = new LambdaQueryChainWrapper<>(baseMapper) .eq(Equipment::getServerId, equipment.getServerId()) .eq(Equipment::getEquipmentType, type) .eq(Equipment::getEqptName, equipment.getEqptName()) .list(); return equipmentList.size() > 0; } @Override public Boolean findEquipmentByCode(Equipment equipment) { List equipmentList = new LambdaQueryChainWrapper<>(baseMapper) .eq(Equipment::getServerId, equipment.getServerId()) .eq(Equipment::getEqptCode, equipment.getEqptCode()) .list(); return equipmentList.size() > 0; } @Override public List findFunctionInformationList(String functionType) { Functions entity = (Functions) JaxbUtil.xmlToBean("F:\\项目\\IOT\\IOT文件\\FunctionConfig.xml", Functions.class); switch (functionType) { case "Convert": return entity.getConvertEntity().getFunctionList(); case "Math": return entity.getMathEntity().getFunctionEntityList(); case "String": return entity.getStringEntity().getFunctionEntityList(); case "File": return entity.getFileEntity().getFunctionEntityList(); case "Time": return entity.getTimeEntity().getFunctionEntityList(); case "Database": return entity.getDatabaseEntity().getFunctionEntityList(); case "Custom": return entity.getCustomEntity().getFunctionEntityList(); default: return null; } } @Override public void createEmptyEquipmentTable(Date deployDate, String serverId) { List equipmentList = new LambdaQueryChainWrapper<>(baseMapper) .eq(Equipment::getServerId, serverId) .eq(Equipment::getEquipmentType, 0) .ge(Equipment::getCreateTime, deployDate) .list(); equipmentList.forEach(equipment -> { createSqlServerTable(equipment.getControlSystem() + '_' + equipment.getEqptCode(), "CollectTime DATETIME DEFAULT GETDATE() NOT NULL", "EquipmentID NVARCHAR(50) NOT NULL", "PRIMARY KEY (CollectTime)" ); }); } /** * 创建实时数据表 * * @param tableName * @param columns */ private void createSqlServerTable(String tableName, String... columns) { String tableSql = String.format( "IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = '%s' ) " + "CREATE TABLE [%s] (%s)", tableName, tableName, String.join(", ", columns) ); try (Connection conn = dataSource.getConnection()) { Statement stmt = conn.createStatement(); stmt.executeUpdate(tableSql); System.out.println("表创建成功: " + tableName); } catch (SQLException e) { e.printStackTrace(); } } @Override @Transactional(rollbackFor = Exception.class) public Result addEmpty(Equipment equipment) { // 验证编码名称是否重复 if (this.findEquipmentByName(equipment, 0)) { return Result.error("设备名称已存在!"); } if (this.findEquipmentByCode(equipment)) { return Result.error("设备编号已存在!"); } // 分类 equipment.setEquipmentType(0); ServerDeploy serverDeploy = serverDeployService.getById(equipment.getServerId()); this.save(equipment); equipment.setReadTopic("IOT/" + serverDeploy.getServerCode() + "/VirtualDevices/" + equipment.getEqptCode() + "/Read"); equipment.setWriteTopic("IOT." + serverDeploy.getServerCode() + ".VirtualDevices." + equipment.getEqptCode()); this.updateById(equipment); // 新增虚设备时调用 // 新建项目目录时或者项目载入时调用 Map param = new HashMap<>(); param.put("path", "D:/iot/" + serverDeploy.getServerCode() + "/script"); HttpClientUtil.doGet("http://localhost:3002/ScriptCompiler/ProjectPath", param); param.clear(); param.put("id", equipment.getEqptCode()); HttpClientUtil.doGet("http://localhost:3002/ScriptCompiler/AddDevicescript", param); return Result.ok("添加成功!"); } @Override public Equipment findEquipmentByCode(String code) { return new LambdaQueryChainWrapper<>(baseMapper) .eq(Equipment::getEqptCode, code) .one(); } @Override public void insertMysqlData(String tableName, String[] columns, Object[] values) { if (columns.length != values.length) { throw new IllegalArgumentException("字段与值的数量不匹配"); } // 转义表名和列名(SQL Server使用方括号[]) String escapedTableName = "[" + tableName.replace("]", "]]") + "]"; // 构建列名和占位符 StringBuilder columnBuilder = new StringBuilder(); StringBuilder placeholderBuilder = new StringBuilder(); for (int i = 0; i < columns.length; i++) { if (i > 0) { columnBuilder.append(", "); placeholderBuilder.append(", "); } // 转义列名,处理可能包含的特殊字符 String escapedColumn = "[" + columns[i].replace("]", "]]") + "]"; columnBuilder.append(escapedColumn); placeholderBuilder.append("?"); } String sql = String.format("INSERT INTO %s (%s) VALUES (%s)", escapedTableName, columnBuilder.toString(), placeholderBuilder.toString()); // log.debug("构建SQL: {}", sql); try (Connection conn = dataSource.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { // 设置参数,根据值类型选择合适的set方法 for (int i = 0; i < values.length; i++) { Object value = values[i]; String columnName = columns[i]; // log.debug("设置参数 {}: 列名={}, 值={}, 类型={}", // i+1, columnName, value, value != null ? value.getClass().getName() : "NULL"); if (value == null) { // 对于NULL值,需要指定类型 if (columnName.toLowerCase().contains("bool")) { pstmt.setNull(i + 1, Types.BIT); } else if (columnName.toLowerCase().contains("int")) { pstmt.setNull(i + 1, Types.INTEGER); } else if (columnName.toLowerCase().contains("time") || columnName.toLowerCase().contains("date")) { pstmt.setNull(i + 1, Types.TIMESTAMP); } else { pstmt.setNull(i + 1, Types.VARCHAR); } } else if (value instanceof String) { pstmt.setString(i + 1, (String) value); } else if (value instanceof Integer) { pstmt.setInt(i + 1, (Integer) value); } else if (value instanceof Long) { pstmt.setLong(i + 1, (Long) value); } else if (value instanceof Boolean) { pstmt.setBoolean(i + 1, (Boolean) value); } else if (value instanceof java.util.Date) { // 将java.util.Date转换为java.sql.Timestamp pstmt.setTimestamp(i + 1, new java.sql.Timestamp(((java.util.Date) value).getTime())); } else if (value instanceof java.util.Calendar) { pstmt.setTimestamp(i + 1, new java.sql.Timestamp( ((java.util.Calendar) value).getTimeInMillis())); } else if (value instanceof byte[]) { pstmt.setBytes(i + 1, (byte[]) value); } else if (value instanceof boolean[]) { // 布尔数组处理:转换为逗号分隔的字符串 boolean[] boolArray = (boolean[]) value; StringBuilder sb = new StringBuilder(); for (int j = 0; j < boolArray.length; j++) { if (j > 0) sb.append(","); sb.append(boolArray[j] ? "1" : "0"); } pstmt.setString(i + 1, sb.toString()); } else if (value instanceof int[]) { // 整数数组处理:转换为逗号分隔的字符串 int[] intArray = (int[]) value; StringBuilder sb = new StringBuilder(); for (int j = 0; j < intArray.length; j++) { if (j > 0) sb.append(","); sb.append(intArray[j]); } pstmt.setString(i + 1, sb.toString()); } else { LocalDateTime localDateTime = LocalDateTime.parse(values[i].toString()); pstmt.setTimestamp(i + 1, Timestamp.valueOf(localDateTime)); } } pstmt.executeUpdate(); // log.debug("数据插入成功: {}", tableName); } catch (SQLException e) { log.error("SQL Server插入数据失败: " + sql, e); throw new RuntimeException("SQL Server插入数据失败", e); } } }