Compare commits

..

No commits in common. 'main' and 'plp' have entirely different histories.
main ... plp

@ -1,6 +1,5 @@
package cn.iocoder.yudao.framework.common.util.opc; package cn.iocoder.yudao.framework.common.util.opc;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient; import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig; import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder; import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder;
@ -25,7 +24,6 @@ import java.util.function.Predicate;
* OPC UA - Eclipse Milo 0.6.9 * OPC UA - Eclipse Milo 0.6.9
* OPC UA * OPC UA
*/ */
@Slf4j
public class OpcUtils { public class OpcUtils {
// 静态成员变量,所有实例共享 // 静态成员变量,所有实例共享
@ -48,15 +46,14 @@ public class OpcUtils {
public static boolean connect(String url, String username, String password, int timeoutSeconds) { public static boolean connect(String url, String username, String password, int timeoutSeconds) {
if (isConnected) { if (isConnected) {
log.info(" {} 客户端已连接,无需重复连接",LOG_PREFIX); System.out.println(LOG_PREFIX + "客户端已连接,无需重复连接");
return true; return true;
} }
serverUrl = url; serverUrl = url;
try { try {
System.out.println(LOG_PREFIX + "正在连接到OPC UA服务器: " + url);
log.info(" {} 正在连接到OPC UA服务器 {}",LOG_PREFIX,url);
// 提取主机和端口 // 提取主机和端口
final String targetHost = extractHostFromUrl(url); final String targetHost = extractHostFromUrl(url);
@ -65,7 +62,6 @@ public class OpcUtils {
System.out.println(LOG_PREFIX + "目标主机: " + targetHost + ", 端口: " + targetPort + ", 路径: " + path); System.out.println(LOG_PREFIX + "目标主机: " + targetHost + ", 端口: " + targetPort + ", 路径: " + path);
// 将主机名解析为IP地址 // 将主机名解析为IP地址
final String ipAddress = resolveToIpAddress(targetHost); final String ipAddress = resolveToIpAddress(targetHost);
System.out.println(LOG_PREFIX + "解析为IP地址: " + ipAddress); System.out.println(LOG_PREFIX + "解析为IP地址: " + ipAddress);

@ -54,11 +54,11 @@ public class ErpProductController {
ErpProductPageReqVO productPageReqVO = new ErpProductPageReqVO(); ErpProductPageReqVO productPageReqVO = new ErpProductPageReqVO();
productPageReqVO.setName(createReqVO.getName()); productPageReqVO.setName(createReqVO.getName());
if (!productMapper.selectProductExist(productPageReqVO).getList().isEmpty()) { if (!productMapper.selectProductExist(productPageReqVO).getList().isEmpty()) {
return error(400,"名称+规格不能重复"); return error(400,"名称不能重复");
} }
productPageReqVO = new ErpProductPageReqVO(); productPageReqVO = new ErpProductPageReqVO();
productPageReqVO.setCode(createReqVO.getBarCode()); productPageReqVO.setCode(createReqVO.getBarCode());
if (!productMapper.selectProductCodeExist(productPageReqVO).getList().isEmpty()) { if (!productMapper.selectProductExist(productPageReqVO).getList().isEmpty()) {
return error(400,"编码不能重复"); return error(400,"编码不能重复");
} }
return success(productService.createProduct(createReqVO)); return success(productService.createProduct(createReqVO));

@ -115,12 +115,4 @@ public class ErpProductUnitController {
} }
@GetMapping("/flag-list")
@Operation(summary = "获得产品主单位列表")
public CommonResult<List<ErpProductUnitDO>> getProductUnitListByFlag() {
List<ErpProductUnitDO> productUnitDOList = productUnitService.getProductUnitListByFlag();
return success(productUnitDOList);
}
} }

@ -27,7 +27,4 @@ public class ErpProductPageReqVO extends PageParam {
@Schema(description = "产品编号", example = "11161") @Schema(description = "产品编号", example = "11161")
private String code; private String code;
@Schema(description = "产品规格", example = "红色")
private String standard;
} }

@ -24,13 +24,4 @@ public class ErpProductUnitSaveReqVO {
@InEnum(CommonStatusEnum.class) @InEnum(CommonStatusEnum.class)
private Integer status; private Integer status;
@Schema(description = "是否主单位", example = "芋艿")
private String primaryFlag;
@Schema(description = "关联主单位id", example = "芋艿")
private Long primaryId;
@Schema(description = "换算比例", example = "芋艿")
private Double changeRate;
} }

@ -29,17 +29,10 @@ public interface ErpProductMapper extends BaseMapperX<ErpProductDO> {
.orderByDesc(ErpProductDO::getId)); .orderByDesc(ErpProductDO::getId));
} }
default PageResult<ErpProductDO> selectProductCodeExist(ErpProductPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ErpProductDO>()
.eqIfPresent(ErpProductDO::getName, reqVO.getName())
.eqIfPresent(ErpProductDO::getBarCode, reqVO.getCode())
.orderByAsc(ErpProductDO::getId));
}
default PageResult<ErpProductDO> selectProductExist(ErpProductPageReqVO reqVO) { default PageResult<ErpProductDO> selectProductExist(ErpProductPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ErpProductDO>() return selectPage(reqVO, new LambdaQueryWrapperX<ErpProductDO>()
.eqIfPresent(ErpProductDO::getName, reqVO.getName()) .eqIfPresent(ErpProductDO::getName, reqVO.getName())
.eqIfPresent(ErpProductDO::getStandard, reqVO.getStandard()) .eqIfPresent(ErpProductDO::getBarCode, reqVO.getCode())
.orderByAsc(ErpProductDO::getId)); .orderByAsc(ErpProductDO::getId));
} }

