diff --git a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java index 8e0c092126..da286cccc3 100644 --- a/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java +++ b/yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java @@ -44,6 +44,7 @@ public interface ErrorCodeConstants { 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_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 DEVICE_DOES_NOT_EXIST= new ErrorCode(1_003_000_000, "该采集设备不存在"); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java index 3f3fca4045..f7674579f7 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/DeviceController.java @@ -59,18 +59,18 @@ public class DeviceController { tDengineService.initDatabaseAndTable(device.getId()); //添加定时任务 // 创建 JobSaveReqVO 对象实例 - JobSaveReqVO jobSaveReqVO = new JobSaveReqVO(); - // 设置任务属性(根据您的业务需求设置具体值) - jobSaveReqVO.setName("deviceJob_" + device.getId()); // 处理器名称唯一 - jobSaveReqVO.setHandlerName("deviceJob"); // 处理器名称唯一 - jobSaveReqVO.setHandlerParam("{\"deviceId\": \"" + device.getId() + "\"}"); // 使用设备ID作为参数值 - jobSaveReqVO.setCronExpression("*/5 * * * * ?"); // CRON表达式,每5秒执行一次[1,3](@ref) - jobSaveReqVO.setRetryCount(3); // 重试次数 - jobSaveReqVO.setRetryInterval(5000); // 重试间隔(毫秒) - jobSaveReqVO.setMonitorTimeout(30000); // 监控超时时间(毫秒) - jobSaveReqVO.setDeviceId(device.getId()); - - jobService.createJob(jobSaveReqVO); +// JobSaveReqVO jobSaveReqVO = new JobSaveReqVO(); +// // 设置任务属性(根据您的业务需求设置具体值) +// jobSaveReqVO.setName("deviceJob_" + device.getId()); // 处理器名称唯一 +// jobSaveReqVO.setHandlerName("deviceJob"); // 处理器名称唯一 +// jobSaveReqVO.setHandlerParam("{\"deviceId\": \"" + device.getId() + "\"}"); // 使用设备ID作为参数值 +// jobSaveReqVO.setCronExpression("*/5 * * * * ?"); // CRON表达式,每5秒执行一次[1,3](@ref) +// jobSaveReqVO.setRetryCount(3); // 重试次数 +// jobSaveReqVO.setRetryInterval(5000); // 重试间隔(毫秒) +// jobSaveReqVO.setMonitorTimeout(30000); // 监控超时时间(毫秒) +// jobSaveReqVO.setDeviceId(device.getId()); +// +// jobService.createJob(jobSaveReqVO); return success(device); } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java index 7b3cbc7387..c52ccc51c9 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/TDengineService.java @@ -308,20 +308,20 @@ public class TDengineService { * @return 设备数据列表,按时间戳倒序排列 */ @DS("tdengine") - public List> getstDeviceDataOrderByTimeDesc(Long id,String collectionStartTime, String collectionEndTime) { + public List> getstDeviceDataOrderByTimeDesc(Long id,String StartTime, String EndTime) { String tableName = "d_" + id; StringBuilder sqlBuilder = new StringBuilder(); List params = new ArrayList<>(); sqlBuilder.append("SELECT ts, query_data FROM besure.").append(tableName).append(" WHERE 1=1"); - if (collectionStartTime != null) { + if (StartTime != null) { // 直接将时间字符串拼接到SQL中 - sqlBuilder.append(" AND ts >= '").append(collectionStartTime).append("'"); + sqlBuilder.append(" AND ts >= '").append(StartTime).append("'"); } - if (collectionEndTime != null) { - sqlBuilder.append(" AND ts <= '").append(collectionEndTime).append("'"); + if (EndTime != null) { + sqlBuilder.append(" AND ts <= '").append(EndTime).append("'"); } sqlBuilder.append(" ORDER BY ts DESC"); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeServiceImpl.java index 610c00185d..f5c9aae5d6 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/deviceattributetype/DeviceAttributeTypeServiceImpl.java @@ -1,7 +1,13 @@ 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.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.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.validation.constraints.NotEmpty; @@ -33,6 +39,12 @@ public class DeviceAttributeTypeServiceImpl implements DeviceAttributeTypeServic @Resource private DeviceAttributeTypeMapper deviceAttributeTypeMapper; + @Resource + private DeviceModelAttributeMapper deviceModelAttributeMapper; + + @Resource + private DeviceContactModelMapper deviceContactModelMapper; + @Override public Long createDeviceAttributeType(DeviceAttributeTypeSaveReqVO createReqVO) { // 重复判断 @@ -62,8 +74,10 @@ public class DeviceAttributeTypeServiceImpl implements DeviceAttributeTypeServic if (count > 0) { throw exception(DEVICE_CODE_EXISTS); } + + DeviceAttributeTypeDO deviceAttributeTypeDO = deviceAttributeTypeMapper.selectById(updateReqVO.getId()); // 校验存在 - validateDeviceAttributeTypeExists(updateReqVO.getId()); + validateDeviceAttributeTypeExists(deviceAttributeTypeDO); // 更新 DeviceAttributeTypeDO updateObj = BeanUtils.toBean(updateReqVO, DeviceAttributeTypeDO.class); deviceAttributeTypeMapper.updateById(updateObj); @@ -71,17 +85,41 @@ public class DeviceAttributeTypeServiceImpl implements DeviceAttributeTypeServic @Override @Transactional(rollbackFor = Exception.class) - public void deleteDeviceAttributeType( List ids) { - for (Long id : ids) { - // 校验存在 - validateDeviceAttributeTypeExists(id); + public void deleteDeviceAttributeType(List ids) { + if (CollectionUtils.isEmpty(ids)) { + return; + } + + // 批量校验存在性 + List existList = deviceAttributeTypeMapper.selectBatchIds(ids); + if (existList.size() != ids.size()) { + throw exception(DEVICE_ATTRIBUTE_TYPE_NOT_EXISTS); } - // 删除 + + // 批量校验引用 + validateBatchReferences(ids); + + // 批量删除 deviceAttributeTypeMapper.deleteByIds(ids); } - private void validateDeviceAttributeTypeExists(Long id) { - if (deviceAttributeTypeMapper.selectById(id) == null) { + private void validateBatchReferences(List ids) { + // 批量查询引用 + boolean hasModelRef = deviceModelAttributeMapper.exists( + Wrappers.lambdaQuery() + .in(DeviceModelAttributeDO::getAttributeType, ids)); + + boolean hasContactRef = deviceContactModelMapper.exists( + Wrappers.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); } } diff --git a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java index da3ef9d026..2122cb24dd 100644 --- a/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java +++ b/yudao-module-mes/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java @@ -67,6 +67,19 @@ public interface ErrorCodeConstants { ErrorCode ENERGY_TYPE_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_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_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_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_CODE_EXISTS = new ErrorCode(5_0087, "设备维修记录编码已存在"); @@ -90,6 +105,8 @@ public interface ErrorCodeConstants { //======================================设备管理相关 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_IS_SELF = new ErrorCode(1002000002, "不能设置自己为父级"); 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_CODE_NOT_ONLY = new ErrorCode(1002000006, "设备类型编码已存在"); 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_ID_NOT_EXISTS = new ErrorCode(1002000009, "项目Id不存在"); 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_ID_NOT_NULL = new ErrorCode(1002000014, "工单检验结果Id不存在"); 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_CODE_EXISTS = new ErrorCode(1002000016, "维修项目编码已存在"); + + //======================================能源设相关 1002010000================================================= + + ErrorCode ENERGY_RECORD_NOT_EXISTS = new ErrorCode(1002010000, "能源设备历史记录不存在"); } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/EnergyDeviceController.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/EnergyDeviceController.java index 3d7d3c14da..138cdb8109 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/EnergyDeviceController.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/EnergyDeviceController.java @@ -66,8 +66,8 @@ public class EnergyDeviceController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('mes:energy-device:query')") public CommonResult getEnergyDevice(@RequestParam("id") Long id) { - EnergyDeviceDO energyDevice = energyDeviceService.getEnergyDevice(id); - return success(BeanUtils.toBean(energyDevice, EnergyDeviceRespVO.class)); + EnergyDeviceRespVO energyDeviceRespVO = energyDeviceService.getEnergyDevice(id); + return success(energyDeviceRespVO); } @GetMapping("/getList") @Operation(summary = "获得能源设备列表") @@ -97,6 +97,16 @@ public class EnergyDeviceController { BeanUtils.toBean(list, EnergyDeviceRespVO.class)); } + @PostMapping("/queryDataRecords") + @Operation(summary = "查询数据记录") + @PreAuthorize("@ss.hasPermission('mes:energy-device:create')") + public CommonResult> 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") diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/EnergyDeviceRespVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/EnergyDeviceRespVO.java index 2e8123a633..a71495d550 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/EnergyDeviceRespVO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/EnergyDeviceRespVO.java @@ -1,5 +1,6 @@ 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 lombok.*; import java.util.*; @@ -17,7 +18,7 @@ import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; public class EnergyDeviceRespVO { @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "25931") - @ExcelProperty("ID") +// @ExcelProperty("ID") private Long id; @Schema(description = "名称", example = "芋艿") @@ -34,23 +35,23 @@ public class EnergyDeviceRespVO { // private String deviceType; @Schema(description = "信息资料") - @ExcelProperty("信息资料") +// @ExcelProperty("信息资料") private String info; @Schema(description = "抄表周期cron") - @ExcelProperty("抄表周期cron") +// @ExcelProperty("抄表周期cron") private String checkCron; @Schema(description = "最后抄表时间") - @ExcelProperty("最后抄表时间") +// @ExcelProperty("最后抄表时间") private LocalDateTime lastCheckTime; @Schema(description = "最后抄表值") - @ExcelProperty("最后抄表值") +// @ExcelProperty("最后抄表值") private BigDecimal lastCheckValue; @Schema(description = "单位", example = "赵六") - @ExcelProperty("单位") +// @ExcelProperty("单位") private String unitName; @Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED) @@ -59,10 +60,15 @@ public class EnergyDeviceRespVO { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("创建时间") + @ColumnWidth(20) private LocalDateTime createTime; + @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("更新时间") + private LocalDateTime updateTime; + @Schema(description = "能耗类型ID", example = "1") - @ExcelProperty("能耗类型ID") +// @ExcelProperty("能耗类型ID") private Long deviceTypeId; @Schema(description = "能耗类型名称", example = "水") @@ -70,7 +76,7 @@ public class EnergyDeviceRespVO { private String deviceTypeName; @Schema(description = "所属区域ID", example = "1") - @ExcelProperty("所属区域ID") +// @ExcelProperty("所属区域ID") private Long orgId; @Schema(description = "所属区域名称", example = "车间1") @@ -78,6 +84,23 @@ public class EnergyDeviceRespVO { private String orgName; @Schema(description = "计算规则", example = "车间1") - @ExcelProperty("计算规则") +// @ExcelProperty("计算规则") private String rules; + + @Schema(description = "计算规则集合") + private List operationRulesVOList; + + + @Schema(description = "能耗总用量") + @ExcelProperty("能耗总用量") + private String energyConsumption; + + + @Schema(description = "子列表点位参数值") + @ExcelProperty("子列表点位参数值") + private Map sublistPointList; + + @Schema(description = "列表") + Map> operationRulesVOMap; + } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/EnergyDeviceSaveReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/EnergyDeviceSaveReqVO.java index 27ea480095..4878561648 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/EnergyDeviceSaveReqVO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/EnergyDeviceSaveReqVO.java @@ -6,6 +6,7 @@ import lombok.*; import javax.validation.constraints.*; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.List; @Schema(description = "管理后台 - 能源设备新增/修改 Request VO") @Data @@ -54,4 +55,9 @@ public class EnergyDeviceSaveReqVO { @Schema(description = "计算规则", example = "车间1") private String rules; + + @Schema(description = "计算规则集合") + private List operationRulesVOList; + + } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/OperationRulesVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/OperationRulesVO.java new file mode 100644 index 0000000000..c3e6c462e0 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/OperationRulesVO.java @@ -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; + +} diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/EnergyRecordController.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/EnergyRecordController.java new file mode 100644 index 0000000000..591d82db3e --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/EnergyRecordController.java @@ -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 createEnergyRecord(@Valid @RequestBody EnergyRecordSaveReqVO createReqVO) { + return success(energyRecordService.createEnergyRecord(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新能源设备历史记录") + @PreAuthorize("@ss.hasPermission('mes:energy-record:update')") + public CommonResult 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 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 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> getEnergyRecordPage(@Valid EnergyRecordPageReqVO pageReqVO) { + PageResult 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 list = energyRecordService.getEnergyRecordPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "能源设备历史记录.xls", "数据", EnergyRecordRespVO.class, + BeanUtils.toBean(list, EnergyRecordRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/vo/EnergyRecordPageReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/vo/EnergyRecordPageReqVO.java new file mode 100644 index 0000000000..9cbaa41db5 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/vo/EnergyRecordPageReqVO.java @@ -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; + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/vo/EnergyRecordRespVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/vo/EnergyRecordRespVO.java new file mode 100644 index 0000000000..de5225fd51 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/vo/EnergyRecordRespVO.java @@ -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; + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/vo/EnergyRecordSaveReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/vo/EnergyRecordSaveReqVO.java new file mode 100644 index 0000000000..434c251b85 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energyrecord/vo/EnergyRecordSaveReqVO.java @@ -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; + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/vo/LineAnalysisTreeDTO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/vo/LineAnalysisTreeDTO.java index 25b89dda3c..b897c9ed77 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/vo/LineAnalysisTreeDTO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/vo/LineAnalysisTreeDTO.java @@ -27,6 +27,7 @@ public class LineAnalysisTreeDTO { public static class LineNode { private Long id; // 产线ID private String name; // 产线名称 + private Long parentId; private List equipments = new ArrayList<>(); } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/energydevice/EnergyDeviceDO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/energydevice/EnergyDeviceDO.java index 059a168900..eeebe2745e 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/energydevice/EnergyDeviceDO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/energydevice/EnergyDeviceDO.java @@ -72,13 +72,13 @@ public class EnergyDeviceDO extends BaseDO { /** * 所属区域ID */ - private Long OrgId; + private Long orgId; /** * 所属区域名称 */ - private String OrgName; + private String orgName; /** * 计算规则 */ - private String Rules; + private String rules; } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/energyrecord/EnergyRecordDO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/energyrecord/EnergyRecordDO.java new file mode 100644 index 0000000000..01a5c3d538 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/energyrecord/EnergyRecordDO.java @@ -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; + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/energyrecord/EnergyRecordMapper.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/energyrecord/EnergyRecordMapper.java new file mode 100644 index 0000000000..f1bdb9c3da --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/energyrecord/EnergyRecordMapper.java @@ -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 { + + default PageResult selectPage(EnergyRecordPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(EnergyRecordDO::getEnergyDeviceId, reqVO.getEnergyDeviceId()) + .eqIfPresent(EnergyRecordDO::getRecordData, reqVO.getRecordData()) + .eqIfPresent(EnergyRecordDO::getIsEnable, reqVO.getIsEnable()) + .betweenIfPresent(EnergyRecordDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(EnergyRecordDO::getId)); + } + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/criticalcomponent/CriticalComponentServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/criticalcomponent/CriticalComponentServiceImpl.java index 6ba5377764..c74c20ace4 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/criticalcomponent/CriticalComponentServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/criticalcomponent/CriticalComponentServiceImpl.java @@ -1,11 +1,23 @@ 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 javax.annotation.Resource; import org.springframework.validation.annotation.Validated; import org.springframework.transaction.annotation.Transactional; import java.util.*; +import java.util.stream.Collectors; + import cn.iocoder.yudao.module.mes.controller.admin.criticalcomponent.vo.*; import cn.iocoder.yudao.module.mes.dal.dataobject.criticalcomponent.CriticalComponentDO; 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 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.*; /** @@ -29,6 +43,13 @@ public class CriticalComponentServiceImpl implements CriticalComponentService { @Resource private CriticalComponentMapper criticalComponentMapper; + @Resource + private DeviceLedgerMapper deviceLedgerMapper; + + @Resource + private RepairTemsMapper repairTemsMapper; + + @Override public Long createCriticalComponent(CriticalComponentSaveReqVO createReqVO) { // 插入 @@ -48,14 +69,75 @@ public class CriticalComponentServiceImpl implements CriticalComponentService { } @Override - public void deleteCriticalComponent(List idList) { - for (Long id : idList) { - // 校验存在 - validateCriticalComponentExists(id); + public void deleteCriticalComponent(List ids) { + + if (CollectionUtils.isEmpty(ids)) { + return; } + // 批量校验存在性 + List 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 ids) { + + + boolean isExists = repairTemsMapper.exists( + Wrappers.lambdaQuery() + .in(RepairTemsDO::getComponentId, ids)); + + if (isExists){ + throw exception(CRITICAL_COMPONENT_REFERENCES); + } + + + } + + private void validateDeviceLedgerBatchReferences(List ids) { + // 查询所有包含这些ID的记录 + List ledgers = deviceLedgerMapper.selectList( + Wrappers.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 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) { diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/devicetype/DeviceTypeServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/devicetype/DeviceTypeServiceImpl.java index ef4d676301..50512c3439 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/devicetype/DeviceTypeServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/devicetype/DeviceTypeServiceImpl.java @@ -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.module.iot.dal.dataobject.devicemodel.DeviceModelDO; 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.toolkit.Wrappers; import org.springframework.stereotype.Service; @@ -41,6 +43,9 @@ public class DeviceTypeServiceImpl implements DeviceTypeService { @Resource private DeviceTypeMapper deviceTypeMapper; + @Resource + private DeviceLedgerMapper deviceLedgerMapper; + @Override public Long createDeviceType(DeviceTypeSaveReqVO createReqVO) { @@ -79,7 +84,8 @@ public class DeviceTypeServiceImpl implements DeviceTypeService { @Override public void updateDeviceType(DeviceTypeSaveReqVO updateReqVO) { // 1. 校验存在 - validateDeviceTypeExists(updateReqVO.getId()); + DeviceTypeDO deviceTypeDO = deviceTypeMapper.selectById(updateReqVO.getId()); + validateDeviceTypeExists(deviceTypeDO); //编码重复判断 Long count = deviceTypeMapper.selectCount(new LambdaQueryWrapper() .eq(DeviceTypeDO::getCode, updateReqVO.getCode()) @@ -123,17 +129,29 @@ public class DeviceTypeServiceImpl implements DeviceTypeService { @Override public void deleteDeviceType(Long id) { // 1. 校验存在 - validateDeviceTypeExists(id); + DeviceTypeDO deviceTypeDO = deviceTypeMapper.selectById(id); + validateDeviceTypeExists(deviceTypeDO); // 2. 校验是否有子节点 if (hasChildren(id)) { throw exception(DEVICE_TYPE_EXITS_CHILDREN); } + // 3. 校验是否有引用 + validateReferences(deviceTypeDO); - // 3. 删除 + // 4. 删除 deviceTypeMapper.deleteById(id); } + private void validateReferences(DeviceTypeDO deviceTypeDO) { + + boolean isExists = deviceLedgerMapper.exists(Wrappers.lambdaQuery().eq(DeviceLedgerDO::getDeviceType,deviceTypeDO.getId())); + if (isExists){ + throw exception(DEVICE_TYPE_REFERENCES); + + } + } + @Override @Transactional(rollbackFor = Exception.class) public void deleteDeviceTypeBatch(List ids) { @@ -142,8 +160,8 @@ public class DeviceTypeServiceImpl implements DeviceTypeService { } } - private void validateDeviceTypeExists(Long id) { - if (deviceTypeMapper.selectById(id) == null) { + private void validateDeviceTypeExists(DeviceTypeDO deviceTypeDO) { + if (deviceTypeDO == null) { throw exception(DEVICE_TYPE_NOT_EXISTS); } } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/dvsubject/DvSubjectServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/dvsubject/DvSubjectServiceImpl.java index 7746371a9d..7a86d2d7e6 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/dvsubject/DvSubjectServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/dvsubject/DvSubjectServiceImpl.java @@ -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.dal.dataobject.devicetype.DeviceTypeDO; 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.subjectplan.SubjectPlanMapper; 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.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; @@ -33,6 +37,9 @@ public class DvSubjectServiceImpl implements DvSubjectService { @Resource private DvSubjectMapper dvSubjectMapper; + @Resource + private SubjectPlanMapper subjectPlanMapper; + @Override public Long createDvSubject(DvSubjectSaveReqVO createReqVO) { @@ -70,17 +77,38 @@ public class DvSubjectServiceImpl implements DvSubjectService { } @Override + @Transactional(rollbackFor = Exception.class) public void deleteDvSubject(List idList) { + if (CollectionUtils.isEmpty(idList)) { + return; + } - for (Long id : idList) { - // 校验存在 - validateDvSubjectExists(id); + // 批量校验存在性 + List existList = dvSubjectMapper.selectBatchIds(idList); + if (existList.size() != idList.size()) { + throw exception(DV_SUBJECT_NOT_EXISTS); } - // 删除 + // 批量校验引用 + validateBatchReferences(idList); + + // 批量删除 dvSubjectMapper.deleteByIds(idList); } + private void validateBatchReferences(List idList) { + boolean exists = subjectPlanMapper.exists( + Wrappers.lambdaQuery() + .in(SubjectPlanDO::getSubjectId, idList) + ); + + if (exists) { + throw exception(DV_SUBJECT_REFERENCES); + } + } + + + private void validateDvSubjectExists(Long id) { if (dvSubjectMapper.selectById(id) == null) { throw exception(DV_SUBJECT_NOT_EXISTS); diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energydevice/EnergyDeviceService.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energydevice/EnergyDeviceService.java index 5e7302c2d3..ecb6dc0ae8 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energydevice/EnergyDeviceService.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energydevice/EnergyDeviceService.java @@ -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.PageResult; 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.dal.dataobject.energydevice.EnergyDeviceCheckRecordDO; import cn.iocoder.yudao.module.mes.dal.dataobject.energydevice.EnergyDeviceDO; +import org.springframework.web.bind.annotation.RequestParam; import javax.validation.Valid; import java.util.Collection; @@ -50,7 +52,7 @@ public interface EnergyDeviceService { * @param id 编号 * @return 能源设备 */ - EnergyDeviceDO getEnergyDevice(Long id); + EnergyDeviceRespVO getEnergyDevice(Long id); /** * 获得能源设备分页 @@ -106,4 +108,8 @@ public interface EnergyDeviceService { if (ids.isEmpty()) return new HashMap<>(); return convertMap(getList(ids), EnergyDeviceDO::getId); } + + List queryDataRecords(String startTime,String endTime); + + } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energydevice/EnergyDeviceServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energydevice/EnergyDeviceServiceImpl.java index 9a3caeb235..89a0e597ef 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energydevice/EnergyDeviceServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energydevice/EnergyDeviceServiceImpl.java @@ -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.PageResult; 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.EnergyDeviceRespVO; 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.EnergyDeviceDO; 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.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.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,10 +25,11 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; +import java.util.*; 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.*; /** @@ -39,6 +47,9 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService { private EnergyDeviceCheckRecordMapper energyDeviceCheckRecordMapper; @Resource private MesNoRedisDAO noRedisDAO; + @Resource + private TDengineService tDengineService; + @Override public Long createEnergyDevice(EnergyDeviceSaveReqVO createReqVO) { // 插入 @@ -48,17 +59,88 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService { String no = noRedisDAO.generate2(MesNoRedisDAO.ENERGY_NO_PREFIX); energyDevice.setCode(no); } + // 校验编码是否唯一 + if (StringUtils.isNotEmpty(energyDevice.getCode())) { + List existingDevice = energyDeviceMapper.selectList( + Wrappers.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); // 返回 return energyDevice.getId(); } + /** + * 校验运算规则列表 + * + * 规则: + * 1. 列表不能为空 + * 2. 每个元素的设备ID和点位ID不能为空 + * 3. 运算符只能是 +、-、*、/ 四种 + * 4. 最后一个元素的运算符必须为空 + * 5. 除最后一个元素外,其他元素必须都有运算符 + * 6. 系数不能为null,除法时除数不能为0(在计算时校验) + * 7. 不能连续出现两个运算符 + */ + private void verifiyOperationRules(List operationRulesVOList) { + if (CollectionUtils.isEmpty(operationRulesVOList)) { + throw exception(CALCULATION_RULE_NOT_EXISTS); + } + + // 运算符集合 + Set 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 public void updateEnergyDevice(EnergyDeviceSaveReqVO updateReqVO) { // 校验存在 validateEnergyDeviceExists(updateReqVO.getId()); + // 校验运算规则 + verifiyOperationRules(updateReqVO.getOperationRulesVOList()); + // 更新 EnergyDeviceDO updateObj = BeanUtils.toBean(updateReqVO, EnergyDeviceDO.class); + updateObj.setRules(JSON.toJSONString(updateReqVO.getOperationRulesVOList())); + energyDeviceMapper.updateById(updateObj); } @@ -81,8 +163,12 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService { } @Override - public EnergyDeviceDO getEnergyDevice(Long id) { - return energyDeviceMapper.selectById(id); + public EnergyDeviceRespVO getEnergyDevice(Long id) { + EnergyDeviceDO energyDeviceDO = energyDeviceMapper.selectById(id); + EnergyDeviceRespVO energyDeviceRespVO = BeanUtils.toBean(energyDeviceDO, EnergyDeviceRespVO.class); + List operationRulesVOList = JSON.parseArray(energyDeviceDO.getRules(), OperationRulesVO.class); + energyDeviceRespVO.setOperationRulesVOList(operationRulesVOList); + return energyDeviceRespVO; } @Override @@ -154,4 +240,52 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService { public List getList(Collection ids) { return energyDeviceMapper.selectBatchIds(ids); } + + @Override + public List queryDataRecords(String startTime,String endTime) { + List energyDeviceRespVOArrayList = new ArrayList<>(); + List 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 operationRulesVOList = JSON.parseArray(deviceDO.getRules(), OperationRulesVO.class); + Map> operationRulesVOMap =new HashMap<>(); + + for (OperationRulesVO operationRulesVO : operationRulesVOList) { + List operationRulesVOS = new ArrayList<>(); + //获取Td列表 + List> maps = tDengineService.getstDeviceDataOrderByTimeDesc(operationRulesVO.getDeviceId(), startTime, endTime); + for (Map map : maps) { + String queryData = map.get("queryData").toString(); + + //获取json数据列表 + List 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; + } } \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energyrecord/EnergyRecordService.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energyrecord/EnergyRecordService.java new file mode 100644 index 0000000000..54122c5e33 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energyrecord/EnergyRecordService.java @@ -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 getEnergyRecordPage(EnergyRecordPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energyrecord/EnergyRecordServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energyrecord/EnergyRecordServiceImpl.java new file mode 100644 index 0000000000..7cd258ab28 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energyrecord/EnergyRecordServiceImpl.java @@ -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 getEnergyRecordPage(EnergyRecordPageReqVO pageReqVO) { + return energyRecordMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energytype/EnergyTypeServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energytype/EnergyTypeServiceImpl.java index bafa05af29..d9a9dd0756 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energytype/EnergyTypeServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energytype/EnergyTypeServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.mes.service.energytype; import cn.iocoder.yudao.module.iot.dal.dataobject.deviceattributetype.DeviceAttributeTypeDO; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import org.springframework.stereotype.Service; import javax.annotation.Resource; import org.springframework.validation.annotation.Validated; @@ -32,6 +33,10 @@ public class EnergyTypeServiceImpl implements EnergyTypeService { @Override public Long createEnergyType(EnergyTypeSaveReqVO createReqVO) { + + // 校验编码是否重复 + validateCodeUnique(createReqVO); + // 插入 EnergyTypeDO energyType = BeanUtils.toBean(createReqVO, EnergyTypeDO.class); energyTypeMapper.insert(energyType); @@ -39,6 +44,17 @@ public class EnergyTypeServiceImpl implements EnergyTypeService { return energyType.getId(); } + private void validateCodeUnique(EnergyTypeSaveReqVO createReqVO) { + + Long count = energyTypeMapper.selectCount(Wrappers.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 public void updateEnergyType(EnergyTypeSaveReqVO updateReqVO) { // 校验存在 diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/organization/OrganizationServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/organization/OrganizationServiceImpl.java index 275fb05b43..35fcb0124a 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/organization/OrganizationServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/organization/OrganizationServiceImpl.java @@ -263,7 +263,7 @@ public class OrganizationServiceImpl implements OrganizationService { OrganizationListReqVO organizationListReqVO = new OrganizationListReqVO(); List organizationDOS = getOrganizationList(organizationListReqVO); List organizationRespVOS = buildVOList(organizationDOS); - if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(organizationRespVOS)) { + if (organizationRespVOS.isEmpty()) { return Collections.emptyList(); } @@ -306,19 +306,171 @@ public class OrganizationServiceImpl implements OrganizationService { .filter(param -> param.getDeviceId() != null) .collect(Collectors.groupingBy(DeviceContactModelDO::getDeviceId)); + + + // 获取产线与父节点的映射关系 + Map lineParentIdMap = organizationRespVOS.stream() + .collect(Collectors.toMap( + OrganizationRespVO::getId, + line -> line.getParentId() != null ? line.getParentId() : 0L, // 如果父节点为空,使用默认值0 + (existing, replacement) -> existing + )); + // 构建产线ID到产线对象的映射 + Map lineMap = organizationRespVOS.stream() + .collect(Collectors.toMap(OrganizationRespVO::getId, Function.identity())); + + // 获取所有匹配的产线(包括下级匹配的) + List matchedLines = getMatchedLinesWithAncestors( + organizationRespVOS, keyword, allDevices, paramsByDeviceId, lineParentIdMap, lineMap + ); + + // 7. 构建树结构 - return buildTreeStructureWithKeyword(organizationRespVOS, devicesByLineId, paramsByDeviceId,keyword); + return buildTreeStructureWithKeyword(matchedLines, devicesByLineId, paramsByDeviceId,keyword,lineParentIdMap); + + } + + private List getMatchedLinesWithAncestors( + List allLines, + String keyword, + List allDevices, + Map> paramsByDeviceId, + Map lineParentIdMap, + Map lineMap) { + + boolean hasKeyword = StringUtils.isNotBlank(keyword); + String lowerKeyword = hasKeyword ? keyword.toLowerCase() : ""; + + // 存储最终要包含的产线ID + Set 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> entry : paramsByDeviceId.entrySet()) { + Long deviceId = entry.getKey(); + List 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 lineParentIdMap, + Map lineMap, + Set lineIdsToInclude) { + Long currentParentId = lineParentIdMap.get(lineId); + + // 递归向上查找所有父级节点 + while (currentParentId != null && currentParentId != 0L) { + lineIdsToInclude.add(currentParentId); + + // 继续向上查找 + currentParentId = lineParentIdMap.get(currentParentId); + } } + private List buildTreeStructureWithKeyword(List lines, Map> devicesByLineId, Map> paramsByDeviceId, - String keyword) { + String keyword, + Map lineParentIdMap) { // 统一处理关键词 boolean hasKeyword = StringUtils.isNotBlank(keyword); String lowerKeyword = hasKeyword ? keyword.toLowerCase() : ""; + // 如果lines已经过滤过,这里不再需要复杂的匹配判断 + if (!hasKeyword) { + // 没有关键词时,返回完整的树结构 + return lines.stream().map(line -> { + Long parentId = lineParentIdMap.getOrDefault(line.getId(), 0L); + + // 获取该产线的设备 + List lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); + + // 构建设备节点(显示所有设备和参数) + List equipmentNodes = lineDevices.stream() + .map(device -> { + List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); + + List 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 lineMatchedMap = new HashMap<>(); Map deviceMatchedMap = new HashMap<>(); @@ -326,17 +478,16 @@ public class OrganizationServiceImpl implements OrganizationService { // 第一遍:分析匹配情况 for (OrganizationRespVO line : lines) { // 产线是否匹配 - boolean lineMatch = !hasKeyword || - (line.getName() != null && line.getName().toLowerCase().contains(lowerKeyword)); + boolean lineMatch = line.getName() != null && + line.getName().toLowerCase().contains(lowerKeyword); lineMatchedMap.put(line.getId(), lineMatch); // 检查该产线的设备 List lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); for (DeviceDO device : lineDevices) { // 设备是否匹配 - boolean deviceMatch = !hasKeyword || - (device.getDeviceName() != null && - device.getDeviceName().toLowerCase().contains(lowerKeyword)); + boolean deviceMatch = device.getDeviceName() != null && + device.getDeviceName().toLowerCase().contains(lowerKeyword); deviceMatchedMap.put(device.getId(), deviceMatch); } } @@ -344,16 +495,7 @@ public class OrganizationServiceImpl implements OrganizationService { // 第二遍:构建树结构 return lines.stream().map(line -> { boolean lineMatch = lineMatchedMap.getOrDefault(line.getId(), false); - - // 关键修改:如果产线匹配,跳过后续的设备过滤逻辑 - if (hasKeyword && !lineMatch) { - // 检查产线下是否有匹配的设备或参数 - boolean hasMatchingDeviceOrParam = checkIfLineHasMatchingDeviceOrParam( - line, devicesByLineId, paramsByDeviceId, lowerKeyword, deviceMatchedMap); - if (!hasMatchingDeviceOrParam) { - return null; - } - } + Long parentId = lineParentIdMap.getOrDefault(line.getId(), 0L); // 获取该产线的设备 List lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); @@ -362,13 +504,10 @@ public class OrganizationServiceImpl implements OrganizationService { List equipmentNodes = lineDevices.stream() .map(device -> { boolean deviceMatch = deviceMatchedMap.getOrDefault(device.getId(), false); + List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); - // 关键修改:如果产线匹配,保留所有设备 + // 如果产线匹配,显示该产线下的所有设备 if (lineMatch) { - // 产线匹配时,保留该设备 - List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); - - // 产线匹配时,显示所有参数 List parameterNodes = deviceParams.stream() .map(this::buildParameterNode) .collect(Collectors.toList()); @@ -380,33 +519,30 @@ public class OrganizationServiceImpl implements OrganizationService { .build(); } - // 以下为原有逻辑:产线不匹配时的处理 - if (hasKeyword && !deviceMatch) { - boolean hasMatchingParam = checkIfDeviceHasMatchingParam( - device, paramsByDeviceId, lowerKeyword); - if (!hasMatchingParam) { - return null; - } + // 如果设备匹配,显示该设备的所有参数 + if (deviceMatch) { + List parameterNodes = deviceParams.stream() + .map(this::buildParameterNode) + .collect(Collectors.toList()); + + return LineAnalysisTreeDTO.EquipmentNode.builder() + .id(device.getId()) + .name(device.getDeviceName()) + .parameters(parameterNodes) + .build(); } - List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); + // 检查是否有匹配的参数 + boolean hasMatchingParam = deviceParams.stream() + .anyMatch(param -> isParameterMatch(param, lowerKeyword)); + + if (!hasMatchingParam) { + return null; + } - // 构建参数节点 + // 只显示匹配的参数 List parameterNodes = deviceParams.stream() - .filter(param -> { - if (!hasKeyword) { - return true; // 没有关键词,显示所有 - } - - // 有关键词时: - // 如果设备匹配,显示所有参数 - if (deviceMatch) { - return true; - } - - // 否则,只显示匹配的参数 - return isParameterMatch(param, lowerKeyword); - }) + .filter(param -> isParameterMatch(param, lowerKeyword)) .map(this::buildParameterNode) .collect(Collectors.toList()); @@ -417,83 +553,60 @@ public class OrganizationServiceImpl implements OrganizationService { .build(); }) .filter(Objects::nonNull) - .filter(equipmentNode -> !lineMatch || !equipmentNode.getParameters().isEmpty()) // 修改过滤条件 .collect(Collectors.toList()); - // 构建设备节点 return LineAnalysisTreeDTO.LineNode.builder() .id(line.getId()) .name(line.getName()) + .parentId(parentId) .equipments(equipmentNodes) .build(); }) - .filter(Objects::nonNull) - .filter(lineNode -> !hasKeyword || lineMatchedMap.getOrDefault(lineNode.getId(), false) || !lineNode.getEquipments().isEmpty()) .collect(Collectors.toList()); } - /** - * 检查产线下是否有匹配的设备或参数 - */ - private boolean checkIfLineHasMatchingDeviceOrParam(OrganizationRespVO line, - Map> devicesByLineId, - Map> paramsByDeviceId, - String lowerKeyword, - Map deviceMatchedMap) { - - List lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); - - for (DeviceDO device : lineDevices) { - // 检查设备是否匹配 - boolean deviceMatch = deviceMatchedMap.getOrDefault(device.getId(), false); - if (deviceMatch) { - return true; - } - - // 检查设备下的参数是否匹配 - List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); - boolean hasMatchingParam = deviceParams.stream() - .anyMatch(param -> isParameterMatch(param, lowerKeyword)); - if (hasMatchingParam) { - return true; - } - } - - return false; - } - - /** - * 检查设备下是否有匹配的参数 - */ - private boolean checkIfDeviceHasMatchingParam(DeviceDO device, - Map> paramsByDeviceId, - String lowerKeyword) { - - List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); - return deviceParams.stream() - .anyMatch(param -> isParameterMatch(param, lowerKeyword)); - } - private List buildTreeStructure(List lines, - Map> devicesByLineId, - Map> paramsByDeviceId) { - return lines.stream().map(line -> { - LineAnalysisTreeDTO.LineNode lineNode = LineAnalysisTreeDTO.LineNode.builder() - .id(line.getId()) - .name(line.getName()) - .build(); - - // 获取该产线的设备 - List lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); - - // 构建设备节点 - List equipmentNodes = lineDevices.stream() - .map(device -> buildEquipmentNode(device, paramsByDeviceId)) - .collect(Collectors.toList()); +// /** +// * 检查产线下是否有匹配的设备或参数 +// */ +// private boolean checkIfLineHasMatchingDeviceOrParam(OrganizationRespVO line, +// Map> devicesByLineId, +// Map> paramsByDeviceId, +// String lowerKeyword, +// Map deviceMatchedMap) { +// +// List lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); +// +// for (DeviceDO device : lineDevices) { +// // 检查设备是否匹配 +// boolean deviceMatch = deviceMatchedMap.getOrDefault(device.getId(), false); +// if (deviceMatch) { +// return true; +// } +// +// // 检查设备下的参数是否匹配 +// List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); +// boolean hasMatchingParam = deviceParams.stream() +// .anyMatch(param -> isParameterMatch(param, lowerKeyword)); +// if (hasMatchingParam) { +// return true; +// } +// } +// +// return false; +// } +// +// /** +// * 检查设备下是否有匹配的参数 +// */ +// private boolean checkIfDeviceHasMatchingParam(DeviceDO device, +// Map> paramsByDeviceId, +// String lowerKeyword) { +// +// List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); +// return deviceParams.stream() +// .anyMatch(param -> isParameterMatch(param, lowerKeyword)); +// } - lineNode.setEquipments(equipmentNodes); - return lineNode; - }).collect(Collectors.toList()); - } /** * 判断参数是否匹配关键词 @@ -503,33 +616,10 @@ public class OrganizationServiceImpl implements OrganizationService { return true; } - return (param.getAttributeName() != null && param.getAttributeName().toLowerCase().contains(lowerKeyword)) || - (param.getAttributeCode() != null && param.getAttributeCode().toLowerCase().contains(lowerKeyword)); + return (param.getAttributeName() != null && param.getAttributeName().toLowerCase().contains(lowerKeyword)); } - /** - * 构建设备节点 - */ - private LineAnalysisTreeDTO.EquipmentNode buildEquipmentNode(DeviceDO device, - Map> paramsByDeviceId) { - LineAnalysisTreeDTO.EquipmentNode equipmentNode = LineAnalysisTreeDTO.EquipmentNode.builder() - .id(device.getId()) - .name(device.getDeviceName()) - .build(); - - // 获取设备参数 - List deviceParams = - paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); - - // 构建参数节点 - List 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 getAllParameters(List devices) { - if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(devices)) { + if (devices.isEmpty()) { return Collections.emptyList(); } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/planmaintenance/PlanMaintenanceServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/planmaintenance/PlanMaintenanceServiceImpl.java index da715510c4..a07f7821be 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/planmaintenance/PlanMaintenanceServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/planmaintenance/PlanMaintenanceServiceImpl.java @@ -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.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.subjectplan.SubjectPlanMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.taskmanagement.TaskManagementMapper; import cn.iocoder.yudao.module.mes.service.subjectplan.SubjectPlanService; 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.Wrappers; import org.springframework.stereotype.Service; @@ -44,6 +47,9 @@ public class PlanMaintenanceServiceImpl implements PlanMaintenanceService { @Resource private DvSubjectMapper dvSubjectMapper; + @Resource + private TaskManagementMapper taskManagementMapper; + @Override @Transactional(rollbackFor = Exception.class) @@ -118,17 +124,36 @@ public class PlanMaintenanceServiceImpl implements PlanMaintenanceService { @Override @Transactional(rollbackFor = Exception.class) - public void deletePlanMaintenance( List idList) { - for (Long id : idList) { - // 校验存在 - validatePlanMaintenanceExists(id); + public void deletePlanMaintenance(List idList) { + if (CollectionUtils.isEmpty(idList)) { + return; + } + // 批量校验存在性 + List existList = planMaintenanceMapper.selectBatchIds(idList); + if (existList.size() != idList.size()) { + throw exception(PLAN_MAINTENANCE_NOT_EXISTS); } - // 删除 + + // 批量校验引用 + validateBatchReferences(idList); + + // 删除主表 planMaintenanceMapper.deleteByIds(idList); - //删除关联表数据 + + // 删除关联表数据 deleteSubjectPlan(idList); + } + private void validateBatchReferences(List idList) { + boolean exists = taskManagementMapper.exists( + Wrappers.lambdaQuery() + .in(TaskManagementDO::getProjectForm, idList) + ); + + if (exists) { + throw exception(PLAN_MAINTENANCE_REFERENCES); + } } private void deleteSubjectPlan(List idList) { diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/resources/mapper/energyrecord/EnergyRecordMapper.xml b/yudao-module-mes/yudao-module-mes-biz/src/main/resources/mapper/energyrecord/EnergyRecordMapper.xml new file mode 100644 index 0000000000..4e45a91530 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/resources/mapper/energyrecord/EnergyRecordMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file