From d46e120ef178318f63bdd4c90a8c362873adef07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BB=ABUmbrella?= <2539020564@qq.com> Date: Sat, 18 Apr 2026 11:12:33 +0800 Subject: [PATCH] =?UTF-8?q?fen=E8=B0=83=E7=94=A8bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/constant/LauncherConstant.java | 4 +- .../produce/ProduceRunProcessor.java | 37 +++ .../desk/produce/feign/IProduceRunClient.java | 25 ++ .../quality/pojo/dto/QcThicknessIotDTO.java | 22 ++ .../quality/pojo/entity/QcHardnessIot.java | 92 +++++++ .../quality/pojo/entity/QcThicknessIot.java | 66 +++++ .../pojo/entity/QcWithstandVoltageIot.java | 85 ++++++ .../quality/pojo/vo/QcThicknessIotVO.java | 22 ++ .../desk/config/MybatisPlusConfig.java | 25 ++ .../iot/controller/IotWebApiController.java | 53 +++- .../desk/produce/feign/ProduceRunClient.java | 27 ++ .../desk/produce/mapper/MacToolUseMapper.java | 10 + .../desk/produce/mapper/MacToolUseMapper.xml | 29 ++ .../produce/mapper/MesQcProduceRunMapper.java | 5 + .../produce/mapper/QcProduceRunMapper.xml | 7 + .../service/IMesQcProduceRunService.java | 5 + .../impl/MesQcProduceRunServiceImpl.java | 254 +++++++++++++++++- .../quality/mapper/QcHardnessIotMapper.java | 36 +++ .../quality/mapper/QcHardnessIotMapper.xml | 27 ++ .../quality/mapper/QcThicknessIotMapper.java | 40 +++ .../quality/mapper/QcThicknessIotMapper.xml | 30 +++ .../mapper/QcWithstandVoltageIotMapper.java | 35 +++ .../mapper/QcWithstandVoltageIotMapper.xml | 26 ++ .../service/IQcHardnessIotService.java | 21 ++ .../service/IQcThicknessIotService.java | 37 +++ .../IQcWithstandVoltageIotService.java | 21 ++ .../impl/QcHardnessIotServiceImpl.java | 151 +++++++++++ .../impl/QcThicknessIotServiceImpl.java | 67 +++++ .../QcWithstandVoltageIotServiceImpl.java | 156 +++++++++++ .../wrapper/QcThicknessIotWrapper.java | 31 +++ 30 files changed, 1427 insertions(+), 19 deletions(-) create mode 100644 blade-ops/blade-job/src/main/java/org/springblade/job/processor/produce/ProduceRunProcessor.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/feign/IProduceRunClient.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/dto/QcThicknessIotDTO.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcHardnessIot.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcThicknessIot.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcWithstandVoltageIot.java create mode 100644 blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/vo/QcThicknessIotVO.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/config/MybatisPlusConfig.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/produce/feign/ProduceRunClient.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcHardnessIotMapper.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcHardnessIotMapper.xml create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcThicknessIotMapper.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcThicknessIotMapper.xml create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcWithstandVoltageIotMapper.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcWithstandVoltageIotMapper.xml create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcHardnessIotService.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcThicknessIotService.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcWithstandVoltageIotService.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcHardnessIotServiceImpl.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcThicknessIotServiceImpl.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcWithstandVoltageIotServiceImpl.java create mode 100644 blade-service/blade-desk/src/main/java/org/springblade/desk/quality/wrapper/QcThicknessIotWrapper.java diff --git a/blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java b/blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java index 3ef40cfd..301dc202 100644 --- a/blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java +++ b/blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java @@ -32,8 +32,8 @@ public interface LauncherConstant { * nacos dev 地址 */ -// String NACOS_DEV_ADDR = "192.168.249.27:8848"; - String NACOS_DEV_ADDR = "127.0.0.1:8848"; + String NACOS_DEV_ADDR = "192.168.249.27:8848"; +// String NACOS_DEV_ADDR = "127.0.0.1:8848"; /**R * nacos prod 地址 diff --git a/blade-ops/blade-job/src/main/java/org/springblade/job/processor/produce/ProduceRunProcessor.java b/blade-ops/blade-job/src/main/java/org/springblade/job/processor/produce/ProduceRunProcessor.java new file mode 100644 index 00000000..66a8931b --- /dev/null +++ b/blade-ops/blade-job/src/main/java/org/springblade/job/processor/produce/ProduceRunProcessor.java @@ -0,0 +1,37 @@ +package org.springblade.job.processor.produce; + +import jakarta.annotation.Resource; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springblade.desk.produce.feign.IProduceRunClient; +import org.springframework.stereotype.Component; +import tech.powerjob.worker.core.processor.ProcessResult; +import tech.powerjob.worker.core.processor.TaskContext; +import tech.powerjob.worker.core.processor.sdk.BasicProcessor; + +/** + * 生产追溯 - 获取产线相关设备数据 + * + * @author Tom Shuo + */ +@Component +@Data +@Slf4j +public class ProduceRunProcessor implements BasicProcessor { + + @Resource + private IProduceRunClient client; + + @Override + public ProcessResult process(TaskContext context) throws Exception { + log.info("获取产线相关设备数据定时任务开始"); + try { + boolean result = client.createProduceRun(); + log.info("获取产线相关设备数据定时任务结束, result={}", result); + return new ProcessResult(result); + } catch (Exception e) { + log.error("获取产线相关设备数据定时任务失败", e); + return new ProcessResult(false, e.getMessage()); + } + } +} \ No newline at end of file diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/feign/IProduceRunClient.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/feign/IProduceRunClient.java new file mode 100644 index 00000000..529e65de --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/feign/IProduceRunClient.java @@ -0,0 +1,25 @@ +package org.springblade.desk.produce.feign; + +import org.springblade.core.launch.constant.AppConstant; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * 生产追溯定时任务 Feign接口 + * + * @author Tom Shuo + */ +@FeignClient( + value = AppConstant.APPLICATION_DESK_NAME +) +public interface IProduceRunClient { + + String API_PREFIX = "/feign/client/produceRun"; + String CREATE_PRODUCE_RUN = API_PREFIX + "/createProduceRun"; + + /** + * 获取产线相关设备数据(定时任务调用) + */ + @GetMapping(CREATE_PRODUCE_RUN) + boolean createProduceRun(); +} \ No newline at end of file diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/dto/QcThicknessIotDTO.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/dto/QcThicknessIotDTO.java new file mode 100644 index 00000000..e1c68a96 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/dto/QcThicknessIotDTO.java @@ -0,0 +1,22 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.pojo.dto; + +import lombok.Data; +import org.springblade.desk.quality.pojo.entity.QcThicknessIot; + +import java.io.Serial; + +/** + * [QC测厚IOT] 数据传输对象实体类 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +@Data +public class QcThicknessIotDTO extends QcThicknessIot { + @Serial + private static final long serialVersionUID = 1L; + +} \ No newline at end of file diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcHardnessIot.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcHardnessIot.java new file mode 100644 index 00000000..bc94d713 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcHardnessIot.java @@ -0,0 +1,92 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.pojo.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * [硬度检测数据IOT] 实体类 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +@Data +@TableName("QC_HARDNESS_IOT") +@Schema(description = "QcHardnessIot Entity对象") +public class QcHardnessIot implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "QH_ID", type = IdType.AUTO) + @Schema(description = "主键ID") + private Long qhId; + + /** + * 设备号 + */ + public static final String COL_DEVICE_CODE = "DEVICE_CODE"; + @Schema(description = "设备号") + private String deviceCode; + + /** + * 批次号 + */ + public static final String COL_BATCH_NO = "BATCH_NO"; + @Schema(description = "批次号") + private String batchNo; + + /** + * 数据上传时间 + */ + public static final String COL_FILETIME = "FILETIME"; + @Schema(description = "数据上传时间") + private String filetime; + + /** + * 检测内容 + */ + public static final String COL_DATA_CONTENT = "DATA_CONTENT"; + @Schema(description = "检测内容") + private String dataContent; + + /** + * 创建时间 + */ + public static final String COL_CREATE_TIME = "CREATE_TIME"; + @Schema(description = "创建时间") + private Date createTime; + + /** + * 是否使用 + */ + public static final String COL_NOT_USE = "NOT_USE"; + @Schema(description = "是否使用") + private Integer notUse; + + /** + * 是否已读:0-未读,1-已读,2-超时未读 + */ + public static final String COL_IS_READ = "IS_READ"; + @Schema(description = "是否已读:0-未读,1-已读,2-超时未读") + private Integer isRead; + + /** + * IP + */ + public static final String COL_IP = "IP"; + @Schema(description = "IP") + private String ip; +} \ No newline at end of file diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcThicknessIot.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcThicknessIot.java new file mode 100644 index 00000000..3d8adc56 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcThicknessIot.java @@ -0,0 +1,66 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.pojo.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * [QC测厚IOT] 实体类 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +@Data +@TableName("QC_THICKNESS_IOT") +@Schema(description = "QcThicknessIot Entity对象") +public class QcThicknessIot implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "QT_ID", type = IdType.AUTO) + @Schema(description = "主键ID") + private Long qtId; + /** + * 设备编码 + */ + public static final String COL_DEVICE_CODE = "DEVICE_CODE"; + @Schema(description = "设备编码") + private String deviceCode; + /** + * 文件时间 + */ + public static final String COL_FILETIME = "FILETIME"; + @Schema(description = "文件时间") + private String filetime; + /** + * 数据内容 + */ + public static final String COL_DATA_CONTENT = "DATA_CONTENT"; + @Schema(description = "数据内容") + private String dataContent; + /** + * 创建时间 + */ + public static final String COL_CREATE_TIME = "CREATE_TIME"; + @Schema(description = "创建时间") + private Date createTime; + /** + * 是否使用 + */ + public static final String COL_NOT_USE = "NOT_USE"; + @Schema(description = "是否使用") + private Integer notUse; +} \ No newline at end of file diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcWithstandVoltageIot.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcWithstandVoltageIot.java new file mode 100644 index 00000000..7eda6c31 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcWithstandVoltageIot.java @@ -0,0 +1,85 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.pojo.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * [耐压检测数据IOT] 实体类 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +@Data +@TableName("QC_WITHSTAND_VOLTAGE_IOT") +@Schema(description = "QcWithstandVoltageIot Entity对象") +public class QcWithstandVoltageIot implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "QW_ID", type = IdType.AUTO) + @Schema(description = "主键ID") + private Long qwId; + + /** + * 设备号 + */ + public static final String COL_DEVICE_CODE = "DEVICE_CODE"; + @Schema(description = "设备号") + private String deviceCode; + + /** + * 工单号 + */ + public static final String COL_WO_CODE = "WO_CODE"; + @Schema(description = "工单号") + private String woCode; + + /** + * 检测时间 + */ + public static final String COL_TEST_TIME = "TEST_TIME"; + @Schema(description = "检测时间") + private String testTime; + + /** + * 耐压检测当前参数值内容 + */ + public static final String COL_CUR_CONTENT = "CUR_CONTENT"; + @Schema(description = "耐压检测当前参数值内容") + private String curContent; + + /** + * 耐压检测结果判定范围/标准值 + */ + public static final String COL_RES_RANGE = "RES_RANGE"; + @Schema(description = "耐压检测结果判定范围/标准值") + private String resRange; + + /** + * 创建时间 + */ + public static final String COL_CREATE_TIME = "CREATE_TIME"; + @Schema(description = "创建时间") + private Date createTime; + + /** + * 是否已读:0-未读,1-已读,2-超时未读 + */ + public static final String COL_IS_READ = "IS_READ"; + @Schema(description = "是否已读:0-未读,1-已读,2-超时未读") + private Integer isRead; +} \ No newline at end of file diff --git a/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/vo/QcThicknessIotVO.java b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/vo/QcThicknessIotVO.java new file mode 100644 index 00000000..f2354955 --- /dev/null +++ b/blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/vo/QcThicknessIotVO.java @@ -0,0 +1,22 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.pojo.vo; + +import lombok.Data; +import org.springblade.desk.quality.pojo.entity.QcThicknessIot; + +import java.io.Serial; + +/** + * [QC测厚IOT] 视图实体类 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +@Data +public class QcThicknessIotVO extends QcThicknessIot { + @Serial + private static final long serialVersionUID = 1L; + +} \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/config/MybatisPlusConfig.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/config/MybatisPlusConfig.java new file mode 100644 index 00000000..14b559a0 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/config/MybatisPlusConfig.java @@ -0,0 +1,25 @@ +package org.springblade.desk.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * MyBatis-Plus 配置类 + */ +@Configuration +public class MybatisPlusConfig { + + /** + * 添加分页插件 + */ + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 如果配置多个插件, 注意分页插件要放在最后 + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.ORACLE)); + return interceptor; + } +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/iot/controller/IotWebApiController.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/iot/controller/IotWebApiController.java index 7aaf002a..8cb41c0d 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/iot/controller/IotWebApiController.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/iot/controller/IotWebApiController.java @@ -1,26 +1,19 @@ package org.springblade.desk.iot.controller; +import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; -import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import lombok.extern.slf4j.Slf4j; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.AllArgsConstructor; -import org.hibernate.validator.internal.util.logging.Log; import org.springblade.core.log.exception.ServiceException; -import org.springblade.core.mp.support.Condition; import org.springblade.core.tool.api.R; import org.springblade.desk.basic.pojo.entity.BasicClazz; import org.springblade.desk.basic.service.IBasicClazzService; -import org.springblade.desk.dashboard.pojo.entity.DsBatchPreservePlanEntity; -import org.springblade.desk.dashboard.pojo.vo.DsBatchPreservePlanVO; -import org.springblade.desk.dashboard.service.IDsPartService; -import org.springblade.desk.dashboard.wrapper.DsBatchPreservePlanWrapper; -import org.springblade.desk.device.service.IEquipmentService; import org.springblade.desk.iot.setvice.IEpLineElectricService; -import org.springblade.desk.produce.pojo.vo.EleFilesEditVO; -import org.springblade.desk.produce.service.IProcessQualityMaintenanceService; -import org.springframework.beans.factory.annotation.Autowired; +import org.springblade.desk.quality.service.IQcHardnessIotService; +import org.springblade.desk.quality.service.IQcThicknessIotService; +import org.springblade.desk.quality.service.IQcWithstandVoltageIotService; import org.springframework.web.bind.annotation.*; @@ -31,10 +24,13 @@ import org.springframework.web.bind.annotation.*; @Tag(name = "iot回调专用", description = "iot回调专用") public class IotWebApiController { - @Autowired - IEpLineElectricService lineElectricService; + + private final IEpLineElectricService lineElectricService; private final IBasicClazzService bsBasicClassService; + private final IQcThicknessIotService qcThicknessIotService; + private final IQcHardnessIotService qcHardnessIotService; + private final IQcWithstandVoltageIotService qcWithstandVoltageIotService; @Operation(summary = "产线电量信息调用接口") @RequestMapping(value = "/saveDeviceAhm", method = RequestMethod.POST) @@ -59,5 +55,36 @@ public class IotWebApiController { return R.status(bsBasicClassService.saveBasicClass(data.getString("deviceCode"), data.getString("callNumber"), BasicClazz.TYPE_SUSPENSION_NO)); } + @PostMapping("/pushThickness") + @Operation(summary = "iot系统推送测厚数据接口") + public R pushThickness(@RequestBody JSONObject data) { + if (data == null || data.isEmpty()) { + throw new ServiceException("参数传递异常!"); + } + qcThicknessIotService.pushThickness(data); + return R.success(); + } + + @PostMapping("/pushHardness") + @Operation(summary = "iot系统推送硬度检测数据接口") + public R pushHardness(@RequestBody JSONArray dataArray) { + if (dataArray == null || dataArray.isEmpty()) { + throw new ServiceException("参数传递异常!"); + } + log.info("iot系统推送硬度检测数据: {}", dataArray.toJSONString()); + qcHardnessIotService.pushHardness(dataArray); + return R.success(); + } + + @PostMapping("/pushWithstandVoltage") + @Operation(summary = "iot系统推送耐压检测数据接口") + public R pushWithstandVoltage(@RequestBody JSONObject data) { + if (data == null || data.isEmpty()) { + throw new ServiceException("参数传递异常!"); + } + log.info("iot系统推送耐压检测数据: {}", data.toJSONString()); + qcWithstandVoltageIotService.pushWithstandVoltage(data); + return R.success(); + } } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/feign/ProduceRunClient.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/feign/ProduceRunClient.java new file mode 100644 index 00000000..4fb9d17a --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/feign/ProduceRunClient.java @@ -0,0 +1,27 @@ +package org.springblade.desk.produce.feign; + +import io.swagger.v3.oas.annotations.Hidden; +import lombok.RequiredArgsConstructor; +import org.springblade.core.tenant.annotation.NonDS; +import org.springblade.desk.produce.service.IMesQcProduceRunService; +import org.springframework.web.bind.annotation.RestController; + +/** + * 生产追溯定时任务 Feign实现 + * + * @author Tom Shuo + */ +@NonDS +@Hidden +@RestController +@RequiredArgsConstructor +public class ProduceRunClient implements IProduceRunClient { + + private final IMesQcProduceRunService mesQcProduceRunService; + + @Override + public boolean createProduceRun() { + mesQcProduceRunService.createProduceRun(); + return true; + } +} \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MacToolUseMapper.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MacToolUseMapper.java index 8eddd850..9bfb9071 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MacToolUseMapper.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MacToolUseMapper.java @@ -33,4 +33,14 @@ public interface MacToolUseMapper extends BaseMapper { List getProcessBingingRec(Long wpId); GoodsVO getMaterialMess(String goodsCode); + + /** + * 查询所有未完成的设备绑定记录(含设备分类、挂次号、设备编码) + */ + List> listAllByNoFinished(); + + /** + * 更新作业计划打印标记类型 + */ + void updatePrintType(String deviceCode, String hangNum, String mtnCode); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MacToolUseMapper.xml b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MacToolUseMapper.xml index 984ef96d..8705ce16 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MacToolUseMapper.xml +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MacToolUseMapper.xml @@ -193,4 +193,33 @@ srs.CREATE_TIME DESC) WHERE ROWNUM = 1 + + + + UPDATE MES_WORK_PLAN a SET a.PRINT_TYPE = 'process' + WHERE a.ID IN ( + SELECT DISTINCT c.ID FROM MES_MAC_TOOL_USE c + LEFT JOIN MES_EQUIPMENT b ON c.EQUIPMENT_CARD = b.ID + LEFT JOIN MES_WORK_PLAN wp ON c.WP_ID = wp.ID + WHERE b.DEVICE_CODE = #{deviceCode} + AND c.MTN_CODE = #{mtnCode} + AND c.is_deleted = 0 + + AND c.HANG_NUM = #{hangNum} + + ) + AND (a.PRINT_TYPE IS NULL OR a.PRINT_TYPE != 'process') + + diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MesQcProduceRunMapper.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MesQcProduceRunMapper.java index 37843fc0..4dd604fd 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MesQcProduceRunMapper.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MesQcProduceRunMapper.java @@ -30,4 +30,9 @@ public interface MesQcProduceRunMapper extends BaseMapper List listPrByWpIdIndex(Long id, int i, int i1); List listPrByWpId(Long wpId); + + /** + * 删除指定设备、挂次号、同槽编号的生产追溯记录 + */ + void deleteProduceRun(@Param("deviceCode") String deviceCode, @Param("hangNum") String hangNum, @Param("mtnCode") String mtnCode); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/QcProduceRunMapper.xml b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/QcProduceRunMapper.xml index 76bc9481..f5511a69 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/QcProduceRunMapper.xml +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/QcProduceRunMapper.xml @@ -62,5 +62,12 @@ select * from MES_QC_PRODUCE_RUN where mtn_Code in (select mtn_Code from MES_MAC_TOOL_USE where wp_id = #{wpId}) order by in_date asc + + DELETE FROM MES_QC_PRODUCE_RUN + WHERE DEVICE_ID = #{deviceCode} + AND MTN_CODE = #{mtnCode} + AND HANG_NUM = #{hangNum} + + diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/IMesQcProduceRunService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/IMesQcProduceRunService.java index 41971a5c..89b50bcf 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/IMesQcProduceRunService.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/IMesQcProduceRunService.java @@ -37,4 +37,9 @@ public interface IMesQcProduceRunService extends BaseService listPrByWpIdIndex(Long id, int i, Boolean aTrue); List listPrByWpId(Long id); + + /** + * 获取产线相关设备数据(定时任务入口) + */ + void createProduceRun(); } diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/MesQcProduceRunServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/MesQcProduceRunServiceImpl.java index 01b49829..9e05ae14 100644 --- a/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/MesQcProduceRunServiceImpl.java +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/MesQcProduceRunServiceImpl.java @@ -1,15 +1,27 @@ package org.springblade.desk.produce.service.impl; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springblade.core.mp.base.BaseServiceImpl; +import org.springblade.core.tool.utils.StringUtil; +import org.springblade.desk.produce.mapper.MacToolUseMapper; import org.springblade.desk.produce.mapper.MesQcProduceRunMapper; import org.springblade.desk.produce.pojo.entity.MesQcProduceRunEntity; import org.springblade.desk.produce.pojo.vo.MesQcProduceRunVO; import org.springblade.desk.produce.service.IMesQcProduceRunService; +import org.springframework.http.*; import org.springframework.stereotype.Service; -import com.baomidou.mybatisplus.core.conditions.Wrapper; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.client.RestTemplate; import com.baomidou.mybatisplus.core.metadata.IPage; -import org.springblade.core.mp.base.BaseServiceImpl; + +import java.util.Arrays; import java.util.List; +import java.util.Map; /** * 生产追溯 服务实现类 @@ -17,10 +29,16 @@ import java.util.List; * @author BladeX * @since 2026-02-03 */ +@Slf4j @Service +@RequiredArgsConstructor public class MesQcProduceRunServiceImpl extends BaseServiceImpl implements IMesQcProduceRunService { - @Override + private final MacToolUseMapper macToolUseMapper; + private final RestTemplate httpClientTemplate; + + @Value("${request.iotNew.url}") + private String iotNewUrl; public IPage selectMesQcProduceRunPage(IPage page, MesQcProduceRunVO mesQcProduceRun) { return page.setRecords(baseMapper.selectMesQcProduceRunPage(page, mesQcProduceRun)); } @@ -50,4 +68,232 @@ public class MesQcProduceRunServiceImpl extends BaseServiceImpl> mtuList = macToolUseMapper.listAllByNoFinished(); + if (mtuList == null || mtuList.isEmpty()) { + return; + } + + long startTime = System.currentTimeMillis(); + log.info("获取生产追溯数据任务-开始..., 数量 = {}", mtuList.size()); + + for (Map mtu : mtuList) { + String deviceCode = mtu.get("deviceCode") != null ? mtu.get("deviceCode").toString() : null; + String categorys = mtu.get("categorys") != null ? mtu.get("categorys").toString() : null; + String hangNum = mtu.get("hangNum") != null ? mtu.get("hangNum").toString() : null; + String mtnCode = mtu.get("mtnCode") != null ? mtu.get("mtnCode").toString() : null; + + if (deviceCode == null || categorys == null || mtnCode == null) { + continue; + } + + log.info("获取生产追溯数据-设备号={}, 挂次号={}, 同槽编号={}", deviceCode, hangNum, mtnCode); + + try { + if ("产线设备".equals(categorys)) { + fetchLineDevice(deviceCode, hangNum, mtnCode); + } else if ("烘箱设备".equals(categorys)) { + fetchOvenDevice(deviceCode, hangNum, mtnCode); + } + } catch (Exception e) { + log.error("获取生产追溯数据异常, 设备号={}, 挂次号={}, 同槽编号={}, error={}", deviceCode, hangNum, mtnCode, e.getMessage(), e); + } + } + + log.info("获取生产追溯数据任务-结束, 耗时 = {} ms", System.currentTimeMillis() - startTime); + } + + /** + * 产线设备:调用IOT接口获取Trace数据 + */ + private void fetchLineDevice(String deviceCode, String hangNum, String mtnCode) { + if (StringUtils.isBlank(hangNum)) { + log.warn("产线设备【{}】未绑定到挂次号!", deviceCode); + return; + } + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + JSONObject body = new JSONObject(); + body.put("deviceId", deviceCode); + body.put("params", Arrays.asList("Trace")); + body.put("paramsRequest", "PatId\\\"" + ":\\\"" + hangNum + "\\\""); + + HttpEntity entity = new HttpEntity<>(body, headers); + ResponseEntity responseEntity = httpClientTemplate.postForEntity( + iotNewUrl + "/deviceForZhgd/getNewDataByParams", entity, JSONObject.class); + + JSONObject result = responseEntity.getBody(); + if (result != null && Integer.valueOf(0).equals(result.getInteger("code"))) { + JSONArray resultList = result.getJSONArray("result"); + if (resultList != null && !resultList.isEmpty()) { + JSONObject firstItem = resultList.getJSONObject(0); + JSONObject trace = firstItem.getJSONObject("Trace"); + handleTraceData(trace, deviceCode, hangNum, mtnCode); + } else { + log.warn("设备号={}, 挂次号={}, 同槽编号={}, 返回数据为空: TraceItems is empty", hangNum, deviceCode, mtnCode); + } + } else { + log.error("设备号={}, 挂次号={}, 同槽编号={}, 获取生产追溯数据接口调用失败! 返回: {}", + hangNum, deviceCode, mtnCode, result != null ? result.getString("message") : "null"); + } + } + + /** + * 烘箱设备:调用IOT接口获取温度数据 + */ + private void fetchOvenDevice(String deviceCode, String hangNum, String mtnCode) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + JSONObject body = new JSONObject(); + body.put("deviceId", deviceCode); + body.put("type", 1); + body.put("issueMap", Arrays.asList("CH1")); + + HttpEntity entity = new HttpEntity<>(body, headers); + ResponseEntity responseEntity = httpClientTemplate.postForEntity( + iotNewUrl + "/deviceForZhgd/deviceSetOrIssue", entity, JSONObject.class); + + JSONObject result = responseEntity.getBody(); + if (result != null && Integer.valueOf(0).equals(result.getInteger("code"))) { + JSONArray resultList = result.getJSONArray("result"); + if (resultList != null && !resultList.isEmpty()) { + handleOvenData(resultList.getJSONObject(0), deviceCode, hangNum, mtnCode); + } + } else { + log.error("烘箱设备={}, 获取实时温度接口调用失败! 返回: {}", deviceCode, result != null ? result.getString("message") : "null"); + } + } + + /** + * 处理产线设备Trace数据 + */ + private void handleTraceData(JSONObject trace, String deviceCode, String hangNum, String mtnCode) { + JSONArray traceItems = trace.getJSONArray("TraceItems"); + if (traceItems == null || traceItems.isEmpty()) { + log.info("挂次号:{}, 设备号:{}, 同槽编号:{}, TraceItems为空", hangNum, deviceCode, mtnCode); + return; + } + + List dataList = traceItems.toJavaList(JSONObject.class); + if (dataList == null || dataList.isEmpty()) { + return; + } + + // 删除原有记录 + baseMapper.deleteProduceRun(deviceCode, hangNum, mtnCode); + log.info("挂次号:{}, 设备号:{}, 同槽编号:{}, 删除原有记录", hangNum, deviceCode, mtnCode); + + // 更新作业计划打印标记类型 + macToolUseMapper.updatePrintType(deviceCode, hangNum, mtnCode); + + // 保存新记录 + StringBuilder logBuilder = new StringBuilder("挂次号:").append(hangNum) + .append(",设备号:").append(deviceCode) + .append(",同槽编号:").append(mtnCode) + .append(",生产追溯工序:"); + + for (JSONObject jsonObject : dataList) { + MesQcProduceRunEntity pr = new MesQcProduceRunEntity(); + pr.setDeviceId(deviceCode); + pr.setMtnCode(mtnCode); + pr.setHangNum(hangNum); + pr.setWorkSlot(jsonObject.getString("WorkSlot")); + logBuilder.append(pr.getWorkSlot()).append(","); + pr.setInDate(jsonObject.getString("InDate")); + pr.setOutDate(jsonObject.getString("OutDate")); + pr.setProductStatus(jsonObject.getString("ProductStatus")); + + String currency = jsonObject.getString("Currency"); + if (StringUtils.isNotBlank(currency) && currency.contains("/")) { + List strList = Arrays.asList(currency.split("/")); + if ("0".equals(strList.get(0))) { + pr.setEleStream(strList.get(1)); + } else if ("0".equals(strList.get(1))) { + pr.setEleStream(strList.get(0)); + } else { + pr.setEleStream(currency); + } + } else { + pr.setEleStream(currency); + } + + pr.setEleRate(jsonObject.getString("Conductivity")); + pr.setPhValue(textHandle(jsonObject.getString("pH"))); + pr.setNiValue(textHandle(jsonObject.getString("Ni"))); + pr.setCurveValue(null); + pr.setTempSlot(jsonObject.getString("Temp")); + pr.setVSpeed(null); + pr.setCyropactorControl(null); + pr.setParamsValue(jsonObject.toJSONString()); + pr.setSoftWorkTime(jsonObject.getString("SoftWorkTime")); + pr.setVoltage(jsonObject.getString("Voltage")); + pr.setStartVol(jsonObject.getString("StartVol")); + save(pr); + } + log.info(logBuilder.toString()); + } + + /** + * 处理烘箱设备数据 + */ + private void handleOvenData(JSONObject data, String deviceCode, String hangNum, String mtnCode) { + String v = data.getString("v"); + // 查询是否有未结束的烘箱记录 + List existingList = list(Wrappers.lambdaQuery() + .eq(MesQcProduceRunEntity::getDeviceId, deviceCode) + .eq(MesQcProduceRunEntity::getMtnCode, mtnCode) + .eq(MesQcProduceRunEntity::getWorkSlot, "烘箱")); + + if (existingList == null || existingList.isEmpty()) { + // 新增"开始"记录 + MesQcProduceRunEntity pr = new MesQcProduceRunEntity(); + pr.setDeviceId(deviceCode); + pr.setMtnCode(mtnCode); + pr.setWorkSlot("烘箱"); + pr.setProductStatus("开始"); + pr.setInDate(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date())); + pr.setTempSlot(v); + pr.setParamsValue(data.toJSONString()); + save(pr); + } else { + MesQcProduceRunEntity last = existingList.get(existingList.size() - 1); + if (!"结束".equals(last.getProductStatus())) { + MesQcProduceRunEntity pr = new MesQcProduceRunEntity(); + pr.setDeviceId(deviceCode); + pr.setMtnCode(mtnCode); + pr.setWorkSlot("烘箱"); + pr.setProductStatus("结束"); + pr.setOutDate(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date())); + pr.setTempSlot(v); + pr.setParamsValue(data.toJSONString()); + save(pr); + } + } + } + + private String textHandle(String text) { + if (StringUtils.isBlank(text)) { + return ""; + } + if (text.contains("min") && text.contains("/") && text.contains("max") && !text.contains("P")) { + StringBuilder sb = new StringBuilder(); + String[] splitList = text.split("/"); + for (String str : splitList) { + if (str.contains("min") || str.contains("max")) { + String[] strList = str.split(":"); + String s = strList[1]; + if (s.length() > 5) { + strList[1] = s.substring(0, 4); + } + sb.append(strList[0]).append(":").append(strList[1]).append(" "); + } + } + return sb.toString(); + } + return text; + } +} \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcHardnessIotMapper.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcHardnessIotMapper.java new file mode 100644 index 00000000..60fa8f95 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcHardnessIotMapper.java @@ -0,0 +1,36 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; +import org.springblade.desk.quality.pojo.entity.QcHardnessIot; + +/** + * [硬度检测数据IOT] Mapper 接口 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +public interface QcHardnessIotMapper extends BaseMapper { + + /** + * 根据设备编码和数据内容查询记录(去重) + * + * @param deviceCode 设备编码 + * @param dataContent 数据内容 + * @return QcHardnessIot + */ + QcHardnessIot getDataByDeviceCodeAndDataContent(@Param("deviceCode") String deviceCode, @Param("dataContent") String dataContent); + + /** + * 将同设备编码下所有未读记录标记为超时未读(isRead=2) + * + * @param deviceCode 设备编码 + */ + @Update("UPDATE QC_HARDNESS_IOT SET IS_READ = 2 WHERE DEVICE_CODE = #{deviceCode} AND IS_READ = 0") + void updateAllToRead(@Param("deviceCode") String deviceCode); + +} \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcHardnessIotMapper.xml b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcHardnessIotMapper.xml new file mode 100644 index 00000000..4903aaa3 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcHardnessIotMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcThicknessIotMapper.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcThicknessIotMapper.java new file mode 100644 index 00000000..ded29d68 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcThicknessIotMapper.java @@ -0,0 +1,40 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.apache.ibatis.annotations.Param; +import org.springblade.desk.quality.pojo.entity.QcThicknessIot; +import org.springblade.desk.quality.pojo.vo.QcThicknessIotVO; + +import java.util.List; + +/** + * [QC测厚IOT] Mapper 接口 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +public interface QcThicknessIotMapper extends BaseMapper { + + /** + * 自定义分页 + * + * @param page 分页参数 + * @param qcThicknessIot 查询参数 + * @return List + */ + List selectQcThicknessIotPage(IPage page, QcThicknessIotVO qcThicknessIot); + + /** + * 根据设备编码和文件时间查询记录 + * + * @param deviceCode 设备编码 + * @param filetime 文件时间 + * @return QcThicknessIot + */ + QcThicknessIot getDataByFileTime(@Param("deviceCode") String deviceCode, @Param("filetime") String filetime); + +} \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcThicknessIotMapper.xml b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcThicknessIotMapper.xml new file mode 100644 index 00000000..20645eda --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcThicknessIotMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcWithstandVoltageIotMapper.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcWithstandVoltageIotMapper.java new file mode 100644 index 00000000..d0548736 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcWithstandVoltageIotMapper.java @@ -0,0 +1,35 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; +import org.springblade.desk.quality.pojo.entity.QcWithstandVoltageIot; + +/** + * [耐压检测数据IOT] Mapper 接口 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +public interface QcWithstandVoltageIotMapper extends BaseMapper { + + /** + * 根据工单号查询记录(去重) + * + * @param woCode 工单号 + * @return QcWithstandVoltageIot + */ + QcWithstandVoltageIot getDataByWoCode(@Param("woCode") String woCode); + + /** + * 将同工单号下所有未读记录标记为超时未读(isRead=2) + * + * @param woCode 工单号 + */ + @Update("UPDATE QC_WITHSTAND_VOLTAGE_IOT SET IS_READ = 2 WHERE WO_CODE = #{woCode} AND IS_READ = 0") + void updateAllToReadByWoCode(@Param("woCode") String woCode); + +} \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcWithstandVoltageIotMapper.xml b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcWithstandVoltageIotMapper.xml new file mode 100644 index 00000000..ed9f9040 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcWithstandVoltageIotMapper.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcHardnessIotService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcHardnessIotService.java new file mode 100644 index 00000000..20efff36 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcHardnessIotService.java @@ -0,0 +1,21 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.service; + +import com.alibaba.fastjson2.JSONArray; +import com.baomidou.mybatisplus.extension.service.IService; +import org.springblade.desk.quality.pojo.entity.QcHardnessIot; + +/** + * [硬度检测数据IOT] 服务类 + */ +public interface IQcHardnessIotService extends IService { + + /** + * iot系统推送硬度检测数据 + * + * @param dataArray 推送的JSON数组 + */ + void pushHardness(JSONArray dataArray); +} \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcThicknessIotService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcThicknessIotService.java new file mode 100644 index 00000000..6e49af64 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcThicknessIotService.java @@ -0,0 +1,37 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.service; + +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import org.springblade.desk.quality.pojo.entity.QcThicknessIot; +import org.springblade.desk.quality.pojo.vo.QcThicknessIotVO; + +/** + * [QC测厚IOT] 服务类 + */ +public interface IQcThicknessIotService extends IService { + /** + * 自定义分页 + * + * @param page 分页参数 + * @param qcThicknessIot 查询参数 + * @return IPage + */ + IPage selectQcThicknessIotPage(IPage page, QcThicknessIotVO qcThicknessIot); + + /** + * VO + * @param vo + */ + void setVOValue(QcThicknessIotVO vo); + + /** + * iot系统推送测厚数据 + * + * @param data 推送的JSON数据 + */ + void pushThickness(JSONObject data); +} diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcWithstandVoltageIotService.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcWithstandVoltageIotService.java new file mode 100644 index 00000000..2e1d164c --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcWithstandVoltageIotService.java @@ -0,0 +1,21 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.service; + +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.extension.service.IService; +import org.springblade.desk.quality.pojo.entity.QcWithstandVoltageIot; + +/** + * [耐压检测数据IOT] 服务类 + */ +public interface IQcWithstandVoltageIotService extends IService { + + /** + * iot系统推送耐压检测数据 + * + * @param data 推送的JSON数据 + */ + void pushWithstandVoltage(JSONObject data); +} \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcHardnessIotServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcHardnessIotServiceImpl.java new file mode 100644 index 00000000..a13939aa --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcHardnessIotServiceImpl.java @@ -0,0 +1,151 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.service.impl; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springblade.desk.quality.mapper.QcHardnessIotMapper; +import org.springblade.desk.quality.pojo.entity.QcHardnessIot; +import org.springblade.desk.quality.service.IQcHardnessIotService; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * [硬度检测数据IOT] 服务实现类 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +@Service +@Data +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Slf4j +public class QcHardnessIotServiceImpl extends ServiceImpl implements IQcHardnessIotService { + + @Override + public void pushHardness(JSONArray dataArray) { + // 存储需要的字段:hardnessValue列表、IP、deviceCode + List hardnessValues = new ArrayList<>(); + List ipList = new ArrayList<>(); + List deviceCodeList = new ArrayList<>(); + + // 遍历数组提取所需数据 + for (Object obj : dataArray) { + if (!(obj instanceof JSONObject)) { + log.error("数组中包含非JSON对象元素: {}", obj); + continue; + } + + JSONObject data = (JSONObject) obj; + // 提取largeEquipment对象 + JSONObject largeEquipment = data.getJSONObject("largeEquipment"); + if (largeEquipment == null) { + log.warn("未找到largeEquipment字段,跳过当前数据: {}", data); + continue; + } + + // 提取deviceCode并添加到列表 + String deviceCode = largeEquipment.getString("deviceCode"); + if (StringUtils.isNotBlank(deviceCode)) { + deviceCodeList.add(deviceCode); + } + + // 提取IP并添加到列表 + String ip = largeEquipment.getString("IP"); + if (StringUtils.isNotBlank(ip)) { + ipList.add(ip); + } + + // 提取parameter_Values中的hardnessValue + JSONArray paramValuesArray = largeEquipment.getJSONArray("parameter_Values"); + if (paramValuesArray == null) { + log.warn("parameter_Values字段为空,跳过当前数据"); + continue; + } + + // 遍历每个参数值字符串,解析JSON并提取hardnessValue + for (Object paramValObj : paramValuesArray) { + String paramValStr = paramValObj.toString(); + try { + JSONObject paramValJson = JSONObject.parseObject(paramValStr); + Double hardnessValue = paramValJson.getDouble("hardnessValue"); + if (hardnessValue != null) { + hardnessValues.add(hardnessValue); + } else { + log.warn("当前参数中未找到hardnessValue: {}", paramValStr); + } + } catch (Exception e) { + log.error("解析parameter_Values元素失败: {},错误信息: {}", paramValStr, e.getMessage(), e); + } + } + } + + // 处理合并后的数据 + processMergedData(deviceCodeList, ipList, hardnessValues); + } + + /** + * 处理合并后的三个列表数据 + */ + private void processMergedData(List deviceCodeList, List ipList, List hardnessValues) { + // 获取核心字段 + String deviceCode = deviceCodeList.isEmpty() ? "" : deviceCodeList.get(0); + String ip = ipList.isEmpty() ? "" : ipList.get(0); + + if (StringUtils.isBlank(deviceCode)) { + log.warn("未获取到有效设备编码,终止数据处理"); + return; + } + + // 格式化hardnessValue为"hv 值1-值2-值3"格式 + String formattedHardness; + if (hardnessValues.isEmpty()) { + formattedHardness = "hv "; + log.warn("未提取到任何hardnessValue值"); + } else { + List hardnessStrList = new ArrayList<>(); + for (Double hv : hardnessValues) { + hardnessStrList.add(String.valueOf(hv)); + } + formattedHardness = "hv " + String.join("-", hardnessStrList); + } + + // 构建存储的JSON对象 + JSONObject formattedJson = new JSONObject(); + formattedJson.put("formatted_hardness", formattedHardness); + String dataContentStr = formattedJson.toJSONString(); + + // 数据去重检查 + QcHardnessIot duplicateData = baseMapper.getDataByDeviceCodeAndDataContent(deviceCode, dataContentStr); + if (duplicateData != null) { + log.info("已存在相同设备编码+相同硬度数据的记录,无需重复存储"); + return; + } + + // 将同设备编码下所有未读记录标记为超时未读 + baseMapper.updateAllToRead(deviceCode); + + // 新增记录 + QcHardnessIot entity = new QcHardnessIot(); + entity.setCreateTime(new Date()); + entity.setNotUse(2); + entity.setDataContent(dataContentStr); + entity.setDeviceCode(deviceCode); + entity.setIp(ip); + entity.setIsRead(0); + save(entity); + + log.info("新增硬度数据成功,设备编码:{},IP:{},格式化硬度值:{}", deviceCode, ip, formattedHardness); + } +} \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcThicknessIotServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcThicknessIotServiceImpl.java new file mode 100644 index 00000000..771b21e1 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcThicknessIotServiceImpl.java @@ -0,0 +1,67 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springblade.desk.quality.mapper.QcThicknessIotMapper; +import org.springblade.desk.quality.pojo.entity.QcThicknessIot; +import org.springblade.desk.quality.pojo.vo.QcThicknessIotVO; +import org.springblade.desk.quality.service.IQcThicknessIotService; +import org.springframework.stereotype.Service; + +import java.util.Date; + +/** + * [QC测厚IOT] 服务实现类 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +@Service +@Data +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Slf4j +public class QcThicknessIotServiceImpl extends ServiceImpl implements IQcThicknessIotService { + + @Override + public IPage selectQcThicknessIotPage(IPage page, QcThicknessIotVO qcThicknessIot) { + return page.setRecords(baseMapper.selectQcThicknessIotPage(page, qcThicknessIot)); + } + + @Override + public void setVOValue(QcThicknessIotVO vo) { + + } + + @Override + public void pushThickness(JSONObject data) { + String deviceCode = data.getString("devId"); + String fileTime = data.getString("filetime"); + + // 查询是否已存在相同设备编码和文件时间的记录 + QcThicknessIot existing = baseMapper.getDataByFileTime(deviceCode, fileTime); + if (existing != null && existing.getQtId() != null) { + log.info("测厚数据已存在,跳过: deviceCode={}, fileTime={}", deviceCode, fileTime); + return; + } + + // 新增记录 + QcThicknessIot entity = new QcThicknessIot(); + entity.setDeviceCode(deviceCode); + entity.setFiletime(fileTime); + entity.setDataContent(data.toJSONString()); + entity.setCreateTime(new Date()); + entity.setNotUse(2); + save(entity); + + log.info("iot系统推送测厚数据: deviceCode={}, fileTime={}, data={}", deviceCode, fileTime, data.toJSONString()); + } +} \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcWithstandVoltageIotServiceImpl.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcWithstandVoltageIotServiceImpl.java new file mode 100644 index 00000000..f5f25294 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcWithstandVoltageIotServiceImpl.java @@ -0,0 +1,156 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.service.impl; + +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springblade.desk.quality.mapper.QcWithstandVoltageIotMapper; +import org.springblade.desk.quality.pojo.entity.QcWithstandVoltageIot; +import org.springblade.desk.quality.service.IQcWithstandVoltageIotService; +import org.springframework.stereotype.Service; + +import java.util.Date; + +/** + * [耐压检测数据IOT] 服务实现类 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +@Service +@Data +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Slf4j +public class QcWithstandVoltageIotServiceImpl extends ServiceImpl implements IQcWithstandVoltageIotService { + + @Override + public void pushWithstandVoltage(JSONObject data) { + if (data == null) { + log.error("推送的耐压检测数据为空,终止处理"); + return; + } + + // 取出 testResult 数组 + JSONArray testResultArr = data.getJSONArray("testResult"); + if (testResultArr == null || testResultArr.isEmpty()) { + log.warn("testResult 数组为空,数据内容:{}", data.toJSONString()); + return; + } + + JSONObject firstItem = testResultArr.getJSONObject(0); + if (firstItem == null) { + log.warn("testResult[0] 不是有效 JSON 对象,数据内容:{}", data.toJSONString()); + return; + } + + // 提取基础字段 + String deviceCode = StringUtils.defaultString(firstItem.getString("Equipment_code")).trim(); + String woCode = StringUtils.defaultString(firstItem.getString("Workorder_code")).trim(); + String testTime = StringUtils.defaultString(firstItem.getString("Test_time")).trim(); + + if (StringUtils.isBlank(deviceCode)) { + log.warn("耐压检测数据缺少 Equipment_code 字段,数据内容:{}", data.toJSONString()); + return; + } + + // 提取 Parameter_values + JSONArray paramValuesArray = firstItem.getJSONArray("Parameter_values"); + if (paramValuesArray == null || paramValuesArray.isEmpty()) { + log.warn("设备编码 {} 的 Parameter_values 字段为空,无法解析参数", deviceCode); + return; + } + + // 定义需要解析的参数变量 + String resistanceLowerLimit = ""; + String resistanceLowerUnit = ""; + String resistanceUpperLimit = ""; + String resistanceUpperUnit = ""; + String leakageCurrentUpperLimit = ""; + String leakageCurrentUpperUnit = ""; + + // 遍历参数数组提取目标参数 + for (Object paramObj : paramValuesArray) { + if (!(paramObj instanceof JSONObject)) { + log.warn("Parameter_values中包含非JSON对象元素: {}", paramObj); + continue; + } + + JSONObject paramJson = (JSONObject) paramObj; + String paramName = StringUtils.defaultString(paramJson.getString("Parameter_name")).trim(); + String paramValue = StringUtils.defaultString(paramJson.getString("Parameter_value")).trim(); + String paramUnit = StringUtils.defaultString(paramJson.getString("Parameter_unit")).trim(); + + if ("resistanceLowerLimit".equals(paramName)) { + resistanceLowerLimit = paramValue; + resistanceLowerUnit = paramUnit; + } else if ("resistanceUpperLimit".equals(paramName)) { + resistanceUpperLimit = paramValue; + resistanceUpperUnit = paramUnit; + } else if ("leakageCurrentUpperLimit".equals(paramName)) { + leakageCurrentUpperLimit = paramValue; + leakageCurrentUpperUnit = paramUnit; + } + } + + // 拼接RES_RANGE(电阻上下限:值+单位-值+单位) + String resRange = ""; + if (StringUtils.isNotBlank(resistanceLowerLimit) && StringUtils.isNotBlank(resistanceUpperLimit)) { + resRange = resistanceLowerLimit + resistanceLowerUnit + "-" + resistanceUpperLimit + resistanceUpperUnit; + } else { + log.warn("设备编码{}的电阻上下限参数不完整(下限:{},上限:{})", + deviceCode, resistanceLowerLimit, resistanceUpperLimit); + } + + // 拼接CUR_CONTENT(漏电流上限:<值+单位,无击穿,无飞弧) + String curContent = ""; + if (StringUtils.isNotBlank(leakageCurrentUpperLimit)) { + curContent = "<" + leakageCurrentUpperLimit + leakageCurrentUpperUnit + ",无击穿,无飞弧"; + } else { + log.warn("设备编码{}的漏电流上限参数缺失", deviceCode); + } + + // 处理数据入库 + processWithstandVoltageData(deviceCode, woCode, testTime, resRange, curContent); + } + + private void processWithstandVoltageData(String deviceCode, String woCode, String testTime, + String resRange, String curContent) { + // 按工单号查重 + QcWithstandVoltageIot duplicateData = null; + if (StringUtils.isNotBlank(woCode)) { + duplicateData = baseMapper.getDataByWoCode(woCode); + } + + if (duplicateData != null) { + log.info("已存在相同工单号的耐压数据记录,无需重复存储,工单号:{}", woCode); + return; + } + + // 将同工单号的旧未读记录标记为超时未读 + if (StringUtils.isNotBlank(woCode)) { + baseMapper.updateAllToReadByWoCode(woCode); + } + + // 新增记录 + QcWithstandVoltageIot entity = new QcWithstandVoltageIot(); + entity.setCreateTime(new Date()); + entity.setDeviceCode(deviceCode); + entity.setWoCode(woCode); + entity.setTestTime(testTime); + entity.setResRange(resRange); + entity.setCurContent(curContent); + entity.setIsRead(0); + save(entity); + + log.info("新增耐压检测数据成功,工单号:{},设备编码:{},检测时间:{},电阻范围:{},检测内容:{}", + woCode, deviceCode, testTime, resRange, curContent); + } +} \ No newline at end of file diff --git a/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/wrapper/QcThicknessIotWrapper.java b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/wrapper/QcThicknessIotWrapper.java new file mode 100644 index 00000000..4cbe62b2 --- /dev/null +++ b/blade-service/blade-desk/src/main/java/org/springblade/desk/quality/wrapper/QcThicknessIotWrapper.java @@ -0,0 +1,31 @@ +/** + * Author: Tom Shuo + */ +package org.springblade.desk.quality.wrapper; + +import org.springblade.core.mp.support.BaseEntityWrapper; +import org.springblade.core.tool.utils.BeanUtil; +import org.springblade.desk.quality.pojo.entity.QcThicknessIot; +import org.springblade.desk.quality.pojo.vo.QcThicknessIotVO; + +import java.util.Objects; + +/** + * [QC测厚IOT] 包装类,返回视图层所需的字段 + * + * @author Tom Shuo + * @since 2026-04-16 + */ +public class QcThicknessIotWrapper extends BaseEntityWrapper { + + public static QcThicknessIotWrapper build() { + return new QcThicknessIotWrapper(); + } + + @Override + public QcThicknessIotVO entityVO(QcThicknessIot qcThicknessIot) { + QcThicknessIotVO VO = Objects.requireNonNull(BeanUtil.copyProperties(qcThicknessIot, QcThicknessIotVO.class)); + + return VO; + } +} \ No newline at end of file