@ -92,13 +92,6 @@ public interface ErpProductUnitService {
*/ */
List<ErpProductUnitDO> getProductUnitList(); List<ErpProductUnitDO> getProductUnitList();
/**
*
*
* @return
*/
List<ErpProductUnitDO> getProductUnitListByFlag();
/** /**
* *
* *

@ -8,7 +8,6 @@ import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUn
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductUnitMapper; import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductUnitMapper;
import cn.iocoder.yudao.module.erp.framework.bean.ProductUnitEnum; import cn.iocoder.yudao.module.erp.framework.bean.ProductUnitEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -53,7 +52,7 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
updateReqVO.getId().equals(ProductUnitEnum.Kilogram.getUnitId()) updateReqVO.getId().equals(ProductUnitEnum.Kilogram.getUnitId())
|| updateReqVO.getId().equals(ProductUnitEnum.Gram.getUnitId()) || updateReqVO.getId().equals(ProductUnitEnum.Gram.getUnitId())
|| updateReqVO.getId().equals(ProductUnitEnum.Each.getUnitId())){ || updateReqVO.getId().equals(ProductUnitEnum.Each.getUnitId())){
throw exception(new ErrorCode(40001,"内置单位不允许更改")); throw exception(new ErrorCode(500,"内置单位不允许更改"));
} }
// 1.1 校验存在 // 1.1 校验存在
validateProductUnitExists(updateReqVO.getId()); validateProductUnitExists(updateReqVO.getId());
@ -130,10 +129,4 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
public ErpProductUnitDO getProductUnitByName(String name) { public ErpProductUnitDO getProductUnitByName(String name) {
return productUnitMapper.selectByName(name); return productUnitMapper.selectByName(name);
} }
@Override
public List<ErpProductUnitDO> getProductUnitListByFlag() {
QueryWrapper<ErpProductUnitDO> wrapper = new QueryWrapper<>();
wrapper.eq("primary_flag", "Y");
return productUnitMapper.selectList(wrapper);
}
} }

@ -52,12 +52,6 @@
<artifactId>yudao-spring-boot-starter-mybatis</artifactId> <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.cronutils</groupId>
<artifactId>cron-utils</artifactId>
<version>9.2.0</version>
</dependency>
<!-- Test 测试相关 --> <!-- Test 测试相关 -->
<dependency> <dependency>
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>

@ -1,14 +1,11 @@
// DeviceTask.java - 原有设备任务 // DeviceTask.java - 原有设备任务
package cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.coretask; package cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.coretask;
import cn.iocoder.yudao.framework.common.enums.DeviceConnectionStatusEnum;
import cn.iocoder.yudao.framework.common.util.opc.OpcUtils; import cn.iocoder.yudao.framework.common.util.opc.OpcUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.DeviceBasicStatusEnum; import cn.iocoder.yudao.module.iot.controller.admin.device.enums.DeviceBasicStatusEnum;
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.DeviceStatusEnum; import cn.iocoder.yudao.module.iot.controller.admin.device.enums.DeviceStatusEnum;
import cn.iocoder.yudao.module.iot.controller.admin.device.enums.TaskTypeEnum; import cn.iocoder.yudao.module.iot.controller.admin.device.enums.TaskTypeEnum;
import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.core.Task; import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.core.Task;
import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.scheduler.TaskSchedulerManager;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceSaveReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.devicemodelrules.vo.PointRulesRespVO; import cn.iocoder.yudao.module.iot.controller.admin.devicemodelrules.vo.PointRulesRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicecontactmodel.DeviceContactModelDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicecontactmodel.DeviceContactModelDO;
@ -20,7 +17,6 @@ import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactMod
import cn.iocoder.yudao.module.iot.dal.mysql.deviceoperationrecord.DeviceOperationRecordMapper; import cn.iocoder.yudao.module.iot.dal.mysql.deviceoperationrecord.DeviceOperationRecordMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.devicepointrules.DevicePointRulesMapper; import cn.iocoder.yudao.module.iot.dal.mysql.devicepointrules.DevicePointRulesMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.devicewarinningrecord.DeviceWarinningRecordMapper; import cn.iocoder.yudao.module.iot.dal.mysql.devicewarinningrecord.DeviceWarinningRecordMapper;
import cn.iocoder.yudao.module.iot.service.device.DeviceService;
import cn.iocoder.yudao.module.iot.service.device.TDengineService; import cn.iocoder.yudao.module.iot.service.device.TDengineService;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -30,7 +26,6 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -53,10 +48,6 @@ public class DeviceTask implements Task {
@Resource @Resource
private TDengineService tDengineService; private TDengineService tDengineService;
@Resource
@Lazy
private DeviceService deviceService;
@Resource @Resource
private DevicePointRulesMapper devicePointRulesMapper; private DevicePointRulesMapper devicePointRulesMapper;
@ -66,10 +57,6 @@ public class DeviceTask implements Task {
@Resource @Resource
private DeviceWarinningRecordMapper deviceWarinningRecordMapper; private DeviceWarinningRecordMapper deviceWarinningRecordMapper;
@Resource
@Lazy
private TaskSchedulerManager taskSchedulerManager;
@Override @Override
public String getTaskType() { public String getTaskType() {
return TaskTypeEnum.DEVICE.getCode(); return TaskTypeEnum.DEVICE.getCode();
@ -116,6 +103,13 @@ public class DeviceTask implements Task {
logger.info("执行设备任务任务ID: {}, 参数: {}, 时间: {}", logger.info("执行设备任务任务ID: {}, 参数: {}, 时间: {}",
taskId, taskParam, currentTime); taskId, taskParam, currentTime);
// 解析参数,假设格式为 deviceId:deviceCode
// String[] params = taskParam.split(":");
// if (params.length >= 2) {
// Long deviceId = Long.parseLong(params[0]);
// String deviceCode = params[1];
// executeDeviceLogic(deviceId, deviceCode);
// }
executeDeviceLogic(taskId,taskParam); executeDeviceLogic(taskId,taskParam);
@ -154,6 +148,32 @@ public class DeviceTask implements Task {
OpcUtils.disconnect(); OpcUtils.disconnect();
} }
/**
*
*/
// private void executeDeviceLogic(Long sourceDeviceId, String param) {
// logger.info("执行设备逻辑源设备ID: {},参数: {}", sourceDeviceId, param);
//
// // 1. 计算实际设备ID
// Long deviceId = sourceDeviceId - 1000000L;
// logger.info("处理后设备ID: {}", deviceId);
//
// if (deviceId == null) {
// throw new RuntimeException("设备ID不能为空");
// }
//
// // 2. 获取设备信息
// DeviceDO device = getDeviceInfo(deviceId);
//
// // 3. 连接OPC服务器
// connectOpcServer(device);
//
// // 4. 处理数据读取和入库
// processDeviceData(deviceId, device);
//
// // 5. 断开连接
// OpcUtils.disconnect();
// }
/** /**
* *
@ -179,95 +199,25 @@ public class DeviceTask implements Task {
String username = StringUtils.defaultString(device.getUsername()); String username = StringUtils.defaultString(device.getUsername());
String password = StringUtils.defaultString(device.getPassword()); String password = StringUtils.defaultString(device.getPassword());
boolean connected = false; boolean connected = OpcUtils.connect(device.getUrl(), username, password, 10);
try {
connected = OpcUtils.connect(device.getUrl(), username, password, 10);
if (!connected) { if (!connected) {
throw new RuntimeException("连接OPC服务器失败URL: " + device.getUrl());
log.error("设备 {} 连接OPC服务器失败URL: {}", device.getId(), device.getUrl());
device.setStatus(String.valueOf(DeviceConnectionStatusEnum.DISCONNECTED.getStatus()));
deviceMapper.updateById(device);
taskSchedulerManager.stopDeviceTask(device.getId());
DeviceOperationRecordDO deviceOperationRecordDO = new DeviceOperationRecordDO();
deviceOperationRecordDO.setDeviceId(device.getId());
deviceOperationRecordDO.setRule(DeviceStatusEnum.OFFLINE.getCode());
//TODO 默认内置管理员
deviceOperationRecordDO.setCreator("1");
deviceOperationRecordDO.setUpdater("1");
deviceOperationRecordMapper.insert(deviceOperationRecordDO);
//抛出异常终止任务
throw new RuntimeException("连接opcuv服务器异常");
}
log.info("设备 {} 成功连接OPC服务器URL: {}", device.getId(), device.getUrl());
} catch (Exception e) {
log.error("设备 {} 连接OPC服务器异常URL: {}", device.getId(), device.getUrl(), e);
device.setStatus(String.valueOf(DeviceConnectionStatusEnum.DISCONNECTED.getStatus()));
deviceMapper.updateById(device);
taskSchedulerManager.stopDeviceTask(device.getId());
DeviceOperationRecordDO deviceOperationRecordDO = new DeviceOperationRecordDO();
deviceOperationRecordDO.setDeviceId(device.getId());
deviceOperationRecordDO.setRule(DeviceStatusEnum.OFFLINE.getCode());
//TODO 默认内置管理员
deviceOperationRecordDO.setCreator("1");
deviceOperationRecordDO.setUpdater("1");
deviceOperationRecordMapper.insert(deviceOperationRecordDO);
//抛出异常终止任务
throw new RuntimeException(e);
} }
} }
/** /**
* *
*/ */
private void processDeviceData(Long deviceId, DeviceDO device) { private void processDeviceData(Long deviceId, DeviceDO device) {
DeviceDO deviceDO = deviceMapper.selectById(deviceId);
// 1. 查询点位配置 // 1. 查询点位配置
List<DeviceContactModelDO> points = getDevicePoints(deviceId); List<DeviceContactModelDO> points = getDevicePoints(deviceId);
if (CollectionUtils.isEmpty(points)) { if (CollectionUtils.isEmpty(points)) {
logger.warn("设备 {} 未配置点位", deviceId); logger.warn("设备 {} 未配置点位", deviceId);
//更新状态为待机中
DeviceOperationRecordDO record = new DeviceOperationRecordDO();
record.setDeviceId(device.getId());
record.setRule(DeviceStatusEnum.STANDBY.getCode());
record.setTotalStandbyTime(deviceDO.getSampleCycle());
//TODO 创建人和更新人为内置默认管理员
record.setCreator("1");
record.setUpdater("1");
deviceOperationRecordMapper.insert(record);
return; return;
} }
logger.info("设备 {} 需要读取 {} 个点位", deviceId, points.size()); logger.info("设备 {} 需要读取 {} 个点位", deviceId, points.size());
DevicePointRulesDO devicePointRulesDO = devicePointRulesMapper.selectOne(Wrappers.<DevicePointRulesDO>lambdaQuery()
.eq(DevicePointRulesDO::getDeviceId, deviceId)
.eq(DevicePointRulesDO::getIdentifier, DeviceBasicStatusEnum.RUNNING));
if(devicePointRulesDO !=null && devicePointRulesDO.getFieldRule() == null ){
//更新状态为待机中
DeviceOperationRecordDO record = new DeviceOperationRecordDO();
record.setDeviceId(device.getId());
record.setRule(DeviceStatusEnum.STANDBY.getCode());
record.setTotalStandbyTime(deviceDO.getSampleCycle());
//TODO 创建人和更新人为内置默认管理员
record.setCreator("1");
record.setUpdater("1");
deviceOperationRecordMapper.insert(record);
}
// 2. 读取并处理数据 // 2. 读取并处理数据
int successCount = 0; int successCount = 0;
List<DeviceContactModelDO> validDataList = new ArrayList<>(); List<DeviceContactModelDO> validDataList = new ArrayList<>();

@ -41,12 +41,9 @@ public class DeviceModelAttributeRespVO {
@ExcelProperty("寄存器地址") @ExcelProperty("寄存器地址")
private String address; private String address;
@Schema(description = "单位")
private String dataUnit;
@Schema(description = "单位") @Schema(description = "单位")
@ExcelProperty("单位") @ExcelProperty("单位")
private String dataUnitName; private String dataUnit;
@Schema(description = "倍率") @Schema(description = "倍率")
@ExcelProperty("倍率") @ExcelProperty("倍率")

@ -56,7 +56,4 @@ public class RecipeRespVO {
// @ExcelProperty("关联设备ID") // @ExcelProperty("关联设备ID")
private Long deviceId; private Long deviceId;
@Schema(description = "设备Id")
private Long machineId;
} }

@ -37,7 +37,4 @@ public class RecipeSaveReqVO {
@Schema(description = "数据单位") @Schema(description = "数据单位")
private String dataUnit; private String dataUnit;
@Schema(description = "设备Id")
private Long machineId;
} }

@ -1,15 +1,9 @@
package cn.iocoder.yudao.module.iot.controller.admin.recipedevicerecord; package cn.iocoder.yudao.module.iot.controller.admin.recipedevicerecord;
import cn.iocoder.yudao.framework.common.util.opc.OpcUtils;
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceRespVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicecontactmodel.DeviceContactModelDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.recipe.RecipeDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.recipeplandetail.RecipePlanDetailDO; import cn.iocoder.yudao.module.iot.dal.dataobject.recipeplandetail.RecipePlanDetailDO;
import cn.iocoder.yudao.module.iot.service.device.DeviceService; import cn.iocoder.yudao.module.iot.service.device.DeviceService;
import cn.iocoder.yudao.module.iot.service.devicecontactmodel.DeviceContactModelService;
import cn.iocoder.yudao.module.iot.service.recipe.RecipeService; import cn.iocoder.yudao.module.iot.service.recipe.RecipeService;
import cn.iocoder.yudao.module.iot.service.recipeplandetail.RecipePlanDetailService; import cn.iocoder.yudao.module.iot.service.recipeplandetail.RecipePlanDetailService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -22,23 +16,17 @@ import javax.validation.*;
import javax.servlet.http.*; import javax.servlet.http.*;
import java.util.*; import java.util.*;
import java.io.IOException; import java.io.IOException;
import java.util.function.Function;
import java.util.stream.Collectors;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_NOT_EXISTS;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.RECIPE_NOT_EXISTS;
import cn.iocoder.yudao.module.iot.controller.admin.recipedevicerecord.vo.*; import cn.iocoder.yudao.module.iot.controller.admin.recipedevicerecord.vo.*;
import cn.iocoder.yudao.module.iot.dal.dataobject.recipedevicerecord.RecipeDeviceRecordDO; import cn.iocoder.yudao.module.iot.dal.dataobject.recipedevicerecord.RecipeDeviceRecordDO;
@ -85,9 +73,6 @@ public class RecipeDeviceRecordController {
@Resource @Resource
private DeviceService deviceService; private DeviceService deviceService;
@Resource
private DeviceContactModelService deviceContactModelService;
@PostMapping("/create") @PostMapping("/create")
@ -149,6 +134,7 @@ public class RecipeDeviceRecordController {
/** /**
* *
* @param recipeId ID * @param recipeId ID
* @param pointList [{id: 1, refer: "参考值1"}, {id: 2, refer: "参考值2"}]
* @return * @return
* @throws JsonProcessingException JSON * @throws JsonProcessingException JSON
*/ */
@ -159,7 +145,6 @@ public class RecipeDeviceRecordController {
@RequestParam("id") Long recipeId) { @RequestParam("id") Long recipeId) {
try {
RecipePlanDetailDO recipePlanDetailDO = recipePlanDetailService.getRecipePlanDetail(recipeId); RecipePlanDetailDO recipePlanDetailDO = recipePlanDetailService.getRecipePlanDetail(recipeId);
//RecipeRespVO recipeRespVO = recipeService.getRecipeWithDeviceId(recipePlanDetailDO.getRecipeId()); //RecipeRespVO recipeRespVO = recipeService.getRecipeWithDeviceId(recipePlanDetailDO.getRecipeId());
@ -167,57 +152,30 @@ public class RecipeDeviceRecordController {
// ========== 第一步:查询配方关联的点位属性信息 ========== // ========== 第一步:查询配方关联的点位属性信息 ==========
// 1.1 根据recipeId查询iot_recipe_device_attribute表记录 // 1.1 根据recipeId查询iot_recipe_device_attribute表记录
recipePlanDetailDO.setRecipeId(recipeId); recipePlanDetailDO.setRecipeId(32L);
List<RecipeDeviceAttributeDO> attributeList = recipeDeviceAttributeService.getByRecipeId(recipePlanDetailDO.getRecipeId()); List<RecipeDeviceAttributeDO> attributeList = recipeDeviceAttributeService.getByRecipeId(recipePlanDetailDO.getRecipeId());
// if (CollectionUtils.isEmpty(attributeList)) {
//先删除在添加 // return success(false); // 无关联属性,直接返回
List<RecipeDeviceRecordDO> recipeDeviceRecordDOS = recipeDeviceRecordService.getListByRecipeId(recipeId); // }
if (!recipeDeviceRecordDOS.isEmpty()){ Map<Long, Map<String, Object>> deviceDataMap = deviceService.createDeviceDataMap(103L);//recipeRespVO.getDeviceId()
recipeDeviceRecordService.deleteByIds(recipeDeviceRecordDOS);
}
RecipeDO recipe = recipeService.getRecipe(recipeId);
if (recipe == null){
throw exception(RECIPE_NOT_EXISTS);
}
DeviceRespVO device = deviceService.getDevice(recipe.getMachineId());
if (device== null ){
throw exception(DEVICE_NOT_EXISTS);
}
Map<Long, DeviceContactModelDO> deviceContactModelMap = new HashMap<>();
List<DeviceContactModelDO> deviceContactModelDOS = deviceContactModelService.selectListByDeviceId(device.getId());
if (!deviceContactModelDOS.isEmpty()){
deviceContactModelMap = deviceContactModelDOS.stream()
.collect(Collectors.toMap(
DeviceContactModelDO::getId,
Function.identity()
));
}
OpcUtils.connect(device.getUrl(),device.getUsername(),device.getPassword(),10);
for (RecipeDeviceAttributeDO attributeDO : attributeList) { for (RecipeDeviceAttributeDO attributeDO : attributeList) {
DeviceContactModelDO deviceContactModelDO = deviceContactModelMap.get(attributeDO.getAttributeId()); Map<String, Object> data = deviceDataMap.get(attributeDO.getAttributeId());
if (deviceContactModelDO == null){ if (data != null ) {
continue;
}
// 创建 // 创建
RecipeDeviceRecordDO recipeDeviceRecordDO = new RecipeDeviceRecordDO(); RecipeDeviceRecordDO recipeDeviceRecordDO = new RecipeDeviceRecordDO();
recipeDeviceRecordDO.setRecipeId(recipeId); recipeDeviceRecordDO.setRecipeId(recipeId);
recipeDeviceRecordDO.setAttributeCode(deviceContactModelDO.getAttributeName()); recipeDeviceRecordDO.setAttributeCode(attributeDO.getAttributeName());
recipeDeviceRecordDO.setDataType(deviceContactModelDO.getDataType()); recipeDeviceRecordDO.setDataType(attributeDO.getDataType());
recipeDeviceRecordDO.setDataUnit(deviceContactModelDO.getDataUnit()); recipeDeviceRecordDO.setDataUnit(attributeDO.getDataUnit());
recipeDeviceRecordDO.setValue((String) OpcUtils.readValue(deviceContactModelDO.getAddress())); if (data.get("addressValue") != null && data.get("addressValue").toString() != null) {
recipeDeviceRecordDO.setValue(data.get("addressValue").toString());
}
recipeDeviceRecordService.createRecipeDeviceRecord(BeanUtils.toBean(recipeDeviceRecordDO, RecipeDeviceRecordSaveReqVO.class)); recipeDeviceRecordService.createRecipeDeviceRecord(BeanUtils.toBean(recipeDeviceRecordDO, RecipeDeviceRecordSaveReqVO.class));
} }
} finally {
OpcUtils.disconnect();
} }
return success(true); return success(true);
} }

@ -52,5 +52,4 @@ public class RecipeDeviceRecordPageReqVO extends PageParam {
@Schema(description = "配方id", example = "32535") @Schema(description = "配方id", example = "32535")
private Long recipeId; private Long recipeId;
} }

@ -25,7 +25,7 @@ public class RecipePlanDetailSaveReqVO {
private Long recipeId; private Long recipeId;
@Schema(description = "关联计划关联mes_plan表的id", requiredMode = Schema.RequiredMode.REQUIRED, example = "28398") @Schema(description = "关联计划关联mes_plan表的id", requiredMode = Schema.RequiredMode.REQUIRED, example = "28398")
// @NotNull(message = "关联计划关联mes_plan表的id不能为空") @NotNull(message = "关联计划关联mes_plan表的id不能为空")
private Long planId; private Long planId;
@Schema(description = "来源(新增/生产中)") @Schema(description = "来源(新增/生产中)")

@ -60,11 +60,4 @@ public class RecipeDO extends BaseDO {
*/ */
private String dataUnit; private String dataUnit;
/**
*
*/
private Long machineId;
} }

@ -523,16 +523,9 @@ public class DeviceServiceImpl implements DeviceService {
}else if(Objects.equals(createReqVO.getIsConnect(), DeviceConnectionStatusEnum.DISCONNECTED.getStatus())){ }else if(Objects.equals(createReqVO.getIsConnect(), DeviceConnectionStatusEnum.DISCONNECTED.getStatus())){
boolean disconnect = OpcUtils.disconnect(); boolean disconnect = OpcUtils.disconnect();
if (disconnect){ if (disconnect){
//更新连接状态
deviceDO.setStatus(String.valueOf(DeviceConnectionStatusEnum.DISCONNECTED.getStatus())); deviceDO.setStatus(String.valueOf(DeviceConnectionStatusEnum.DISCONNECTED.getStatus()));
deviceMapper.updateById(deviceDO); deviceMapper.updateById(deviceDO);
//停止定时任务
taskSchedulerManager.stopDeviceTask(deviceDO.getId()); taskSchedulerManager.stopDeviceTask(deviceDO.getId());
//更新运行状态
updateOperationalStatus(deviceDO);
}else { }else {
throw exception(OPC_CLOSE_CONNECT_FAILURE); throw exception(OPC_CLOSE_CONNECT_FAILURE);
} }
@ -543,13 +536,6 @@ public class DeviceServiceImpl implements DeviceService {
return Boolean.TRUE; return Boolean.TRUE;
} }
private void updateOperationalStatus(DeviceDO deviceDO) {
DeviceOperationRecordDO deviceOperationRecordDO = new DeviceOperationRecordDO();
deviceOperationRecordDO.setDeviceId(deviceDO.getId());
deviceOperationRecordDO.setRule(DeviceStatusEnum.OFFLINE.getCode());
deviceOperationRecordMapper.insert(deviceOperationRecordDO);
}
private DeviceDO validateConnectRequest(DeviceSaveReqVO createReqVO) { private DeviceDO validateConnectRequest(DeviceSaveReqVO createReqVO) {
if(createReqVO.getId() == null){ if(createReqVO.getId() == null){
throw exception(DEVICE_ID_DOES_NOT_EXIST); throw exception(DEVICE_ID_DOES_NOT_EXIST);

@ -53,6 +53,4 @@ public interface DeviceContactModelService {
PageResult<DeviceContactModelDO> getDeviceContactModelPage(DeviceContactModelPageReqVO pageReqVO); PageResult<DeviceContactModelDO> getDeviceContactModelPage(DeviceContactModelPageReqVO pageReqVO);
List<DeviceContactModelDO> getDeviceContactModelList(Long id); List<DeviceContactModelDO> getDeviceContactModelList(Long id);
List<DeviceContactModelDO> selectListByDeviceId(Long id);
} }

@ -99,9 +99,4 @@ public class DeviceContactModelServiceImpl implements DeviceContactModelService
.orderByDesc(DeviceContactModelDO::getCreateTime)); .orderByDesc(DeviceContactModelDO::getCreateTime));
} }
@Override
public List<DeviceContactModelDO> selectListByDeviceId(Long id) {
return deviceContactModelMapper.selectList(Wrappers.<DeviceContactModelDO>lambdaQuery().eq(DeviceContactModelDO::getDeviceId,id));
}
} }

