Merge branch 'hhk' into main

plp
HuangHuiKang 3 weeks ago
commit 72d1836fd3

@ -44,6 +44,7 @@ public interface ErrorCodeConstants {
ErrorCode DEVICE_ATTRIBUTE_NOT_EXISTS = new ErrorCode(1_003_000_000, "设备属性不存在"); ErrorCode DEVICE_ATTRIBUTE_NOT_EXISTS = new ErrorCode(1_003_000_000, "设备属性不存在");
ErrorCode DEVICE_ATTRIBUTE_TYPE_NOT_EXISTS = new ErrorCode(1_003_000_000, "采集点分类不存在"); ErrorCode DEVICE_ATTRIBUTE_TYPE_NOT_EXISTS = new ErrorCode(1_003_000_000, "采集点分类不存在");
ErrorCode DEVICE_CODE_EXISTS = new ErrorCode(1_003_000_000, "采集点编码已存在"); ErrorCode DEVICE_CODE_EXISTS = new ErrorCode(1_003_000_000, "采集点编码已存在");
ErrorCode DEVICE_ATTRIBUTE_TYPE_REFERENCES_EXISTS = new ErrorCode(1_003_000_000, "存在采集点类型已被引用,请先删除对应引用");
ErrorCode ENDPOINT_DOES_NOT_EXIS = new ErrorCode(1_003_000_000, "暂未设置设备端点"); ErrorCode ENDPOINT_DOES_NOT_EXIS = new ErrorCode(1_003_000_000, "暂未设置设备端点");
ErrorCode DEVICE_DOES_NOT_EXIST= new ErrorCode(1_003_000_000, "该采集设备不存在"); ErrorCode DEVICE_DOES_NOT_EXIST= new ErrorCode(1_003_000_000, "该采集设备不存在");

@ -59,18 +59,18 @@ public class DeviceController {
tDengineService.initDatabaseAndTable(device.getId()); tDengineService.initDatabaseAndTable(device.getId());
//添加定时任务 //添加定时任务
// 创建 JobSaveReqVO 对象实例 // 创建 JobSaveReqVO 对象实例
JobSaveReqVO jobSaveReqVO = new JobSaveReqVO(); // JobSaveReqVO jobSaveReqVO = new JobSaveReqVO();
// 设置任务属性(根据您的业务需求设置具体值) // // 设置任务属性(根据您的业务需求设置具体值)
jobSaveReqVO.setName("deviceJob_" + device.getId()); // 处理器名称唯一 // jobSaveReqVO.setName("deviceJob_" + device.getId()); // 处理器名称唯一
jobSaveReqVO.setHandlerName("deviceJob"); // 处理器名称唯一 // jobSaveReqVO.setHandlerName("deviceJob"); // 处理器名称唯一
jobSaveReqVO.setHandlerParam("{\"deviceId\": \"" + device.getId() + "\"}"); // 使用设备ID作为参数值 // jobSaveReqVO.setHandlerParam("{\"deviceId\": \"" + device.getId() + "\"}"); // 使用设备ID作为参数值
jobSaveReqVO.setCronExpression("*/5 * * * * ?"); // CRON表达式每5秒执行一次[1,3](@ref) // jobSaveReqVO.setCronExpression("*/5 * * * * ?"); // CRON表达式每5秒执行一次[1,3](@ref)
jobSaveReqVO.setRetryCount(3); // 重试次数 // jobSaveReqVO.setRetryCount(3); // 重试次数
jobSaveReqVO.setRetryInterval(5000); // 重试间隔(毫秒) // jobSaveReqVO.setRetryInterval(5000); // 重试间隔(毫秒)
jobSaveReqVO.setMonitorTimeout(30000); // 监控超时时间(毫秒) // jobSaveReqVO.setMonitorTimeout(30000); // 监控超时时间(毫秒)
jobSaveReqVO.setDeviceId(device.getId()); // jobSaveReqVO.setDeviceId(device.getId());
//
jobService.createJob(jobSaveReqVO); // jobService.createJob(jobSaveReqVO);
return success(device); return success(device);
} }

