feat(excoil): 添加出口卷数据同步功能

- 新增 MesExCoil 实体类定义数据库表结构
- 创建 MesExCoilBo 业务对象用于数据传输
- 实现 IMesExCoilService 接口及 MesExCoilServiceImpl 服务类
- 添加 MesExCoilController 控制器提供 REST API 接口
- 集成 MyBatis Plus 持久层框架实现数据库操作
- 实现出入口厚度、宽度、重量等完整字段映射
- 添加同步 L2 系统出口卷实绩数据功能
- 支持首次全量同步和后续增量同步模式
- 实现数据校验、分页查询、导出等功能
- 配置数据写入时间和同步时间字段处理
This commit is contained in:
2026-05-21 15:26:46 +08:00
parent 52cbc21088
commit baed852ff4
11 changed files with 1279 additions and 1 deletions

View File

@@ -428,6 +428,21 @@ public class SqlServerApiClient {
return executeSql("oracle", sql.toString(), params);
}
public ExecuteSqlResponse queryExcoilByInsdateRange(String startTime, String endTime) {
Map<String, Object> params = new java.util.HashMap<>();
StringBuilder sql = new StringBuilder("SELECT * FROM JXPLTCM.PLTCM_PDO_EXCOIL WHERE 1=1");
if (startTime != null && !startTime.trim().isEmpty()) {
sql.append(" AND INSDATE > TO_DATE(:startTime, 'YYYY-MM-DD HH24:MI:SS')");
params.put("startTime", startTime.trim());
}
if (endTime != null && !endTime.trim().isEmpty()) {
sql.append(" AND INSDATE <= TO_DATE(:endTime, 'YYYY-MM-DD HH24:MI:SS')");
params.put("endTime", endTime.trim());
}
sql.append(" ORDER BY INSDATE ASC");
return executeSql("oracle", sql.toString(), params);
}
public ExecuteSqlResponse queryExcoilList(int page, int pageSize) {
int endRow = page * pageSize;
int startRow = endRow - pageSize;

View File

@@ -161,6 +161,13 @@ public class SqlServerApiBusinessService {
return asRowList(client.queryExcoilByTimeRange(startTime, endTime));
}
/**
* 出口卷实绩列表(按数据写入时间),用于增量同步。
*/
public List<Map<String, Object>> getExcoilByInsdateRange(String startTime, String endTime) {
return asRowList(client.queryExcoilByInsdateRange(startTime, endTime));
}
/**
* 出口卷实绩列表(分页),来自 PLTCM_PDO_EXCOIL。
*/

View File

@@ -156,7 +156,7 @@ public class SqlServerApiController {
}
/**
* 出口卷实绩列表(按时间),来自 PLTCM_PDO_EXCOIL。
* 出口卷实绩列表(按下线时间),来自 PLTCM_PDO_EXCOIL。
* startTime / endTime 格式yyyy-MM-dd HH:mm:ss
*/
@GetMapping("/excoil/by-time")
@@ -166,6 +166,17 @@ public class SqlServerApiController {
return R.ok(businessService.getExcoilByTimeRange(startTime, endTime));
}
/**
* 出口卷实绩列表(按数据写入时间),用于增量同步。
* startTimeexclusive/ endTimeinclusive格式yyyy-MM-dd HH:mm:ss
*/
@GetMapping("/excoil/by-insdate")
public R<List<Map<String, Object>>> excoilByInsdate(
@RequestParam(required = false) String startTime,
@RequestParam(required = false) String endTime) {
return R.ok(businessService.getExcoilByInsdateRange(startTime, endTime));
}
/**
* 出口卷实绩列表(分页),来自 PLTCM_PDO_EXCOIL。
*/

View File

@@ -0,0 +1,112 @@
package com.klp.mes.excoil.controller;
import java.util.List;
import java.util.Arrays;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.klp.common.annotation.RepeatSubmit;
import com.klp.common.annotation.Log;
import com.klp.common.core.controller.BaseController;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.domain.R;
import com.klp.common.core.validate.AddGroup;
import com.klp.common.core.validate.EditGroup;
import com.klp.common.enums.BusinessType;
import com.klp.common.utils.poi.ExcelUtil;
import com.klp.mes.excoil.domain.vo.MesExCoilVo;
import com.klp.mes.excoil.domain.bo.MesExCoilBo;
import com.klp.mes.excoil.service.IMesExCoilService;
import com.klp.common.core.page.TableDataInfo;
/**
* 出口卷数据同步
*
* @author klp
* @date 2026-05-21
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/excoil/exCoil")
public class MesExCoilController extends BaseController {
private final IMesExCoilService iMesExCoilService;
/**
* 查询出口卷数据同步列表
*/
@GetMapping("/list")
public TableDataInfo<MesExCoilVo> list(MesExCoilBo bo, PageQuery pageQuery) {
return iMesExCoilService.queryPageList(bo, pageQuery);
}
/**
* 导出出口卷数据同步列表
*/
@Log(title = "出口卷数据同步", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(MesExCoilBo bo, HttpServletResponse response) {
List<MesExCoilVo> list = iMesExCoilService.queryList(bo);
ExcelUtil.exportExcel(list, "出口卷数据同步", MesExCoilVo.class, response);
}
/**
* 获取出口卷数据同步详细信息
*
* @param exId 主键
*/
@GetMapping("/{exId}")
public R<MesExCoilVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long exId) {
return R.ok(iMesExCoilService.queryById(exId));
}
/**
* 新增出口卷数据同步
*/
@Log(title = "出口卷数据同步", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody MesExCoilBo bo) {
return toAjax(iMesExCoilService.insertByBo(bo));
}
/**
* 修改出口卷数据同步
*/
@Log(title = "出口卷数据同步", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody MesExCoilBo bo) {
return toAjax(iMesExCoilService.updateByBo(bo));
}
/**
* 删除出口卷数据同步
*
* @param exIds 主键串
*/
@Log(title = "出口卷数据同步", businessType = BusinessType.DELETE)
@DeleteMapping("/{exIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] exIds) {
return toAjax(iMesExCoilService.deleteWithValidByIds(Arrays.asList(exIds), true));
}
/**
* 从 L2 系统同步出口卷实绩数据。
* 首次全量同步,后续增量同步(以 insdate 为锚点)。
*/
@Log(title = "出口卷数据同步", businessType = BusinessType.OTHER)
@RepeatSubmit(interval = 300000, message = "同步任务已提交,请勿重复操作")
@PostMapping("/sync")
public R<Map<String, Object>> sync() {
Map<String, Object> result = iMesExCoilService.syncExCoilData();
return R.ok(result);
}
}