@ -3,9 +3,6 @@ package cn.iocoder.yudao.module.iot.service.devicemodelattribute;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttributeTypeDO; import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttributeTypeDO;
import cn.iocoder.yudao.module.iot.dal.mysql.deviceattributetype.DeviceAttributeTypeMapper; import cn.iocoder.yudao.module.iot.dal.mysql.deviceattributetype.DeviceAttributeTypeMapper;
import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants; import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants;
@ -35,7 +32,6 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.dal.mysql.devicemodelattribute.DeviceModelAttributeMapper; import cn.iocoder.yudao.module.iot.dal.mysql.devicemodelattribute.DeviceModelAttributeMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
/** /**
@ -57,9 +53,6 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
@Resource @Resource
private DeviceAttributeTypeMapper deviceAttributeTypeMapper; private DeviceAttributeTypeMapper deviceAttributeTypeMapper;
@Resource
private ErpProductUnitService productUnitService;
@Override @Override
public Long createDeviceModelAttribute(DeviceModelAttributeSaveReqVO createReqVO) { public Long createDeviceModelAttribute(DeviceModelAttributeSaveReqVO createReqVO) {
@ -122,33 +115,9 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
// List<DeviceAttributeTypeDO> attributeTypes = deviceAttributeTypeMapper.selectList(); // List<DeviceAttributeTypeDO> attributeTypes = deviceAttributeTypeMapper.selectList();
// Map<Long, String> typeNameMap = attributeTypes.stream() // Map<Long, String> typeNameMap = attributeTypes.stream()
// .collect(Collectors.toMap(DeviceAttributeTypeDO::getId, DeviceAttributeTypeDO::getName)); // .collect(Collectors.toMap(DeviceAttributeTypeDO::getId, DeviceAttributeTypeDO::getName));
Map<Long, ErpProductUnitDO> unitMap = productUnitService.getProductUnitMap(
pageResult.getList().stream()
.map(DeviceModelAttributeDO::getDataUnit)
.filter(StringUtils::isNotEmpty)
.map(str -> {
try {
return Long.valueOf(str.trim());
} catch (NumberFormatException e) {
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toSet())
);
// 转换并设置类型名称
PageResult<DeviceModelAttributeRespVO> respPageResult = BeanUtils.toBean(pageResult, DeviceModelAttributeRespVO.class, deviceModelAttribute -> {
String dataUnitStr = deviceModelAttribute.getDataUnit();
if (StringUtils.isNotBlank(dataUnitStr)) {
try {
Long dataUnitId = Long.valueOf(dataUnitStr.trim());
MapUtils.findAndThen(unitMap, dataUnitId,
unit -> deviceModelAttribute.setDataUnitName(unit.getName()));
} catch (NumberFormatException e) {
} // 转换并设置类型名称
} PageResult<DeviceModelAttributeRespVO> respPageResult = BeanUtils.toBean(pageResult, DeviceModelAttributeRespVO.class);
});
// respPageResult.getList().forEach(item -> { // respPageResult.getList().forEach(item -> {
// String typeName = typeNameMap.get(item.getAttributeType()); // String typeName = typeNameMap.get(item.getAttributeType());

@ -52,7 +52,4 @@ public interface RecipeDeviceRecordService {
*/ */
PageResult<RecipeDeviceRecordDO> getRecipeDeviceRecordPage(RecipeDeviceRecordPageReqVO pageReqVO); PageResult<RecipeDeviceRecordDO> getRecipeDeviceRecordPage(RecipeDeviceRecordPageReqVO pageReqVO);
List<RecipeDeviceRecordDO> getListByRecipeId(Long recipeId);
void deleteByIds(List<RecipeDeviceRecordDO> recipeDeviceRecordDOS);
} }

