fen调用bug修复

liweidong
绫Umbrella 1 week ago
parent 0f42ef0b5b
commit d46e120ef1
  1. 4
      blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java
  2. 37
      blade-ops/blade-job/src/main/java/org/springblade/job/processor/produce/ProduceRunProcessor.java
  3. 25
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/produce/feign/IProduceRunClient.java
  4. 22
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/dto/QcThicknessIotDTO.java
  5. 92
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcHardnessIot.java
  6. 66
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcThicknessIot.java
  7. 85
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/entity/QcWithstandVoltageIot.java
  8. 22
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/quality/pojo/vo/QcThicknessIotVO.java
  9. 25
      blade-service/blade-desk/src/main/java/org/springblade/desk/config/MybatisPlusConfig.java
  10. 53
      blade-service/blade-desk/src/main/java/org/springblade/desk/iot/controller/IotWebApiController.java
  11. 27
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/feign/ProduceRunClient.java
  12. 10
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MacToolUseMapper.java
  13. 29
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MacToolUseMapper.xml
  14. 5
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/MesQcProduceRunMapper.java
  15. 7
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/mapper/QcProduceRunMapper.xml
  16. 5
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/IMesQcProduceRunService.java
  17. 254
      blade-service/blade-desk/src/main/java/org/springblade/desk/produce/service/impl/MesQcProduceRunServiceImpl.java
  18. 36
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcHardnessIotMapper.java
  19. 27
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcHardnessIotMapper.xml
  20. 40
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcThicknessIotMapper.java
  21. 30
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcThicknessIotMapper.xml
  22. 35
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcWithstandVoltageIotMapper.java
  23. 26
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/mapper/QcWithstandVoltageIotMapper.xml
  24. 21
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcHardnessIotService.java
  25. 37
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcThicknessIotService.java
  26. 21
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/IQcWithstandVoltageIotService.java
  27. 151
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcHardnessIotServiceImpl.java
  28. 67
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcThicknessIotServiceImpl.java
  29. 156
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/service/impl/QcWithstandVoltageIotServiceImpl.java
  30. 31
      blade-service/blade-desk/src/main/java/org/springblade/desk/quality/wrapper/QcThicknessIotWrapper.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 地址

@ -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());
}
}
}

@ -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();
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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;
}
}

@ -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();
}
}

@ -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;
}
}

@ -33,4 +33,14 @@ public interface MacToolUseMapper extends BaseMapper<MacToolUse> {
List<MesMacToolUseVO> getProcessBingingRec(Long wpId);
GoodsVO getMaterialMess(String goodsCode);
/**
* 查询所有未完成的设备绑定记录含设备分类挂次号设备编码
*/
List<Map<String, Object>> listAllByNoFinished();
/**
* 更新作业计划打印标记类型
*/
void updatePrintType(String deviceCode, String hangNum, String mtnCode);
}

@ -193,4 +193,33 @@
srs.CREATE_TIME DESC) WHERE ROWNUM = 1
</select>
<select id="listAllByNoFinished" resultType="java.util.Map">
SELECT b.DEVICE_CODE AS "deviceCode", b.CATEGORYS AS "categorys", a.HANG_NUM AS "hangNum", a.MTN_CODE AS "mtnCode"
FROM MES_MAC_TOOL_USE a
LEFT JOIN MES_EQUIPMENT b ON a.EQUIPMENT_CARD = b.ID
WHERE a.EQUIPMENT_CARD IS NOT NULL
AND a.BS_FEI_BA_SET IS NOT NULL
AND a.HANG_NUM IS NOT NULL
AND b.CATEGORYS IS NOT NULL
AND a.FINISHED = 0
AND a.is_deleted = 0
GROUP BY b.DEVICE_CODE, b.CATEGORYS, a.HANG_NUM, a.MTN_CODE
</select>
<update id="updatePrintType">
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
<if test="hangNum != null and hangNum != ''">
AND c.HANG_NUM = #{hangNum}
</if>
)
AND (a.PRINT_TYPE IS NULL OR a.PRINT_TYPE != 'process')
</update>
</mapper>

@ -30,4 +30,9 @@ public interface MesQcProduceRunMapper extends BaseMapper<MesQcProduceRunEntity>
List<MesQcProduceRunEntity> listPrByWpIdIndex(Long id, int i, int i1);
List<MesQcProduceRunEntity> listPrByWpId(Long wpId);
/**
* 删除指定设备挂次号同槽编号的生产追溯记录
*/
void deleteProduceRun(@Param("deviceCode") String deviceCode, @Param("hangNum") String hangNum, @Param("mtnCode") String mtnCode);
}