View File

@@ -0,0 +1,196 @@
package com.klp.mes.excoil.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 出口卷数据同步对象 mes_ex_coil
*
* @author klp
* @date 2026-05-21
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("mes_ex_coil")
public class MesExCoil extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* 主键ID
*/
@TableId(value = "ex_id")
private Long exId;
/**
* 出口卷号(唯一标识)
*/
private String excoilid;
/**
* 入口卷号
*/
private String encoilid;
/**
* 热卷号
*/
private String hotCoilid;
/**
* 钢种
*/
private String grade;
/**
* 订单质量
*/
private String orderQuality;
/**
* 产品类型
*/
private String productType;
/**
* 状态
*/
private String status;
/**
* 班次
*/
private String shift;
/**
* 包装类型
*/
private String parkType;
/**
* 切边类型
*/
private String sideTrim;
/**
* 入口厚度
*/
private BigDecimal entryThick;
/**
* 入口宽度
*/
private BigDecimal entryWidth;
/**
* 入口重量
*/
private BigDecimal entryWeight;
/**
* 使用入口重量
*/
private BigDecimal usedEntryWeight;
/**
* 出口厚度
*/
private BigDecimal exitThick;
/**
* 出口宽度
*/
private BigDecimal exitWidth;
/**
* 出口长度
*/
private BigDecimal exitLength;
/**
* 出口重量
*/
private BigDecimal exitWeight;
/**
* 计算出口重量
*/
private BigDecimal calcExitWeight;
/**
* 实测出口重量
*/
private BigDecimal measExitWeight;
/**
* 出口正偏差
*/
private BigDecimal exitPosDev;
/**
* 出口负偏差
*/
private BigDecimal exitNegDev;
/**
* 内径
*/
private BigDecimal innerDiameter;
/**
* 外径
*/
private BigDecimal outerDiameter;
/**
* 头部位置
*/
private BigDecimal headpos;
/**
* 尾部位置
*/
private BigDecimal tailpos;
/**
* 质量
*/
private BigDecimal quality;
/**
* 板形质量
*/
private BigDecimal shapeQuality;
/**
* 机组
*/
private String crew;
/**
* 报告标志
*/
private Long reportFlag;
/**
* 子ID
*/
private Long subid;
/**
* 序号
*/
private Long rn;
/**
* 上线时间
*/
private Date onlineDate;
/**
* 开始时间
*/
private Date startDate;
/**
* 结束时间
*/
private Date endDate;
/**
* 焊接时间
*/
private Date weldedDate;
/**
* 数据写入时间(来源系统)
*/
private Date insdate;
/**
* 同步时间
*/
private Date syncTime;
/**
* 同步备注
*/
private String comments;
/**
* 备注
*/
private String remark;
/**
* 删除标识 0正常 2删除
*/
@TableLogic
private Long delFlag;
}