@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.iot.service.recipedevicerecord; package cn.iocoder.yudao.module.iot.service.recipedevicerecord;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -32,7 +31,6 @@ public class RecipeDeviceRecordServiceImpl implements RecipeDeviceRecordService
@Override @Override
public Long createRecipeDeviceRecord(RecipeDeviceRecordSaveReqVO createReqVO) { public Long createRecipeDeviceRecord(RecipeDeviceRecordSaveReqVO createReqVO) {
// 插入 // 插入
RecipeDeviceRecordDO recipeDeviceRecord = BeanUtils.toBean(createReqVO, RecipeDeviceRecordDO.class); RecipeDeviceRecordDO recipeDeviceRecord = BeanUtils.toBean(createReqVO, RecipeDeviceRecordDO.class);
recipeDeviceRecordMapper.insert(recipeDeviceRecord); recipeDeviceRecordMapper.insert(recipeDeviceRecord);
@ -73,16 +71,4 @@ public class RecipeDeviceRecordServiceImpl implements RecipeDeviceRecordService
return recipeDeviceRecordMapper.selectPage(pageReqVO); return recipeDeviceRecordMapper.selectPage(pageReqVO);
} }
@Override
public List<RecipeDeviceRecordDO> getListByRecipeId(Long recipeId) {
return recipeDeviceRecordMapper.selectList(Wrappers.<RecipeDeviceRecordDO>lambdaQuery().eq(RecipeDeviceRecordDO::getRecipeId, recipeId));
}
@Override
public void deleteByIds(List<RecipeDeviceRecordDO> recipeDeviceRecordDOS) {
recipeDeviceRecordMapper.deleteByIds(recipeDeviceRecordDOS);
}
} }