@ -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
</select>
<delete id="deleteProduceRun">
DELETE FROM MES_QC_PRODUCE_RUN
WHERE DEVICE_ID = #{deviceCode}
AND MTN_CODE = #{mtnCode}
AND HANG_NUM = #{hangNum}
</delete>
</mapper>

@ -37,4 +37,9 @@ public interface IMesQcProduceRunService extends BaseService<MesQcProduceRunEnti
List<MesQcProduceRunEntity> listPrByWpIdIndex(Long id, int i, Boolean aTrue);
List<MesQcProduceRunEntity> listPrByWpId(Long id);
/**
* 获取产线相关设备数据定时任务入口
*/
void createProduceRun();
}

@ -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<MesQcProduceRunMapper, MesQcProduceRunEntity> implements IMesQcProduceRunService {
@Override
private final MacToolUseMapper macToolUseMapper;
private final RestTemplate httpClientTemplate;
@Value("${request.iotNew.url}")
private String iotNewUrl;
public IPage<MesQcProduceRunVO> selectMesQcProduceRunPage(IPage<MesQcProduceRunVO> page, MesQcProduceRunVO mesQcProduceRun) {
return page.setRecords(baseMapper.selectMesQcProduceRunPage(page, mesQcProduceRun));
}
@ -50,4 +68,232 @@ public class MesQcProduceRunServiceImpl extends BaseServiceImpl<MesQcProduceRunM
return baseMapper.listPrByWpId(id);
}
}
@Override
public void createProduceRun() {
List<Map<String, Object>> mtuList = macToolUseMapper.listAllByNoFinished();
if (mtuList == null || mtuList.isEmpty()) {
return;
}
long startTime = System.currentTimeMillis();
log.info("获取生产追溯数据任务-开始..., 数量 = {}", mtuList.size());
for (Map<String, Object> 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<JSONObject> entity = new HttpEntity<>(body, headers);
ResponseEntity<JSONObject> 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<JSONObject> entity = new HttpEntity<>(body, headers);
ResponseEntity<JSONObject> 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<JSONObject> 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<String> 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<MesQcProduceRunEntity> existingList = list(Wrappers.<MesQcProduceRunEntity>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;
}
}

@ -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<QcHardnessIot> {
/**
* 根据设备编码和数据内容查询记录去重
*
* @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);
}

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.springblade.desk.quality.mapper.QcHardnessIotMapper">
<!-- 通用查询映射结果 -->
<resultMap id="qcHardnessIotResultMap"
type="org.springblade.desk.quality.pojo.entity.QcHardnessIot">
<id column="QH_ID" property="qhId"/>
<result column="DEVICE_CODE" property="deviceCode"/>
<result column="BATCH_NO" property="batchNo"/>
<result column="FILETIME" property="filetime"/>
<result column="DATA_CONTENT" property="dataContent"/>
<result column="CREATE_TIME" property="createTime"/>
<result column="NOT_USE" property="notUse"/>
<result column="IS_READ" property="isRead"/>
<result column="IP" property="ip"/>
</resultMap>
<select id="getDataByDeviceCodeAndDataContent" resultMap="qcHardnessIotResultMap">
SELECT QH_ID, DEVICE_CODE, BATCH_NO, FILETIME, DATA_CONTENT, CREATE_TIME, NOT_USE, IS_READ, IP
FROM QC_HARDNESS_IOT
WHERE DEVICE_CODE = #{deviceCode} AND DATA_CONTENT = #{dataContent}
FETCH FIRST 1 ROWS ONLY
</select>
</mapper>

@ -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<QcThicknessIot> {
/**
* 自定义分页
*
* @param page 分页参数
* @param qcThicknessIot 查询参数
* @return List<QcThicknessIotVO>
*/
List<QcThicknessIotVO> selectQcThicknessIotPage(IPage page, QcThicknessIotVO qcThicknessIot);
/**
* 根据设备编码和文件时间查询记录
*
* @param deviceCode 设备编码
* @param filetime 文件时间
* @return QcThicknessIot
*/
QcThicknessIot getDataByFileTime(@Param("deviceCode") String deviceCode, @Param("filetime") String filetime);
}

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.springblade.desk.quality.mapper.QcThicknessIotMapper">
<!-- 通用查询映射结果 -->
<resultMap id="qcThicknessIotResultMap"
type="org.springblade.desk.quality.pojo.entity.QcThicknessIot">
<id column="QT_ID" property="qtId"/>
<result column="DEVICE_CODE" property="deviceCode"/>
<result column="FILETIME" property="filetime"/>
<result column="DATA_CONTENT" property="dataContent"/>
<result column="CREATE_TIME" property="createTime"/>
<result column="NOT_USE" property="notUse"/>
</resultMap>
<select id="selectQcThicknessIotPage" resultMap="qcThicknessIotResultMap">
SELECT QT_ID, DEVICE_CODE, FILETIME, DATA_CONTENT, CREATE_TIME, NOT_USE
FROM QC_THICKNESS_IOT
ORDER BY CREATE_TIME DESC
</select>
<select id="getDataByFileTime" resultMap="qcThicknessIotResultMap">
SELECT QT_ID, DEVICE_CODE, FILETIME, DATA_CONTENT, CREATE_TIME, NOT_USE
FROM QC_THICKNESS_IOT
WHERE DEVICE_CODE = #{deviceCode} AND FILETIME = #{filetime}
FETCH FIRST 1 ROWS ONLY
</select>
</mapper>

@ -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<QcWithstandVoltageIot> {
/**
* 根据工单号查询记录去重
*
* @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);
}

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.springblade.desk.quality.mapper.QcWithstandVoltageIotMapper">
<!-- 通用查询映射结果 -->
<resultMap id="qcWithstandVoltageIotResultMap"
type="org.springblade.desk.quality.pojo.entity.QcWithstandVoltageIot">
<id column="QW_ID" property="qwId"/>
<result column="DEVICE_CODE" property="deviceCode"/>
<result column="WO_CODE" property="woCode"/>
<result column="TEST_TIME" property="testTime"/>
<result column="CUR_CONTENT" property="curContent"/>
<result column="RES_RANGE" property="resRange"/>
<result column="CREATE_TIME" property="createTime"/>
<result column="IS_READ" property="isRead"/>
</resultMap>
<select id="getDataByWoCode" resultMap="qcWithstandVoltageIotResultMap">
SELECT QW_ID, DEVICE_CODE, WO_CODE, TEST_TIME, CUR_CONTENT, RES_RANGE, CREATE_TIME, IS_READ
FROM QC_WITHSTAND_VOLTAGE_IOT
WHERE WO_CODE = #{woCode}
FETCH FIRST 1 ROWS ONLY
</select>
</mapper>

@ -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<QcHardnessIot> {
/**
* iot系统推送硬度检测数据
*
* @param dataArray 推送的JSON数组
*/
void pushHardness(JSONArray dataArray);
}

@ -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<QcThicknessIot> {
/**
* 自定义分页
*
* @param page 分页参数
* @param qcThicknessIot 查询参数
* @return IPage<QcThicknessIotVO>
*/
IPage<QcThicknessIotVO> selectQcThicknessIotPage(IPage<QcThicknessIotVO> page, QcThicknessIotVO qcThicknessIot);
/**
* VO
* @param vo
*/
void setVOValue(QcThicknessIotVO vo);
/**
* iot系统推送测厚数据
*
* @param data 推送的JSON数据
*/
void pushThickness(JSONObject data);
}

@ -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<QcWithstandVoltageIot> {
/**
* iot系统推送耐压检测数据
*
* @param data 推送的JSON数据
*/
void pushWithstandVoltage(JSONObject data);
}

@ -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<QcHardnessIotMapper, QcHardnessIot> implements IQcHardnessIotService {
@Override
public void pushHardness(JSONArray dataArray) {
// 存储需要的字段:hardnessValue列表、IP、deviceCode
List<Double> hardnessValues = new ArrayList<>();
List<String> ipList = new ArrayList<>();
List<String> 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<String> deviceCodeList, List<String> ipList, List<Double> 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<String> 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);
}
}

@ -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<QcThicknessIotMapper, QcThicknessIot> implements IQcThicknessIotService {
@Override
public IPage<QcThicknessIotVO> selectQcThicknessIotPage(IPage<QcThicknessIotVO> 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());
}
}

@ -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<QcWithstandVoltageIotMapper, QcWithstandVoltageIot> 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);
}
}

@ -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<QcThicknessIot, QcThicknessIotVO> {
public static QcThicknessIotWrapper build() {
return new QcThicknessIotWrapper();
}
@Override
public QcThicknessIotVO entityVO(QcThicknessIot qcThicknessIot) {
QcThicknessIotVO VO = Objects.requireNonNull(BeanUtil.copyProperties(qcThicknessIot, QcThicknessIotVO.class));
return VO;
}
}
Loading…
Cancel
Save