This commit is contained in:
2026-05-21 16:35:07 +08:00
11 changed files with 1335 additions and 1 deletions

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,359 @@
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);
}
if (apiRows == null || apiRows.isEmpty()) {
Map<String, Object> result = new HashMap<>();
result.put("totalFetched", 0);
result.put("insertCount", 0);
result.put("updateCount", 0);
result.put("fullSync", isFullSync);
return result;
}
int insertCount = 0;
int updateCount = 0;
Date now = new Date();
// 1. 批量转换所有数据
List<MesExCoil> allEntities = new ArrayList<>(apiRows.size());
for (Map<String, Object> row : apiRows) {
MesExCoil entity = mapRowToEntity(row);
entity.setSyncTime(now);
allEntities.add(entity);
}
// // 2. 收集所有 excoilid
// List<String> excoilids = allEntities.stream()
// .map(MesExCoil::getExcoilid)
// .filter(StringUtils::isNotBlank)
// .distinct()
// .collect(java.util.stream.Collectors.toList());
// // 3. 批量查询已存在的记录
// Map<String, MesExCoil> existingMap = new HashMap<>();
// if (!excoilids.isEmpty()) {
// LambdaQueryWrapper<MesExCoil> wrapper = Wrappers.lambdaQuery();
// wrapper.in(MesExCoil::getExcoilid, excoilids);
// List<MesExCoil> existingList = baseMapper.selectList(wrapper);
// existingMap = existingList.stream()
// .collect(java.util.stream.Collectors.toMap(MesExCoil::getExcoilid, v -> v, (a, b) -> a));
// }
// 4. 分离新增和更新的记录
List<MesExCoil> toInsert = new ArrayList<>();
// List<MesExCoil> toUpdate = new ArrayList<>();
for (MesExCoil entity : allEntities) {
// MesExCoil existing = existingMap.get(entity.getExcoilid());
// if (existing != null) {
// // 更新:设置主键
// entity.setExId(existing.getExId());
// toUpdate.add(entity);
// } else {
// 新增
toInsert.add(entity);
// }
}
// 5. 批量插入
if (!toInsert.isEmpty()) {
// 分批插入每批500条
int batchSize = 500;
for (int i = 0; i < toInsert.size(); i += batchSize) {
int end = Math.min(i + batchSize, toInsert.size());
List<MesExCoil> batch = toInsert.subList(i, end);
baseMapper.insertBatch(batch);
}
insertCount = toInsert.size();
}
// // 6. 批量更新
// if (!toUpdate.isEmpty()) {
// // 分批更新每批500条
// int batchSize = 500;
// for (int i = 0; i < toUpdate.size(); i += batchSize) {
// int end = Math.min(i + batchSize, toUpdate.size());
// List<MesExCoil> batch = toUpdate.subList(i, end);
// baseMapper.updateBatchById(batch, batch.size());
// }
// updateCount = toUpdate.size();
// }
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;
}
}
}