@ -308,20 +308,20 @@ public class TDengineService {
* @return * @return
*/ */
@DS("tdengine") @DS("tdengine")
public List<Map<String, Object>> getstDeviceDataOrderByTimeDesc(Long id,String collectionStartTime, String collectionEndTime) { public List<Map<String, Object>> getstDeviceDataOrderByTimeDesc(Long id,String StartTime, String EndTime) {
String tableName = "d_" + id; String tableName = "d_" + id;
StringBuilder sqlBuilder = new StringBuilder(); StringBuilder sqlBuilder = new StringBuilder();
List<Object> params = new ArrayList<>(); List<Object> params = new ArrayList<>();
sqlBuilder.append("SELECT ts, query_data FROM besure.").append(tableName).append(" WHERE 1=1"); sqlBuilder.append("SELECT ts, query_data FROM besure.").append(tableName).append(" WHERE 1=1");
if (collectionStartTime != null) { if (StartTime != null) {
// 直接将时间字符串拼接到SQL中 // 直接将时间字符串拼接到SQL中
sqlBuilder.append(" AND ts >= '").append(collectionStartTime).append("'"); sqlBuilder.append(" AND ts >= '").append(StartTime).append("'");
} }
if (collectionEndTime != null) { if (EndTime != null) {
sqlBuilder.append(" AND ts <= '").append(collectionEndTime).append("'"); sqlBuilder.append(" AND ts <= '").append(EndTime).append("'");
} }
sqlBuilder.append(" ORDER BY ts DESC"); sqlBuilder.append(" ORDER BY ts DESC");

@ -1,7 +1,13 @@
package cn.iocoder.yudao.module.iot.service.deviceattributetype; package cn.iocoder.yudao.module.iot.service.deviceattributetype;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO;
import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
import cn.iocoder.yudao.module.iot.dal.mysql.devicecontactmodel.DeviceContactModelMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.devicemodel.DeviceModelMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.devicemodelattribute.DeviceModelAttributeMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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 javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
@ -33,6 +39,12 @@ public class DeviceAttributeTypeServiceImpl implements DeviceAttributeTypeServic
@Resource @Resource
private DeviceAttributeTypeMapper deviceAttributeTypeMapper; private DeviceAttributeTypeMapper deviceAttributeTypeMapper;
@Resource
private DeviceModelAttributeMapper deviceModelAttributeMapper;
@Resource
private DeviceContactModelMapper deviceContactModelMapper;
@Override @Override
public Long createDeviceAttributeType(DeviceAttributeTypeSaveReqVO createReqVO) { public Long createDeviceAttributeType(DeviceAttributeTypeSaveReqVO createReqVO) {
// 重复判断 // 重复判断
@ -62,8 +74,10 @@ public class DeviceAttributeTypeServiceImpl implements DeviceAttributeTypeServic
if (count > 0) { if (count > 0) {
throw exception(DEVICE_CODE_EXISTS); throw exception(DEVICE_CODE_EXISTS);
} }
DeviceAttributeTypeDO deviceAttributeTypeDO = deviceAttributeTypeMapper.selectById(updateReqVO.getId());
// 校验存在 // 校验存在
validateDeviceAttributeTypeExists(updateReqVO.getId()); validateDeviceAttributeTypeExists(deviceAttributeTypeDO);
// 更新 // 更新
DeviceAttributeTypeDO updateObj = BeanUtils.toBean(updateReqVO, DeviceAttributeTypeDO.class); DeviceAttributeTypeDO updateObj = BeanUtils.toBean(updateReqVO, DeviceAttributeTypeDO.class);
deviceAttributeTypeMapper.updateById(updateObj); deviceAttributeTypeMapper.updateById(updateObj);
@ -71,17 +85,41 @@ public class DeviceAttributeTypeServiceImpl implements DeviceAttributeTypeServic
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteDeviceAttributeType( List<Long> ids) { public void deleteDeviceAttributeType(List<Long> ids) {
for (Long id : ids) { if (CollectionUtils.isEmpty(ids)) {
// 校验存在 return;
validateDeviceAttributeTypeExists(id); }
// 批量校验存在性
List<DeviceAttributeTypeDO> existList = deviceAttributeTypeMapper.selectBatchIds(ids);
if (existList.size() != ids.size()) {
throw exception(DEVICE_ATTRIBUTE_TYPE_NOT_EXISTS);
} }
// 删除
// 批量校验引用
validateBatchReferences(ids);
// 批量删除
deviceAttributeTypeMapper.deleteByIds(ids); deviceAttributeTypeMapper.deleteByIds(ids);
} }
private void validateDeviceAttributeTypeExists(Long id) { private void validateBatchReferences(List<Long> ids) {
if (deviceAttributeTypeMapper.selectById(id) == null) { // 批量查询引用
boolean hasModelRef = deviceModelAttributeMapper.exists(
Wrappers.<DeviceModelAttributeDO>lambdaQuery()
.in(DeviceModelAttributeDO::getAttributeType, ids));
boolean hasContactRef = deviceContactModelMapper.exists(
Wrappers.<DeviceContactModelDO>lambdaQuery()
.in(DeviceContactModelDO::getAttributeType, ids));
if (hasModelRef || hasContactRef) {
throw exception(DEVICE_ATTRIBUTE_TYPE_REFERENCES_EXISTS);
}
}
private void validateDeviceAttributeTypeExists(DeviceAttributeTypeDO deviceAttributeTypeDO) {
if (deviceAttributeTypeDO == null) {
throw exception(DEVICE_ATTRIBUTE_TYPE_NOT_EXISTS); throw exception(DEVICE_ATTRIBUTE_TYPE_NOT_EXISTS);
} }
} }

@ -67,6 +67,19 @@ public interface ErrorCodeConstants {
ErrorCode ENERGY_TYPE_NOT_EXISTS = new ErrorCode(5_0084, "能耗类型不存在"); ErrorCode ENERGY_TYPE_NOT_EXISTS = new ErrorCode(5_0084, "能耗类型不存在");
ErrorCode ENERGY_DEVICE_NOT_EXISTS = new ErrorCode(5_0084, "能耗设备不存在"); ErrorCode ENERGY_DEVICE_NOT_EXISTS = new ErrorCode(5_0084, "能耗设备不存在");
ErrorCode ENERGY_DEVICE_CHECK_RECORD_NOT_EXISTS = new ErrorCode(5_0085, "能耗抄表记录不存在"); ErrorCode ENERGY_DEVICE_CHECK_RECORD_NOT_EXISTS = new ErrorCode(5_0085, "能耗抄表记录不存在");
ErrorCode ENERGY_DEVICE_CHECK_CODE_EXISTS = new ErrorCode(5_0086, "能耗类型编码已存在");
ErrorCode CALCULATION_RULE_NOT_EXISTS = new ErrorCode(5_0087, "运算规则不能为空");
ErrorCode CALCULATION_LAST_RULE_NO_OPERATOR = new ErrorCode(5_0088, "最后一个运算规则不能有运算符");
ErrorCode CALCULATION_OPERATOR_MISSING = new ErrorCode(5_0089, "运算规则缺少运算符");
ErrorCode CALCULATION_OPERATOR_INVALID = new ErrorCode(5_0090, "运算符不合法");
ErrorCode CALCULATION_CONSECUTIVE_OPERATORS = new ErrorCode(5_0081, "不能连续出现运算符");
ErrorCode CALCULATION_CONSECUTIVE_NOT_EXISTS = new ErrorCode(5_0082, "运算规则不存在");
ErrorCode ENERGY_LIST_NOT_EXISTS = new ErrorCode(5_0082, "能耗设备列表不存在");
ErrorCode ENERGY_DEVICE_CODE_DUPLICATE = new ErrorCode(5_0082, "能耗设备编码已存在");
ErrorCode MOLD_RECORD_SUBJECT_NOT_EXISTS = new ErrorCode(5_0086, "维保项目不存在"); ErrorCode MOLD_RECORD_SUBJECT_NOT_EXISTS = new ErrorCode(5_0086, "维保项目不存在");
ErrorCode MOLD_RECORD_ITEM_NOT_EXISTS = new ErrorCode(5_0087, "维保方案不存在"); ErrorCode MOLD_RECORD_ITEM_NOT_EXISTS = new ErrorCode(5_0087, "维保方案不存在");
@ -76,7 +89,9 @@ public interface ErrorCodeConstants {
ErrorCode DV_CHECK_NOT_EXISTS = new ErrorCode(5_0087, "维保计划不存在"); ErrorCode DV_CHECK_NOT_EXISTS = new ErrorCode(5_0087, "维保计划不存在");
ErrorCode DV_SUBJECT_NOT_EXISTS = new ErrorCode(5_0087, "维保项目不存在"); ErrorCode DV_SUBJECT_NOT_EXISTS = new ErrorCode(5_0087, "项目不存在");
ErrorCode DV_SUBJECT_REFERENCES = new ErrorCode(5_0087, "存在项目已被引用,请先删除所引用");
ErrorCode DV_REPAIR_NOT_EXISTS = new ErrorCode(5_0087, "设备维修记录不存在"); ErrorCode DV_REPAIR_NOT_EXISTS = new ErrorCode(5_0087, "设备维修记录不存在");
ErrorCode DV_REPAIR_CODE_EXISTS = new ErrorCode(5_0087, "设备维修记录编码已存在"); ErrorCode DV_REPAIR_CODE_EXISTS = new ErrorCode(5_0087, "设备维修记录编码已存在");
@ -90,6 +105,8 @@ public interface ErrorCodeConstants {
//======================================设备管理相关 1002000000================================================= //======================================设备管理相关 1002000000=================================================
ErrorCode DEVICE_TYPE_NOT_EXISTS = new ErrorCode(1002000000, "设备类型不存在"); ErrorCode DEVICE_TYPE_NOT_EXISTS = new ErrorCode(1002000000, "设备类型不存在");
ErrorCode DEVICE_TYPE_REFERENCES = new ErrorCode(1002000000, "该设备类型已被引用,请先删除相关引用");
ErrorCode DEVICE_TYPE_PARENT_NOT_EXISTS = new ErrorCode(1002000001, "父级设备类型不存在"); ErrorCode DEVICE_TYPE_PARENT_NOT_EXISTS = new ErrorCode(1002000001, "父级设备类型不存在");
ErrorCode DEVICE_TYPE_PARENT_IS_SELF = new ErrorCode(1002000002, "不能设置自己为父级"); ErrorCode DEVICE_TYPE_PARENT_IS_SELF = new ErrorCode(1002000002, "不能设置自己为父级");
ErrorCode DEVICE_TYPE_PARENT_IS_CHILD = new ErrorCode(1002000003, "不能设置子节点为父级"); ErrorCode DEVICE_TYPE_PARENT_IS_CHILD = new ErrorCode(1002000003, "不能设置子节点为父级");
@ -97,6 +114,8 @@ public interface ErrorCodeConstants {
ErrorCode DEVICE_LEDGER_NOT_EXISTS = new ErrorCode(1002000005, "该设备不存在"); ErrorCode DEVICE_LEDGER_NOT_EXISTS = new ErrorCode(1002000005, "该设备不存在");
ErrorCode DEVICE_LEDGER_CODE_NOT_ONLY = new ErrorCode(1002000006, "设备类型编码已存在"); ErrorCode DEVICE_LEDGER_CODE_NOT_ONLY = new ErrorCode(1002000006, "设备类型编码已存在");
ErrorCode PLAN_MAINTENANCE_NOT_EXISTS = new ErrorCode(1002000007, "方案维护不存在"); ErrorCode PLAN_MAINTENANCE_NOT_EXISTS = new ErrorCode(1002000007, "方案维护不存在");
ErrorCode PLAN_MAINTENANCE_REFERENCES = new ErrorCode(1002000007, "该方案维护已被引用,请先删除引用");
ErrorCode SUBJECT_PLAN_NOT_EXISTS = new ErrorCode(1002000008, "项目方案关联不存在"); ErrorCode SUBJECT_PLAN_NOT_EXISTS = new ErrorCode(1002000008, "项目方案关联不存在");
ErrorCode SUBJECT_ID_NOT_EXISTS = new ErrorCode(1002000009, "项目Id不存在"); ErrorCode SUBJECT_ID_NOT_EXISTS = new ErrorCode(1002000009, "项目Id不存在");
ErrorCode DEVICE_LEDGER_EXISTS = new ErrorCode(1002000010, "设备台账编码已存在"); ErrorCode DEVICE_LEDGER_EXISTS = new ErrorCode(1002000010, "设备台账编码已存在");
@ -106,7 +125,13 @@ public interface ErrorCodeConstants {
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不存在");
ErrorCode CRITICAL_COMPONENT_NOT_EXISTS = new ErrorCode(1002000015, "设备关键件不存在"); ErrorCode CRITICAL_COMPONENT_NOT_EXISTS = new ErrorCode(1002000015, "设备关键件不存在");
ErrorCode CRITICAL_COMPONENT_REFERENCES= new ErrorCode(1002000015, "存在设备关键件已被引用,请先删除引用");
ErrorCode REPAIR_TEMS_NOT_EXISTS = new ErrorCode(1002000016, "维修项目不存在"); ErrorCode REPAIR_TEMS_NOT_EXISTS = new ErrorCode(1002000016, "维修项目不存在");
ErrorCode REPAIR_TEMS_CODE_EXISTS = new ErrorCode(1002000016, "维修项目编码已存在"); ErrorCode REPAIR_TEMS_CODE_EXISTS = new ErrorCode(1002000016, "维修项目编码已存在");
//======================================能源设相关 1002010000=================================================
ErrorCode ENERGY_RECORD_NOT_EXISTS = new ErrorCode(1002010000, "能源设备历史记录不存在");
} }

@ -66,8 +66,8 @@ public class EnergyDeviceController {
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('mes:energy-device:query')") @PreAuthorize("@ss.hasPermission('mes:energy-device:query')")
public CommonResult<EnergyDeviceRespVO> getEnergyDevice(@RequestParam("id") Long id) { public CommonResult<EnergyDeviceRespVO> getEnergyDevice(@RequestParam("id") Long id) {
EnergyDeviceDO energyDevice = energyDeviceService.getEnergyDevice(id); EnergyDeviceRespVO energyDeviceRespVO = energyDeviceService.getEnergyDevice(id);
return success(BeanUtils.toBean(energyDevice, EnergyDeviceRespVO.class)); return success(energyDeviceRespVO);
} }
@GetMapping("/getList") @GetMapping("/getList")
@Operation(summary = "获得能源设备列表") @Operation(summary = "获得能源设备列表")
@ -97,6 +97,16 @@ public class EnergyDeviceController {
BeanUtils.toBean(list, EnergyDeviceRespVO.class)); BeanUtils.toBean(list, EnergyDeviceRespVO.class));
} }
@PostMapping("/queryDataRecords")
@Operation(summary = "查询数据记录")
@PreAuthorize("@ss.hasPermission('mes:energy-device:create')")
public CommonResult<List<EnergyDeviceRespVO>> queryDataRecords(@RequestParam(name = "startTime", required = false ) String startTime,
@RequestParam(name = "endTime", required = false ) String endTime) {
return success(energyDeviceService.queryDataRecords(startTime,endTime));
}
// ==================== 子表(抄表记录) ==================== // ==================== 子表(抄表记录) ====================
@GetMapping("/energy-device-check-record/page") @GetMapping("/energy-device-check-record/page")

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo; package cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import java.util.*; import java.util.*;
@ -17,7 +18,7 @@ import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
public class EnergyDeviceRespVO { public class EnergyDeviceRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "25931") @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "25931")
@ExcelProperty("ID") // @ExcelProperty("ID")
private Long id; private Long id;
@Schema(description = "名称", example = "芋艿") @Schema(description = "名称", example = "芋艿")
@ -34,23 +35,23 @@ public class EnergyDeviceRespVO {
// private String deviceType; // private String deviceType;
@Schema(description = "信息资料") @Schema(description = "信息资料")
@ExcelProperty("信息资料") // @ExcelProperty("信息资料")
private String info; private String info;
@Schema(description = "抄表周期cron") @Schema(description = "抄表周期cron")
@ExcelProperty("抄表周期cron") // @ExcelProperty("抄表周期cron")
private String checkCron; private String checkCron;
@Schema(description = "最后抄表时间") @Schema(description = "最后抄表时间")
@ExcelProperty("最后抄表时间") // @ExcelProperty("最后抄表时间")
private LocalDateTime lastCheckTime; private LocalDateTime lastCheckTime;
@Schema(description = "最后抄表值") @Schema(description = "最后抄表值")
@ExcelProperty("最后抄表值") // @ExcelProperty("最后抄表值")
private BigDecimal lastCheckValue; private BigDecimal lastCheckValue;
@Schema(description = "单位", example = "赵六") @Schema(description = "单位", example = "赵六")
@ExcelProperty("单位") // @ExcelProperty("单位")
private String unitName; private String unitName;
@Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED)
@ -59,10 +60,15 @@ public class EnergyDeviceRespVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间") @ExcelProperty("创建时间")
@ColumnWidth(20)
private LocalDateTime createTime; private LocalDateTime createTime;
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("更新时间")
private LocalDateTime updateTime;
@Schema(description = "能耗类型ID", example = "1") @Schema(description = "能耗类型ID", example = "1")
@ExcelProperty("能耗类型ID") // @ExcelProperty("能耗类型ID")
private Long deviceTypeId; private Long deviceTypeId;
@Schema(description = "能耗类型名称", example = "水") @Schema(description = "能耗类型名称", example = "水")
@ -70,7 +76,7 @@ public class EnergyDeviceRespVO {
private String deviceTypeName; private String deviceTypeName;
@Schema(description = "所属区域ID", example = "1") @Schema(description = "所属区域ID", example = "1")
@ExcelProperty("所属区域ID") // @ExcelProperty("所属区域ID")
private Long orgId; private Long orgId;
@Schema(description = "所属区域名称", example = "车间1") @Schema(description = "所属区域名称", example = "车间1")
@ -78,6 +84,23 @@ public class EnergyDeviceRespVO {
private String orgName; private String orgName;
@Schema(description = "计算规则", example = "车间1") @Schema(description = "计算规则", example = "车间1")
@ExcelProperty("计算规则") // @ExcelProperty("计算规则")
private String rules; private String rules;
@Schema(description = "计算规则集合")
private List<OperationRulesVO> operationRulesVOList;
@Schema(description = "能耗总用量")
@ExcelProperty("能耗总用量")
private String energyConsumption;
@Schema(description = "子列表点位参数值")
@ExcelProperty("子列表点位参数值")
private Map<String,String> sublistPointList;
@Schema(description = "列表")
Map<Long,List<OperationRulesVO>> operationRulesVOMap;
} }

@ -6,6 +6,7 @@ import lombok.*;
import javax.validation.constraints.*; import javax.validation.constraints.*;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 能源设备新增/修改 Request VO") @Schema(description = "管理后台 - 能源设备新增/修改 Request VO")
@Data @Data
@ -54,4 +55,9 @@ public class EnergyDeviceSaveReqVO {
@Schema(description = "计算规则", example = "车间1") @Schema(description = "计算规则", example = "车间1")
private String rules; private String rules;
@Schema(description = "计算规则集合")
private List<OperationRulesVO> operationRulesVOList;
} }

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 能耗设备运算规则 VO")
@Data
public class OperationRulesVO {
@Schema(description = "设备Id")
private Long deviceId;
@Schema(description = "点位Id")
private Long pointId;
@Schema(description = "运算符号")
private String operator;
@Schema(description = "点位参数值")
private String pointValue;
}

@ -0,0 +1,95 @@
package cn.iocoder.yudao.module.mes.controller.admin.energyrecord;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.mes.controller.admin.energyrecord.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.energyrecord.EnergyRecordDO;
import cn.iocoder.yudao.module.mes.service.energyrecord.EnergyRecordService;
@Tag(name = "管理后台 - 能源设备历史记录")
@RestController
@RequestMapping("/mes/energy-record")
@Validated
public class EnergyRecordController {
@Resource
private EnergyRecordService energyRecordService;
@PostMapping("/create")
@Operation(summary = "创建能源设备历史记录")
@PreAuthorize("@ss.hasPermission('mes:energy-record:create')")
public CommonResult<Long> createEnergyRecord(@Valid @RequestBody EnergyRecordSaveReqVO createReqVO) {
return success(energyRecordService.createEnergyRecord(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新能源设备历史记录")
@PreAuthorize("@ss.hasPermission('mes:energy-record:update')")
public CommonResult<Boolean> updateEnergyRecord(@Valid @RequestBody EnergyRecordSaveReqVO updateReqVO) {
energyRecordService.updateEnergyRecord(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除能源设备历史记录")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('mes:energy-record:delete')")
public CommonResult<Boolean> deleteEnergyRecord(@RequestParam("id") Long id) {
energyRecordService.deleteEnergyRecord(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得能源设备历史记录")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('mes:energy-record:query')")
public CommonResult<EnergyRecordRespVO> getEnergyRecord(@RequestParam("id") Long id) {
EnergyRecordDO energyRecord = energyRecordService.getEnergyRecord(id);
return success(BeanUtils.toBean(energyRecord, EnergyRecordRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得能源设备历史记录分页")
@PreAuthorize("@ss.hasPermission('mes:energy-record:query')")
public CommonResult<PageResult<EnergyRecordRespVO>> getEnergyRecordPage(@Valid EnergyRecordPageReqVO pageReqVO) {
PageResult<EnergyRecordDO> pageResult = energyRecordService.getEnergyRecordPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, EnergyRecordRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出能源设备历史记录 Excel")
@PreAuthorize("@ss.hasPermission('mes:energy-record:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportEnergyRecordExcel(@Valid EnergyRecordPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<EnergyRecordDO> list = energyRecordService.getEnergyRecordPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "能源设备历史记录.xls", "数据", EnergyRecordRespVO.class,
BeanUtils.toBean(list, EnergyRecordRespVO.class));
}
}

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.mes.controller.admin.energyrecord.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 能源设备历史记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class EnergyRecordPageReqVO extends PageParam {
@Schema(description = "能源设备id", example = "25594")
private Long energyDeviceId;
@Schema(description = "能耗历史数据")
private String recordData;
@Schema(description = "是否启用")
private Boolean isEnable;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.mes.controller.admin.energyrecord.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 能源设备历史记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class EnergyRecordRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "14404")
@ExcelProperty("ID")
private Long id;
@Schema(description = "能源设备id", example = "25594")
@ExcelProperty("能源设备id")
private Long energyDeviceId;
@Schema(description = "能耗历史数据")
@ExcelProperty("能耗历史数据")
private String recordData;
@Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("是否启用")
private Boolean isEnable;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.mes.controller.admin.energyrecord.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 能源设备历史记录新增/修改 Request VO")
@Data
public class EnergyRecordSaveReqVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "14404")
private Long id;
@Schema(description = "能源设备id", example = "25594")
private Long energyDeviceId;
@Schema(description = "能耗历史数据")
private String recordData;
@Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "是否启用不能为空")
private Boolean isEnable;
}

@ -27,6 +27,7 @@ public class LineAnalysisTreeDTO {
public static class LineNode { public static class LineNode {
private Long id; // 产线ID private Long id; // 产线ID
private String name; // 产线名称 private String name; // 产线名称
private Long parentId;
private List<EquipmentNode> equipments = new ArrayList<>(); private List<EquipmentNode> equipments = new ArrayList<>();
} }

@ -72,13 +72,13 @@ public class EnergyDeviceDO extends BaseDO {
/** /**
* ID * ID
*/ */
private Long OrgId; private Long orgId;
/** /**
* *
*/ */
private String OrgName; private String orgName;
/** /**
* *
*/ */
private String Rules; private String rules;
} }

@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.mes.dal.dataobject.energyrecord;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* DO
*
* @author
*/
@TableName("mes_energy_record")
@KeySequence("mes_energy_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EnergyRecordDO extends BaseDO {
/**
* ID
*/
@TableId
private Long id;
/**
* id
*/
private Long energyDeviceId;
/**
*
*/
private String recordData;
/**
*
*/
private Boolean isEnable;
}

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.mes.dal.mysql.energyrecord;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.mes.dal.dataobject.energyrecord.EnergyRecordDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.mes.controller.admin.energyrecord.vo.*;
/**
* Mapper
*
* @author
*/
@Mapper
public interface EnergyRecordMapper extends BaseMapperX<EnergyRecordDO> {
default PageResult<EnergyRecordDO> selectPage(EnergyRecordPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<EnergyRecordDO>()
.eqIfPresent(EnergyRecordDO::getEnergyDeviceId, reqVO.getEnergyDeviceId())
.eqIfPresent(EnergyRecordDO::getRecordData, reqVO.getRecordData())
.eqIfPresent(EnergyRecordDO::getIsEnable, reqVO.getIsEnable())
.betweenIfPresent(EnergyRecordDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(EnergyRecordDO::getId));
}
}

@ -1,11 +1,23 @@
package cn.iocoder.yudao.module.mes.service.criticalcomponent; package cn.iocoder.yudao.module.mes.service.criticalcomponent;
import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttributeTypeDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO;
import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.repairtems.RepairTemsDO;
import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.repairtems.RepairTemsMapper;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import cn.iocoder.yudao.module.mes.controller.admin.criticalcomponent.vo.*; import cn.iocoder.yudao.module.mes.controller.admin.criticalcomponent.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.criticalcomponent.CriticalComponentDO; import cn.iocoder.yudao.module.mes.dal.dataobject.criticalcomponent.CriticalComponentDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
@ -15,6 +27,8 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.dal.mysql.criticalcomponent.CriticalComponentMapper; import cn.iocoder.yudao.module.mes.dal.mysql.criticalcomponent.CriticalComponentMapper;
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.module.iot.enums.ErrorCodeConstants.DEVICE_ATTRIBUTE_TYPE_NOT_EXISTS;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_ATTRIBUTE_TYPE_REFERENCES_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
/** /**
@ -29,6 +43,13 @@ public class CriticalComponentServiceImpl implements CriticalComponentService {
@Resource @Resource
private CriticalComponentMapper criticalComponentMapper; private CriticalComponentMapper criticalComponentMapper;
@Resource
private DeviceLedgerMapper deviceLedgerMapper;
@Resource
private RepairTemsMapper repairTemsMapper;
@Override @Override
public Long createCriticalComponent(CriticalComponentSaveReqVO createReqVO) { public Long createCriticalComponent(CriticalComponentSaveReqVO createReqVO) {
// 插入 // 插入
@ -48,14 +69,75 @@ public class CriticalComponentServiceImpl implements CriticalComponentService {
} }
@Override @Override
public void deleteCriticalComponent(List<Long> idList) { public void deleteCriticalComponent(List<Long> ids) {
for (Long id : idList) {
// 校验存在 if (CollectionUtils.isEmpty(ids)) {
validateCriticalComponentExists(id); return;
} }
// 批量校验存在性
List<CriticalComponentDO> existList = criticalComponentMapper.selectBatchIds(ids);
if (existList.size() != ids.size()) {
throw exception(CRITICAL_COMPONENT_NOT_EXISTS);
}
// 检验设备台账引用
validateDeviceLedgerBatchReferences(ids);
//检验项目维护引用
validateDvjectBatchReferences(ids);
// 删除 // 删除
criticalComponentMapper.deleteByIds(idList); criticalComponentMapper.deleteByIds(ids);
}
private void validateDvjectBatchReferences(List<Long> ids) {
boolean isExists = repairTemsMapper.exists(
Wrappers.<RepairTemsDO>lambdaQuery()
.in(RepairTemsDO::getComponentId, ids));
if (isExists){
throw exception(CRITICAL_COMPONENT_REFERENCES);
}
}
private void validateDeviceLedgerBatchReferences(List<Long> ids) {
// 查询所有包含这些ID的记录
List<DeviceLedgerDO> ledgers = deviceLedgerMapper.selectList(
Wrappers.<DeviceLedgerDO>lambdaQuery()
.isNotNull(DeviceLedgerDO::getComponentId)
.select(DeviceLedgerDO::getComponentId)
);
if (CollectionUtils.isEmpty(ledgers)) {
return;
}
// 检查每个componentId字段是否包含目标ID
for (DeviceLedgerDO ledger : ledgers) {
if (StringUtils.isBlank(ledger.getComponentId())) {
continue;
}
// 将逗号分隔的ID转换为Set
Set<Long> componentIds = Arrays.stream(ledger.getComponentId().split(","))
.map(String::trim)
.filter(StringUtils::isNotBlank)
.map(Long::valueOf)
.collect(Collectors.toSet());
// 检查是否有交集
for (Long id : ids) {
if (componentIds.contains(id)) {
throw exception(CRITICAL_COMPONENT_REFERENCES);
}
}
}
} }
private void validateCriticalComponentExists(Long id) { private void validateCriticalComponentExists(Long id) {

@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.mes.service.devicetype;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodel.DeviceModelDO; import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodel.DeviceModelDO;
import cn.iocoder.yudao.module.mes.controller.admin.devicetype.vo.DeviceTypeTreeRespVO; import cn.iocoder.yudao.module.mes.controller.admin.devicetype.vo.DeviceTypeTreeRespVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -41,6 +43,9 @@ public class DeviceTypeServiceImpl implements DeviceTypeService {
@Resource @Resource
private DeviceTypeMapper deviceTypeMapper; private DeviceTypeMapper deviceTypeMapper;
@Resource
private DeviceLedgerMapper deviceLedgerMapper;
@Override @Override
public Long createDeviceType(DeviceTypeSaveReqVO createReqVO) { public Long createDeviceType(DeviceTypeSaveReqVO createReqVO) {
@ -79,7 +84,8 @@ public class DeviceTypeServiceImpl implements DeviceTypeService {
@Override @Override
public void updateDeviceType(DeviceTypeSaveReqVO updateReqVO) { public void updateDeviceType(DeviceTypeSaveReqVO updateReqVO) {
// 1. 校验存在 // 1. 校验存在
validateDeviceTypeExists(updateReqVO.getId()); DeviceTypeDO deviceTypeDO = deviceTypeMapper.selectById(updateReqVO.getId());
validateDeviceTypeExists(deviceTypeDO);
//编码重复判断 //编码重复判断
Long count = deviceTypeMapper.selectCount(new LambdaQueryWrapper<DeviceTypeDO>() Long count = deviceTypeMapper.selectCount(new LambdaQueryWrapper<DeviceTypeDO>()
.eq(DeviceTypeDO::getCode, updateReqVO.getCode()) .eq(DeviceTypeDO::getCode, updateReqVO.getCode())
@ -123,17 +129,29 @@ public class DeviceTypeServiceImpl implements DeviceTypeService {
@Override @Override
public void deleteDeviceType(Long id) { public void deleteDeviceType(Long id) {
// 1. 校验存在 // 1. 校验存在
validateDeviceTypeExists(id); DeviceTypeDO deviceTypeDO = deviceTypeMapper.selectById(id);
validateDeviceTypeExists(deviceTypeDO);
// 2. 校验是否有子节点 // 2. 校验是否有子节点
if (hasChildren(id)) { if (hasChildren(id)) {
throw exception(DEVICE_TYPE_EXITS_CHILDREN); throw exception(DEVICE_TYPE_EXITS_CHILDREN);
} }
// 3. 校验是否有引用
validateReferences(deviceTypeDO);
// 3. 删除 // 4. 删除
deviceTypeMapper.deleteById(id); deviceTypeMapper.deleteById(id);
} }
private void validateReferences(DeviceTypeDO deviceTypeDO) {
boolean isExists = deviceLedgerMapper.exists(Wrappers.<DeviceLedgerDO>lambdaQuery().eq(DeviceLedgerDO::getDeviceType,deviceTypeDO.getId()));
if (isExists){
throw exception(DEVICE_TYPE_REFERENCES);
}
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteDeviceTypeBatch(List<Long> ids) { public void deleteDeviceTypeBatch(List<Long> ids) {
@ -142,8 +160,8 @@ public class DeviceTypeServiceImpl implements DeviceTypeService {
} }
} }
private void validateDeviceTypeExists(Long id) { private void validateDeviceTypeExists(DeviceTypeDO deviceTypeDO) {
if (deviceTypeMapper.selectById(id) == null) { if (deviceTypeDO == null) {
throw exception(DEVICE_TYPE_NOT_EXISTS); throw exception(DEVICE_TYPE_NOT_EXISTS);
} }
} }

@ -7,10 +7,14 @@ import cn.iocoder.yudao.module.mes.controller.admin.dvsubject.vo.DvSubjectPageRe
import cn.iocoder.yudao.module.mes.controller.admin.dvsubject.vo.DvSubjectSaveReqVO; import cn.iocoder.yudao.module.mes.controller.admin.dvsubject.vo.DvSubjectSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.devicetype.DeviceTypeDO; import cn.iocoder.yudao.module.mes.dal.dataobject.devicetype.DeviceTypeDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.dvsubject.DvSubjectDO; import cn.iocoder.yudao.module.mes.dal.dataobject.dvsubject.DvSubjectDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.subjectplan.SubjectPlanDO;
import cn.iocoder.yudao.module.mes.dal.mysql.dvsubject.DvSubjectMapper; import cn.iocoder.yudao.module.mes.dal.mysql.dvsubject.DvSubjectMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.subjectplan.SubjectPlanMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -33,6 +37,9 @@ public class DvSubjectServiceImpl implements DvSubjectService {
@Resource @Resource
private DvSubjectMapper dvSubjectMapper; private DvSubjectMapper dvSubjectMapper;
@Resource
private SubjectPlanMapper subjectPlanMapper;
@Override @Override
public Long createDvSubject(DvSubjectSaveReqVO createReqVO) { public Long createDvSubject(DvSubjectSaveReqVO createReqVO) {
@ -70,17 +77,38 @@ public class DvSubjectServiceImpl implements DvSubjectService {
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public void deleteDvSubject(List<Long> idList) { public void deleteDvSubject(List<Long> idList) {
if (CollectionUtils.isEmpty(idList)) {
return;
}
for (Long id : idList) { // 批量校验存在性
// 校验存在 List<DvSubjectDO> existList = dvSubjectMapper.selectBatchIds(idList);
validateDvSubjectExists(id); if (existList.size() != idList.size()) {
throw exception(DV_SUBJECT_NOT_EXISTS);
} }
// 删除 // 批量校验引用
validateBatchReferences(idList);
// 批量删除
dvSubjectMapper.deleteByIds(idList); dvSubjectMapper.deleteByIds(idList);
} }
private void validateBatchReferences(List<Long> idList) {
boolean exists = subjectPlanMapper.exists(
Wrappers.<SubjectPlanDO>lambdaQuery()
.in(SubjectPlanDO::getSubjectId, idList)
);
if (exists) {
throw exception(DV_SUBJECT_REFERENCES);
}
}
private void validateDvSubjectExists(Long id) { private void validateDvSubjectExists(Long id) {
if (dvSubjectMapper.selectById(id) == null) { if (dvSubjectMapper.selectById(id) == null) {
throw exception(DV_SUBJECT_NOT_EXISTS); throw exception(DV_SUBJECT_NOT_EXISTS);

@ -3,9 +3,11 @@ package cn.iocoder.yudao.module.mes.service.energydevice;
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.module.mes.controller.admin.energydevice.vo.EnergyDevicePageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDevicePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceSaveReqVO; import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceCheckRecordDO; import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceCheckRecordDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceDO; import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceDO;
import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.Collection; import java.util.Collection;
@ -50,7 +52,7 @@ public interface EnergyDeviceService {
* @param id * @param id
* @return * @return
*/ */
EnergyDeviceDO getEnergyDevice(Long id); EnergyDeviceRespVO getEnergyDevice(Long id);
/** /**
* *
@ -106,4 +108,8 @@ public interface EnergyDeviceService {
if (ids.isEmpty()) return new HashMap<>(); if (ids.isEmpty()) return new HashMap<>();
return convertMap(getList(ids), EnergyDeviceDO::getId); return convertMap(getList(ids), EnergyDeviceDO::getId);
} }
List<EnergyDeviceRespVO> queryDataRecords(String startTime,String endTime);
} }

@ -3,13 +3,20 @@ package cn.iocoder.yudao.module.mes.service.energydevice;
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.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO;
import cn.iocoder.yudao.module.iot.service.device.TDengineService;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDevicePageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDevicePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceSaveReqVO; import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceSaveReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.OperationRulesVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceCheckRecordDO; import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceCheckRecordDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceDO; import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceDO;
import cn.iocoder.yudao.module.mes.dal.mysql.energydevice.EnergyDeviceCheckRecordMapper; import cn.iocoder.yudao.module.mes.dal.mysql.energydevice.EnergyDeviceCheckRecordMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.energydevice.EnergyDeviceMapper; import cn.iocoder.yudao.module.mes.dal.mysql.energydevice.EnergyDeviceMapper;
import cn.iocoder.yudao.module.mes.dal.redis.no.MesNoRedisDAO; import cn.iocoder.yudao.module.mes.dal.redis.no.MesNoRedisDAO;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -18,10 +25,11 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collection; import java.util.*;
import java.util.List;
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.module.iot.enums.ErrorCodeConstants.DEVICE_ID_DOES_NOT_EXIST;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.POINT_ID_MODEL_NOT_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
/** /**
@ -39,6 +47,9 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService {
private EnergyDeviceCheckRecordMapper energyDeviceCheckRecordMapper; private EnergyDeviceCheckRecordMapper energyDeviceCheckRecordMapper;
@Resource @Resource
private MesNoRedisDAO noRedisDAO; private MesNoRedisDAO noRedisDAO;
@Resource
private TDengineService tDengineService;
@Override @Override
public Long createEnergyDevice(EnergyDeviceSaveReqVO createReqVO) { public Long createEnergyDevice(EnergyDeviceSaveReqVO createReqVO) {
// 插入 // 插入
@ -48,17 +59,88 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService {
String no = noRedisDAO.generate2(MesNoRedisDAO.ENERGY_NO_PREFIX); String no = noRedisDAO.generate2(MesNoRedisDAO.ENERGY_NO_PREFIX);
energyDevice.setCode(no); energyDevice.setCode(no);
} }
// 校验编码是否唯一
if (StringUtils.isNotEmpty(energyDevice.getCode())) {
List<EnergyDeviceDO> existingDevice = energyDeviceMapper.selectList(
Wrappers.<EnergyDeviceDO>lambdaQuery().eq(EnergyDeviceDO::getCode,createReqVO.getCode()));
if (!existingDevice.isEmpty()) {
throw exception(ENERGY_DEVICE_CODE_DUPLICATE);
}
}
//校验运算规则
verifiyOperationRules(createReqVO.getOperationRulesVOList());
energyDevice.setRules(JSON.toJSONString(createReqVO.getOperationRulesVOList()));
energyDeviceMapper.insert(energyDevice); energyDeviceMapper.insert(energyDevice);
// 返回 // 返回
return energyDevice.getId(); return energyDevice.getId();
} }
/**
*
*
*
* 1.
* 2. IDID
* 3. +-*/
* 4.
* 5.
* 6. null0
* 7.
*/
private void verifiyOperationRules(List<OperationRulesVO> operationRulesVOList) {
if (CollectionUtils.isEmpty(operationRulesVOList)) {
throw exception(CALCULATION_RULE_NOT_EXISTS);
}
// 运算符集合
Set<String> validOperators = new HashSet<>(Arrays.asList("+", "-", "*", "/"));
for (int i = 0; i < operationRulesVOList.size(); i++) {
OperationRulesVO rule = operationRulesVOList.get(i);
// 1. 校验设备ID和点位ID
if (rule.getDeviceId() == null) {
throw exception(DEVICE_ID_DOES_NOT_EXIST);
}
if (rule.getPointId() == null) {
throw exception(POINT_ID_MODEL_NOT_EXISTS);
}
// 2. 获取运算符
String operator = rule.getOperator();
boolean isLastElement = (i == operationRulesVOList.size() - 1);
if (isLastElement) {
// 最后一个元素:运算符必须为空
if (StringUtils.isNotBlank(operator)) {
throw exception(CALCULATION_LAST_RULE_NO_OPERATOR);
}
} else {
// 非最后一个元素:必须有运算符
if (StringUtils.isBlank(operator)) {
throw exception(CALCULATION_OPERATOR_MISSING);
}
// 校验运算符是否合法
if (!validOperators.contains(operator)) {
throw exception(CALCULATION_OPERATOR_INVALID);
}
}
}
}
@Override @Override
public void updateEnergyDevice(EnergyDeviceSaveReqVO updateReqVO) { public void updateEnergyDevice(EnergyDeviceSaveReqVO updateReqVO) {
// 校验存在 // 校验存在
validateEnergyDeviceExists(updateReqVO.getId()); validateEnergyDeviceExists(updateReqVO.getId());
// 校验运算规则
verifiyOperationRules(updateReqVO.getOperationRulesVOList());
// 更新 // 更新
EnergyDeviceDO updateObj = BeanUtils.toBean(updateReqVO, EnergyDeviceDO.class); EnergyDeviceDO updateObj = BeanUtils.toBean(updateReqVO, EnergyDeviceDO.class);
updateObj.setRules(JSON.toJSONString(updateReqVO.getOperationRulesVOList()));
energyDeviceMapper.updateById(updateObj); energyDeviceMapper.updateById(updateObj);
} }
@ -81,8 +163,12 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService {
} }
@Override @Override
public EnergyDeviceDO getEnergyDevice(Long id) { public EnergyDeviceRespVO getEnergyDevice(Long id) {
return energyDeviceMapper.selectById(id); EnergyDeviceDO energyDeviceDO = energyDeviceMapper.selectById(id);
EnergyDeviceRespVO energyDeviceRespVO = BeanUtils.toBean(energyDeviceDO, EnergyDeviceRespVO.class);
List<OperationRulesVO> operationRulesVOList = JSON.parseArray(energyDeviceDO.getRules(), OperationRulesVO.class);
energyDeviceRespVO.setOperationRulesVOList(operationRulesVOList);
return energyDeviceRespVO;
} }
@Override @Override
@ -154,4 +240,52 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService {
public List<EnergyDeviceDO> getList(Collection<Long> ids) { public List<EnergyDeviceDO> getList(Collection<Long> ids) {
return energyDeviceMapper.selectBatchIds(ids); return energyDeviceMapper.selectBatchIds(ids);
} }
@Override
public List<EnergyDeviceRespVO> queryDataRecords(String startTime,String endTime) {
List<EnergyDeviceRespVO> energyDeviceRespVOArrayList = new ArrayList<>();
List<EnergyDeviceDO> energyDeviceDO = energyDeviceMapper.selectList();
if (energyDeviceDO.isEmpty()){
throw exception(ENERGY_LIST_NOT_EXISTS);
}
for (EnergyDeviceDO deviceDO : energyDeviceDO) {
EnergyDeviceRespVO energyDeviceRespVO = new EnergyDeviceRespVO();
if (StringUtils.isBlank(deviceDO.getRules())){
continue;
}
//查询每个点位的Id
List<OperationRulesVO> operationRulesVOList = JSON.parseArray(deviceDO.getRules(), OperationRulesVO.class);
Map<Long,List<OperationRulesVO>> operationRulesVOMap =new HashMap<>();
for (OperationRulesVO operationRulesVO : operationRulesVOList) {
List<OperationRulesVO> operationRulesVOS = new ArrayList<>();
//获取Td列表
List<Map<String, Object>> maps = tDengineService.getstDeviceDataOrderByTimeDesc(operationRulesVO.getDeviceId(), startTime, endTime);
for (Map<String, Object> map : maps) {
String queryData = map.get("queryData").toString();
//获取json数据列表
List<DeviceContactModelDO> deviceContactModelDOS = JSON.parseArray(queryData, DeviceContactModelDO.class);
for (DeviceContactModelDO deviceContactModelDO : deviceContactModelDOS) {
if (operationRulesVO.equals(deviceContactModelDO.getId())){
OperationRulesVO operationRulesVO1 = new OperationRulesVO();
operationRulesVO1.setPointId(deviceContactModelDO.getId());
operationRulesVO1.setPointValue((String) deviceContactModelDO.getAddressValue());
operationRulesVOS.add(operationRulesVO1);
}
}
}
operationRulesVOMap.put(operationRulesVO.getPointId(),operationRulesVOS);
}
energyDeviceRespVO.setOperationRulesVOMap(operationRulesVOMap);
energyDeviceRespVOArrayList.add(energyDeviceRespVO);
}
return energyDeviceRespVOArrayList;
}
} }

@ -0,0 +1,55 @@
package cn.iocoder.yudao.module.mes.service.energyrecord;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.mes.controller.admin.energyrecord.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.energyrecord.EnergyRecordDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
/**
* Service
*
* @author
*/
public interface EnergyRecordService {
/**
*
*
* @param createReqVO
* @return
*/
Long createEnergyRecord(@Valid EnergyRecordSaveReqVO createReqVO);
/**
*
*
* @param updateReqVO
*/
void updateEnergyRecord(@Valid EnergyRecordSaveReqVO updateReqVO);
/**
*
*
* @param id
*/
void deleteEnergyRecord(Long id);
/**
*
*
* @param id
* @return
*/
EnergyRecordDO getEnergyRecord(Long id);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<EnergyRecordDO> getEnergyRecordPage(EnergyRecordPageReqVO pageReqVO);
}

@ -0,0 +1,74 @@
package cn.iocoder.yudao.module.mes.service.energyrecord;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.mes.controller.admin.energyrecord.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.energyrecord.EnergyRecordDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.dal.mysql.energyrecord.EnergyRecordMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
/**
* Service
*
* @author
*/
@Service
@Validated
public class EnergyRecordServiceImpl implements EnergyRecordService {
@Resource
private EnergyRecordMapper energyRecordMapper;
@Override
public Long createEnergyRecord(EnergyRecordSaveReqVO createReqVO) {
// 插入
EnergyRecordDO energyRecord = BeanUtils.toBean(createReqVO, EnergyRecordDO.class);
energyRecordMapper.insert(energyRecord);
// 返回
return energyRecord.getId();
}
@Override
public void updateEnergyRecord(EnergyRecordSaveReqVO updateReqVO) {
// 校验存在
validateEnergyRecordExists(updateReqVO.getId());
// 更新
EnergyRecordDO updateObj = BeanUtils.toBean(updateReqVO, EnergyRecordDO.class);
energyRecordMapper.updateById(updateObj);
}
@Override
public void deleteEnergyRecord(Long id) {
// 校验存在
validateEnergyRecordExists(id);
// 删除
energyRecordMapper.deleteById(id);
}
private void validateEnergyRecordExists(Long id) {
if (energyRecordMapper.selectById(id) == null) {
throw exception(ENERGY_RECORD_NOT_EXISTS);
}
}
@Override
public EnergyRecordDO getEnergyRecord(Long id) {
return energyRecordMapper.selectById(id);
}
@Override
public PageResult<EnergyRecordDO> getEnergyRecordPage(EnergyRecordPageReqVO pageReqVO) {
return energyRecordMapper.selectPage(pageReqVO);
}
}

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.mes.service.energytype; package cn.iocoder.yudao.module.mes.service.energytype;
import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttributeTypeDO; import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttributeTypeDO;
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,6 +33,10 @@ public class EnergyTypeServiceImpl implements EnergyTypeService {
@Override @Override
public Long createEnergyType(EnergyTypeSaveReqVO createReqVO) { public Long createEnergyType(EnergyTypeSaveReqVO createReqVO) {
// 校验编码是否重复
validateCodeUnique(createReqVO);
// 插入 // 插入
EnergyTypeDO energyType = BeanUtils.toBean(createReqVO, EnergyTypeDO.class); EnergyTypeDO energyType = BeanUtils.toBean(createReqVO, EnergyTypeDO.class);
energyTypeMapper.insert(energyType); energyTypeMapper.insert(energyType);
@ -39,6 +44,17 @@ public class EnergyTypeServiceImpl implements EnergyTypeService {
return energyType.getId(); return energyType.getId();
} }
private void validateCodeUnique(EnergyTypeSaveReqVO createReqVO) {
Long count = energyTypeMapper.selectCount(Wrappers.<EnergyTypeDO>lambdaQuery()
.eq(EnergyTypeDO::getCode, createReqVO.getCode())
.ne(createReqVO.getId() != null, EnergyTypeDO::getId, createReqVO.getId() ));
if (count != null && count > 0) {
throw exception(ENERGY_DEVICE_CHECK_CODE_EXISTS);
}
}
@Override @Override
public void updateEnergyType(EnergyTypeSaveReqVO updateReqVO) { public void updateEnergyType(EnergyTypeSaveReqVO updateReqVO) {
// 校验存在 // 校验存在

@ -263,7 +263,7 @@ public class OrganizationServiceImpl implements OrganizationService {
OrganizationListReqVO organizationListReqVO = new OrganizationListReqVO(); OrganizationListReqVO organizationListReqVO = new OrganizationListReqVO();
List<OrganizationDO> organizationDOS = getOrganizationList(organizationListReqVO); List<OrganizationDO> organizationDOS = getOrganizationList(organizationListReqVO);
List<OrganizationRespVO> organizationRespVOS = buildVOList(organizationDOS); List<OrganizationRespVO> organizationRespVOS = buildVOList(organizationDOS);
if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(organizationRespVOS)) { if (organizationRespVOS.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }
@ -306,19 +306,171 @@ public class OrganizationServiceImpl implements OrganizationService {
.filter(param -> param.getDeviceId() != null) .filter(param -> param.getDeviceId() != null)
.collect(Collectors.groupingBy(DeviceContactModelDO::getDeviceId)); .collect(Collectors.groupingBy(DeviceContactModelDO::getDeviceId));
// 获取产线与父节点的映射关系
Map<Long, Long> lineParentIdMap = organizationRespVOS.stream()
.collect(Collectors.toMap(
OrganizationRespVO::getId,
line -> line.getParentId() != null ? line.getParentId() : 0L, // 如果父节点为空使用默认值0
(existing, replacement) -> existing
));
// 构建产线ID到产线对象的映射
Map<Long, OrganizationRespVO> lineMap = organizationRespVOS.stream()
.collect(Collectors.toMap(OrganizationRespVO::getId, Function.identity()));
// 获取所有匹配的产线(包括下级匹配的)
List<OrganizationRespVO> matchedLines = getMatchedLinesWithAncestors(
organizationRespVOS, keyword, allDevices, paramsByDeviceId, lineParentIdMap, lineMap
);
// 7. 构建树结构 // 7. 构建树结构
return buildTreeStructureWithKeyword(organizationRespVOS, devicesByLineId, paramsByDeviceId,keyword); return buildTreeStructureWithKeyword(matchedLines, devicesByLineId, paramsByDeviceId,keyword,lineParentIdMap);
}
private List<OrganizationRespVO> getMatchedLinesWithAncestors(
List<OrganizationRespVO> allLines,
String keyword,
List<DeviceDO> allDevices,
Map<Long, List<DeviceContactModelDO>> paramsByDeviceId,
Map<Long, Long> lineParentIdMap,
Map<Long, OrganizationRespVO> lineMap) {
boolean hasKeyword = StringUtils.isNotBlank(keyword);
String lowerKeyword = hasKeyword ? keyword.toLowerCase() : "";
// 存储最终要包含的产线ID
Set<Long> lineIdsToInclude = new HashSet<>();
// 1. 首先找出直接匹配的产线
for (OrganizationRespVO line : allLines) {
boolean lineMatch = !hasKeyword ||
(line.getName() != null && line.getName().toLowerCase().contains(lowerKeyword));
if (lineMatch) {
// 添加到结果集
lineIdsToInclude.add(line.getId());
// 向上查找所有父级节点
addAllAncestors(line.getId(), lineParentIdMap, lineMap, lineIdsToInclude);
}
}
// 2. 查找设备匹配的产线
if (hasKeyword) {
for (DeviceDO device : allDevices) {
boolean deviceMatch = device.getDeviceName() != null &&
device.getDeviceName().toLowerCase().contains(lowerKeyword);
if (deviceMatch) {
// 找到这个设备所属的产线
for (OrganizationRespVO line : allLines) {
if (line.getMachineId() != null && line.getMachineId().equals(device.getId())) {
lineIdsToInclude.add(line.getId());
addAllAncestors(line.getId(), lineParentIdMap, lineMap, lineIdsToInclude);
}
}
}
}
}
// 3. 查找参数匹配的产线
if (hasKeyword) {
for (Map.Entry<Long, List<DeviceContactModelDO>> entry : paramsByDeviceId.entrySet()) {
Long deviceId = entry.getKey();
List<DeviceContactModelDO> params = entry.getValue();
boolean hasMatchingParam = params.stream()
.anyMatch(param -> param.getAttributeName() != null &&
param.getAttributeName().toLowerCase().contains(lowerKeyword));
if (hasMatchingParam) {
// 找到这个设备所属的产线
for (OrganizationRespVO line : allLines) {
if (line.getMachineId() != null && line.getMachineId().equals(deviceId)) {
lineIdsToInclude.add(line.getId());
addAllAncestors(line.getId(), lineParentIdMap, lineMap, lineIdsToInclude);
}
}
}
}
}
// 如果没有关键词,返回所有产线
if (!hasKeyword) {
return allLines;
}
// 只返回需要包含的产线
return allLines.stream()
.filter(line -> lineIdsToInclude.contains(line.getId()))
.collect(Collectors.toList());
}
private void addAllAncestors(Long lineId,
Map<Long, Long> lineParentIdMap,
Map<Long, OrganizationRespVO> lineMap,
Set<Long> lineIdsToInclude) {
Long currentParentId = lineParentIdMap.get(lineId);
// 递归向上查找所有父级节点
while (currentParentId != null && currentParentId != 0L) {
lineIdsToInclude.add(currentParentId);
// 继续向上查找
currentParentId = lineParentIdMap.get(currentParentId);
}
} }
private List<LineAnalysisTreeDTO.LineNode> buildTreeStructureWithKeyword(List<OrganizationRespVO> lines, private List<LineAnalysisTreeDTO.LineNode> buildTreeStructureWithKeyword(List<OrganizationRespVO> lines,
Map<Long, List<DeviceDO>> devicesByLineId, Map<Long, List<DeviceDO>> devicesByLineId,
Map<Long, List<DeviceContactModelDO>> paramsByDeviceId, Map<Long, List<DeviceContactModelDO>> paramsByDeviceId,
String keyword) { String keyword,
Map<Long, Long> lineParentIdMap) {
// 统一处理关键词 // 统一处理关键词
boolean hasKeyword = StringUtils.isNotBlank(keyword); boolean hasKeyword = StringUtils.isNotBlank(keyword);
String lowerKeyword = hasKeyword ? keyword.toLowerCase() : ""; String lowerKeyword = hasKeyword ? keyword.toLowerCase() : "";
// 如果lines已经过滤过这里不再需要复杂的匹配判断
if (!hasKeyword) {
// 没有关键词时,返回完整的树结构
return lines.stream().map(line -> {
Long parentId = lineParentIdMap.getOrDefault(line.getId(), 0L);
// 获取该产线的设备
List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>());
// 构建设备节点(显示所有设备和参数)
List<LineAnalysisTreeDTO.EquipmentNode> equipmentNodes = lineDevices.stream()
.map(device -> {
List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>());
List<LineAnalysisTreeDTO.ParameterNode> parameterNodes = deviceParams.stream()
.map(this::buildParameterNode)
.collect(Collectors.toList());
return LineAnalysisTreeDTO.EquipmentNode.builder()
.id(device.getId())
.name(device.getDeviceName())
.parameters(parameterNodes)
.build();
})
.collect(Collectors.toList());
return LineAnalysisTreeDTO.LineNode.builder()
.id(line.getId())
.name(line.getName())
.parentId(parentId)
.equipments(equipmentNodes)
.build();
}).collect(Collectors.toList());
}
// 有关键词时lines已经包含了匹配的产线及其父级产线
// 但我们仍然需要根据关键词过滤设备和参数
// 记录匹配情况 // 记录匹配情况
Map<Long, Boolean> lineMatchedMap = new HashMap<>(); Map<Long, Boolean> lineMatchedMap = new HashMap<>();
Map<Long, Boolean> deviceMatchedMap = new HashMap<>(); Map<Long, Boolean> deviceMatchedMap = new HashMap<>();
@ -326,17 +478,16 @@ public class OrganizationServiceImpl implements OrganizationService {
// 第一遍:分析匹配情况 // 第一遍:分析匹配情况
for (OrganizationRespVO line : lines) { for (OrganizationRespVO line : lines) {
// 产线是否匹配 // 产线是否匹配
boolean lineMatch = !hasKeyword || boolean lineMatch = line.getName() != null &&
(line.getName() != null && line.getName().toLowerCase().contains(lowerKeyword)); line.getName().toLowerCase().contains(lowerKeyword);
lineMatchedMap.put(line.getId(), lineMatch); lineMatchedMap.put(line.getId(), lineMatch);
// 检查该产线的设备 // 检查该产线的设备
List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>());
for (DeviceDO device : lineDevices) { for (DeviceDO device : lineDevices) {
// 设备是否匹配 // 设备是否匹配
boolean deviceMatch = !hasKeyword || boolean deviceMatch = device.getDeviceName() != null &&
(device.getDeviceName() != null && device.getDeviceName().toLowerCase().contains(lowerKeyword);
device.getDeviceName().toLowerCase().contains(lowerKeyword));
deviceMatchedMap.put(device.getId(), deviceMatch); deviceMatchedMap.put(device.getId(), deviceMatch);
} }
} }
@ -344,16 +495,7 @@ public class OrganizationServiceImpl implements OrganizationService {
// 第二遍:构建树结构 // 第二遍:构建树结构
return lines.stream().map(line -> { return lines.stream().map(line -> {
boolean lineMatch = lineMatchedMap.getOrDefault(line.getId(), false); boolean lineMatch = lineMatchedMap.getOrDefault(line.getId(), false);
Long parentId = lineParentIdMap.getOrDefault(line.getId(), 0L);
// 关键修改:如果产线匹配,跳过后续的设备过滤逻辑
if (hasKeyword && !lineMatch) {
// 检查产线下是否有匹配的设备或参数
boolean hasMatchingDeviceOrParam = checkIfLineHasMatchingDeviceOrParam(
line, devicesByLineId, paramsByDeviceId, lowerKeyword, deviceMatchedMap);
if (!hasMatchingDeviceOrParam) {
return null;
}
}
// 获取该产线的设备 // 获取该产线的设备
List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>());
@ -362,13 +504,10 @@ public class OrganizationServiceImpl implements OrganizationService {
List<LineAnalysisTreeDTO.EquipmentNode> equipmentNodes = lineDevices.stream() List<LineAnalysisTreeDTO.EquipmentNode> equipmentNodes = lineDevices.stream()
.map(device -> { .map(device -> {
boolean deviceMatch = deviceMatchedMap.getOrDefault(device.getId(), false); boolean deviceMatch = deviceMatchedMap.getOrDefault(device.getId(), false);
List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>());
// 关键修改:如果产线匹配,保留所有设备 // 如果产线匹配,显示该产线下的所有设备
if (lineMatch) { if (lineMatch) {
// 产线匹配时,保留该设备
List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>());
// 产线匹配时,显示所有参数
List<LineAnalysisTreeDTO.ParameterNode> parameterNodes = deviceParams.stream() List<LineAnalysisTreeDTO.ParameterNode> parameterNodes = deviceParams.stream()
.map(this::buildParameterNode) .map(this::buildParameterNode)
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -380,33 +519,30 @@ public class OrganizationServiceImpl implements OrganizationService {
.build(); .build();
} }
// 以下为原有逻辑:产线不匹配时的处理 // 如果设备匹配,显示该设备的所有参数
if (hasKeyword && !deviceMatch) { if (deviceMatch) {
boolean hasMatchingParam = checkIfDeviceHasMatchingParam( List<LineAnalysisTreeDTO.ParameterNode> parameterNodes = deviceParams.stream()
device, paramsByDeviceId, lowerKeyword); .map(this::buildParameterNode)
if (!hasMatchingParam) { .collect(Collectors.toList());
return null;
} return LineAnalysisTreeDTO.EquipmentNode.builder()
.id(device.getId())
.name(device.getDeviceName())
.parameters(parameterNodes)
.build();
} }
List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); // 检查是否有匹配的参数
boolean hasMatchingParam = deviceParams.stream()
.anyMatch(param -> isParameterMatch(param, lowerKeyword));
if (!hasMatchingParam) {
return null;
}
// 构建参数节点 // 只显示匹配的参数
List<LineAnalysisTreeDTO.ParameterNode> parameterNodes = deviceParams.stream() List<LineAnalysisTreeDTO.ParameterNode> parameterNodes = deviceParams.stream()
.filter(param -> { .filter(param -> isParameterMatch(param, lowerKeyword))
if (!hasKeyword) {
return true; // 没有关键词,显示所有
}
// 有关键词时:
// 如果设备匹配,显示所有参数
if (deviceMatch) {
return true;
}
// 否则,只显示匹配的参数
return isParameterMatch(param, lowerKeyword);
})
.map(this::buildParameterNode) .map(this::buildParameterNode)
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -417,83 +553,60 @@ public class OrganizationServiceImpl implements OrganizationService {
.build(); .build();
}) })
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(equipmentNode -> !lineMatch || !equipmentNode.getParameters().isEmpty()) // 修改过滤条件
.collect(Collectors.toList()); .collect(Collectors.toList());
// 构建设备节点
return LineAnalysisTreeDTO.LineNode.builder() return LineAnalysisTreeDTO.LineNode.builder()
.id(line.getId()) .id(line.getId())
.name(line.getName()) .name(line.getName())
.parentId(parentId)
.equipments(equipmentNodes) .equipments(equipmentNodes)
.build(); .build();
}) })
.filter(Objects::nonNull)
.filter(lineNode -> !hasKeyword || lineMatchedMap.getOrDefault(lineNode.getId(), false) || !lineNode.getEquipments().isEmpty())
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
/** // /**
* 线 // * 检查产线下是否有匹配的设备或参数
*/ // */
private boolean checkIfLineHasMatchingDeviceOrParam(OrganizationRespVO line, // private boolean checkIfLineHasMatchingDeviceOrParam(OrganizationRespVO line,
Map<Long, List<DeviceDO>> devicesByLineId, // Map<Long, List<DeviceDO>> devicesByLineId,
Map<Long, List<DeviceContactModelDO>> paramsByDeviceId, // Map<Long, List<DeviceContactModelDO>> paramsByDeviceId,
String lowerKeyword, // String lowerKeyword,
Map<Long, Boolean> deviceMatchedMap) { // Map<Long, Boolean> deviceMatchedMap) {
//
List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); // List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>());
//
for (DeviceDO device : lineDevices) { // for (DeviceDO device : lineDevices) {
// 检查设备是否匹配 // // 检查设备是否匹配
boolean deviceMatch = deviceMatchedMap.getOrDefault(device.getId(), false); // boolean deviceMatch = deviceMatchedMap.getOrDefault(device.getId(), false);
if (deviceMatch) { // if (deviceMatch) {
return true; // return true;
} // }
//
// 检查设备下的参数是否匹配 // // 检查设备下的参数是否匹配
List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); // List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>());
boolean hasMatchingParam = deviceParams.stream() // boolean hasMatchingParam = deviceParams.stream()
.anyMatch(param -> isParameterMatch(param, lowerKeyword)); // .anyMatch(param -> isParameterMatch(param, lowerKeyword));
if (hasMatchingParam) { // if (hasMatchingParam) {
return true; // return true;
} // }
} // }
//
return false; // return false;
} // }
//
/** // /**
* // * 检查设备下是否有匹配的参数
*/ // */
private boolean checkIfDeviceHasMatchingParam(DeviceDO device, // private boolean checkIfDeviceHasMatchingParam(DeviceDO device,
Map<Long, List<DeviceContactModelDO>> paramsByDeviceId, // Map<Long, List<DeviceContactModelDO>> paramsByDeviceId,
String lowerKeyword) { // String lowerKeyword) {
//
List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); // List<DeviceContactModelDO> deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>());
return deviceParams.stream() // return deviceParams.stream()
.anyMatch(param -> isParameterMatch(param, lowerKeyword)); // .anyMatch(param -> isParameterMatch(param, lowerKeyword));
} // }
private List<LineAnalysisTreeDTO.LineNode> buildTreeStructure(List<OrganizationRespVO> lines,
Map<Long, List<DeviceDO>> devicesByLineId,
Map<Long, List<DeviceContactModelDO>> paramsByDeviceId) {
return lines.stream().map(line -> {
LineAnalysisTreeDTO.LineNode lineNode = LineAnalysisTreeDTO.LineNode.builder()
.id(line.getId())
.name(line.getName())
.build();
// 获取该产线的设备
List<DeviceDO> lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>());
// 构建设备节点
List<LineAnalysisTreeDTO.EquipmentNode> equipmentNodes = lineDevices.stream()
.map(device -> buildEquipmentNode(device, paramsByDeviceId))
.collect(Collectors.toList());
lineNode.setEquipments(equipmentNodes);
return lineNode;
}).collect(Collectors.toList());
}
/** /**
* *
@ -503,33 +616,10 @@ public class OrganizationServiceImpl implements OrganizationService {
return true; return true;
} }
return (param.getAttributeName() != null && param.getAttributeName().toLowerCase().contains(lowerKeyword)) || return (param.getAttributeName() != null && param.getAttributeName().toLowerCase().contains(lowerKeyword));
(param.getAttributeCode() != null && param.getAttributeCode().toLowerCase().contains(lowerKeyword));
} }
/**
*
*/
private LineAnalysisTreeDTO.EquipmentNode buildEquipmentNode(DeviceDO device,
Map<Long, List<DeviceContactModelDO>> paramsByDeviceId) {
LineAnalysisTreeDTO.EquipmentNode equipmentNode = LineAnalysisTreeDTO.EquipmentNode.builder()
.id(device.getId())
.name(device.getDeviceName())
.build();
// 获取设备参数
List<DeviceContactModelDO> deviceParams =
paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>());
// 构建参数节点
List<LineAnalysisTreeDTO.ParameterNode> parameterNodes = deviceParams.stream()
.map(this::buildParameterNode)
.collect(Collectors.toList());
equipmentNode.setParameters(parameterNodes);
return equipmentNode;
}
/** /**
* *
@ -549,7 +639,7 @@ public class OrganizationServiceImpl implements OrganizationService {
private List<DeviceContactModelDO> getAllParameters(List<DeviceDO> devices) { private List<DeviceContactModelDO> getAllParameters(List<DeviceDO> devices) {
if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(devices)) { if (devices.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }

@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.mes.service.planmaintenance;
import cn.iocoder.yudao.module.mes.dal.dataobject.dvsubject.DvSubjectDO; import cn.iocoder.yudao.module.mes.dal.dataobject.dvsubject.DvSubjectDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.subjectplan.SubjectPlanDO; import cn.iocoder.yudao.module.mes.dal.dataobject.subjectplan.SubjectPlanDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.taskmanagement.TaskManagementDO;
import cn.iocoder.yudao.module.mes.dal.mysql.dvsubject.DvSubjectMapper; import cn.iocoder.yudao.module.mes.dal.mysql.dvsubject.DvSubjectMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.subjectplan.SubjectPlanMapper; import cn.iocoder.yudao.module.mes.dal.mysql.subjectplan.SubjectPlanMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.taskmanagement.TaskManagementMapper;
import cn.iocoder.yudao.module.mes.service.subjectplan.SubjectPlanService; import cn.iocoder.yudao.module.mes.service.subjectplan.SubjectPlanService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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 org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -44,6 +47,9 @@ public class PlanMaintenanceServiceImpl implements PlanMaintenanceService {
@Resource @Resource
private DvSubjectMapper dvSubjectMapper; private DvSubjectMapper dvSubjectMapper;
@Resource
private TaskManagementMapper taskManagementMapper;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -118,17 +124,36 @@ public class PlanMaintenanceServiceImpl implements PlanMaintenanceService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deletePlanMaintenance( List<Long> idList) { public void deletePlanMaintenance(List<Long> idList) {
for (Long id : idList) { if (CollectionUtils.isEmpty(idList)) {
// 校验存在 return;
validatePlanMaintenanceExists(id); }
// 批量校验存在性
List<PlanMaintenanceDO> existList = planMaintenanceMapper.selectBatchIds(idList);
if (existList.size() != idList.size()) {
throw exception(PLAN_MAINTENANCE_NOT_EXISTS);
} }
// 删除
// 批量校验引用
validateBatchReferences(idList);
// 删除主表
planMaintenanceMapper.deleteByIds(idList); planMaintenanceMapper.deleteByIds(idList);
//删除关联表数据
// 删除关联表数据
deleteSubjectPlan(idList); deleteSubjectPlan(idList);
}
private void validateBatchReferences(List<Long> idList) {
boolean exists = taskManagementMapper.exists(
Wrappers.<TaskManagementDO>lambdaQuery()
.in(TaskManagementDO::getProjectForm, idList)
);
if (exists) {
throw exception(PLAN_MAINTENANCE_REFERENCES);
}
} }
private void deleteSubjectPlan(List<Long> idList) { private void deleteSubjectPlan(List<Long> idList) {

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.mes.dal.mysql.energyrecord.EnergyRecordMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>
Loading…
Cancel
Save