package org.jeecg.modules.iot.service.impl; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; 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.entity.*; import org.jeecg.modules.iot.service.*; import org.jeecg.modules.iot.util.FtpUtil; import org.jeecg.modules.iot.mapper.ServerDeployMapper; import org.jeecg.modules.iot.mqtt.config.MqttCustomerClient; import org.jeecg.modules.iot.util.FileUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; /** * @Description: 项目分类 * @Author: cuikaidong * @Date: 2024-12-20 * @Version: V1.0 */ @Service public class ServerDeployServiceImpl extends ServiceImpl implements IServerDeployService { @Autowired private IServerDeployService serverDeployService; @Autowired private IInfluxdbDeployService influxdbDeployService; @Autowired private IMqttDeployService mqttDeployService; @Autowired private MqttCustomerClient mqttCustomerClient; @Autowired private IEquipmentService equipmentService; @Autowired private IParameterGroupService parameterGroupService; @Autowired private IRealParameterService realParameterService; @Autowired private IEmptyParameterService emptyParameterService; @Override public ServerDeploy findByServerCode(String serverCode) { ServerDeploy serverDeploy = new LambdaQueryChainWrapper<>(baseMapper) .eq(ServerDeploy::getServerCode, serverCode) .one(); return serverDeploy; } @Override public List findByProjectClassifyId(String id) { return new LambdaQueryChainWrapper<>(baseMapper) .eq(ServerDeploy::getProjectClassifyId, id) .list(); } @Override public void updateServerGuardState(List mqttClient) { List serverDeploys = serverDeployService.list(); serverDeploys.forEach(s -> { s.setGuardState(0); s.setCollectState(0); }); serverDeployService.updateBatchById(serverDeploys); // 修改守护程序在线状态 if (!mqttClient.isEmpty()) { Set collect = mqttClient.stream().map(MqttClient::getClientid).collect(Collectors.toSet()); // 方案一:使用条件判断,避免传入空集合 List serverDeployList; if (CollectionUtils.isNotEmpty(collect)) { serverDeployList = new LambdaQueryChainWrapper<>(baseMapper) .in(ServerDeploy::getServerCode, collect) .list(); } else { // 集合为空时返回空列表,避免查询 serverDeployList = Collections.emptyList(); } serverDeployList.forEach(l -> l.setGuardState(1)); serverDeployService.updateBatchById(serverDeployList); } } @Override @Transactional(rollbackFor = Exception.class) public Result addDeployDocument(String id) { // 验证FTP连接 boolean isConnected = FtpUtil.testFtpConnection(); if (!isConnected) { return Result.error("FTP连接失败,请检查配置!"); } // 获取当前时间 Date now = new Date(); // 定义日期格式 SimpleDateFormat formatter = new SimpleDateFormat("MMddHHmmss"); // 格式化当前时间 String formattedDate = formatter.format(now); // 服务器配置 ServerDeploy serverDeploy = baseMapper.selectById(id); // Mqtt配置 MqttDeploy mqttDeploy = mqttDeployService.findByServerIdMqttDeploy(id); // influxdb配置 InfluxdbDeploy influxdbDeploy = influxdbDeployService.findByServerIdInfluxdb(id); if (mqttDeploy == null) { return Result.error("请先配置MQTT服务"); } if (influxdbDeploy == null) { return Result.error("请先配置influxdb服务"); } // 设备信息 List equipmentList = equipmentService.findEquipmentByServerId(id); // 参数组信息 List parameterGroups = parameterGroupService.findParameterGroupByServerId(id); // 实设备参数 List realParameters = new ArrayList<>(); if (!CollectionUtils.isEmpty(parameterGroups)) { Set parameterGroupIds = parameterGroups.stream().map(ParameterGroup::getId).collect(Collectors.toSet()); realParameters = realParameterService.findRealParameterByIds(parameterGroupIds); } // 虚设备参数 List emptyParameters = new ArrayList<>(); if (!CollectionUtils.isEmpty(equipmentList)) { Set equipmentIds = equipmentList.stream().map(Equipment::getId).collect(Collectors.toSet()); emptyParameters = emptyParameterService.findParameterByEquipmentIds(equipmentIds); } try { // 创建解析器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder db = factory.newDocumentBuilder(); Document document = db.newDocument(); // 不显示standalone="no" document.setXmlStandalone(true); Element bookstore = document.createElement("ServiceInfo"); // 为bookstore节点添加属性 bookstore.setAttribute("ID", serverDeploy.getServerCode()); bookstore.setAttribute("Name", serverDeploy.getServerName()); bookstore.setAttribute("IP", serverDeploy.getServerAddress()); bookstore.setAttribute("Port", serverDeploy.getServerPort()); bookstore.setAttribute("FileVersion", serverDeploy.getLatestCollectVersion()); bookstore.setAttribute("ParameterVersion", formattedDate); // 向bookstore根节点中添加子节点book // 授权信息 Element authorize = document.createElement("Authorize"); // 为authorize节点添加属性 authorize.setAttribute("Licence", serverDeploy.getAuthorize()); // 将book节点添加到bookstore根节点中 bookstore.appendChild(authorize); // 接口信息 Element Interface = document.createElement("Interface"); Element mqttService = document.createElement("MqttService"); // 为Interface节点添加属性 if (mqttDeploy != null) { mqttService.setAttribute("IP", mqttDeploy.getAddress()); mqttService.setAttribute("Port", mqttDeploy.getPort().toString()); mqttService.setAttribute("ClientID", mqttDeploy.getClintId()); mqttService.setAttribute("User", mqttDeploy.getUserName()); mqttService.setAttribute("PassWord", mqttDeploy.getUserPassword()); } else { mqttService.setAttribute("IP", ""); mqttService.setAttribute("Port", ""); mqttService.setAttribute("ClientID", ""); mqttService.setAttribute("User", ""); mqttService.setAttribute("PassWord", ""); } Element timingLibrary = document.createElement("TimingLibrary"); if (influxdbDeploy != null) { timingLibrary.setAttribute("IP", influxdbDeploy.getAddress()); timingLibrary.setAttribute("Port", influxdbDeploy.getPort().toString()); timingLibrary.setAttribute("Bucket", influxdbDeploy.getBucket()); timingLibrary.setAttribute("Org", influxdbDeploy.getOrganization()); timingLibrary.setAttribute("Token", influxdbDeploy.getAuthorizeCode()); } else { timingLibrary.setAttribute("IP", ""); timingLibrary.setAttribute("Port", ""); timingLibrary.setAttribute("Bucket", ""); timingLibrary.setAttribute("Org", ""); timingLibrary.setAttribute("Token", ""); } Interface.appendChild(mqttService); Interface.appendChild(timingLibrary); // 实设备,虚设备信息 Element deviceInfos = document.createElement("DeviceInfos"); // 添加属性 deviceInfos.setAttribute("WriteMessage", "IOT/" + serverDeploy.getServerCode() + "/WriteMessage"); // 实设备列表节点 Element actualDevices = document.createElement("ActualDevices"); // 虚设备列表节点 Element virtualDevices = document.createElement("VirtualDevices"); // 遍历设备信息 List finalRealParameters = realParameters; List finalEmptyParameters = emptyParameters; equipmentList.forEach(e -> { if (e.getEquipmentType().equals(1)) { Element deviceInfo = document.createElement("DeviceInfo"); // 设备节点 deviceInfo.setAttribute("ID", e.getEqptCode()); deviceInfo.setAttribute("Name", e.getEqptName()); deviceInfo.setAttribute("Model", e.getEqptModel()); deviceInfo.setAttribute("Type", e.getEqptType()); deviceInfo.setAttribute("Describe", e.getEqptDescribe()); deviceInfo.setAttribute("ControlSystem", e.getControlSystem()); deviceInfo.setAttribute("Protocol", e.getProtocol()); deviceInfo.setAttribute("DriveType", e.getDriveType()); deviceInfo.setAttribute("Address", e.getAddress()); deviceInfo.setAttribute("LibraryName", e.getLibraryName()); deviceInfo.setAttribute("Class", e.getClassName()); deviceInfo.setAttribute("LibraryVersion", e.getLibraryVersion()); deviceInfo.setAttribute("CollectionCycle", e.getCollectionCycle()); deviceInfo.setAttribute("ReconnectCycle", e.getReconnectCycle()); deviceInfo.setAttribute("IsCollection", e.getIsCollection()); deviceInfo.setAttribute("FloatPosition", e.getFloatPosition()); deviceInfo.setAttribute("ReadTopic", e.getReadTopic()); deviceInfo.setAttribute("WriteTopic", e.getWriteTopic()); actualDevices.appendChild(deviceInfo); // 参数组信息 parameterGroups.forEach(p -> { if (p.getEquipmentId().equals(e.getId())) { Element groupInfo = document.createElement("GroupInfo"); // 参数组节点 groupInfo.setAttribute("ID", p.getCode()); groupInfo.setAttribute("Name", p.getName()); groupInfo.setAttribute("Describe", p.getRemark()); groupInfo.setAttribute("CollectionCycle", p.getCollectionCycle()); deviceInfo.appendChild(groupInfo); if (!CollectionUtils.isEmpty(finalRealParameters)) { finalRealParameters.forEach(r -> { if (p.getId().equals(r.getParameterGroupId())) { Element tagInfo = document.createElement("TagInfo"); // 参数节点 tagInfo.setAttribute("ID", r.getParameterCode().toString()); tagInfo.setAttribute("Name", r.getParameterName()); tagInfo.setAttribute("Address", r.getAddress()); tagInfo.setAttribute("DataType", r.getParameterType()); if (r.getReadWriteType().equals("只读")){ tagInfo.setAttribute("ReadOrWrite", "R"); }else{ tagInfo.setAttribute("ReadOrWrite", "R/W"); } tagInfo.setAttribute("Describe", r.getParameterDescribe()); tagInfo.setAttribute("TagType", "OutsideTag"); tagInfo.setAttribute("DataLength", r.getDataLength() + ""); groupInfo.appendChild(tagInfo); } }); } } }); } else if (e.getEquipmentType().equals(0)) { Element emptyDeviceInfo = document.createElement("DeviceInfo"); // 设备节点 emptyDeviceInfo.setAttribute("ID", e.getEqptCode()); emptyDeviceInfo.setAttribute("Name", e.getEqptName()); if (e.getIsCollection().equals("1")) { emptyDeviceInfo.setAttribute("IsCollection", "Y"); } else { emptyDeviceInfo.setAttribute("IsCollection", "N"); } emptyDeviceInfo.setAttribute("Remarks", e.getRemark()); emptyDeviceInfo.setAttribute("ReadTopic", e.getReadTopic()); emptyDeviceInfo.setAttribute("Measurement", e.getWriteTopic()); virtualDevices.appendChild(emptyDeviceInfo); // 参数信息 if (!CollectionUtils.isEmpty(equipmentList)) { finalEmptyParameters.forEach(empty -> { if (empty.getEquipmentId().equals(e.getId())) { Element tagInfo = document.createElement("TagInfo"); // 参数节点 tagInfo.setAttribute("ID", empty.getParameterCode() + ""); tagInfo.setAttribute("Name", empty.getParameterName()); tagInfo.setAttribute("SourcePath", empty.getAddress()); tagInfo.setAttribute("DataType", empty.getParameterType()); if (empty.getReadWriteType().equals("只读")) { tagInfo.setAttribute("ReadOrWrite", "R"); } else { tagInfo.setAttribute("ReadOrWrite", "R/W"); } tagInfo.setAttribute("Describe", empty.getParameterDescribe()); if (empty.getType().equals("1")) { tagInfo.setAttribute("TagType", "InsideTag"); } else { tagInfo.setAttribute("TagType", "CustomTag"); } tagInfo.setAttribute("ScriptName", ""); // 脚本名称 tagInfo.setAttribute("ScriptTagList", empty.getScriptTagList());// 脚本地址 tagInfo.setAttribute("DataLength", empty.getDataLength()); emptyDeviceInfo.appendChild(tagInfo); } }); } } }); // 遍历参数组信息 // 遍历参数信息 deviceInfos.appendChild(actualDevices); // 给实设备,虚设备信息添加子节点 deviceInfos.appendChild(virtualDevices); // 给实设备,虚设备信息添加子节点 bookstore.appendChild(Interface); bookstore.appendChild(deviceInfos); // 将bookstore节点(已包含book)添加到dom树中 document.appendChild(bookstore); // 创建TransformerFactory对象 TransformerFactory tff = TransformerFactory.newInstance(); // 创建 Transformer对象 Transformer tf = tff.newTransformer(); // 输出内容是否使用换行 tf.setOutputProperty(OutputKeys.ENCODING, "GB2312"); tf.setOutputProperty(OutputKeys.INDENT, "yes"); // 创建xml文件并写入内容 tf.transform(new DOMSource(document), new StreamResult(new File("D:/iot/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/CollectionConfiguration.lmx"))); // 创建写库表结构查询虚设备列表,增加设备表 equipmentService.createEmptyEquipmentTable(serverDeploy.getDeployIssueTime(),serverDeploy.getId()); // 查询虚设备参数,增加字段 emptyParameterService.createEmptyEmptyField(serverDeploy.getDeployIssueTime(),serverDeploy.getId()); } catch (Exception e) { e.printStackTrace(); return Result.error("配置文件生成失败"); } // 更新版本 serverDeploy.setLatestDeployVersion(formattedDate); serverDeploy.setDeployIssueTime(new Date()); baseMapper.updateById(serverDeploy); // 生成本地文件夹 // FileUtil.createDir("D:/iot/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate); FileUtil.createDir("D:/iot/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/script"); // 上传到ftp String basePath = "/deploy"; // FTP服务器基础目录 String filePath = serverDeploy.getServerCode() + "/deploy/" + formattedDate; // FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath String filename = "CollectionConfiguration.lmx";// 上传到FTP服务器上的文件名 //创建一个输入流 try { FileInputStream fileInputStream = new FileInputStream("D:/iot/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/CollectionConfiguration.lmx"); FtpUtil.uploadFile(basePath, filePath, filename, fileInputStream); } catch (FileNotFoundException e) { e.printStackTrace(); } // 存储脚本,复制整个文件夹 FtpUtil.uploadFolder(new File("D:/iot/"+serverDeploy.getServerCode()+"/script/"), "/deploy/"+serverDeploy.getServerCode()+"/deploy/"+formattedDate+"/script"); // 生成脚本 // 发送配置文件版信号 MqttParameter mqttParameter = new MqttParameter(); mqttParameter.setId(serverDeploy.getServerCode()); mqttParameter.setType("version"); mqttParameter.setParameter2(formattedDate); mqttParameter.setParameter4(basePath +"/" +filePath); mqttCustomerClient.pushlish(2, false, serverDeploy.getServerCode(), mqttParameter); return Result.ok("配置文件生成成功"); } }