diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/mold/MoldBrandController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/mold/MoldBrandController.java index 93d01f123..690796c57 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/mold/MoldBrandController.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/mold/MoldBrandController.java @@ -114,7 +114,7 @@ public class MoldBrandController { @Operation(summary = "获得模具分页") @Parameter(name = "brandId", description = "型号id") @PreAuthorize("@ss.hasPermission('erp:mold-brand:query')") - public CommonResult> getMoldPage(PageParam pageReqVO, @RequestParam("brandId") Long brandId) { + public CommonResult> getMoldPage(PageParam pageReqVO, @RequestParam(value = "brandId", required = false) Long brandId) { return success(moldBrandService.getMoldPage(pageReqVO, brandId)); } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/mold/vo/MoldBrandRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/mold/vo/MoldBrandRespVO.java index d5125adff..ca0e6de7e 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/mold/vo/MoldBrandRespVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/mold/vo/MoldBrandRespVO.java @@ -71,8 +71,8 @@ public class MoldBrandRespVO { private LocalDateTime createTime; @Schema(description = "工序", example = "你说的对") + @ExcelProperty(value = "工序", converter = DictConvert.class) @DictFormat("mes_org_type") - @ExcelProperty(value = "工序") private String orgType; // , converter = OrgTypeConverter.class } \ No newline at end of file diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/mold/MoldMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/mold/MoldMapper.java index f20c5284e..c42aed010 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/mold/MoldMapper.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/mold/MoldMapper.java @@ -21,7 +21,7 @@ public interface MoldMapper extends BaseMapperX { default PageResult selectPage(PageParam reqVO, Long brandId) { return selectPage(reqVO, new LambdaQueryWrapperX() - .eq(MoldDO::getBrandId, brandId) + .eqIfPresent(MoldDO::getBrandId, brandId) .orderByDesc(MoldDO::getId)); } @@ -33,7 +33,7 @@ public interface MoldMapper extends BaseMapperX { return selectList(new LambdaQueryWrapperX() .eqIfPresent(MoldDO::getCode, reqVO.getCode()) .likeIfPresent(MoldDO::getName, reqVO.getName()) - .eq(MoldDO::getBrandId, reqVO.getBrandId()) + .eqIfPresent(MoldDO::getBrandId, reqVO.getBrandId()) .orderByDesc(MoldDO::getId)); } 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 f7674579f..90ca470c1 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 @@ -230,8 +230,11 @@ public class DeviceController { return success(deviceService.getDeviceAttribute(id)); } - - + @GetMapping("/devicePointList") + @PreAuthorize("@ss.hasPermission('iot:device:query')") + public CommonResult> devicePointList() { + return success( deviceService.devicePointList()); + } } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DevicePointRespVO.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DevicePointRespVO.java new file mode 100644 index 000000000..5d7359a35 --- /dev/null +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/DevicePointRespVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.iot.controller.admin.device.vo; + + +import cn.iocoder.yudao.module.iot.dal.devicecontactmodel.DeviceContactModelDO; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.List; + +@Schema(description = "管理后台 - 设备参数集合列表 Resp VO") +@Data +@ToString(callSuper = true) +public class DevicePointRespVO { + + @Schema(description = "设备Id") + private Long deviceId; + + @Schema(description = "设备名称") + private String deviceName; + + @Schema(description = "子集参数列表") + private List contactModelDOList; + + +} diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java index b04f2d853..a882bc6e1 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceService.java @@ -125,4 +125,5 @@ public interface DeviceService { Map> createDeviceDataMap(Long deviceId); + List devicePointList(); } \ No newline at end of file diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java index d00a25d90..c91206f06 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/DeviceServiceImpl.java @@ -27,10 +27,12 @@ import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceAttributeMapper; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.core.JdbcTemplate; @@ -55,6 +57,7 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; */ @Service @Validated +@Slf4j public class DeviceServiceImpl implements DeviceService { @Resource @@ -307,19 +310,45 @@ public class DeviceServiceImpl implements DeviceService { resultMap.put(recordId, recordInfoMap); } else { // 如果记录没有ID,可以记录日志或使用其他策略(如生成临时ID),这里简单跳过 - System.err.println("警告:发现一条数据记录缺少ID,已跳过。"); + log.error("发现一条数据记录缺少ID,已跳过"); } } } } catch (Exception e) { // 异常处理 - System.err.println("处理设备" + deviceId + "的数据时发生异常: " + e.getMessage()); - // 可以选择在异常时返回空Map,或包含错误信息的特殊Map,根据业务需求决定 + log.error("处理设备" + deviceId + "的数据时发生异常: ", e.getMessage()); + return new HashMap<>(); } return resultMap; } + @Override + public List devicePointList() { + + List devicePointRespVOList = new ArrayList<>(); + List deviceDOS = deviceMapper.selectList(Wrappers.lambdaQuery().orderByDesc(DeviceDO::getCreateTime)); + if (deviceDOS.isEmpty()){ + return devicePointRespVOList; + } + for (DeviceDO deviceDO : deviceDOS) { + DevicePointRespVO devicePointRespVO = new DevicePointRespVO(); + devicePointRespVO.setDeviceId(deviceDO.getId()); + devicePointRespVO.setDeviceName(deviceDO.getDeviceName()); + + List deviceContactModelDOS = deviceContactModelMapper.selectList( + Wrappers.lambdaQuery() + .eq(DeviceContactModelDO::getDeviceId, deviceDO.getId())); + + if (!deviceContactModelDOS.isEmpty()){ + devicePointRespVO.setContactModelDOList(deviceContactModelDOS); + } + devicePointRespVOList.add(devicePointRespVO); + + } + return devicePointRespVOList; + } + @Override public Long createDeviceAttribute(DeviceAttributeDO deviceAttribute) { 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 c52ccc51c..e7214d358 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 @@ -5,6 +5,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.taosdata.jdbc.utils.BlobUtil; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; import org.springframework.dao.EmptyResultDataAccessException; @@ -22,6 +23,7 @@ import java.text.SimpleDateFormat; import java.util.*; @Service +@Slf4j public class TDengineService { @Resource private JdbcTemplate jdbcTemplate; @@ -374,11 +376,9 @@ public class TDengineService { return result; } }); - } catch (EmptyResultDataAccessException e) { - return Collections.singletonList(createEmptyResult(id)); } catch (Exception e) { - System.err.println("查询设备" + id + "的最新数据时发生异常: " + e.getMessage()); - e.printStackTrace(); + log.error("查询设备" + id + "的最新数据时发生异常", e); +// e.printStackTrace(); return Collections.singletonList(createEmptyResult(id)); } } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeServiceImpl.java index 207f60c22..0e71443ec 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/devicemodelattribute/DeviceModelAttributeServiceImpl.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.iot.dal.mysql.deviceattributetype.DeviceAttribute import cn.iocoder.yudao.module.iot.service.device.TDengineService; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -36,6 +37,7 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*; */ @Service @Validated +@Slf4j public class DeviceModelAttributeServiceImpl implements DeviceModelAttributeService { @Resource @@ -170,7 +172,10 @@ public class DeviceModelAttributeServiceImpl implements DeviceModelAttributeServ } } catch (Exception e) { - throw new RuntimeException("处理设备数据时发生异常", e); + log.error(e.getMessage()); +// e.printStackTrace(); +// throw new RuntimeException("处理设备数据时发生异常", e); + return new ArrayList<>(); } 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 519a225c7..df66aca89 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 @@ -9,9 +9,16 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode; */ public interface ErrorCodeConstants { + + ErrorCode MOLD_REPAIR_ID_NULL = new ErrorCode(5_0090, "维修单ID不能为空"); + ErrorCode MOLD_REPAIR_MAPPER_NULL = new ErrorCode(5_0091, "维修单行数据Mapper初始化失败"); + ErrorCode MOLD_REPAIR_LINE_NULL = new ErrorCode(5_0092, "维修单行数据不能为空"); + ErrorCode MOLD_REPAIR_SUBJECT_ID_NULL = new ErrorCode(5_0093, "维修项目ID不能为空"); + ErrorCode BOM_NOT_EXISTS = new ErrorCode(5_001, "产品BOM不存在"); ErrorCode BOM_EXISTS = new ErrorCode(5_002, "产品BOM已存在"); ErrorCode ORGANIZATION_NOT_EXISTS = new ErrorCode(5_0011, "产线工位不存在"); + ErrorCode ORGANIZATION_ID_NOT_EXISTS = new ErrorCode(5_0011, "产线工位不存在"); ErrorCode ORGANIZATION_EXITS_CHILDREN = new ErrorCode(5_0012, "存在存在子产线工位,无法删除"); ErrorCode ORGANIZATION_PARENT_NOT_EXITS = new ErrorCode(5_0013,"父级产线工位不存在"); ErrorCode ORGANIZATION_PARENT_ERROR = new ErrorCode(5_0014, "不能设置自己为父产线工位"); 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 138cdb810..e5f422db5 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 @@ -6,6 +6,7 @@ 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.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo.EnergyDeviceConsumptionReqVO; 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; @@ -24,6 +25,7 @@ import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; import java.util.List; +import java.util.Map; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -97,12 +99,11 @@ public class EnergyDeviceController { BeanUtils.toBean(list, EnergyDeviceRespVO.class)); } - @PostMapping("/queryDataRecords") + @GetMapping("/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)); + public CommonResult> queryDataRecords(@Valid EnergyDeviceConsumptionReqVO deviceConsumptionReqVO) { + return success(energyDeviceService.queryDataRecords(deviceConsumptionReqVO)); } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/EnergyDeviceConsumptionReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/EnergyDeviceConsumptionReqVO.java new file mode 100644 index 000000000..d5aead46b --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/energydevice/vo/EnergyDeviceConsumptionReqVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.mes.controller.admin.energydevice.vo; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 能耗管理/能耗报表 Request VO") +@Data +public class EnergyDeviceConsumptionReqVO { + + @Schema(description = "表名称") + private String name; + + @Schema(description = "所属区域") + private Long orgId; + + @Schema(description = "开始时间") + private String startTime; + + @Schema(description = "结束时间") + private String endTime; + + +} 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 a71495d55..a564d1bff 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 @@ -100,7 +100,7 @@ public class EnergyDeviceRespVO { @ExcelProperty("子列表点位参数值") private Map sublistPointList; - @Schema(description = "列表") - Map> operationRulesVOMap; + @Schema(description = "点位差值列表") + private 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/moldrepair/MoldRepairController.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/moldrepair/MoldRepairController.java new file mode 100644 index 000000000..23d3cd5ad --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/moldrepair/MoldRepairController.java @@ -0,0 +1,149 @@ +package cn.iocoder.yudao.module.mes.controller.admin.moldrepair; + +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +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.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.MoldRepairPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.MoldRepairRespVO; +import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.MoldRepairSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair.MoldRepairDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair.MoldRepairLineDO; +import cn.iocoder.yudao.module.mes.service.moldrepair.MoldRepairService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 设备维修记录") +@RestController +@RequestMapping("/mes/mold-repair") +@Validated +public class MoldRepairController { + + @Resource + private MoldRepairService moldRepairService; + + @Resource + private AdminUserApi adminUserApi; + + @PostMapping("/create") + @Operation(summary = "创建设备维修记录") + @PreAuthorize("@ss.hasPermission('mes:mold-repair:create')") + public CommonResult createMoldRepair(@Valid @RequestBody MoldRepairSaveReqVO createReqVO) { + return success(moldRepairService.createMoldRepair(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新设备维修记录") + @PreAuthorize("@ss.hasPermission('mes:mold-repair:update')") + public CommonResult updateMoldRepair(@Valid @RequestBody MoldRepairSaveReqVO updateReqVO) { + moldRepairService.updateMoldRepair(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除设备维修记录") + @Parameter(name = "ids", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('mes:mold-repair:delete')") + public CommonResult deleteMoldRepair(@RequestParam("ids") String ids) { + + // 将逗号分隔的字符串转换为Long类型的List + List idList = Arrays.stream(ids.split(",")) + .map(String::trim) // 去除可能存在的空格 + .map(Long::valueOf) + .collect(Collectors.toList()); + moldRepairService.deleteMoldRepair(idList); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得设备维修记录") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('mes:mold-repair:query')") + public CommonResult getMoldRepair(@RequestParam("id") Long id) { + MoldRepairDO moldRepair = moldRepairService.getMoldRepair(id); + return success(BeanUtils.toBean(moldRepair, MoldRepairRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得设备维修记录分页") + @PreAuthorize("@ss.hasPermission('mes:mold-repair:query')") + public CommonResult> getMoldRepairPage(@Valid MoldRepairPageReqVO pageReqVO) { + PageResult pageResult = moldRepairService.getMoldRepairPage(pageReqVO); + PageResult moldRepairRespVOPageResult = BeanUtils.toBean(pageResult, MoldRepairRespVO.class); + return success(buildCreatorName(moldRepairRespVOPageResult)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出设备维修记录 Excel") + @PreAuthorize("@ss.hasPermission('mes:mold-repair:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportMoldRepairExcel(@Valid MoldRepairPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = moldRepairService.getMoldRepairPage(pageReqVO).getList(); + List moldRepairRespVOList = BeanUtils.toBean(list, MoldRepairRespVO.class); + for (MoldRepairRespVO moldSubjectRespVO : moldRepairRespVOList) { + if (moldSubjectRespVO.getAcceptedBy() !=null) { + AdminUserRespDTO user = adminUserApi.getUser(Long.valueOf(moldSubjectRespVO.getAcceptedBy())); + moldSubjectRespVO.setAcceptedBy("(" + user.getUsername() + ")" + user.getNickname()); + } + if (moldSubjectRespVO.getConfirmBy() !=null) { + AdminUserRespDTO user = adminUserApi.getUser(Long.valueOf(moldSubjectRespVO.getConfirmBy())); + moldSubjectRespVO.setConfirmBy("(" + user.getUsername() + ")" + user.getNickname()); + } + if (moldSubjectRespVO.getStatus() !=null) { + moldSubjectRespVO.setStatusName(moldSubjectRespVO.getStatus() != null ? + (moldSubjectRespVO.getStatus() == 0 ? "待完成" : "已完成") : null); + } + + } + // 导出 Excel + ExcelUtils.write(response, "设备维修记录.xls", "数据", MoldRepairRespVO.class,moldRepairRespVOList); + } + + // ==================== 子表(设备维修记录行) ==================== + + @GetMapping("/mold-repair-line/list-by-repair-id") + @Operation(summary = "获得设备维修记录行列表") + @Parameter(name = "repairId", description = "维修单ID") + @PreAuthorize("@ss.hasPermission('mes:mold-repair:query')") + public CommonResult> getMoldRepairLineListByRepairId(@RequestParam("repairId") Long repairId) { + return success(moldRepairService.getMoldRepairLineListByRepairId(repairId)); + } + + + private PageResult buildCreatorName(PageResult moldSubjectRespVOPageResult) { + for (MoldRepairRespVO moldSubjectRespVO : moldSubjectRespVOPageResult.getList()) { + if (moldSubjectRespVO.getAcceptedBy() !=null) { + AdminUserRespDTO user = adminUserApi.getUser(Long.valueOf(moldSubjectRespVO.getAcceptedBy())); + moldSubjectRespVO.setAcceptedBy("(" + user.getUsername() + ")" + user.getNickname()); + } + if (moldSubjectRespVO.getConfirmBy() !=null) { + AdminUserRespDTO user = adminUserApi.getUser(Long.valueOf(moldSubjectRespVO.getConfirmBy())); + moldSubjectRespVO.setConfirmBy("(" + user.getUsername() + ")" + user.getNickname()); + } + } + + return moldSubjectRespVOPageResult; + } + +} \ 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/moldrepair/enums/MoldRecordStatusEnum.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/moldrepair/enums/MoldRecordStatusEnum.java new file mode 100644 index 000000000..c517dea0c --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/moldrepair/enums/MoldRecordStatusEnum.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.mes.controller.admin.moldrepair.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 单据状态枚举 + */ +@Getter +@AllArgsConstructor +public enum MoldRecordStatusEnum { + + PENDING(0, "待完成"), + COMPLETED(1, "已完成"), + // 可以根据需要添加其他状态 + CANCELED(2, "已取消"); + + @JsonValue + private final Integer code; + private final String name; + + @JsonCreator + public static MoldRecordStatusEnum getByCode(Integer code) { + if (code == null) { + return null; + } + for (MoldRecordStatusEnum status : MoldRecordStatusEnum.values()) { + if (status.getCode().equals(code)) { + return status; + } + } + return null; + } +} \ 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/moldrepair/vo/MoldRepairPageReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/moldrepair/vo/MoldRepairPageReqVO.java new file mode 100644 index 000000000..ac8d76db0 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/moldrepair/vo/MoldRepairPageReqVO.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.mes.controller.admin.moldrepair.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 MoldRepairPageReqVO extends PageParam { + + @Schema(description = "维修单编号") + private String repairCode; + + @Schema(description = "维修单名称", example = "王五") + private String repairName; + + @Schema(description = "模具ID", example = "6979") + private Long moldId; + + @Schema(description = "模具编码") + private String moldCode; + + @Schema(description = "模具名称", example = "张三") + private String moldName; + + @Schema(description = "品牌") + private String moldBrand; + + @Schema(description = "规格型号") + private String moldSpec; + + @Schema(description = "模具类型", example = "1622") + private Long moldTypeId; + + @Schema(description = "报修日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] requireDate; + + @Schema(description = "完成日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] finishDate; + + @Schema(description = "验收日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] confirmDate; + + @Schema(description = "维修结果") + private String repairResult; + + @Schema(description = "维修人员") + private String acceptedBy; + + @Schema(description = "验收人员") + private String confirmBy; + + @Schema(description = "单据状态0-待完成 1-已完成", example = "1") + private Integer status; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + + @Schema(description = "ids集合导出用") + private String ids; +} \ 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/moldrepair/vo/MoldRepairRespVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/moldrepair/vo/MoldRepairRespVO.java new file mode 100644 index 000000000..ebf7fe917 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/moldrepair/vo/MoldRepairRespVO.java @@ -0,0 +1,113 @@ +package cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo; + +import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.enums.MoldRecordStatusEnum; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; + +@Schema(description = "管理后台 - 模具维修记录 Response VO") +@Data +@ExcelIgnoreUnannotated +public class MoldRepairRespVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "27809") +// @ExcelProperty("ID") + private Long id; + + @Schema(description = "维修单编号", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("维修单编号") + private String repairCode; + + @Schema(description = "维修单名称", example = "王五") + @ExcelProperty("维修单名称") + private String repairName; + + @Schema(description = "模具ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "6979") +// @ExcelProperty("模具ID") + private Long moldId; + + @Schema(description = "模具编码", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("模具编码") + private String moldCode; + + @Schema(description = "模具名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三") + @ExcelProperty("模具名称") + private String moldName; + + @Schema(description = "品牌") + @ExcelProperty("品牌") + private String moldBrand; + + @Schema(description = "规格型号") + @ExcelProperty("规格型号") + private String moldSpec; + + @Schema(description = "模具类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1622") +// @ExcelProperty(value = "模具类型", converter = DictConvert.class) + @DictFormat("mes_machine_type") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private Long moldTypeId; + + @Schema(description = "报修日期") + @ExcelProperty("报修日期") + @ColumnWidth(20) + private LocalDateTime requireDate; + + @Schema(description = "完成日期") + @ExcelProperty("完成日期") + @ColumnWidth(20) + private LocalDateTime finishDate; + + @Schema(description = "验收日期") + @ExcelProperty("验收日期") + @ColumnWidth(20) + private LocalDateTime confirmDate; + + @Schema(description = "维修结果") + @ExcelProperty("维修结果") + private String repairResult; + + @Schema(description = "维修人员") + @ExcelProperty("维修人员") + private String acceptedBy; + + @Schema(description = "验收人员") + @ExcelProperty("验收人员") + private String confirmBy; + + @Schema(description = "单据状态", example = "1") + @ExcelProperty(value = "单据状态 0-待完成 1-已完成") + @DictFormat("mes_mold_record_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private Integer status; + + @Schema(description = "单据状态", example = "1") + @ExcelProperty(value = "单据状态 0-待完成 1-已完成") + @DictFormat("mes_mold_record_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中 + private String statusName; + + @Schema(description = "备注", example = "你猜") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + @ColumnWidth(20) + private LocalDateTime createTime; + + @Schema(description = "模具类型 1-模具 2-关键件", example = "你猜") + private Integer deviceType; + + @Schema(description = "模具Id", example = "你猜") + private Long deviceId; + + @Schema(description = "关键件Id", example = "你猜") + private Long componentId; + + +} \ 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/moldrepair/vo/MoldRepairSaveReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/moldrepair/vo/MoldRepairSaveReqVO.java new file mode 100644 index 000000000..e1afd0e83 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/moldrepair/vo/MoldRepairSaveReqVO.java @@ -0,0 +1,84 @@ +package cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo; + +import cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair.MoldRepairLineDO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "管理后台 - 模具维修记录新增/修改 Request VO") +@Data +public class MoldRepairSaveReqVO { + + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "27809") + private Long id; + + @Schema(description = "维修单编号", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "维修单编号不能为空") + private String repairCode; + + @Schema(description = "维修单名称", example = "王五") + private String repairName; + + @Schema(description = "模具ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "6979") +// @NotNull(message = "模具ID不能为空") + private Long moldId; + + @Schema(description = "模具编码", requiredMode = Schema.RequiredMode.REQUIRED) +// @NotEmpty(message = "模具编码不能为空") + private String moldCode; + + @Schema(description = "模具名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三") +// @NotEmpty(message = "模具名称不能为空") + private String moldName; + + @Schema(description = "品牌") + private String moldBrand; + + @Schema(description = "规格型号") + private String moldSpec; + + @Schema(description = "模具类型-待用", requiredMode = Schema.RequiredMode.REQUIRED, example = "1622") +// @NotNull(message = "模具类型不能为空") + private Long moldTypeId; + + @Schema(description = "报修日期") + private LocalDateTime requireDate; + + @Schema(description = "完成日期") + private LocalDateTime finishDate; + + @Schema(description = "验收日期") + private LocalDateTime confirmDate; + + @Schema(description = "维修结果") + private String repairResult; + + @Schema(description = "维修人员") + private String acceptedBy; + + @Schema(description = "验收人员") + private String confirmBy; + + @Schema(description = "单据状态", example = "1") + private String status; + + @Schema(description = "备注", example = "你猜") + private String remark; + + @Schema(description = "模具维修记录行列表") + private List moldRepairLines; + + @Schema(description = "模具类型 1-模具 2-关键件") + private Integer deviceType; + + @Schema(description = "模具Id") + private Long deviceId; + + @Schema(description = "关键件Id") + private Long componentId; + +} \ 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/OrganizationController.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/OrganizationController.java index 5e977f66f..f9be752d2 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/OrganizationController.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/OrganizationController.java @@ -4,10 +4,7 @@ import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.LineAnalysisTreeDTO; -import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationListReqVO; -import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationRespVO; -import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationSaveReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.*; import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO; import cn.iocoder.yudao.module.mes.service.organization.OrganizationService; import io.swagger.v3.oas.annotations.Operation; @@ -98,10 +95,22 @@ public class OrganizationController { @GetMapping("/deviceParameterAnalysis") @Operation(summary = "设备运行参数分析") @PreAuthorize("@ss.hasPermission('iot:device:query')") - public CommonResult> deviceParameterAnalysis(@RequestParam(value = "keyword", required = false) String keyword) { - List list = organizationService.deviceParameterAnalysis(keyword); + public CommonResult> deviceParameterAnalysis(@RequestParam(value = "keyword", required = false) String keyword, + @RequestParam(value = "showDevices") Integer showDevices + ) { + List list = organizationService.deviceParameterAnalysis(keyword,showDevices); return success(list); } +// +// @GetMapping("/getParametersById") +// @Operation(summary = "根据产线Id获取点位参数") +// @Parameter(name = "id", description = "编号", required = true, example = "1024") +// //@PreAuthorize("@ss.hasPermission('mes:organization:query')") +// public CommonResult> getParametersById(@RequestParam("id") Long id) { +// List organization = organizationService.getDeviceParametersByOrganizationId(id); +// return success(organization); +// } + } \ 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/DeviceParametersDTO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/vo/DeviceParametersDTO.java new file mode 100644 index 000000000..eb127ad65 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/vo/DeviceParametersDTO.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.mes.controller.admin.organization.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DeviceParametersDTO { + /** + * 设备ID + */ + private Long deviceId; + + /** + * 设备名称 + */ + private String deviceName; + + /** + * 设备编码(可选) + */ + private String deviceCode; + + /** + * 设备类型(可选) + */ + private String deviceType; + + /** + * 设备状态(可选) + */ + private String deviceStatus; + + /** + * 参数列表 + */ + private List parameters; +} \ 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 b897c9ed7..665bdf77a 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,8 +27,12 @@ public class LineAnalysisTreeDTO { public static class LineNode { private Long id; // 产线ID private String name; // 产线名称 + private String orgClass; // 组织等级 private Long parentId; - private List equipments = new ArrayList<>(); +// private List equipments = new ArrayList<>(); + private List equipments; + private List children; + } // 设备节点 @@ -39,7 +43,7 @@ public class LineAnalysisTreeDTO { public static class EquipmentNode { private Long id; // 设备ID private String name; // 设备名称 - private List parameters = new ArrayList<>(); + private List parameters; } // 参数节点 diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/vo/ParameterInfoDTO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/vo/ParameterInfoDTO.java new file mode 100644 index 000000000..b7687b40f --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/organization/vo/ParameterInfoDTO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.mes.controller.admin.organization.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ParameterInfoDTO { + /** + * 参数ID + */ + private Long parameterId; + + /** + * 参数名称 + */ + private String parameterName; + + /** + * 参数代码 + */ + private String parameterCode; + + /** + * 参数类型 + */ + private String parameterType; + + /** + * 数据类型 + */ + private String dataType; + + /** + * 单位 + */ + private String unit; + + /** + * 系数 + */ + private Double ratio; +} \ 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/taskmanagement/vo/TaskManagementSaveReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/taskmanagement/vo/TaskManagementSaveReqVO.java index 2f977cae0..5690472bf 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/taskmanagement/vo/TaskManagementSaveReqVO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/taskmanagement/vo/TaskManagementSaveReqVO.java @@ -27,9 +27,11 @@ public class TaskManagementSaveReqVO { private Integer taskType; @Schema(description = "设备列表") + @NotEmpty(message = "名称不能为空") private String deviceList; @Schema(description = "项目表单") + @NotNull private Long projectForm; @Schema(description = "起止开始日期") diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/ticketmanagement/vo/TicketManagementBatchUpdateReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/ticketmanagement/vo/TicketManagementBatchUpdateReqVO.java index f3539708b..55f3f7e89 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/ticketmanagement/vo/TicketManagementBatchUpdateReqVO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/ticketmanagement/vo/TicketManagementBatchUpdateReqVO.java @@ -16,5 +16,5 @@ public class TicketManagementBatchUpdateReqVO { @Schema(description = "作业状态", example = "2") @NotNull(message = "作业状态不能为空") - private Integer jobStatus ; // 默认值为2 + private Integer jobStatus ; } \ 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/moldrepair/MoldRepairDO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/moldrepair/MoldRepairDO.java new file mode 100644 index 000000000..c40f70bfd --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/moldrepair/MoldRepairDO.java @@ -0,0 +1,117 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair; + +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +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_mold_repair") +@KeySequence("mes_mold_repair_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MoldRepairDO extends BaseDO { + + /** + * ID + */ + @TableId + private Long id; + /** + * 维修单编号 + */ + private String repairCode; + /** + * 维修单名称 + */ + private String repairName; + /** + * 模具ID + */ + private Long moldId; + /** + * 模具编码 + */ + private String moldCode; + /** + * 模具名称 + */ + private String moldName; + /** + * 品牌 + */ + private String moldBrand; + /** + * 规格型号 + */ + private String moldSpec; + /** + * 模具类型 + * + * 枚举 {@link TODO mes_machine_type 对应的类} + */ + private Long moldTypeId; + /** + * 报修日期 + */ + private LocalDateTime requireDate; + /** + * 完成日期 + */ + private LocalDateTime finishDate; + /** + * 验收日期 + */ + private LocalDateTime confirmDate; + /** + * 维修结果 + */ + private String repairResult; + /** + * 维修人员 + */ + private String acceptedBy; + /** + * 验收人员 + */ + private String confirmBy; + /** + * 单据状态0-待完成 1-已完成 + * + * 枚举 {@link TODO mes_mold_record_status 对应的类} + */ + private Integer status; + /** + * 备注 + */ + private String remark; + + /** + * 模具类型 1-模具 2-关键件 + */ + private Integer moldType; + + /** + * 设备Id + */ + private Long deviceId; + + /** + * 关键件Id + */ + private Long componentId; + +} \ 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/moldrepair/MoldRepairLineDO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/moldrepair/MoldRepairLineDO.java new file mode 100644 index 000000000..aed8c3b19 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/moldrepair/MoldRepairLineDO.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair; + +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_mold_repair_line") +@KeySequence("mes_mold_repair_line_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MoldRepairLineDO extends BaseDO { + + /** + * ID + */ + @TableId + private Long id; + /** + * 维修单ID + */ + private Long repairId; + /** + * 项目ID + */ + private Long subjectId; + /** + * 项目编码 + */ + private String subjectCode; + /** + * 项目名称 + */ + private String subjectName; + /** + * 项目类型 + */ + private String subjectType; + /** + * 项目内容 + */ + private String subjectContent; + /** + * 标准 + */ + private String subjectStandard; + /** + * 故障描述 + */ + private String malfunction; + /** + * 故障描述资源 + */ + private String malfunctionUrl; + /** + * 维修情况 + */ + private String repairDes; + /** + * 备注 + */ + private String remark; + +} \ 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/moldrepair/MoldRepairLineMapper.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/moldrepair/MoldRepairLineMapper.java new file mode 100644 index 000000000..4c3889e17 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/moldrepair/MoldRepairLineMapper.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.moldrepair; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +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.moldrepair.MoldRepairLineDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 设备维修记录行 Mapper + * + * @author 内蒙必硕 + */ +@Mapper +public interface MoldRepairLineMapper extends BaseMapperX { + + default List selectListByRepairId(Long repairId) { + return selectList(MoldRepairLineDO::getRepairId, repairId); + } + + default int deleteByRepairId(Long repairId) { + return delete(MoldRepairLineDO::getRepairId, repairId); + } + +} \ 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/moldrepair/MoldRepairMapper.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/moldrepair/MoldRepairMapper.java new file mode 100644 index 000000000..211a194c7 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/moldrepair/MoldRepairMapper.java @@ -0,0 +1,59 @@ +package cn.iocoder.yudao.module.mes.dal.mysql.moldrepair; + +import java.util.*; +import java.util.stream.Collectors; + +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.moldrepair.MoldRepairDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.moldsubject.MoldSubjectDO; +import com.alibaba.excel.util.StringUtils; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.*; + +/** + * 设备维修记录 Mapper + * + * @author 内蒙必硕 + */ +@Mapper +public interface MoldRepairMapper extends BaseMapperX { + + default PageResult selectPage(MoldRepairPageReqVO reqVO) { + + + LambdaQueryWrapperX dvRepairDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>(); + dvRepairDOLambdaQueryWrapperX + .eqIfPresent(MoldRepairDO::getRepairCode, reqVO.getRepairCode()) + .likeIfPresent(MoldRepairDO::getRepairName, reqVO.getRepairName()) + .eqIfPresent(MoldRepairDO::getMoldId, reqVO.getMoldId()) + .eqIfPresent(MoldRepairDO::getMoldCode, reqVO.getMoldCode()) + .likeIfPresent(MoldRepairDO::getMoldName, reqVO.getMoldName()) + .eqIfPresent(MoldRepairDO::getMoldBrand, reqVO.getMoldBrand()) + .eqIfPresent(MoldRepairDO::getMoldSpec, reqVO.getMoldSpec()) + .eqIfPresent(MoldRepairDO::getMoldTypeId, reqVO.getMoldTypeId()) + .betweenIfPresent(MoldRepairDO::getRequireDate, reqVO.getRequireDate()) + .betweenIfPresent(MoldRepairDO::getFinishDate, reqVO.getFinishDate()) + .betweenIfPresent(MoldRepairDO::getConfirmDate, reqVO.getConfirmDate()) + .eqIfPresent(MoldRepairDO::getRepairResult, reqVO.getRepairResult()) + .eqIfPresent(MoldRepairDO::getAcceptedBy, reqVO.getAcceptedBy()) + .eqIfPresent(MoldRepairDO::getConfirmBy, reqVO.getConfirmBy()) + .eqIfPresent(MoldRepairDO::getStatus, reqVO.getStatus()) + .eqIfPresent(MoldRepairDO::getRemark, reqVO.getRemark()) + .betweenIfPresent(MoldRepairDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(MoldRepairDO::getCreateTime); + + // 单独处理 ids 条件 + if (StringUtils.isNotBlank(reqVO.getIds())) { + List idList = Arrays.stream(reqVO.getIds().split(",")) + .map(String::trim) + .map(Long::valueOf) + .collect(Collectors.toList()); + dvRepairDOLambdaQueryWrapperX.in(MoldRepairDO::getId, idList); + } + + return selectPage(reqVO,dvRepairDOLambdaQueryWrapperX ); + } + +} \ 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/EnergyDeviceService.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/energydevice/EnergyDeviceService.java index ecb6dc0ae..e916916b5 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 @@ -2,6 +2,7 @@ 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.EnergyDeviceConsumptionReqVO; 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; @@ -109,7 +110,7 @@ public interface EnergyDeviceService { return convertMap(getList(ids), EnergyDeviceDO::getId); } - List queryDataRecords(String startTime,String endTime); + List queryDataRecords(EnergyDeviceConsumptionReqVO deviceConsumptionReqVO); } \ 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 89a0e597e..79734439a 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 @@ -4,19 +4,21 @@ 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.dal.mysql.devicecontactmodel.DeviceContactModelMapper; 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.controller.admin.energydevice.vo.*; 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.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,6 +26,8 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.text.DecimalFormat; import java.time.LocalDateTime; import java.util.*; @@ -39,6 +43,7 @@ import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; */ @Service @Validated +@Slf4j public class EnergyDeviceServiceImpl implements EnergyDeviceService { @Resource @@ -49,6 +54,8 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService { private MesNoRedisDAO noRedisDAO; @Resource private TDengineService tDengineService; + @Resource + private DeviceContactModelMapper deviceContactModelMapper; @Override public Long createEnergyDevice(EnergyDeviceSaveReqVO createReqVO) { @@ -242,50 +249,647 @@ public class EnergyDeviceServiceImpl implements EnergyDeviceService { } @Override - public List queryDataRecords(String startTime,String endTime) { - List energyDeviceRespVOArrayList = new ArrayList<>(); - List energyDeviceDO = energyDeviceMapper.selectList(); - if (energyDeviceDO.isEmpty()){ + public List queryDataRecords(EnergyDeviceConsumptionReqVO deviceConsumptionReqVO) { + List result = new ArrayList<>(); + List energyDeviceDO = energyDeviceMapper.selectList( + Wrappers.lambdaQuery() + .like(StringUtils.isNotBlank(deviceConsumptionReqVO.getName()), EnergyDeviceDO::getName, deviceConsumptionReqVO.getName()) + .eq(deviceConsumptionReqVO.getOrgId() != null, EnergyDeviceDO::getOrgId, deviceConsumptionReqVO.getOrgId())); + + if (energyDeviceDO == null || energyDeviceDO.isEmpty()) { throw exception(ENERGY_LIST_NOT_EXISTS); } + for (EnergyDeviceDO deviceDO : energyDeviceDO) { - EnergyDeviceRespVO energyDeviceRespVO = new EnergyDeviceRespVO(); - if (StringUtils.isBlank(deviceDO.getRules())){ + 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); + if (operationRulesVOList == null || operationRulesVOList.isEmpty()) { + continue; + } + + try { + // 计算设备结果 + EnergyDeviceRespVO deviceRespVO = buildEnergyDeviceRespVO(deviceDO, operationRulesVOList, deviceConsumptionReqVO.getStartTime(), deviceConsumptionReqVO.getEndTime()); + if (deviceRespVO != null) { + result.add(deviceRespVO); + } + } catch (Exception e) { + log.error("计算设备结果失败, deviceId: {}", deviceDO.getId(), e); + } + } + + return result; + } + + /** + * 构建EnergyDeviceRespVO对象 + */ + private EnergyDeviceRespVO buildEnergyDeviceRespVO(EnergyDeviceDO deviceDO, + List rules, + String startTime, String endTime) { + if (deviceDO == null || rules == null || rules.isEmpty()) { + return null; + } + + EnergyDeviceRespVO respVO = new EnergyDeviceRespVO(); + + // 设置设备基本信息 + respVO.setId(deviceDO.getId()); + respVO.setName(deviceDO.getName()); + respVO.setCode(deviceDO.getCode()); + respVO.setInfo(deviceDO.getInfo()); + respVO.setCheckCron(deviceDO.getCheckCron()); + respVO.setLastCheckTime(deviceDO.getLastCheckTime()); + respVO.setLastCheckValue(deviceDO.getLastCheckValue()); + respVO.setUnitName(deviceDO.getUnitName()); + respVO.setIsEnable(deviceDO.getIsEnable()); + respVO.setCreateTime(deviceDO.getCreateTime()); + respVO.setUpdateTime(deviceDO.getUpdateTime()); + respVO.setDeviceTypeId(deviceDO.getDeviceTypeId()); + respVO.setDeviceTypeName(deviceDO.getDeviceTypeName()); + respVO.setOrgId(deviceDO.getOrgId()); + respVO.setOrgName(deviceDO.getOrgName()); + respVO.setRules(deviceDO.getRules()); + respVO.setOperationRulesVOList(rules); + + // 计算数据结果 + Map calculationResult = calculateDeviceData(deviceDO, rules, startTime, endTime); + if (calculationResult == null) { + return respVO; + } + + // 设置能耗总用量差值 + Double totalDifference = (Double) calculationResult.get("totalDifference"); + if (totalDifference != null) { + respVO.setEnergyConsumption(formatDouble(totalDifference)); + } else { + respVO.setEnergyConsumption("0.0"); + } + + // 设置每个点位参数的差值,key为点位参数名称 + Map operationRulesVOMap = buildPointDifferenceMap(calculationResult, deviceDO, rules); + respVO.setOperationRulesVOMap(operationRulesVOMap); + + return respVO; + } + + + /** + * 从查询结果中提取特定点位的数据 + */ + private Map getPointData(Map dataMap, Long pointId) { + if (dataMap == null || pointId == null) { + return null; + } + + try { + Object queryDataObj = dataMap.get("queryData"); + if (queryDataObj == null) { + return null; + } + + String queryData = queryDataObj.toString(); + if (StringUtils.isBlank(queryData)) { + return null; + } + + // 处理编码问题 + queryData = fixEncoding(queryData); + + // 解析JSON数组 + JSONArray jsonArray = JSON.parseArray(queryData); + + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject jsonObj = jsonArray.getJSONObject(i); + + // 安全获取id + Long dataPointId = null; + try { + dataPointId = jsonObj.getLong("id"); + } catch (Exception e) { + continue; + } + + if (dataPointId == null) { + continue; + } + + // 匹配点位ID + if (pointId.equals(dataPointId)) { + Map pointData = new HashMap<>(); + + // 提取所有需要的字段 + pointData.put("id", dataPointId); + + // 安全获取字段 + pointData.put("address", getJsonString(jsonObj, "address")); + + // 处理值 + Object value = jsonObj.get("addressValue"); + Double doubleValue = null; + if (value != null) { + try { + if (value instanceof Number) { + doubleValue = ((Number) value).doubleValue(); + } else { + doubleValue = Double.parseDouble(value.toString()); + } + } catch (NumberFormatException e) { + log.warn("点位值无法转换为数字: pointId={}, value={}", pointId, value); + doubleValue = null; } } + pointData.put("value", doubleValue); + pointData.put("addressValue", value); + + pointData.put("attributeCode", getJsonString(jsonObj, "attributeCode")); + pointData.put("attributeName", getJsonString(jsonObj, "attributeName")); + pointData.put("attributeType", getJsonString(jsonObj, "attributeType")); + pointData.put("dataType", getJsonString(jsonObj, "dataType")); + pointData.put("dataUnit", getJsonString(jsonObj, "dataUnit")); + + // 安全获取ratio + try { + Float ratio = jsonObj.getFloat("ratio"); + pointData.put("ratio", ratio); + } catch (Exception e) { + pointData.put("ratio", null); + } + + return pointData; + } + } + + } catch (Exception e) { + log.error("解析点位数据失败, pointId: {}", pointId, e); + } + + return null; + } + + /** + * 从JSON对象安全获取字符串 + */ + private String getJsonString(JSONObject jsonObj, String key) { + try { + return jsonObj.getString(key); + } catch (Exception e) { + return ""; + } + } + + /** + * 格式化double值为字符串 + */ + private String formatDouble(Double value) { + if (value == null) { + return "0.0"; + } + + DecimalFormat df = new DecimalFormat("#.##"); + return df.format(value); + } + /** + * 计算设备数据 + */ + private Map calculateDeviceData(EnergyDeviceDO deviceDO, + List rules, + String startTime, String endTime) { + if (deviceDO == null || rules == null || rules.isEmpty()) { + return null; + } + + Map result = new HashMap<>(); + + try { + // 分别计算最新和最晚时间的数据 + Map latestData = getTimePointData(rules, startTime, endTime, true); + Map earliestData = getTimePointData(rules, startTime, endTime, false); + + if (latestData == null || earliestData == null) { + return result; + } + + // 使用相同的规则计算两个时间点的总值 + Double latestTotal = calculateTotalByRules(latestData, rules); + Double earliestTotal = calculateTotalByRules(earliestData, rules); + + // 计算每个点位的差值 + List> pointDifferences = calculatePointDifferences(latestData, earliestData, rules); + + result.put("latestData", latestData); + result.put("earliestData", earliestData); + result.put("latestTotal", latestTotal != null ? latestTotal : 0.0); + result.put("earliestTotal", earliestTotal != null ? earliestTotal : 0.0); + result.put("totalDifference", (latestTotal != null && earliestTotal != null) ? + latestTotal - earliestTotal : 0.0); + result.put("pointDifferences", pointDifferences != null ? pointDifferences : Collections.emptyList()); + + } catch (Exception e) { + log.error("计算设备数据失败, deviceId: {}", deviceDO.getId(), e); + } + + return result; + } + + /** + * 从设备数据中获取点位值 + */ + private Double getPointValueFromDataByDevice(Map timePointData, Long deviceId, Long pointId) { + if (timePointData == null || deviceId == null || pointId == null) { + return null; + } + + String deviceKey = "device_" + deviceId; + Map deviceData = (Map) timePointData.get(deviceKey); + if (deviceData == null) { + return null; + } + + return getPointValueFromData(deviceData, pointId); + } + + /** + * 获取点位值 + */ + private Double getPointValueFromData(Map dataMap, Long pointId) { + if (dataMap == null || pointId == null) { + return null; + } + + Map pointData = getPointData(dataMap, pointId); + if (pointData != null) { + Object value = pointData.get("value"); + if (value instanceof Double) { + return (Double) value; + } else if (value instanceof Number) { + return ((Number) value).doubleValue(); + } + } + return null; + } + + /** + * 获取指定时间点的数据 + */ + private Map getTimePointData(List rules, + String startTime, String endTime, + boolean isLatest) { + if (rules == null || rules.isEmpty()) { + return null; + } + + Map timePointData = new HashMap<>(); + String timestamp = null; + + for (OperationRulesVO rule : rules) { + if (rule == null || rule.getDeviceId() == null) { + continue; + } + + List> maps = null; + try { + maps = tDengineService.getstDeviceDataOrderByTimeDesc( + rule.getDeviceId(), startTime, endTime); + } catch (Exception e) { + log.error("查询设备数据失败, deviceId: {}", rule.getDeviceId(), e); + continue; + } + + if (maps == null || maps.isEmpty()) { + continue; + } + + Map dataMap = null; + try { + if (isLatest) { + dataMap = maps.get(0); + } else { + dataMap = maps.get(maps.size() - 1); + } + } catch (Exception e) { + log.error("获取时间点数据失败, deviceId: {}, isLatest: {}", rule.getDeviceId(), isLatest, e); + continue; + } + + if (dataMap == null) { + continue; + } + + if (timestamp == null && dataMap.containsKey("timestamp")) { + Object tsObj = dataMap.get("timestamp"); + if (tsObj != null) { + timestamp = tsObj.toString(); } - operationRulesVOMap.put(operationRulesVO.getPointId(),operationRulesVOS); + } + String deviceKey = "device_" + rule.getDeviceId(); + if (!timePointData.containsKey(deviceKey)) { + timePointData.put(deviceKey, dataMap); } - energyDeviceRespVO.setOperationRulesVOMap(operationRulesVOMap); - energyDeviceRespVOArrayList.add(energyDeviceRespVO); } + if (timestamp != null) { + timePointData.put("timestamp", timestamp); + } else { + timePointData.put("timestamp", ""); + } + + return timePointData.isEmpty() ? null : timePointData; + } + + /** + * 根据规则计算总值 + */ + private Double calculateTotalByRules(Map timePointData, List rules) { + if (timePointData == null || timePointData.isEmpty() || rules == null || rules.isEmpty()) { + return 0.0; + } + + Double total = null; + String lastOperator = null; + + for (int i = 0; i < rules.size(); i++) { + OperationRulesVO rule = rules.get(i); + if (rule == null || rule.getDeviceId() == null || rule.getPointId() == null) { + continue; + } + + String deviceKey = "device_" + rule.getDeviceId(); + Map deviceData = (Map) timePointData.get(deviceKey); + if (deviceData == null) { + continue; + } + + Double pointValue = getPointValueFromData(deviceData, rule.getPointId()); + if (pointValue == null) { + continue; + } + + if (total == null) { + total = pointValue; + } else { + String operator = null; + if (rule.getOperator() != null) { + operator = rule.getOperator().trim(); + } + + if (StringUtils.isEmpty(operator)) { + operator = lastOperator; + } + + if (StringUtils.isNotEmpty(operator)) { + try { + total = applyOperator(total, pointValue, operator); + } catch (Exception e) { + log.error("应用运算符失败: current={}, value={}, operator={}", total, pointValue, operator, e); + total += pointValue; + } + } else { + total += pointValue; + } + } + + lastOperator = rule.getOperator(); + } + + return total != null ? total : 0.0; + } + + /** + * 计算每个点位的差值 + */ + private List> calculatePointDifferences(Map latestData, + Map earliestData, + List rules) { + List> differences = new ArrayList<>(); + + if (rules == null || rules.isEmpty()) { + return differences; + } + + for (OperationRulesVO rule : rules) { + if (rule == null || rule.getDeviceId() == null || rule.getPointId() == null) { + continue; + } + + Map pointDiff = new HashMap<>(); + pointDiff.put("pointId", rule.getPointId()); + pointDiff.put("operator", rule.getOperator() != null ? rule.getOperator() : ""); + pointDiff.put("deviceId", rule.getDeviceId()); + + Double latestValue = getPointValueFromDataByDevice(latestData, rule.getDeviceId(), rule.getPointId()); + Double earliestValue = getPointValueFromDataByDevice(earliestData, rule.getDeviceId(), rule.getPointId()); + + pointDiff.put("latestValue", latestValue != null ? latestValue : 0.0); + pointDiff.put("earliestValue", earliestValue != null ? earliestValue : 0.0); + + if (latestValue != null && earliestValue != null) { + Double difference = latestValue - earliestValue; + pointDiff.put("difference", difference); + } else if (latestValue != null) { + pointDiff.put("difference", latestValue); + } else if (earliestValue != null) { + pointDiff.put("difference", -earliestValue); + } else { + pointDiff.put("difference", 0.0); + } + + differences.add(pointDiff); + } + + return differences; + } + + /** + * 应用运算符计算 + */ + private Double applyOperator(Double current, Double value, String operator) { + if (current == null || value == null || operator == null) { + return current; + } + + String op = operator.trim(); + switch (op) { + case "+": + return current + value; + case "-": + return current - value; + case "*": + return current * value; + case "/": + if (Math.abs(value) > 0.000001) { // 避免除零 + return current / value; + } else { + log.warn("除数不能为0: current={}, value={}", current, value); + return current; + } + default: + log.warn("不支持的操作符: {}, 使用加法", operator); + return current + value; + } + } + + /** + * 修复编码问题 + */ + private String fixEncoding(String str) { + if (StringUtils.isBlank(str)) { + return str; + } + + try { + // 尝试UTF-8解码 + byte[] bytes = str.getBytes(StandardCharsets.ISO_8859_1); + return new String(bytes, StandardCharsets.UTF_8); + } catch (Exception e) { + return str; + } + } + + + /** + * 优化:批量构建点位差值Map + */ + private Map buildPointDifferenceMap(Map calculationResult, + EnergyDeviceDO deviceDO, + List originalRules) { + Map result = new HashMap<>(); + + if (calculationResult == null || originalRules == null || originalRules.isEmpty()) { + return result; + } + + List> pointDifferences = (List>) calculationResult.get("pointDifferences"); + if (pointDifferences == null || pointDifferences.isEmpty()) { + return result; + } + + // 获取最新数据用于获取点位名称 + Map latestData = (Map) calculationResult.get("latestData"); + + // 收集所有点位ID + List allPointIds = new ArrayList<>(); + for (Map pointDiff : pointDifferences) { + Long pointId = (Long) pointDiff.get("pointId"); + if (pointId != null) { + allPointIds.add(pointId); + } + } + + // 批量从本地数据库获取点位名称 + Map pointNameMap = batchGetPointNamesFromLocalDB(allPointIds); + + for (Map pointDiff : pointDifferences) { + Long pointId = (Long) pointDiff.get("pointId"); + if (pointId == null) { + continue; + } + + // 获取点位名称 + String pointName = null; + + // 1. 尝试从TD数据库获取 + pointName = getPointNameFromTDData(latestData, pointId, pointDiff); + + // 2. 如果TD数据库没有,从本地数据库获取 + if (StringUtils.isBlank(pointName)) { + pointName = pointNameMap.get(pointId); + } + + // 获取差值 + Double difference = (Double) pointDiff.get("difference"); + String differenceStr = formatDouble(difference != null ? difference : 0.0); + + // 以点位名称为key,差值为value + if (StringUtils.isNotBlank(pointName)) { + result.put(pointName, differenceStr); + } else { + // 如果还没有点位名称,使用点位ID作为key + result.put("点位" + pointId, differenceStr); + } + } + + return result; + } + + /** + * 从TD数据库数据中获取点位名称 + */ + private String getPointNameFromTDData(Map timePointData, Long pointId, Map pointDiff) { + if (timePointData == null || pointId == null || pointDiff == null) { + return null; + } + + Long deviceId = (Long) pointDiff.get("deviceId"); + if (deviceId == null) { + return null; + } + + String deviceKey = "device_" + deviceId; + Map deviceData = (Map) timePointData.get(deviceKey); + if (deviceData == null) { + return null; + } + + Map pointData = getPointData(deviceData, pointId); + if (pointData == null) { + return null; + } + + String attributeName = (String) pointData.get("attributeName"); + if (StringUtils.isNotBlank(attributeName)) { + return attributeName; + } + + String attributeCode = (String) pointData.get("attributeCode"); + if (StringUtils.isNotBlank(attributeCode)) { + return attributeCode; + } + + return null; + } + + /** + * 批量获取点位名称(优化性能) + */ + private Map batchGetPointNamesFromLocalDB(List pointIds) { + Map result = new HashMap<>(); + + if (pointIds == null || pointIds.isEmpty()) { + return result; + } + + try { + // 批量查询点位信息 + List deviceContacts = deviceContactModelMapper.selectBatchIds(pointIds); + if (deviceContacts != null && !deviceContacts.isEmpty()) { + for (DeviceContactModelDO deviceContact : deviceContacts) { + if (deviceContact == null || deviceContact.getId() == null) { + continue; + } + + String pointName = null; + if (StringUtils.isNotBlank(deviceContact.getAttributeName())) { + pointName = deviceContact.getAttributeName(); + } else if (StringUtils.isNotBlank(deviceContact.getAttributeCode())) { + pointName = deviceContact.getAttributeCode(); + } + + if (StringUtils.isNotBlank(pointName)) { + result.put(deviceContact.getId(), pointName); + } + } + } + } catch (Exception e) { + log.error("批量查询点位信息失败, pointIds: {}", pointIds, e); + } - return energyDeviceRespVOArrayList; + return result; } } \ 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/moldrepair/MoldRepairService.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/moldrepair/MoldRepairService.java new file mode 100644 index 000000000..76db64da0 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/moldrepair/MoldRepairService.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.mes.service.moldrepair; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.MoldRepairPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.MoldRepairSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair.MoldRepairDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair.MoldRepairLineDO; + +import javax.validation.Valid; +import java.util.List; + +/** + * 设备维修记录 Service 接口 + * + * @author 内蒙必硕 + */ +public interface MoldRepairService { + + /** + * 创建设备维修记录 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createMoldRepair(@Valid MoldRepairSaveReqVO createReqVO); + + /** + * 更新设备维修记录 + * + * @param updateReqVO 更新信息 + */ + void updateMoldRepair(@Valid MoldRepairSaveReqVO updateReqVO); + + /** + * 删除设备维修记录 + * + * @param id 编号 + */ + void deleteMoldRepair(List idList); + + /** + * 获得设备维修记录 + * + * @param id 编号 + * @return 设备维修记录 + */ + MoldRepairDO getMoldRepair(Long id); + + /** + * 获得设备维修记录分页 + * + * @param pageReqVO 分页查询 + * @return 设备维修记录分页 + */ + PageResult getMoldRepairPage(MoldRepairPageReqVO pageReqVO); + + // ==================== 子表(设备维修记录行) ==================== + + /** + * 获得设备维修记录行列表 + * + * @param repairId 维修单ID + * @return 设备维修记录行列表 + */ + List getMoldRepairLineListByRepairId(Long repairId); + +} \ 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/moldrepair/MoldRepairServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/moldrepair/MoldRepairServiceImpl.java new file mode 100644 index 000000000..29b515ed8 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/moldrepair/MoldRepairServiceImpl.java @@ -0,0 +1,177 @@ +package cn.iocoder.yudao.module.mes.service.moldrepair; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodel.DeviceModelDO; +import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.MoldRepairPageReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.moldrepair.vo.MoldRepairSaveReqVO; +import cn.iocoder.yudao.module.mes.dal.dataobject.devicetype.DeviceTypeDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair.MoldRepairDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.moldrepair.MoldRepairLineDO; +import cn.iocoder.yudao.module.mes.dal.mysql.moldrepair.MoldRepairLineMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.moldrepair.MoldRepairMapper; +import cn.iocoder.yudao.module.mes.service.moldrepair.MoldRepairService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.List; +import lombok.extern.slf4j.Slf4j; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_MODEL_CODE_EXISTS; +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; + +import org.springframework.util.CollectionUtils; +import cn.iocoder.yudao.framework.common.exception.ServiceException; + + +/** + * 设备维修记录 Service 实现类 + * + * @author 内蒙必硕 + */ +@Slf4j +@Service +@Validated +public class MoldRepairServiceImpl implements MoldRepairService { + + @Resource + private MoldRepairMapper moldRepairMapper; + @Resource + private MoldRepairLineMapper moldRepairLineMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createMoldRepair(MoldRepairSaveReqVO createReqVO) { + + //编码重复判断 + Long count = moldRepairMapper.selectCount(new LambdaQueryWrapper() + .eq(MoldRepairDO::getRepairCode, createReqVO.getRepairCode()) + ); + + if (count > 0) { + throw exception(DV_REPAIR_CODE_EXISTS); + } + // 插入 + MoldRepairDO moldRepair = BeanUtils.toBean(createReqVO, MoldRepairDO.class); + moldRepairMapper.insert(moldRepair); + + // 插入子表 + createMoldRepairLineList(moldRepair.getId(), createReqVO.getMoldRepairLines()); + // 返回 + return moldRepair.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateMoldRepair(MoldRepairSaveReqVO updateReqVO) { + // 校验存在 + validateMoldRepairExists(updateReqVO.getId()); + + //编码重复判断 + Long count = moldRepairMapper.selectCount(new LambdaQueryWrapper() + .eq(MoldRepairDO::getRepairCode, updateReqVO.getRepairCode()) + .ne(MoldRepairDO::getId, updateReqVO.getId()) + + ); + + if (count > 0) { + throw exception(DV_REPAIR_CODE_EXISTS); + } + + // 更新 + MoldRepairDO updateObj = BeanUtils.toBean(updateReqVO, MoldRepairDO.class); + moldRepairMapper.updateById(updateObj); + + // 更新子表 + updateMoldRepairLineList(updateReqVO.getId(), updateReqVO.getMoldRepairLines()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteMoldRepair(List idList) { + for (Long id : idList) { + // 校验存在 + validateMoldRepairExists(id); + // 删除 + moldRepairMapper.deleteById(id); + // 删除子表 + deleteMoldRepairLineByRepairId(id); + } + + } + + private void validateMoldRepairExists(Long id) { + if (moldRepairMapper.selectById(id) == null) { + throw exception(DV_REPAIR_NOT_EXISTS); + } + } + + @Override + public MoldRepairDO getMoldRepair(Long id) { + return moldRepairMapper.selectById(id); + } + + @Override + public PageResult getMoldRepairPage(MoldRepairPageReqVO pageReqVO) { + return moldRepairMapper.selectPage(pageReqVO); + } + + // ==================== 子表(设备维修记录行) ==================== + + @Override + public List getMoldRepairLineListByRepairId(Long repairId) { + return moldRepairLineMapper.selectListByRepairId(repairId); + } + +// private void createMoldRepairLineList(Long repairId, List list) { +// list.forEach(o -> o.setRepairId(repairId)); +// moldRepairLineMapper.insertBatch(list); +// } + private void createMoldRepairLineList(Long repairId, List list) { + // 2. 校验维修单ID非空 + if (repairId == null) { + log.error("创建维修单行数据失败:维修单ID为null"); + throw new ServiceException(MOLD_REPAIR_ID_NULL); + } + + // 3. 校验列表非空(核心:解决第125行空指针) + if (CollectionUtils.isEmpty(list)) { + log.warn("维修单{}暂无行数据,跳过行记录创建", repairId); + return; + } + + // 4. 遍历列表,校验每个元素非空并设置repairId + for (MoldRepairLineDO lineDO : list) { + if (lineDO == null) { + log.warn("维修单{}发现空的行数据,跳过处理", repairId); + continue; // 跳过空元素,不影响其他数据 + } + lineDO.setRepairId(repairId); // 设置主表关联ID + } + + // 5. 校验mapper是否注入(兜底) + if (moldRepairLineMapper == null) { + log.error("创建维修单行数据失败:moldRepairLineMapper未注入"); + throw new ServiceException(MOLD_REPAIR_MAPPER_NULL); + } + + // 6. 批量插入 + moldRepairLineMapper.insertBatch(list); + log.info("维修单{}成功创建{}条行数据", repairId, list.size()); + } + + private void updateMoldRepairLineList(Long repairId, List list) { + deleteMoldRepairLineByRepairId(repairId); + list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下:1)id 冲突;2)updateTime 不更新 + createMoldRepairLineList(repairId, list); + } + + private void deleteMoldRepairLineByRepairId(Long repairId) { + moldRepairLineMapper.deleteByRepairId(repairId); + } + +} \ 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/moldtaskmanagement/MoldTaskManagementServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/moldtaskmanagement/MoldTaskManagementServiceImpl.java index 0fed43f2c..81c43e075 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/moldtaskmanagement/MoldTaskManagementServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/moldtaskmanagement/MoldTaskManagementServiceImpl.java @@ -1,15 +1,15 @@ package cn.iocoder.yudao.module.mes.service.moldtaskmanagement; import cn.iocoder.yudao.module.erp.dal.dataobject.mold.MoldDO; -import cn.iocoder.yudao.module.mes.dal.dataobject.dvsubject.DvSubjectDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.moldsubject.MoldSubjectDO; import cn.iocoder.yudao.module.mes.dal.dataobject.moldplanmaintenance.MoldPlanMaintenanceDO; -import cn.iocoder.yudao.module.mes.dal.dataobject.subjectplan.SubjectPlanDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.subjectmoldplan.SubjectMoldPlanDO; import cn.iocoder.yudao.module.mes.dal.dataobject.moldticketmanagement.MoldTicketManagementDO; import cn.iocoder.yudao.module.mes.dal.dataobject.moldticketresults.MoldTicketResultsDO; import cn.iocoder.yudao.module.erp.dal.mysql.mold.MoldMapper; -import cn.iocoder.yudao.module.mes.dal.mysql.dvsubject.DvSubjectMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.moldsubject.MoldSubjectMapper; import cn.iocoder.yudao.module.mes.dal.mysql.moldplanmaintenance.MoldPlanMaintenanceMapper; -import cn.iocoder.yudao.module.mes.dal.mysql.subjectplan.SubjectPlanMapper; +import cn.iocoder.yudao.module.mes.dal.mysql.subjectmoldplan.SubjectMoldPlanMapper; import cn.iocoder.yudao.module.mes.dal.mysql.moldticketmanagement.MoldTicketManagementMapper; import cn.iocoder.yudao.module.mes.dal.mysql.moldticketresults.MoldTicketResultsMapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -33,12 +33,16 @@ import cn.iocoder.yudao.module.mes.dal.mysql.moldtaskmanagement.MoldTaskManageme import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; +import org.springframework.util.CollectionUtils; +import lombok.extern.slf4j.Slf4j; + /** * 设备类型 Service 实现类 * * @author 内蒙必硕 */ @Service +@Slf4j @Validated public class MoldTaskManagementServiceImpl implements MoldTaskManagementService { @@ -58,11 +62,11 @@ public class MoldTaskManagementServiceImpl implements MoldTaskManagementService private MoldPlanMaintenanceMapper moldplanMaintenanceMapper; @Resource - private SubjectPlanMapper subjectPlanMapper; + private SubjectMoldPlanMapper subjectmoldPlanMapper; @Resource - private DvSubjectMapper dvSubjectMapper; + private MoldSubjectMapper moldSubjectMapper; @Override public Long createMoldTaskManagement(MoldTaskManagementSaveReqVO createReqVO) { @@ -103,19 +107,56 @@ public class MoldTaskManagementServiceImpl implements MoldTaskManagementService return moldtaskManagementMapper.selectById(id); } - @Override - public PageResult getMoldTaskManagementPage(MoldTaskManagementPageReqVO pageReqVO) { +// @Override +// public PageResult getMoldTaskManagementPage(MoldTaskManagementPageReqVO pageReqVO) { +// +// PageResult moldtaskManagementDOPageResult = moldtaskManagementMapper.selectPage(pageReqVO); +// for (MoldTaskManagementDO moldtaskManagementDO : moldtaskManagementDOPageResult.getList()) { +// MoldPlanMaintenanceDO moldplanMaintenanceDO = moldplanMaintenanceMapper.selectById(moldtaskManagementDO.getProjectForm()); +// moldtaskManagementDO.setProjectFormName(moldplanMaintenanceDO.getPlanName()); +// } +// +// +// return moldtaskManagementDOPageResult; +// } +@Override +public PageResult getMoldTaskManagementPage(MoldTaskManagementPageReqVO pageReqVO) { + // 1. 查询分页数据 + PageResult moldtaskManagementDOPageResult = moldtaskManagementMapper.selectPage(pageReqVO); + + // 2. 空列表直接返回,避免遍历空指针 + if (CollectionUtils.isEmpty(moldtaskManagementDOPageResult.getList())) { + return moldtaskManagementDOPageResult; + } - PageResult moldtaskManagementDOPageResult = moldtaskManagementMapper.selectPage(pageReqVO); - for (MoldTaskManagementDO moldtaskManagementDO : moldtaskManagementDOPageResult.getList()) { - MoldPlanMaintenanceDO moldplanMaintenanceDO = moldplanMaintenanceMapper.selectById(moldtaskManagementDO.getProjectForm()); - moldtaskManagementDO.setProjectFormName(moldplanMaintenanceDO.getPlanName()); + // 3. 遍历处理每条数据,添加全量空值校验 + for (MoldTaskManagementDO moldtaskManagementDO : moldtaskManagementDOPageResult.getList()) { + // 3.1 校验关联的维保计划ID(projectForm)非空 + Long projectFormId = moldtaskManagementDO.getProjectForm(); + if (projectFormId == null) { + log.warn("模具任务{}的维保计划ID为空,跳过计划名称填充", moldtaskManagementDO.getId()); + moldtaskManagementDO.setProjectFormName("无维保计划"); // 兜底默认值 + continue; } - - return moldtaskManagementDOPageResult; + // 3.2 查询维保计划 + MoldPlanMaintenanceDO moldplanMaintenanceDO = moldplanMaintenanceMapper.selectById(projectFormId); + + // 3.3 校验查询结果非空 + if (moldplanMaintenanceDO == null) { + log.warn("模具任务{}关联的维保计划{}不存在", moldtaskManagementDO.getId(), projectFormId); + moldtaskManagementDO.setProjectFormName("维保计划不存在"); // 兜底 + } else { + // 3.4 正常赋值(确保planName非空,避免空字符串) + String planName = moldplanMaintenanceDO.getPlanName(); + moldtaskManagementDO.setProjectFormName(planName == null ? "未命名维保计划" : planName); + } } + // 4. 返回处理后的结果 + return moldtaskManagementDOPageResult; +} + @Override public void createMoldTicket(Long id) { @@ -147,15 +188,15 @@ public class MoldTaskManagementServiceImpl implements MoldTaskManagementService moldticketManagementDO.setTaskEndTime(moldtaskManagementDO.getEndDate().atStartOfDay()); moldticketManagementMapper.insert(moldticketManagementDO); - List dvSubjectDOList = new ArrayList<>(); - List subjectPlanDOList = subjectPlanMapper.selectList(Wrappers.lambdaQuery().eq(SubjectPlanDO::getPlanId, moldticketManagementDO.getPlanId())); - for (SubjectPlanDO subjectPlanDO : subjectPlanDOList) { - DvSubjectDO dvSubjectDO = dvSubjectMapper.selectById(subjectPlanDO.getSubjectId()); + List moldSubjectDOList = new ArrayList<>(); + List subjectmoldPlanDOList = subjectmoldPlanMapper.selectList(Wrappers.lambdaQuery().eq(SubjectMoldPlanDO::getPlanId, moldticketManagementDO.getPlanId())); + for (SubjectMoldPlanDO subjectmoldPlanDO : subjectmoldPlanDOList) { + MoldSubjectDO moldSubjectDO = moldSubjectMapper.selectById(subjectmoldPlanDO.getSubjectId()); MoldTicketResultsDO moldticketResultsDO = new MoldTicketResultsDO(); - moldticketResultsDO.setInspectionItemName(dvSubjectDO.getSubjectName()); - moldticketResultsDO.setInspectionMethod(dvSubjectDO.getInspectionMethod()); - moldticketResultsDO.setJudgmentCriteria(dvSubjectDO.getJudgmentCriteria()); + moldticketResultsDO.setInspectionItemName(moldSubjectDO.getSubjectName()); + moldticketResultsDO.setInspectionMethod(moldSubjectDO.getInspectionMethod()); + moldticketResultsDO.setJudgmentCriteria(moldSubjectDO.getJudgmentCriteria()); moldticketResultsDO.setManagementId(moldticketManagementDO.getId()); moldticketResultsDO.setMoldId(moldId); moldticketResultsMapper.insert(moldticketResultsDO); diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/organization/OrganizationService.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/organization/OrganizationService.java index 26d3fa7f0..db9d11463 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/organization/OrganizationService.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/organization/OrganizationService.java @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.mes.service.organization; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.LineAnalysisTreeDTO; -import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationListReqVO; -import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationRespVO; -import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationSaveReqVO; +import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.*; import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO; import javax.validation.Valid; @@ -80,5 +77,7 @@ public interface OrganizationService { return convertMap(getOrganizationVOList(ids), OrganizationDO::getId); } - List deviceParameterAnalysis(String keyword); + List deviceParameterAnalysis(String keyword,Integer showDevices); + +// List getDeviceParametersByOrganizationId(Long id); } \ 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/organization/OrganizationServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/organization/OrganizationServiceImpl.java index 35fcb0124..fbbab65da 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 @@ -257,374 +257,405 @@ public class OrganizationServiceImpl implements OrganizationService { } @Override - public List deviceParameterAnalysis(String keyword) { + public List deviceParameterAnalysis(String keyword, Integer showDevices) { + // 参数验证 + if (showDevices == null || (showDevices != 1 && showDevices != 2)) { + showDevices = 1; // 默认展示设备和参数 + } + + boolean needShowDevices = showDevices == 1; // 1-展示,2-不展示 - //1. 获取产线集合 + // 1. 获取产线集合 OrganizationListReqVO organizationListReqVO = new OrganizationListReqVO(); List organizationDOS = getOrganizationList(organizationListReqVO); List organizationRespVOS = buildVOList(organizationDOS); if (organizationRespVOS.isEmpty()) { - return Collections.emptyList(); + return Collections.emptyList(); } - // 2. 获取所有有machineId的产线 - List machineIds = organizationRespVOS.stream() + // 2. 获取所有有machineId的组织 + List deviceIds = organizationRespVOS.stream() .map(OrganizationRespVO::getMachineId) .filter(Objects::nonNull) + .distinct() .collect(Collectors.toList()); - // 3. 根据machineId查询设备 - List allDevices = Collections.emptyList(); - if (!machineIds.isEmpty()) { + // 3. 查询设备信息 + Map deviceMap; + if (!deviceIds.isEmpty()) { LambdaQueryWrapper deviceWrapper = new LambdaQueryWrapper<>(); - deviceWrapper.in(DeviceDO::getId, machineIds) + deviceWrapper.in(DeviceDO::getId, deviceIds) .eq(DeviceDO::getIsEnable, true); - allDevices = deviceMapper.selectList(deviceWrapper); + List devices = deviceMapper.selectList(deviceWrapper); + deviceMap = devices.stream() + .collect(Collectors.toMap(DeviceDO::getId, Function.identity())); + } else { + deviceMap = new HashMap<>(); } - // 4. 获取所有参数 - List allParameters = getAllParameters(allDevices); - - - // 5. 构建映射关系 - Map deviceById = allDevices.stream() - .collect(Collectors.toMap(DeviceDO::getId, Function.identity())); + // 4. 查询设备参数 + Map> paramsByDeviceId; + if (!deviceIds.isEmpty()) { + LambdaQueryWrapper paramWrapper = new LambdaQueryWrapper<>(); + paramWrapper.in(DeviceContactModelDO::getDeviceId, deviceIds) + .orderByAsc(DeviceContactModelDO::getSort); + List allParameters = deviceContactModelMapper.selectList(paramWrapper); + + paramsByDeviceId = allParameters.stream() + .filter(param -> param.getDeviceId() != null) + .collect(Collectors.groupingBy(DeviceContactModelDO::getDeviceId)); + } else { + paramsByDeviceId = new HashMap<>(); + } - // 6. 构建设备按产线分组的映射 - Map> devicesByLineId = new HashMap<>(); - for (OrganizationRespVO line : organizationRespVOS) { - if (line.getMachineId() != null) { - DeviceDO device = deviceById.get(line.getMachineId()); - if (device != null) { - devicesByLineId.computeIfAbsent(line.getId(), k -> new ArrayList<>()) - .add(device); - } + // 5. 构建产线ID到orgClass的映射 + Map lineOrgClassMap = new HashMap<>(); + for (int i = 0; i < organizationDOS.size(); i++) { + OrganizationDO orgDO = organizationDOS.get(i); + OrganizationRespVO orgVO = organizationRespVOS.get(i); + if (orgDO.getOrgClass() != null && orgVO != null) { + lineOrgClassMap.put(orgVO.getId(), orgDO.getOrgClass()); } } - Map> paramsByDeviceId = allParameters.stream() - .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(matchedLines, devicesByLineId, paramsByDeviceId,keyword,lineParentIdMap); - - } - - private List getMatchedLinesWithAncestors( - List allLines, - String keyword, - List allDevices, - Map> paramsByDeviceId, - Map lineParentIdMap, - Map lineMap) { + // 6. 构建组织ID到子节点的映射 + Map> childrenByParentId = organizationRespVOS.stream() + .filter(org -> org.getParentId() != null && org.getParentId() != 0L) + .collect(Collectors.groupingBy(OrganizationRespVO::getParentId)); + // 7. 如果有搜索关键词,筛选匹配的节点 + Set matchedNodeIds = new HashSet<>(); boolean hasKeyword = StringUtils.isNotBlank(keyword); - String lowerKeyword = hasKeyword ? keyword.toLowerCase() : ""; - // 存储最终要包含的产线ID - Set lineIdsToInclude = new HashSet<>(); + if (hasKeyword) { + String lowerKeyword = keyword.toLowerCase(); - // 1. 首先找出直接匹配的产线 - for (OrganizationRespVO line : allLines) { - boolean lineMatch = !hasKeyword || - (line.getName() != null && line.getName().toLowerCase().contains(lowerKeyword)); + // 查找组织名称匹配的节点 + for (OrganizationRespVO node : organizationRespVOS) { + boolean nodeMatched = false; - if (lineMatch) { - // 添加到结果集 - lineIdsToInclude.add(line.getId()); - // 向上查找所有父级节点 - addAllAncestors(line.getId(), lineParentIdMap, lineMap, lineIdsToInclude); - } - } + // 1. 检查组织名称是否匹配 + if (node.getName() != null && node.getName().toLowerCase().contains(lowerKeyword)) { + nodeMatched = true; + } - // 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); + // 2. 如果没有组织名称匹配,检查该节点是否有设备匹配 + if (!nodeMatched && needShowDevices && node.getMachineId() != null) { + DeviceDO device = deviceMap.get(node.getMachineId()); + if (device != null) { + // 检查设备名称是否匹配 + if (device.getDeviceName() != null && + device.getDeviceName().toLowerCase().contains(lowerKeyword)) { + nodeMatched = true; } - } - } - } - } - // 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 (!nodeMatched) { + List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); + boolean hasMatchingParam = deviceParams.stream() + .anyMatch(param -> param.getAttributeName() != null && + param.getAttributeName().toLowerCase().contains(lowerKeyword)); + if (hasMatchingParam) { + nodeMatched = true; + } } } } + + if (nodeMatched) { + // 将当前节点加入匹配列表 + matchedNodeIds.add(node.getId()); + // 迭代添加所有子节点 + addAllDescendants(node.getId(), childrenByParentId, matchedNodeIds); + } } - } - // 如果没有关键词,返回所有产线 - if (!hasKeyword) { - return allLines; + // 如果没有匹配任何节点,返回空列表 + if (matchedNodeIds.isEmpty()) { + return Collections.emptyList(); + } + } else { + // 无关键词时,包含所有节点 + matchedNodeIds.addAll(organizationRespVOS.stream() + .map(OrganizationRespVO::getId) + .collect(Collectors.toSet())); } - // 只返回需要包含的产线 - 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); + // 8. 找到最顶层的匹配节点(没有匹配的父节点) + Set topLevelNodeIds = new HashSet<>(matchedNodeIds); - // 继续向上查找 - currentParentId = lineParentIdMap.get(currentParentId); + // 从匹配节点中移除那些父节点也在匹配列表中的节点 + for (OrganizationRespVO node : organizationRespVOS) { + if (matchedNodeIds.contains(node.getId()) && node.getParentId() != null && + node.getParentId() != 0L && matchedNodeIds.contains(node.getParentId())) { + topLevelNodeIds.remove(node.getId()); + } } - } - private List buildTreeStructureWithKeyword(List lines, - Map> devicesByLineId, - Map> paramsByDeviceId, - String keyword, - Map lineParentIdMap) { + // 9. 获取顶层节点 + Map nodeMap = organizationRespVOS.stream() + .collect(Collectors.toMap(OrganizationRespVO::getId, Function.identity())); - // 统一处理关键词 - boolean hasKeyword = StringUtils.isNotBlank(keyword); - String lowerKeyword = hasKeyword ? keyword.toLowerCase() : ""; + List topLevelNodes = topLevelNodeIds.stream() + .map(nodeMap::get) + .filter(Objects::nonNull) + .collect(Collectors.toList()); - // 如果lines已经过滤过,这里不再需要复杂的匹配判断 - if (!hasKeyword) { - // 没有关键词时,返回完整的树结构 - return lines.stream().map(line -> { - Long parentId = lineParentIdMap.getOrDefault(line.getId(), 0L); + // 10. 构建树结构 + return buildOrganizationTreeWithChildren(topLevelNodes, matchedNodeIds, childrenByParentId, + deviceMap, paramsByDeviceId, lineOrgClassMap, keyword, organizationRespVOS, needShowDevices, hasKeyword); + } - // 获取该产线的设备 - List lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); + /** + * 迭代添加所有子孙节点 + */ + private void addAllDescendants(Long nodeId, + Map> childrenByParentId, + Set matchedNodeIds) { + if (childrenByParentId == null || childrenByParentId.isEmpty()) { + return; + } - // 构建设备节点(显示所有设备和参数) - List equipmentNodes = lineDevices.stream() - .map(device -> { - List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); + // 使用队列进行广度优先遍历 + Queue queue = new LinkedList<>(); + queue.offer(nodeId); - List parameterNodes = deviceParams.stream() - .map(this::buildParameterNode) - .collect(Collectors.toList()); + while (!queue.isEmpty()) { + Long currentId = queue.poll(); - 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<>(); - - // 第一遍:分析匹配情况 - for (OrganizationRespVO line : lines) { - // 产线是否匹配 - 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 = device.getDeviceName() != null && - device.getDeviceName().toLowerCase().contains(lowerKeyword); - deviceMatchedMap.put(device.getId(), deviceMatch); + List children = childrenByParentId.get(currentId); + if (children != null && !children.isEmpty()) { + for (OrganizationRespVO child : children) { + matchedNodeIds.add(child.getId()); + queue.offer(child.getId()); + } } } + } - // 第二遍:构建树结构 - return lines.stream().map(line -> { - boolean lineMatch = lineMatchedMap.getOrDefault(line.getId(), false); - Long parentId = lineParentIdMap.getOrDefault(line.getId(), 0L); + /** + * 构建组织树(包含当前节点及其所有子节点) + */ + private List buildOrganizationTreeWithChildren( + List topLevelNodes, + Set matchedNodeIds, + Map> childrenByParentId, + Map deviceMap, + Map> paramsByDeviceId, + Map lineOrgClassMap, + String keyword, + List allOrganizationRespVOS, + boolean needShowDevices, + boolean hasKeyword) { - // 获取该产线的设备 - List lineDevices = devicesByLineId.getOrDefault(line.getId(), new ArrayList<>()); + // 创建节点映射 + Map nodeMap = new HashMap<>(); - // 构建设备节点 - List equipmentNodes = lineDevices.stream() - .map(device -> { - boolean deviceMatch = deviceMatchedMap.getOrDefault(device.getId(), false); - List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); + // 创建所有组织节点的映射 + Map allNodesMap = allOrganizationRespVOS.stream() + .collect(Collectors.toMap(OrganizationRespVO::getId, Function.identity())); - // 如果产线匹配,显示该产线下的所有设备 - if (lineMatch) { - List parameterNodes = deviceParams.stream() - .map(this::buildParameterNode) - .collect(Collectors.toList()); + // 获取所有匹配节点的完整列表(包括所有子孙节点) + Set allMatchedAndDescendantIds = new HashSet<>(); + for (Long matchedId : matchedNodeIds) { + allMatchedAndDescendantIds.add(matchedId); + addAllDescendants(matchedId, childrenByParentId, allMatchedAndDescendantIds); + } - return LineAnalysisTreeDTO.EquipmentNode.builder() - .id(device.getId()) - .name(device.getDeviceName()) - .parameters(parameterNodes) - .build(); - } + // 构建所有匹配节点的树节点 + for (OrganizationRespVO node : allOrganizationRespVOS) { + if (!allMatchedAndDescendantIds.contains(node.getId())) { + continue; + } - // 如果设备匹配,显示该设备的所有参数 - 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 equipmentNodes = new ArrayList<>(); + + if (needShowDevices) { + // 有搜索关键词时获取所有设备,无关键词时只获取当前节点的设备 + List deviceIds = hasKeyword ? + getAllDeviceIdsForNode(node.getId(), childrenByParentId, allNodesMap, allMatchedAndDescendantIds) : + getCurrentDeviceId(node, allNodesMap); + + for (Long deviceId : deviceIds) { + DeviceDO device = deviceMap.get(deviceId); + if (device != null) { + // 获取设备参数 + List deviceParams = paramsByDeviceId.getOrDefault(device.getId(), new ArrayList<>()); + + // 检查设备和参数是否匹配关键词 + boolean shouldIncludeDevice = false; + List filteredParams = new ArrayList<>(); + + if (hasKeyword) { + String lowerKeyword = keyword.toLowerCase(); + // 检查当前节点是否匹配关键词(组织名称匹配) + boolean isNodeNameMatched = node.getName() != null && + node.getName().toLowerCase().contains(lowerKeyword); + + if (!isNodeNameMatched) { + // 有关键词但不是组织名称匹配的情况 + boolean deviceNameMatches = device.getDeviceName() != null && + device.getDeviceName().toLowerCase().contains(lowerKeyword); + + // 检查参数是否匹配 + filteredParams = deviceParams.stream() + .filter(param -> param.getAttributeName() != null && + param.getAttributeName().toLowerCase().contains(lowerKeyword)) + .collect(Collectors.toList()); - // 检查是否有匹配的参数 - boolean hasMatchingParam = deviceParams.stream() - .anyMatch(param -> isParameterMatch(param, lowerKeyword)); + boolean hasMatchingParam = !filteredParams.isEmpty(); - if (!hasMatchingParam) { - return null; + // 如果设备名称或参数匹配,则包含设备 + if (deviceNameMatches || hasMatchingParam) { + shouldIncludeDevice = true; + // 如果设备名称匹配但参数不匹配,包含所有参数 + if (deviceNameMatches && filteredParams.isEmpty()) { + filteredParams = new ArrayList<>(deviceParams); + } } + } else { + // 是组织名称匹配的情况:包含所有设备和参数 + shouldIncludeDevice = true; + filteredParams = new ArrayList<>(deviceParams); + } + } else { + // 无关键词的情况:包含所有设备和参数 + shouldIncludeDevice = true; + filteredParams = new ArrayList<>(deviceParams); + } - // 只显示匹配的参数 - List parameterNodes = deviceParams.stream() - .filter(param -> isParameterMatch(param, lowerKeyword)) - .map(this::buildParameterNode) - .collect(Collectors.toList()); + if (shouldIncludeDevice) { + List paramInfos = filteredParams.stream() + .map(this::convertToSimpleInfo) + .collect(Collectors.toList()); - return LineAnalysisTreeDTO.EquipmentNode.builder() + // 检查设备是否已添加(避免重复) + boolean alreadyAdded = equipmentNodes.stream() + .anyMatch(e -> e.getId().equals(device.getId())); + + if (!alreadyAdded) { + equipmentNodes.add(LineAnalysisTreeDTO.EquipmentNode.builder() .id(device.getId()) .name(device.getDeviceName()) - .parameters(parameterNodes) - .build(); - }) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - - return LineAnalysisTreeDTO.LineNode.builder() - .id(line.getId()) - .name(line.getName()) - .parentId(parentId) - .equipments(equipmentNodes) - .build(); - }) - .collect(Collectors.toList()); - } + .parameters(paramInfos) + .build()); + } + } + } + } + } -// /** -// * 检查产线下是否有匹配的设备或参数 -// */ -// 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)); -// } + LineAnalysisTreeDTO.LineNode lineNode = LineAnalysisTreeDTO.LineNode.builder() + .id(node.getId()) + .name(node.getName()) + .orgClass(lineOrgClassMap.getOrDefault(node.getId(), null)) + .parentId(node.getParentId()) + .equipments(equipmentNodes) + .children(new ArrayList<>()) + .build(); + + nodeMap.put(node.getId(), lineNode); + } + + // 构建父子关系 + List result = new ArrayList<>(); + + for (LineAnalysisTreeDTO.LineNode lineNode : nodeMap.values()) { + if (lineNode.getParentId() == null || lineNode.getParentId() == 0L) { + // 根节点 + result.add(lineNode); + } else { + // 查找父节点 + LineAnalysisTreeDTO.LineNode parentNode = nodeMap.get(lineNode.getParentId()); + if (parentNode != null) { + parentNode.getChildren().add(lineNode); + } else { + // 父节点不在当前构建的节点中,但当前节点是匹配的 + // 这种情况下,当前节点应该作为根节点展示 + result.add(lineNode); + } + } + } + // 过滤:只保留顶层节点 + List filteredResult = new ArrayList<>(); + Set topLevelNodeIds = topLevelNodes.stream() + .map(OrganizationRespVO::getId) + .collect(Collectors.toSet()); + + for (LineAnalysisTreeDTO.LineNode node : result) { + if (topLevelNodeIds.contains(node.getId())) { + filteredResult.add(node); + } else if (node.getParentId() == null || node.getParentId() == 0L) { + // 或者是没有父节点的根节点 + filteredResult.add(node); + } + } + + return filteredResult; + } /** - * 判断参数是否匹配关键词 + * 获取当前节点自身的设备ID */ - private boolean isParameterMatch(DeviceContactModelDO param, String lowerKeyword) { - if (StringUtils.isBlank(lowerKeyword)) { - return true; + private List getCurrentDeviceId(OrganizationRespVO node, Map allNodesMap) { + List deviceIds = new ArrayList<>(); + + // 获取当前节点 + OrganizationRespVO currentNode = allNodesMap.get(node.getId()); + if (currentNode != null && currentNode.getMachineId() != null) { + deviceIds.add(currentNode.getMachineId()); } - return (param.getAttributeName() != null && param.getAttributeName().toLowerCase().contains(lowerKeyword)); + return deviceIds; } + /** + * 获取节点及其子孙节点的设备ID + */ + private List getAllDeviceIdsForNode(Long nodeId, + Map> childrenByParentId, + Map allNodesMap, + Set matchedNodeIds) { + Set deviceIds = new HashSet<>(); + + // 先检查当前节点是否有设备 + OrganizationRespVO currentNode = allNodesMap.get(nodeId); + if (currentNode != null && currentNode.getMachineId() != null) { + deviceIds.add(currentNode.getMachineId()); + } + + // 使用队列迭代获取所有子孙节点 + Queue queue = new LinkedList<>(); + queue.offer(nodeId); + + while (!queue.isEmpty()) { + Long currentId = queue.poll(); + + // 获取当前节点的子节点 + List children = childrenByParentId.get(currentId); + if (children != null) { + for (OrganizationRespVO child : children) { + if (matchedNodeIds.contains(child.getId())) { + // 如果子节点有设备,添加到设备列表 + if (child.getMachineId() != null) { + deviceIds.add(child.getMachineId()); + } + // 继续处理子节点的子节点 + queue.offer(child.getId()); + } + } + } + } + return new ArrayList<>(deviceIds); + } /** - * 构建参数节点 + * 将设备参数转换为简化的参数信息 */ - private LineAnalysisTreeDTO.ParameterNode buildParameterNode(DeviceContactModelDO param) { + private LineAnalysisTreeDTO.ParameterNode convertToSimpleInfo(DeviceContactModelDO param) { return LineAnalysisTreeDTO.ParameterNode.builder() .id(param.getId()) .name(param.getAttributeName()) @@ -636,29 +667,4 @@ public class OrganizationServiceImpl implements OrganizationService { .build(); } - - private List getAllParameters(List devices) { - - if (devices.isEmpty()) { - return Collections.emptyList(); - } - - List deviceIds = devices.stream() - .map(DeviceDO::getId) - .collect(Collectors.toList()); - - LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - wrapper.in(DeviceContactModelDO::getDeviceId, deviceIds) - .orderByAsc(DeviceContactModelDO::getSort); // 按排序字段排序 - - List result = deviceContactModelMapper.selectList(wrapper); - - // 调试日志 - System.out.println("查询条件: 设备IDs=" + deviceIds); - System.out.println("查询结果数量: " + result.size()); - - return result; - } - - } \ 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/taskmanagement/TaskManagementServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/taskmanagement/TaskManagementServiceImpl.java index 996f2f5bd..e966396c4 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/taskmanagement/TaskManagementServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/taskmanagement/TaskManagementServiceImpl.java @@ -109,7 +109,9 @@ public class TaskManagementServiceImpl implements TaskManagementService { PageResult taskManagementDOPageResult = taskManagementMapper.selectPage(pageReqVO); for (TaskManagementDO taskManagementDO : taskManagementDOPageResult.getList()) { PlanMaintenanceDO planMaintenanceDO = planMaintenanceMapper.selectById(taskManagementDO.getProjectForm()); - taskManagementDO.setProjectFormName(planMaintenanceDO.getPlanName()); + if (planMaintenanceDO !=null) { + taskManagementDO.setProjectFormName(planMaintenanceDO.getPlanName()); + } } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/resources/mapper/moldrepair/MoldRepairMapper.xml b/yudao-module-mes/yudao-module-mes-biz/src/main/resources/mapper/moldrepair/MoldRepairMapper.xml new file mode 100644 index 000000000..fc057b247 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/resources/mapper/moldrepair/MoldRepairMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file