View File

@@ -0,0 +1,229 @@
package com.klp.mes.excoil.domain.bo;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 出口卷数据同步业务对象 mes_ex_coil
*
* @author klp
* @date 2026-05-21
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class MesExCoilBo extends BaseEntity {
/**
* 主键ID
*/
private Long exId;
/**
* 出口卷号(唯一标识)
*/
private String excoilid;
/**
* 入口卷号
*/
private String encoilid;
/**
* 热卷号
*/
private String hotCoilid;
/**
* 钢种
*/
private String grade;
/**
* 订单质量
*/
private String orderQuality;
/**
* 产品类型
*/
private String productType;
/**
* 状态
*/
private String status;
/**
* 班次
*/
private String shift;
/**
* 包装类型
*/
private String parkType;
/**
* 切边类型
*/
private String sideTrim;
/**
* 入口厚度
*/
private BigDecimal entryThick;
/**
* 入口宽度
*/
private BigDecimal entryWidth;
/**
* 入口重量
*/
private BigDecimal entryWeight;
/**
* 使用入口重量
*/
private BigDecimal usedEntryWeight;
/**
* 出口厚度
*/
private BigDecimal exitThick;
/**
* 出口宽度
*/
private BigDecimal exitWidth;
/**
* 出口长度
*/
private BigDecimal exitLength;
/**
* 出口重量
*/
private BigDecimal exitWeight;
/**
* 计算出口重量
*/
private BigDecimal calcExitWeight;
/**
* 实测出口重量
*/
private BigDecimal measExitWeight;
/**
* 出口正偏差
*/
private BigDecimal exitPosDev;
/**
* 出口负偏差
*/
private BigDecimal exitNegDev;
/**
* 内径
*/
private BigDecimal innerDiameter;
/**
* 外径
*/
private BigDecimal outerDiameter;
/**
* 头部位置
*/
private BigDecimal headpos;
/**
* 尾部位置
*/
private BigDecimal tailpos;
/**
* 质量
*/
private BigDecimal quality;
/**
* 板形质量
*/
private BigDecimal shapeQuality;
/**
* 机组
*/
private String crew;
/**
* 报告标志
*/
private Long reportFlag;
/**
* 子ID
*/
private Long subid;
/**
* 序号
*/
private Long rn;
/**
* 上线时间
*/
private Date onlineDate;
/**
* 开始时间
*/
private Date startDate;
/**
* 结束时间
*/
private Date endDate;
/**
* 焊接时间
*/
private Date weldedDate;
/**
* 数据写入时间(来源系统)
*/
private Date insdate;
/**
* 同步时间
*/
private Date syncTime;
/**
* 同步备注
*/
private String comments;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,272 @@
package com.klp.mes.excoil.domain.vo;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.klp.common.annotation.ExcelDictFormat;
import com.klp.common.convert.ExcelDictConvert;
import lombok.Data;
/**
* 出口卷数据同步视图对象 mes_ex_coil
*
* @author klp
* @date 2026-05-21
*/
@Data
@ExcelIgnoreUnannotated
public class MesExCoilVo {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long exId;
/**
* 出口卷号(唯一标识)
*/
@ExcelProperty(value = "出口卷号(唯一标识)")
private String excoilid;
/**
* 入口卷号
*/
@ExcelProperty(value = "入口卷号")
private String encoilid;
/**
* 热卷号
*/
@ExcelProperty(value = "热卷号")
private String hotCoilid;
/**
* 钢种
*/
@ExcelProperty(value = "钢种")
private String grade;
/**
* 订单质量
*/
@ExcelProperty(value = "订单质量")
private String orderQuality;
/**
* 产品类型
*/
@ExcelProperty(value = "产品类型")
private String productType;
/**
* 状态
*/
@ExcelProperty(value = "状态")
private String status;
/**
* 班次
*/
@ExcelProperty(value = "班次")
private String shift;
/**
* 包装类型
*/
@ExcelProperty(value = "包装类型")
private String parkType;
/**
* 切边类型
*/
@ExcelProperty(value = "切边类型")
private String sideTrim;
/**
* 入口厚度
*/
@ExcelProperty(value = "入口厚度")
private BigDecimal entryThick;
/**
* 入口宽度
*/
@ExcelProperty(value = "入口宽度")
private BigDecimal entryWidth;
/**
* 入口重量
*/
@ExcelProperty(value = "入口重量")
private BigDecimal entryWeight;
/**
* 使用入口重量
*/
@ExcelProperty(value = "使用入口重量")
private BigDecimal usedEntryWeight;
/**
* 出口厚度
*/
@ExcelProperty(value = "出口厚度")
private BigDecimal exitThick;
/**
* 出口宽度
*/
@ExcelProperty(value = "出口宽度")
private BigDecimal exitWidth;
/**
* 出口长度
*/
@ExcelProperty(value = "出口长度")
private BigDecimal exitLength;
/**
* 出口重量
*/
@ExcelProperty(value = "出口重量")
private BigDecimal exitWeight;
/**
* 计算出口重量
*/
@ExcelProperty(value = "计算出口重量")
private BigDecimal calcExitWeight;
/**
* 实测出口重量
*/
@ExcelProperty(value = "实测出口重量")
private BigDecimal measExitWeight;
/**
* 出口正偏差
*/
@ExcelProperty(value = "出口正偏差")
private BigDecimal exitPosDev;
/**
* 出口负偏差
*/
@ExcelProperty(value = "出口负偏差")
private BigDecimal exitNegDev;
/**
* 内径
*/
@ExcelProperty(value = "内径")
private BigDecimal innerDiameter;
/**
* 外径
*/
@ExcelProperty(value = "外径")
private BigDecimal outerDiameter;
/**
* 头部位置
*/
@ExcelProperty(value = "头部位置")
private BigDecimal headpos;
/**
* 尾部位置
*/
@ExcelProperty(value = "尾部位置")
private BigDecimal tailpos;
/**
* 质量
*/
@ExcelProperty(value = "质量")
private BigDecimal quality;
/**
* 板形质量
*/
@ExcelProperty(value = "板形质量")
private BigDecimal shapeQuality;
/**
* 机组
*/
@ExcelProperty(value = "机组")
private String crew;
/**
* 报告标志
*/
@ExcelProperty(value = "报告标志")
private Long reportFlag;
/**
* 子ID
*/
@ExcelProperty(value = "子ID")
private Long subid;
/**
* 序号
*/
@ExcelProperty(value = "序号")
private Long rn;
/**
* 上线时间
*/
@ExcelProperty(value = "上线时间")
private Date onlineDate;
/**
* 开始时间
*/
@ExcelProperty(value = "开始时间")
private Date startDate;
/**
* 结束时间
*/
@ExcelProperty(value = "结束时间")
private Date endDate;
/**
* 焊接时间
*/
@ExcelProperty(value = "焊接时间")
private Date weldedDate;
/**
* 数据写入时间(来源系统)
*/
@ExcelProperty(value = "数据写入时间(来源系统)")
private Date insdate;
/**
* 同步时间
*/
@ExcelProperty(value = "同步时间")
private Date syncTime;
/**
* 同步备注
*/
@ExcelProperty(value = "同步备注")
private String comments;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,17 @@
package com.klp.mes.excoil.mapper;
import com.klp.mes.excoil.domain.MesExCoil;
import com.klp.mes.excoil.domain.vo.MesExCoilVo;
import com.klp.common.core.mapper.BaseMapperPlus;
import java.util.Date;
/**
* 出口卷数据同步Mapper接口
*
* @author klp
* @date 2026-05-21
*/
public interface MesExCoilMapper extends BaseMapperPlus<MesExCoilMapper, MesExCoil, MesExCoilVo> {
Date getMaxInsdate();
}

View File

@@ -0,0 +1,55 @@
package com.klp.mes.excoil.service;
import com.klp.mes.excoil.domain.MesExCoil;
import com.klp.mes.excoil.domain.vo.MesExCoilVo;
import com.klp.mes.excoil.domain.bo.MesExCoilBo;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 出口卷数据同步Service接口
*
* @author klp
* @date 2026-05-21
*/
public interface IMesExCoilService {
/**
* 查询出口卷数据同步
*/
MesExCoilVo queryById(Long exId);
/**
* 查询出口卷数据同步列表
*/
TableDataInfo<MesExCoilVo> queryPageList(MesExCoilBo bo, PageQuery pageQuery);
/**
* 查询出口卷数据同步列表
*/
List<MesExCoilVo> queryList(MesExCoilBo bo);
/**
* 新增出口卷数据同步
*/
Boolean insertByBo(MesExCoilBo bo);
/**
* 修改出口卷数据同步
*/
Boolean updateByBo(MesExCoilBo bo);
/**
* 校验并批量删除出口卷数据同步信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 从 L2 系统同步出口卷实绩数据
*/
Map<String, Object> syncExCoilData();
}

View File

@@ -0,0 +1,303 @@
package com.klp.mes.excoil.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.klp.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.klp.mes.excoil.domain.bo.MesExCoilBo;
import com.klp.mes.excoil.domain.vo.MesExCoilVo;
import com.klp.mes.excoil.domain.MesExCoil;
import com.klp.mes.excoil.mapper.MesExCoilMapper;
import com.klp.mes.excoil.service.IMesExCoilService;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RequiredArgsConstructor
@Service
public class MesExCoilServiceImpl implements IMesExCoilService {
private final MesExCoilMapper baseMapper;
@Value("${server.port:8080}")
private int serverPort;
private RestTemplate restTemplate;
private RestTemplate getRestTemplate() {
if (restTemplate == null) {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(5000);
factory.setReadTimeout(600000);
restTemplate = new RestTemplate(factory);
}
return restTemplate;
}
private String getInternalApiBaseUrl() {
return "http://127.0.0.1:" + serverPort;
}
@Override
public MesExCoilVo queryById(Long exId){
return baseMapper.selectVoById(exId);
}
@Override
public TableDataInfo<MesExCoilVo> queryPageList(MesExCoilBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<MesExCoil> lqw = buildQueryWrapper(bo);
Page<MesExCoilVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<MesExCoilVo> queryList(MesExCoilBo bo) {
LambdaQueryWrapper<MesExCoil> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<MesExCoil> buildQueryWrapper(MesExCoilBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<MesExCoil> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getExcoilid()), MesExCoil::getExcoilid, bo.getExcoilid());
lqw.eq(StringUtils.isNotBlank(bo.getEncoilid()), MesExCoil::getEncoilid, bo.getEncoilid());
lqw.eq(StringUtils.isNotBlank(bo.getHotCoilid()), MesExCoil::getHotCoilid, bo.getHotCoilid());
lqw.eq(StringUtils.isNotBlank(bo.getGrade()), MesExCoil::getGrade, bo.getGrade());
lqw.eq(StringUtils.isNotBlank(bo.getOrderQuality()), MesExCoil::getOrderQuality, bo.getOrderQuality());
lqw.eq(StringUtils.isNotBlank(bo.getProductType()), MesExCoil::getProductType, bo.getProductType());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), MesExCoil::getStatus, bo.getStatus());
lqw.eq(StringUtils.isNotBlank(bo.getShift()), MesExCoil::getShift, bo.getShift());
lqw.eq(StringUtils.isNotBlank(bo.getParkType()), MesExCoil::getParkType, bo.getParkType());
lqw.eq(StringUtils.isNotBlank(bo.getSideTrim()), MesExCoil::getSideTrim, bo.getSideTrim());
lqw.eq(bo.getEntryThick() != null, MesExCoil::getEntryThick, bo.getEntryThick());
lqw.eq(bo.getEntryWidth() != null, MesExCoil::getEntryWidth, bo.getEntryWidth());
lqw.eq(bo.getEntryWeight() != null, MesExCoil::getEntryWeight, bo.getEntryWeight());
lqw.eq(bo.getUsedEntryWeight() != null, MesExCoil::getUsedEntryWeight, bo.getUsedEntryWeight());
lqw.eq(bo.getExitThick() != null, MesExCoil::getExitThick, bo.getExitThick());
lqw.eq(bo.getExitWidth() != null, MesExCoil::getExitWidth, bo.getExitWidth());
lqw.eq(bo.getExitLength() != null, MesExCoil::getExitLength, bo.getExitLength());
lqw.eq(bo.getExitWeight() != null, MesExCoil::getExitWeight, bo.getExitWeight());
lqw.eq(bo.getCalcExitWeight() != null, MesExCoil::getCalcExitWeight, bo.getCalcExitWeight());
lqw.eq(bo.getMeasExitWeight() != null, MesExCoil::getMeasExitWeight, bo.getMeasExitWeight());
lqw.eq(bo.getExitPosDev() != null, MesExCoil::getExitPosDev, bo.getExitPosDev());
lqw.eq(bo.getExitNegDev() != null, MesExCoil::getExitNegDev, bo.getExitNegDev());
lqw.eq(bo.getInnerDiameter() != null, MesExCoil::getInnerDiameter, bo.getInnerDiameter());
lqw.eq(bo.getOuterDiameter() != null, MesExCoil::getOuterDiameter, bo.getOuterDiameter());
lqw.eq(bo.getHeadpos() != null, MesExCoil::getHeadpos, bo.getHeadpos());
lqw.eq(bo.getTailpos() != null, MesExCoil::getTailpos, bo.getTailpos());
lqw.eq(bo.getQuality() != null, MesExCoil::getQuality, bo.getQuality());
lqw.eq(bo.getShapeQuality() != null, MesExCoil::getShapeQuality, bo.getShapeQuality());
lqw.eq(StringUtils.isNotBlank(bo.getCrew()), MesExCoil::getCrew, bo.getCrew());
lqw.eq(bo.getReportFlag() != null, MesExCoil::getReportFlag, bo.getReportFlag());
lqw.eq(bo.getSubid() != null, MesExCoil::getSubid, bo.getSubid());
lqw.eq(bo.getRn() != null, MesExCoil::getRn, bo.getRn());
lqw.eq(bo.getOnlineDate() != null, MesExCoil::getOnlineDate, bo.getOnlineDate());
lqw.eq(bo.getStartDate() != null, MesExCoil::getStartDate, bo.getStartDate());
lqw.eq(bo.getEndDate() != null, MesExCoil::getEndDate, bo.getEndDate());
lqw.eq(bo.getWeldedDate() != null, MesExCoil::getWeldedDate, bo.getWeldedDate());
lqw.eq(bo.getInsdate() != null, MesExCoil::getInsdate, bo.getInsdate());
lqw.eq(bo.getSyncTime() != null, MesExCoil::getSyncTime, bo.getSyncTime());
lqw.eq(StringUtils.isNotBlank(bo.getComments()), MesExCoil::getComments, bo.getComments());
return lqw;
}
@Override
public Boolean insertByBo(MesExCoilBo bo) {
MesExCoil add = BeanUtil.toBean(bo, MesExCoil.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setExId(add.getExId());
}
return flag;
}
@Override
public Boolean updateByBo(MesExCoilBo bo) {
MesExCoil update = BeanUtil.toBean(bo, MesExCoil.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
private void validEntityBeforeSave(MesExCoil entity){
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
}
return baseMapper.deleteBatchIds(ids) > 0;
}
@Override
public Map<String, Object> syncExCoilData() {
Date maxInsdate = baseMapper.getMaxInsdate();
boolean isFullSync = (maxInsdate == null);
List<Map<String, Object>> apiRows;
if (isFullSync) {
apiRows = fetchAllFromApi();
} else {
apiRows = fetchIncrementalFromApi(maxInsdate);
}
int insertCount = 0;
int updateCount = 0;
Date now = new Date();
for (Map<String, Object> row : apiRows) {
MesExCoil entity = mapRowToEntity(row);
entity.setSyncTime(now);
LambdaQueryWrapper<MesExCoil> wrapper = Wrappers.lambdaQuery();
wrapper.eq(MesExCoil::getExcoilid, entity.getExcoilid());
MesExCoil existing = baseMapper.selectOne(wrapper);
if (existing != null) {
entity.setExId(existing.getExId());
baseMapper.updateById(entity);
updateCount++;
} else {
baseMapper.insert(entity);
insertCount++;
}
}
Map<String, Object> result = new HashMap<>();
result.put("totalFetched", apiRows.size());
result.put("insertCount", insertCount);
result.put("updateCount", updateCount);
result.put("fullSync", isFullSync);
return result;
}
@SuppressWarnings("unchecked")
private List<Map<String, Object>> fetchAllFromApi() {
List<Map<String, Object>> all = new ArrayList<>();
int page = 1;
int pageSize = 500;
String baseUrl = getInternalApiBaseUrl();
while (true) {
String url = baseUrl + "/sql-server-api/excoil?page=" + page + "&pageSize=" + pageSize;
Map<String, Object> response = getRestTemplate().getForObject(url, Map.class);
if (response == null) break;
Map<String, Object> data = (Map<String, Object>) response.get("data");
if (data == null) break;
List<Map<String, Object>> rows = (List<Map<String, Object>>) data.get("rows");
if (rows == null || rows.isEmpty()) break;
all.addAll(rows);
if (rows.size() < pageSize) break;
page++;
}
return all;
}
@SuppressWarnings("unchecked")
private List<Map<String, Object>> fetchIncrementalFromApi(Date since) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String startTime = sdf.format(since);
String baseUrl = getInternalApiBaseUrl();
String url = baseUrl + "/sql-server-api/excoil/by-insdate?startTime=" + startTime;
Map<String, Object> response = getRestTemplate().getForObject(url, Map.class);
if (response != null && response.get("data") instanceof List) {
return (List<Map<String, Object>>) response.get("data");
}
return new ArrayList<>();
}
private MesExCoil mapRowToEntity(Map<String, Object> row) {
MesExCoil entity = new MesExCoil();
entity.setExcoilid(str(row.get("excoilid")));
entity.setEncoilid(str(row.get("encoilid")));
entity.setHotCoilid(str(row.get("hot_coilid")));
entity.setGrade(str(row.get("grade")));
entity.setOrderQuality(str(row.get("order_quality")));
entity.setProductType(str(row.get("product_type")));
entity.setStatus(str(row.get("status")));
entity.setShift(str(row.get("shift")));
entity.setParkType(str(row.get("park_type")));
entity.setSideTrim(str(row.get("side_trim")));
entity.setEntryThick(bd(row.get("entry_thick")));
entity.setEntryWidth(bd(row.get("entry_width")));
entity.setEntryWeight(bd(row.get("entry_weight")));
entity.setUsedEntryWeight(bd(row.get("used_entry_weight")));
entity.setExitThick(bd(row.get("exit_thick")));
entity.setExitWidth(bd(row.get("exit_width")));
entity.setExitLength(bd(row.get("exit_length")));
entity.setExitWeight(bd(row.get("exit_weight")));
entity.setCalcExitWeight(bd(row.get("calc_exit_weight")));
entity.setMeasExitWeight(bd(row.get("meas_exit_weight")));
entity.setExitPosDev(bd(row.get("exit_pos_dev")));
entity.setExitNegDev(bd(row.get("exit_neg_dev")));
entity.setInnerDiameter(bd(row.get("inner_diameter")));
entity.setOuterDiameter(bd(row.get("outer_diameter")));
entity.setHeadpos(bd(row.get("headpos")));
entity.setTailpos(bd(row.get("tailpos")));
entity.setQuality(bd(row.get("quality")));
entity.setShapeQuality(bd(row.get("shape_quality")));
entity.setCrew(str(row.get("crew")));
entity.setReportFlag(longVal(row.get("report_flag")));
entity.setSubid(longVal(row.get("subid")));
entity.setRn(longVal(row.get("rn")));
entity.setOnlineDate(parseDate(row.get("online_date")));
entity.setStartDate(parseDate(row.get("start_date")));
entity.setEndDate(parseDate(row.get("end_date")));
entity.setWeldedDate(parseDate(row.get("welded_date")));
entity.setInsdate(parseDate(row.get("insdate")));
entity.setComments(str(row.get("comments")));
entity.setRemark(str(row.get("remark")));
return entity;
}
private String str(Object value) {
return value == null ? null : String.valueOf(value);
}
private BigDecimal bd(Object value) {
if (value == null) return null;
if (value instanceof BigDecimal) return (BigDecimal) value;
if (value instanceof Number) return BigDecimal.valueOf(((Number) value).doubleValue());
try { return new BigDecimal(String.valueOf(value)); } catch (Exception e) { return null; }
}
private Long longVal(Object value) {
if (value == null) return null;
if (value instanceof Number) return ((Number) value).longValue();
try { return Long.parseLong(String.valueOf(value)); } catch (Exception e) { return null; }
}
private Date parseDate(Object value) {
if (value == null) return null;
if (value instanceof Date) return (Date) value;
String s = String.valueOf(value);
if (s.isEmpty() || "null".equals(s)) return null;
try {
if (s.contains("T")) {
s = s.replace("T", " ");
if (s.length() > 19) s = s.substring(0, 19);
}
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(s);
} catch (Exception e) {
return null;
}
}
}