@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.iot.service.recipepointrecord; package cn.iocoder.yudao.module.iot.service.recipepointrecord;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -32,12 +31,6 @@ public class RecipePointRecordServiceImpl implements RecipePointRecordService {
@Override @Override
public Long createRecipePointRecord(RecipePointRecordSaveReqVO createReqVO) { public Long createRecipePointRecord(RecipePointRecordSaveReqVO createReqVO) {
List<RecipePointRecordDO> recipePointRecordDOS = recipePointRecordMapper.selectList(Wrappers.<RecipePointRecordDO>lambdaQuery().eq(RecipePointRecordDO::getRecipeId, createReqVO.getRecipeId()));
if (!recipePointRecordDOS.isEmpty()){
recipePointRecordMapper.deleteByIds(recipePointRecordDOS);
}
// 插入 // 插入
RecipePointRecordDO recipePointRecord = BeanUtils.toBean(createReqVO, RecipePointRecordDO.class); RecipePointRecordDO recipePointRecord = BeanUtils.toBean(createReqVO, RecipePointRecordDO.class);
recipePointRecordMapper.insert(recipePointRecord); recipePointRecordMapper.insert(recipePointRecord);

@ -143,8 +143,6 @@ public interface ErrorCodeConstants {
ErrorCode SUBJECT_EXISTS = new ErrorCode(1002000010, "项目编码已存在"); ErrorCode SUBJECT_EXISTS = new ErrorCode(1002000010, "项目编码已存在");
ErrorCode TASK_MANAGEMENT_NOT_EXISTS = new ErrorCode(1002000011, "设备类型不存在"); ErrorCode TASK_MANAGEMENT_NOT_EXISTS = new ErrorCode(1002000011, "设备类型不存在");
ErrorCode TASK_CORN_NOT_EXISTS = new ErrorCode(1002000011, "设备corn表达式为空"); ErrorCode TASK_CORN_NOT_EXISTS = new ErrorCode(1002000011, "设备corn表达式为空");
ErrorCode TASK_CORN_NOT_LE_HOUR = new ErrorCode(1002000011, "corn表达式不能小于一小时");
ErrorCode TICKET_MANAGEMENT_NOT_EXISTS = new ErrorCode(1002000012, "工单管理不存在"); ErrorCode TICKET_MANAGEMENT_NOT_EXISTS = new ErrorCode(1002000012, "工单管理不存在");
ErrorCode TICKET_RESULTS_NOT_EXISTS = new ErrorCode(1002000013, "工单检验结果不存在"); ErrorCode TICKET_RESULTS_NOT_EXISTS = new ErrorCode(1002000013, "工单检验结果不存在");
ErrorCode TICKET_RESULTS_ID_NOT_NULL = new ErrorCode(1002000014, "工单检验结果Id不存在"); ErrorCode TICKET_RESULTS_ID_NOT_NULL = new ErrorCode(1002000014, "工单检验结果Id不存在");

@ -16,11 +16,6 @@ import cn.iocoder.yudao.module.mes.dal.mysql.ticketmanagement.TicketManagementMa
import cn.iocoder.yudao.module.mes.dal.mysql.ticketresults.TicketResultsMapper; import cn.iocoder.yudao.module.mes.dal.mysql.ticketresults.TicketResultsMapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cronutils.model.Cron;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.time.ExecutionTime;
import com.cronutils.parser.CronParser;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -28,8 +23,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -80,12 +73,6 @@ public class TaskManagementServiceImpl implements TaskManagementService {
@Override @Override
public Long createTaskManagement(TaskManagementSaveReqVO createReqVO) { public Long createTaskManagement(TaskManagementSaveReqVO createReqVO) {
String cronExpr = createReqVO.getCronExpression();
// 校验 cron 表达式最小间隔
isCronIntervalAtLeastOneHour(cronExpr);
// 插入 // 插入
TaskManagementDO taskManagement = BeanUtils.toBean(createReqVO, TaskManagementDO.class); TaskManagementDO taskManagement = BeanUtils.toBean(createReqVO, TaskManagementDO.class);
taskManagementMapper.insert(taskManagement); taskManagementMapper.insert(taskManagement);
@ -93,35 +80,6 @@ public class TaskManagementServiceImpl implements TaskManagementService {
return taskManagement.getId(); return taskManagement.getId();
} }
private void isCronIntervalAtLeastOneHour(String cronExpr) {
try {
if (StringUtils.isBlank(cronExpr)){
return;
}
CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ));
Cron cron = parser.parse(cronExpr);
cron.validate();
ExecutionTime executionTime = ExecutionTime.forCron(cron);
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime next1 = executionTime.nextExecution(now).get();
ZonedDateTime next2 = executionTime.nextExecution(next1).get();
Duration duration = Duration.between(next1, next2);
if (duration.toHours() < 1) {
throw exception(TASK_CORN_NOT_LE_HOUR);
}
} catch (Exception e) {
throw exception(TASK_CORN_NOT_LE_HOUR);
}
}
@Override @Override
public void updateTaskManagement(TaskManagementSaveReqVO updateReqVO) { public void updateTaskManagement(TaskManagementSaveReqVO updateReqVO) {
// 校验存在 // 校验存在

Loading…
Cancel
Save