package org.jeecg.modules.iot.service.impl;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import org.apache.http.HttpResponse;
|
import org.apache.http.client.HttpClient;
|
import org.apache.http.client.methods.HttpPost;
|
import org.apache.http.entity.StringEntity;
|
import org.apache.http.impl.client.HttpClients;
|
import org.apache.http.util.EntityUtils;
|
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.modules.iot.depository.DbConfig;
|
import org.jeecg.modules.iot.depository.MysqlDataWriter;
|
import org.jeecg.modules.iot.entity.EmptyParameter;
|
import org.jeecg.modules.iot.entity.Equipment;
|
import org.jeecg.modules.iot.entity.RealParameter;
|
import org.jeecg.modules.iot.entity.ScriptCompilation;
|
import org.jeecg.modules.iot.mapper.EmptyParameterMapper;
|
import org.jeecg.modules.iot.mapper.RealParameterMapper;
|
import org.jeecg.modules.iot.service.IEmptyParameterService;
|
import org.jeecg.modules.iot.service.IEquipmentService;
|
import org.jeecg.modules.iot.util.AESUtil;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import javax.sql.DataSource;
|
import java.sql.*;
|
import java.util.*;
|
import java.util.Date;
|
import java.util.regex.Matcher;
|
import java.util.regex.Pattern;
|
import java.util.stream.Collectors;
|
|
/**
|
* @Description: 虚设备参数
|
* @Author: cuikaidong
|
* @Date: 2025-1-7
|
* @Version: V1.0
|
*/
|
@Service
|
public class EmptyParameterServiceImpl extends ServiceImpl<EmptyParameterMapper, EmptyParameter> implements IEmptyParameterService {
|
|
@Resource
|
private RealParameterMapper realParameterMapper;
|
@Autowired
|
private IEquipmentService equipmentService;
|
@Autowired
|
private DataSource dataSource;
|
|
@Override
|
public List<EmptyParameter> findParameterByEquipmentIds(Set<String> ids) {
|
return new LambdaQueryChainWrapper<>(baseMapper).in(EmptyParameter::getEquipmentId, ids).list();
|
}
|
|
@Override
|
public Result<?> handleCompile(EmptyParameter emptyParameter) {
|
Map<String, String> referenceInfo = new HashMap<>();
|
// 验证脚本实设备
|
List<String> attributes = new ArrayList<>(getAttributes(emptyParameter.getScript(), "IOT_[\\p{L}\\p{N}_]+_[\\p{L}\\p{N}_]+_[\\p{L}\\p{N}_]+"));
|
if (!attributes.isEmpty()) {
|
List<RealParameter> realParameterList = realParameterMapper.findRealParameterList(attributes);
|
// 判断实设备参数数量是否相等
|
if (attributes.size() != realParameterList.size()) {
|
// 求差集
|
Set<String> difference1 = new HashSet<>(attributes);
|
// 使用 Stream API 将 name 字段转换为 Set<String>
|
Set<String> difference2 = realParameterList.stream()
|
.map(RealParameter::getAddress).collect(Collectors.toSet());
|
difference1.removeAll(difference2);
|
return Result.error(difference1 + "属性有误!!!");
|
}
|
realParameterList.forEach(r -> {
|
if (r.getSystemDataType().isEmpty()) {
|
referenceInfo.put(r.getAddress(), r.getParameterType());
|
} else {
|
referenceInfo.put(r.getAddress(), r.getSystemDataType());
|
}
|
});
|
}
|
// 验证虚设备
|
List<String> empAttributes = new ArrayList<>(getAttributes(emptyParameter.getScript(), "IOT_[\\p{L}\\p{N}_]+_[\\p{L}\\p{N}_]+"));
|
if (!empAttributes.isEmpty()) {
|
List<EmptyParameter> emptyParameterList = new ArrayList<>();
|
Set<String> difference = new HashSet<>(empAttributes);
|
if (!attributes.isEmpty()) {
|
// 求差集
|
difference.removeAll(attributes);
|
List<String> www = new ArrayList<>(difference);
|
// 查询数据库中匹配的数量
|
if (!www.isEmpty()) {
|
emptyParameterList = baseMapper.findEmptyParameterList(www);
|
}
|
} else {
|
emptyParameterList = baseMapper.findEmptyParameterList(empAttributes);
|
}
|
// 使用 HashSet 去重
|
Set<EmptyParameter> personSet = new HashSet<>(emptyParameterList);
|
// 判断虚设备参数数量是否相等
|
if (difference.size() != personSet.size()) {
|
// 求差集
|
Set<String> difference1 = new HashSet<>(difference);
|
// 使用 Stream API 将 name 字段转换为 Set<String>
|
Set<String> difference2 = personSet.stream()
|
.map(EmptyParameter::getAddress).collect(Collectors.toSet());
|
difference1.removeAll(difference2);
|
return Result.error(difference1 + "属性有误!!!");
|
}
|
personSet.forEach(p -> {
|
if (p.getSystemDataType().isEmpty()) {
|
referenceInfo.put(p.getAddress(), p.getParameterType());
|
} else {
|
referenceInfo.put(p.getAddress(), p.getSystemDataType());
|
}
|
});
|
}
|
// --------AES_CBC加密---------
|
String cbcResult = AESUtil.encryptCBC(emptyParameter.getScript(), "xhVs6DRXLfUGxw+AhtfQdpQGoa+8SA9d");
|
try {
|
ScriptCompilation scriptCompilation = new ScriptCompilation();
|
Equipment equipment = equipmentService.getById(emptyParameter.getEquipmentId());
|
scriptCompilation.setDeviceId(equipment.getEqptCode());
|
scriptCompilation.setParameterCode(cbcResult);
|
scriptCompilation.setParameterDataType(emptyParameter.getParameterType());
|
scriptCompilation.setParameterName(emptyParameter.getParameterName());
|
scriptCompilation.setReferenceinfo(referenceInfo);
|
String jsonPayload = JSONObject.toJSONString(scriptCompilation);
|
|
// 创建 HttpClient 实例
|
HttpClient httpClient = HttpClients.createDefault();
|
// 创建 HttpPost 请求实例
|
HttpPost httpPost = new HttpPost("http://localhost:3002/ScriptCompiler/ScriptCompiler");
|
// 设置请求头,指定内容类型为 JSON,编码为 UTF-8
|
httpPost.setHeader("Content-Type", "application/json; charset=UTF-8");
|
|
// 创建 StringEntity 并指定编码为 UTF-8
|
StringEntity entity = new StringEntity(jsonPayload, "UTF-8");
|
httpPost.setEntity(entity);
|
|
// 执行请求并获取响应
|
HttpResponse response = httpClient.execute(httpPost);
|
// 获取响应实体内容
|
String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
|
boolean isContain = responseBody.contains("编译成功");
|
if (isContain) {
|
return Result.ok(responseBody);
|
} else {
|
// 输出响应内容
|
return Result.error(responseBody);
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return Result.error("编译失败");
|
}
|
|
@Override
|
public Result<?> preserveScript(EmptyParameter emptyParameter) {
|
Map<String, String> referenceInfo = new HashMap<>();
|
// 验证脚本实设备
|
List<String> attributes = new ArrayList<>(getAttributes(emptyParameter.getScript(), "IOT_[\\p{L}\\p{N}_]+_[\\p{L}\\p{N}_]+_[\\p{L}\\p{N}_]+"));
|
if (!attributes.isEmpty()) {
|
List<RealParameter> realParameterList = realParameterMapper.findRealParameterList(attributes);
|
realParameterList.forEach(r -> {
|
if (r.getSystemDataType().isEmpty()) {
|
referenceInfo.put(r.getAddress(), r.getParameterType());
|
} else {
|
referenceInfo.put(r.getAddress(), r.getSystemDataType());
|
}
|
});
|
}
|
// 验证虚设备
|
List<String> empAttributes = new ArrayList<>(getAttributes(emptyParameter.getScript(), "IOT_[\\p{L}\\p{N}_]+_[\\p{L}\\p{N}_]+"));
|
if (!empAttributes.isEmpty()) {
|
List<EmptyParameter> emptyParameterList = new ArrayList<>();
|
Set<String> difference = new HashSet<>(empAttributes);
|
if (!attributes.isEmpty()) {
|
// 求差集
|
difference.removeAll(attributes);
|
List<String> www = new ArrayList<>(difference);
|
// 查询数据库中匹配的数量
|
if (!www.isEmpty()) {
|
emptyParameterList = baseMapper.findEmptyParameterList(www);
|
}
|
} else {
|
emptyParameterList = baseMapper.findEmptyParameterList(empAttributes);
|
}
|
// 使用 HashSet 去重
|
Set<EmptyParameter> personSet = new HashSet<>(emptyParameterList);
|
personSet.forEach(p -> {
|
if (p.getSystemDataType().isEmpty()) {
|
referenceInfo.put(p.getAddress(), p.getParameterType());
|
} else {
|
referenceInfo.put(p.getAddress(), p.getSystemDataType());
|
}
|
});
|
}
|
// --------AES_CBC加密---------
|
String cbcResult = AESUtil.encryptCBC(emptyParameter.getScript(), "xhVs6DRXLfUGxw+AhtfQdpQGoa+8SA9d");
|
try {
|
ScriptCompilation scriptCompilation = new ScriptCompilation();
|
Equipment equipment = equipmentService.getById(emptyParameter.getEquipmentId());
|
scriptCompilation.setDeviceId(equipment.getEqptCode());
|
scriptCompilation.setParameterCode(cbcResult);
|
scriptCompilation.setParameterDataType(emptyParameter.getParameterType());
|
scriptCompilation.setParameterName(emptyParameter.getParameterName());
|
scriptCompilation.setReferenceinfo(referenceInfo);
|
String jsonPayload = JSONObject.toJSONString(scriptCompilation);
|
|
// 创建 HttpClient 实例
|
HttpClient httpClient = HttpClients.createDefault();
|
// 创建 HttpPost 请求实例
|
HttpPost httpPost = new HttpPost("http://localhost:3002/ScriptCompiler/ScriptSave");
|
// 设置请求头,指定内容类型为 JSON,编码为 UTF-8
|
httpPost.setHeader("Content-Type", "application/json; charset=UTF-8");
|
|
// 创建 StringEntity 并指定编码为 UTF-8
|
StringEntity entity = new StringEntity(jsonPayload, "UTF-8");
|
httpPost.setEntity(entity);
|
|
// 执行请求并获取响应
|
HttpResponse response = httpClient.execute(httpPost);
|
// 获取响应实体内容
|
String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
|
boolean isContain = responseBody.contains("保存成功");
|
// 将 JSON 字符串转换为 JSONObject
|
cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject(responseBody);
|
// 访问 JSON 对象的属性
|
String message = jsonObject.getStr("Message");
|
if (isContain) {
|
// 保存脚本标记列表
|
StringBuilder scriptTagList = new StringBuilder();
|
for (String key : referenceInfo.keySet()) {
|
if (scriptTagList.toString().equals("")) {
|
scriptTagList = new StringBuilder(key);
|
} else {
|
scriptTagList.append("|").append(key);
|
}
|
}
|
// 保存属性
|
emptyParameter.setScriptTagList(scriptTagList.toString());
|
// 保存脚本
|
emptyParameter.setScriptContent(emptyParameter.getScript());
|
baseMapper.updateById(emptyParameter);
|
return Result.ok(message);
|
} else {
|
// 输出响应内容
|
return Result.error(message);
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return Result.error("编译失败");
|
}
|
|
@Override
|
public Integer findEmptyParameterCode(String equipmentId) {
|
List<EmptyParameter> list = new LambdaQueryChainWrapper<>(baseMapper)
|
.eq(EmptyParameter::getEquipmentId, equipmentId)
|
.orderByDesc(EmptyParameter::getParameterCode)
|
.list();
|
if (list.size() == 0) {
|
return 1;
|
}
|
return list.get(0).getParameterCode() + 1;
|
}
|
|
@Override
|
public Boolean findEmptyParameterByName(EmptyParameter emptyParameter) {
|
List<EmptyParameter> realParameters = new LambdaQueryChainWrapper<>(baseMapper)
|
.eq(EmptyParameter::getEquipmentId, emptyParameter.getEquipmentId())
|
.eq(EmptyParameter::getParameterName, emptyParameter.getParameterName())
|
.list();
|
return realParameters.size() > 0;
|
}
|
|
@Override
|
public void createEmptyEmptyField(Date deployDate, String serverId) {
|
List<EmptyParameter> emptyParameterList = baseMapper.findEmptyParameterListByTime(deployDate, serverId);
|
Map<String, List<EmptyParameter>> emptyParameterListMap = emptyParameterList.stream()
|
.collect(Collectors.groupingBy(EmptyParameter::getEqptCode));
|
emptyParameterListMap.forEach((eqptCode, parameterList) -> {
|
Equipment equipment = equipmentService.findEquipmentByCode(eqptCode);
|
List<String> columnDefinitions = new ArrayList<>();
|
Set<String> columnNames = new HashSet<>();
|
// 遍历当前设备下的所有参数
|
parameterList.forEach(param -> {
|
columnDefinitions.add("NVARCHAR(100) DEFAULT ''");
|
columnNames.add(param.getParameterName());
|
});
|
addSqlserverColumns(equipment.getControlSystem() + '_' + eqptCode, new ArrayList<>(columnDefinitions),
|
new ArrayList<>(columnNames));
|
});
|
}
|
|
/**
|
* // 批量导入字段(SQL Server 版本)
|
*
|
* @param tableName
|
* @param columnDefinitions
|
* @param columnNames
|
*/
|
public void addSqlserverColumns(String tableName, List<String> columnDefinitions, List<String> columnNames) {
|
if (columnDefinitions.size() != columnNames.size()) {
|
throw new IllegalArgumentException("字段定义和字段名的数量必须一致");
|
}
|
|
// 转义表名中的方括号,防止SQL注入
|
tableName = tableName.replace("[", "[[").replace("]", "]]");
|
|
StringBuilder sqlBuilder = new StringBuilder();
|
sqlBuilder.append("ALTER TABLE").append("[")
|
.append(tableName).append("] ADD ");
|
|
boolean hasNewColumns = false;
|
for (int i = 0; i < columnDefinitions.size(); i++) {
|
String columnName = columnNames.get(i);
|
if (sqlServeBatchIsColumnExists(tableName, columnName)) {
|
System.out.println("字段已存在,无需添加: " + columnName);
|
continue;
|
}
|
|
String columnDefinition = columnDefinitions.get(i);
|
if (hasNewColumns) {
|
sqlBuilder.append(", ");
|
}
|
sqlBuilder.append("[").append(columnName.replace("[", "[[").replace("]", "]]")).append("] ")
|
.append(columnDefinition);
|
hasNewColumns = true;
|
}
|
|
String sql = sqlBuilder.toString();
|
if (!hasNewColumns) {
|
System.out.println("没有需要添加的新字段");
|
return;
|
}
|
|
try (Connection conn = dataSource.getConnection();
|
Statement stmt = conn.createStatement()) {
|
System.out.println("执行SQL: " + sql); // 调试用
|
stmt.executeUpdate(sql);
|
System.out.println("字段批量添加成功");
|
} catch (SQLException e) {
|
System.err.println("批量添加字段失败: " + sql);
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* 验证字段是否存在(SQL Server 版本)
|
*/
|
private boolean sqlServeBatchIsColumnExists(String tableName, String columnName) {
|
// 自动转义表名(处理方括号和特殊字符)
|
String quotedTable = "[" + tableName.replace("]", "]]") + "]";
|
|
String sql = "SELECT COUNT(*) FROM sys.columns " +
|
"WHERE object_id = OBJECT_ID(?) AND name = ?";
|
|
try (Connection conn = dataSource.getConnection();
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
// 设置第一个参数:转义后的表名
|
stmt.setString(1, quotedTable);
|
// 设置第二个参数:字段名
|
stmt.setString(2, columnName);
|
|
try (ResultSet rs = stmt.executeQuery()) {
|
if (rs.next()) {
|
return rs.getInt(1) > 0;
|
}
|
}
|
} catch (SQLException e) {
|
// log.error("检查字段 {} 在表 {} 中是否存在时出错", columnName, tableName, e);
|
return false;
|
}
|
return false;
|
}
|
|
|
/**
|
* 根据表达式查询脚本中包含的属性
|
*
|
* @param script 脚本
|
* @param regex 表达式
|
* @return 属性
|
*/
|
Set<String> getAttributes(String script, String regex) {
|
Set<String> scriptList = new HashSet<>();
|
// 编译正则表达式
|
Pattern pattern = Pattern.compile(regex);
|
// 创建 Matcher 对象
|
Matcher matcher = pattern.matcher(script);
|
// 查找所有匹配的子字符串
|
while (matcher.find()) {
|
// 获取当前匹配到的内容
|
scriptList.add(matcher.group());
|
}
|
return scriptList;
|
}
|
}
|