View File

@@ -0,0 +1,61 @@
<?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="com.klp.mes.excoil.mapper.MesExCoilMapper">
<resultMap type="com.klp.mes.excoil.domain.MesExCoil" id="MesExCoilResult">
<result property="exId" column="ex_id"/>
<result property="excoilid" column="excoilid"/>
<result property="encoilid" column="encoilid"/>
<result property="hotCoilid" column="hot_coilid"/>
<result property="grade" column="grade"/>
<result property="orderQuality" column="order_quality"/>
<result property="productType" column="product_type"/>
<result property="status" column="status"/>
<result property="shift" column="shift"/>
<result property="parkType" column="park_type"/>
<result property="sideTrim" column="side_trim"/>
<result property="entryThick" column="entry_thick"/>
<result property="entryWidth" column="entry_width"/>
<result property="entryWeight" column="entry_weight"/>
<result property="usedEntryWeight" column="used_entry_weight"/>
<result property="exitThick" column="exit_thick"/>
<result property="exitWidth" column="exit_width"/>
<result property="exitLength" column="exit_length"/>
<result property="exitWeight" column="exit_weight"/>
<result property="calcExitWeight" column="calc_exit_weight"/>
<result property="measExitWeight" column="meas_exit_weight"/>
<result property="exitPosDev" column="exit_pos_dev"/>
<result property="exitNegDev" column="exit_neg_dev"/>
<result property="innerDiameter" column="inner_diameter"/>
<result property="outerDiameter" column="outer_diameter"/>
<result property="headpos" column="headpos"/>
<result property="tailpos" column="tailpos"/>
<result property="quality" column="quality"/>
<result property="shapeQuality" column="shape_quality"/>
<result property="crew" column="crew"/>
<result property="reportFlag" column="report_flag"/>
<result property="subid" column="subid"/>
<result property="rn" column="rn"/>
<result property="onlineDate" column="online_date"/>
<result property="startDate" column="start_date"/>
<result property="endDate" column="end_date"/>
<result property="weldedDate" column="welded_date"/>
<result property="insdate" column="insdate"/>
<result property="syncTime" column="sync_time"/>
<result property="comments" column="comments"/>
<result property="remark" column="remark"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
</resultMap>
<select id="getMaxInsdate" resultType="java.util.Date">
SELECT MAX(insdate) FROM mes_ex_coil
</select>
</mapper>