tjx
2025-10-30 2ecae81fb3ab4057d367650045acc6697567c765
增加条码的持久化逻辑
已修改2个文件
已添加8个文件
616 ■■■■■ 文件已修改
src/main/java/com/gs/xiaomi/dto/BCS101ResponseBody.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/dto/SnListItemDto.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/entity/SnListItem.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/example/SnListItemUsageExample.java 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/mapper/SnListItemMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/SnListItemService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/impl/SnListItemServiceImpl.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/util/SnListItemConverter.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/SnListItemMapper.xml 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/gs/xiaomi/XiaomiApplicationTests.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/dto/BCS101ResponseBody.java
@@ -8,8 +8,11 @@
@Data
public class BCS101ResponseBody {
    /**
     * SN列表
     */
    @JsonProperty("snList")
    private List<String> snList;
    private List<SnListItemDto> snList;
    @JsonProperty("reelList")
    private List<String> reelList;
src/main/java/com/gs/xiaomi/dto/SnListItemDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,97 @@
package com.gs.xiaomi.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
 * SN列表项DTO
 * ç”¨äºŽBCS101接口的请求和响应数据传输
 */
@Data
public class SnListItemDto {
    /**
     * SN或者REELID (必填)
     */
    @JsonProperty("snNo")
    private String snNo;
    /**
     * REEL中物品的数量 (必填)
     */
    @JsonProperty("qty")
    private Integer qty;
    /**
     * SN、REELID物料对应装箱号 (非必填)
     */
    @JsonProperty("cartonId")
    private String cartonId;
    /**
     * SN、REELID对应的生产日期 (必填)
     * æ–™ç›˜çš„DC字段
     */
    @JsonProperty("dateCode")
    private String dateCode;
    /**
     * SN、REELID对应的生产批次 (非必填)
     * æ–™ç›˜çš„lot字段
     */
    @JsonProperty("lotNo")
    private String lotNo;
    /**
     * å°ç±³æ–™å· (必填)
     */
    @JsonProperty("mpnId")
    private String mpnId;
    /**
     * äº§åœ° (非必填)
     * å¡«å†™å†…容需为字母组合无数字、汉字
     */
    @JsonProperty("place")
    private String place;
    /**
     * å“ç‰Œ (非必填)
     * é»˜è®¤ä¸ºç©ºï¼Œå¯ç”¨å¿…填开关后,为必填
     */
    @JsonProperty("brand")
    private String brand;
    /**
     * åˆ¶é€ å•†æ–™å· (非必填)
     */
    @JsonProperty("mpn")
    private String mpn;
    /**
     * åž‹å· (非必填)
     * é»˜è®¤ä¸ºç©ºï¼Œå¯ç”¨å¿…填开关后,为必填
     */
    @JsonProperty("model")
    private String model;
    /**
     * åº“存组织 (非必填)
     * VMI转自有需上传,字段
     */
    @JsonProperty("stockOrg")
    private String stockOrg;
    /**
     * åŽŸå§‹ä¾›åº”å•† (非必填)
     */
    @JsonProperty("originSupplierId")
    private String originSupplierId;
    /**
     * è´¨æ£€å•号 (非必填)
     * å¤®ä»“调拨物料免检时使用
     */
    @JsonProperty("inspInvoNo")
    private String inspInvoNo;
}
src/main/java/com/gs/xiaomi/entity/SnListItem.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,117 @@
package com.gs.xiaomi.entity;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
/**
 * SN/REELID条码信息实体类
 * @TableName SN_LIST_ITEM
 */
@TableName(value = "SN_LIST_ITEM")
@Data
@KeySequence(value = "SEQ_SN_LIST_ITEM", dbType = DbType.ORACLE)
public class SnListItem {
    /**
     * ä¸»é”®ID (使用SEQ_SN_LIST_ITEM序列)
     */
    @TableId
    private Long id;
    /**
     * SN或者REELID (必填)
     */
    private String snNo;
    /**
     * REEL中物品的数量 (必填)
     */
    private Integer qty;
    /**
     * SN、REELID物料对应装箱号 (非必填)
     */
    private String cartonId;
    /**
     * SN、REELID对应的生产日期 (必填)
     * æ–™ç›˜çš„DC字段
     */
    private String dateCode;
    /**
     * SN、REELID对应的生产批次 (非必填)
     * æ–™ç›˜çš„lot字段
     */
    private String lotNo;
    /**
     * å°ç±³æ–™å· (必填)
     */
    private String mpnId;
    /**
     * äº§åœ° (非必填)
     * å¡«å†™å†…容需为字母组合无数字、汉字
     */
    private String place;
    /**
     * å“ç‰Œ (非必填)
     * é»˜è®¤ä¸ºç©ºï¼Œå¯ç”¨å¿…填开关后,为必填
     */
    private String brand;
    /**
     * åˆ¶é€ å•†æ–™å· (非必填)
     */
    private String mpn;
    /**
     * åž‹å· (非必填)
     * é»˜è®¤ä¸ºç©ºï¼Œå¯ç”¨å¿…填开关后,为必填
     */
    private String model;
    /**
     * åº“存组织 (非必填)
     * VMI转自有需上传,字段
     */
    private String stockOrg;
    /**
     * åŽŸå§‹ä¾›åº”å•† (非必填)
     */
    private String originSupplierId;
    /**
     * è´¨æ£€å•号 (非必填)
     * å¤®ä»“调拨物料免检时使用
     */
    private String inspInvoNo;
    /**
     * å…³è”送货单主表ID (外键关联DELIVERY_MAIN表)
     */
    private Long deliveryMainId;
    /**
     * é€è´§å•号 (冗余字段便于查询)
     */
    private String zzasn;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    private Date createdTime;
    /**
     * æ›´æ–°æ—¶é—´
     */
    private Date updatedTime;
}
src/main/java/com/gs/xiaomi/example/SnListItemUsageExample.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,166 @@
package com.gs.xiaomi.example;
import com.gs.xiaomi.dto.BCS101Response;
import com.gs.xiaomi.dto.SnListItemDto;
import com.gs.xiaomi.entity.SnListItem;
import com.gs.xiaomi.service.SnListItemService;
import com.gs.xiaomi.util.SnListItemConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * SnListItem使用示例
 * æ¼”示如何使用DTO和Entity进行数据处理和持久化
 */
@Component
public class SnListItemUsageExample {
    @Autowired
    private SnListItemService snListItemService;
    /**
     * ç¤ºä¾‹1: ä»ŽBCS101接口响应中保存SN列表数据
     *
     * @param response       BCS101接口响应
     * @param deliveryMainId é€è´§å•主表ID
     * @param zzasn          é€è´§å•号
     */
    public void saveSNListFromResponse(BCS101Response response, Long deliveryMainId, String zzasn) {
        // 1. ä»Žå“åº”中获取DTO列表
        List<SnListItemDto> dtoList = response.getBody().getSnList();
        // 2. å°†DTO列表转换为Entity列表,同时设置关联信息
        List<SnListItem> entityList = SnListItemConverter.toEntityList(dtoList, deliveryMainId, zzasn);
        // 3. æ‰¹é‡ä¿å­˜åˆ°æ•°æ®åº“
        snListItemService.saveBatch(entityList);
    }
    /**
     * ç¤ºä¾‹2: æ ¹æ®é€è´§å•号查询SN列表并转换为DTO
     *
     * @param zzasn é€è´§å•号
     * @return DTO列表
     */
    public List<SnListItemDto> querySnListByZzasn(String zzasn) {
        // 1. ä»Žæ•°æ®åº“查询Entity列表
        List<SnListItem> entityList = snListItemService.lambdaQuery()
                .eq(SnListItem::getZzasn, zzasn)
                .list();
        // 2. å°†Entity列表转换为DTO列表
        return SnListItemConverter.toDtoList(entityList);
    }
    /**
     * ç¤ºä¾‹3: å•个DTO保存
     *
     * @param dto            SN条码DTO
     * @param deliveryMainId é€è´§å•主表ID
     * @param zzasn          é€è´§å•号
     */
    public void saveSingleSNItem(SnListItemDto dto, Long deliveryMainId, String zzasn) {
        // 1. DTO转Entity
        SnListItem entity = SnListItemConverter.toEntity(dto, deliveryMainId, zzasn);
        // 2. ä¿å­˜åˆ°æ•°æ®åº“
        snListItemService.save(entity);
    }
    /**
     * ç¤ºä¾‹4: æ ¹æ®SN号查询详细信息
     *
     * @param snNo SN号
     * @return Entity对象
     */
    public SnListItem queryBySnNo(String snNo) {
        return snListItemService.lambdaQuery()
                .eq(SnListItem::getSnNo, snNo)
                .one();
    }
    /**
     * ç¤ºä¾‹5: æ ¹æ®å°ç±³æ–™å·å’Œé€è´§å•号查询
     *
     * @param mpnId å°ç±³æ–™å·
     * @param zzasn é€è´§å•号
     * @return Entity列表
     */
    public List<SnListItem> queryByMpnIdAndZzasn(String mpnId, String zzasn) {
        return snListItemService.lambdaQuery()
                .eq(SnListItem::getMpnId, mpnId)
                .eq(SnListItem::getZzasn, zzasn)
                .list();
    }
    /**
     * ç¤ºä¾‹6: æ ¹æ®è£…箱号查询所有SN
     *
     * @param cartonId è£…箱号
     * @return Entity列表
     */
    public List<SnListItem> queryByCartonId(String cartonId) {
        return snListItemService.lambdaQuery()
                .eq(SnListItem::getCartonId, cartonId)
                .orderByAsc(SnListItem::getCreatedTime)
                .list();
    }
    /**
     * ç¤ºä¾‹7: æ›´æ–°SN条码信息
     *
     * @param id  è®°å½•ID
     * @param dto æ›´æ–°çš„DTO数据
     * @return æ˜¯å¦æ›´æ–°æˆåŠŸ
     */
    public boolean updateSnItem(Long id, SnListItemDto dto) {
        // 1. DTO转Entity
        SnListItem entity = SnListItemConverter.toEntity(dto);
        entity.setId(id);
        // 2. æ›´æ–°åˆ°æ•°æ®åº“
        return snListItemService.updateById(entity);
    }
    /**
     * ç¤ºä¾‹8: åˆ é™¤æŒ‡å®šé€è´§å•的所有SN数据
     *
     * @param zzasn é€è´§å•号
     * @return æ˜¯å¦åˆ é™¤æˆåŠŸ
     */
    public boolean deleteByZzasn(String zzasn) {
        return snListItemService.lambdaUpdate()
                .eq(SnListItem::getZzasn, zzasn)
                .remove();
    }
    /**
     * ç¤ºä¾‹9: ç»Ÿè®¡æŸä¸ªé€è´§å•çš„SN数量
     *
     * @param zzasn é€è´§å•号
     * @return SN数量
     */
    public long countByZzasn(String zzasn) {
        return snListItemService.lambdaQuery()
                .eq(SnListItem::getZzasn, zzasn)
                .count();
    }
    /**
     * ç¤ºä¾‹10: åˆ†é¡µæŸ¥è¯¢SN列表
     *
     * @param zzasn    é€è´§å•号
     * @param pageNum  é¡µç 
     * @param pageSize æ¯é¡µå¤§å°
     * @return Entity列表
     */
    public List<SnListItem> queryByPage(String zzasn, int pageNum, int pageSize) {
        return snListItemService.lambdaQuery()
                .eq(SnListItem::getZzasn, zzasn)
                .orderByDesc(SnListItem::getCreatedTime)
                .last("OFFSET " + (pageNum - 1) * pageSize + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY")
                .list();
    }
}
src/main/java/com/gs/xiaomi/mapper/SnListItemMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package com.gs.xiaomi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gs.xiaomi.entity.SnListItem;
import org.apache.ibatis.annotations.Mapper;
/**
 * SN/REELID条码信息Mapper接口
 */
@Mapper
public interface SnListItemMapper extends BaseMapper<SnListItem> {
}
src/main/java/com/gs/xiaomi/service/SnListItemService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
package com.gs.xiaomi.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gs.xiaomi.entity.SnListItem;
/**
 * SN/REELID条码信息Service接口
 */
public interface SnListItemService extends IService<SnListItem> {
}
src/main/java/com/gs/xiaomi/service/impl/SnListItemServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.gs.xiaomi.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gs.xiaomi.entity.SnListItem;
import com.gs.xiaomi.mapper.SnListItemMapper;
import com.gs.xiaomi.service.SnListItemService;
import org.springframework.stereotype.Service;
/**
 * SN/REELID条码信息Service实现类
 */
@Service
public class SnListItemServiceImpl extends ServiceImpl<SnListItemMapper, SnListItem> implements SnListItemService {
}
src/main/java/com/gs/xiaomi/util/SnListItemConverter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
package com.gs.xiaomi.util;
import com.gs.xiaomi.dto.SnListItemDto;
import com.gs.xiaomi.entity.SnListItem;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 * SnListItem DTO和Entity转换工具类
 */
public class SnListItemConverter {
    /**
     * DTO转Entity
     *
     * @param dto DTO对象
     * @return Entity对象
     */
    public static SnListItem toEntity(SnListItemDto dto) {
        if (dto == null) {
            return null;
        }
        SnListItem entity = new SnListItem();
        BeanUtils.copyProperties(dto, entity);
        entity.setCreatedTime(new Date());
        entity.setUpdatedTime(new Date());
        return entity;
    }
    /**
     * DTO转Entity,带关联信息
     *
     * @param dto             DTO对象
     * @param deliveryMainId  é€è´§å•主表ID
     * @param zzasn           é€è´§å•号
     * @return Entity对象
     */
    public static SnListItem toEntity(SnListItemDto dto, Long deliveryMainId, String zzasn) {
        if (dto == null) {
            return null;
        }
        SnListItem entity = toEntity(dto);
        entity.setDeliveryMainId(deliveryMainId);
        entity.setZzasn(zzasn);
        return entity;
    }
    /**
     * Entity转DTO
     *
     * @param entity Entity对象
     * @return DTO对象
     */
    public static SnListItemDto toDto(SnListItem entity) {
        if (entity == null) {
            return null;
        }
        SnListItemDto dto = new SnListItemDto();
        BeanUtils.copyProperties(entity, dto);
        return dto;
    }
    /**
     * DTO列表转Entity列表
     *
     * @param dtoList DTO列表
     * @return Entity列表
     */
    public static List<SnListItem> toEntityList(List<SnListItemDto> dtoList) {
        if (dtoList == null || dtoList.isEmpty()) {
            return new ArrayList<>();
        }
        return dtoList.stream()
                .map(SnListItemConverter::toEntity)
                .collect(Collectors.toList());
    }
    /**
     * DTO列表转Entity列表,带关联信息
     *
     * @param dtoList         DTO列表
     * @param deliveryMainId  é€è´§å•主表ID
     * @param zzasn           é€è´§å•号
     * @return Entity列表
     */
    public static List<SnListItem> toEntityList(List<SnListItemDto> dtoList, Long deliveryMainId, String zzasn) {
        if (dtoList == null || dtoList.isEmpty()) {
            return new ArrayList<>();
        }
        return dtoList.stream()
                .map(dto -> toEntity(dto, deliveryMainId, zzasn))
                .collect(Collectors.toList());
    }
    /**
     * Entity列表转DTO列表
     *
     * @param entityList Entity列表
     * @return DTO列表
     */
    public static List<SnListItemDto> toDtoList(List<SnListItem> entityList) {
        if (entityList == null || entityList.isEmpty()) {
            return new ArrayList<>();
        }
        return entityList.stream()
                .map(SnListItemConverter::toDto)
                .collect(Collectors.toList());
    }
}
src/main/resources/mapper/SnListItemMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
<?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.gs.xiaomi.mapper.SnListItemMapper">
    <resultMap id="BaseResultMap" type="com.gs.xiaomi.entity.SnListItem">
        <id property="id" column="ID" jdbcType="DECIMAL"/>
        <result property="snNo" column="SN_NO" jdbcType="VARCHAR"/>
        <result property="qty" column="QTY" jdbcType="DECIMAL"/>
        <result property="cartonId" column="CARTON_ID" jdbcType="VARCHAR"/>
        <result property="dateCode" column="DATE_CODE" jdbcType="VARCHAR"/>
        <result property="lotNo" column="LOT_NO" jdbcType="VARCHAR"/>
        <result property="mpnId" column="MPN_ID" jdbcType="VARCHAR"/>
        <result property="place" column="PLACE" jdbcType="VARCHAR"/>
        <result property="brand" column="BRAND" jdbcType="VARCHAR"/>
        <result property="mpn" column="MPN" jdbcType="VARCHAR"/>
        <result property="model" column="MODEL" jdbcType="VARCHAR"/>
        <result property="stockOrg" column="STOCK_ORG" jdbcType="VARCHAR"/>
        <result property="originSupplierId" column="ORIGIN_SUPPLIER_ID" jdbcType="VARCHAR"/>
        <result property="inspInvoNo" column="INSP_INVO_NO" jdbcType="VARCHAR"/>
        <result property="deliveryMainId" column="DELIVERY_MAIN_ID" jdbcType="DECIMAL"/>
        <result property="zzasn" column="ZZASN" jdbcType="VARCHAR"/>
        <result property="createdTime" column="CREATED_TIME" jdbcType="TIMESTAMP"/>
        <result property="updatedTime" column="UPDATED_TIME" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        ID, SN_NO, QTY, CARTON_ID, DATE_CODE, LOT_NO, MPN_ID, PLACE, BRAND, MPN, MODEL,
        STOCK_ORG, ORIGIN_SUPPLIER_ID, INSP_INVO_NO, DELIVERY_MAIN_ID, ZZASN, CREATED_TIME, UPDATED_TIME
    </sql>
</mapper>
src/test/java/com/gs/xiaomi/XiaomiApplicationTests.java
@@ -6,10 +6,14 @@
import com.gs.xiaomi.dto.BCS101Request;
import com.gs.xiaomi.dto.BCS101Response;
import com.gs.xiaomi.dto.NumbericalDto;
import com.gs.xiaomi.dto.SnListItemDto;
import com.gs.xiaomi.entity.DeliveryMain;
import com.gs.xiaomi.entity.SnListItem;
import com.gs.xiaomi.service.BCS101ApiService;
import com.gs.xiaomi.service.DeliveryMainService;
import com.gs.xiaomi.service.SnListItemService;
import com.gs.xiaomi.service.Xm104Service;
import com.gs.xiaomi.util.SnListItemConverter;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -29,6 +33,9 @@
    @Autowired
    private DeliveryMainService deliveryMainService;
    @Autowired
    private SnListItemService snListItemService;
    @Test
    void contextLoads() throws Exception {
@@ -60,11 +67,11 @@
        //List<String> collect = list.stream().map(DeliveryMain::getZzasn).collect(Collectors.toList());
        list.forEach(s->{
            System.out.println(String.valueOf(Integer.parseInt(s.getLifnr()))+":"+s.getZzasn());
        list.forEach(s -> {
            System.out.println(String.valueOf(Integer.parseInt(s.getLifnr())) + ":" + s.getZzasn());
            // åˆ›å»ºæµ‹è¯•请求参数
            BCS101Request request = new BCS101Request();
            request.setSupplierId(String.valueOf(Integer.parseInt(s.getLifnr())) );
            request.setSupplierId(String.valueOf(Integer.parseInt(s.getHubLifnr())));
            request.setDocNo(s.getZzasn());
            request.setDocType("ASNGR");
            request.setPageNo(1);
@@ -83,6 +90,42 @@
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                BCS101Response response = objectMapper.readValue(bcs101Data, BCS101Response.class);
                // æ£€æŸ¥å“åº”是否成功
                if (response.isSuccess()) {
                    // èŽ·å–snList数据
                    List<SnListItemDto> snList = response.getBody().getSnList();
                    if (snList != null && !snList.isEmpty()) {
                        System.out.println("获取到 " + snList.size() + " æ¡SN数据,开始持久化...");
                        // è½¬æ¢DTO为Entity,并设置关联信息
                        List<SnListItem> entityList = SnListItemConverter.toEntityList(
                            snList,
                            s.getId(),      // deliveryMainId - é€è´§å•主表ID
                            s.getZzasn()    // zzasn - é€è´§å•号
                        );
                        // å…ˆåˆ é™¤è¯¥é€è´§å•已有的SN数据(避免重复)
                        snListItemService.lambdaUpdate()
                            .eq(SnListItem::getZzasn, s.getZzasn())
                            .remove();
                        // æ‰¹é‡ä¿å­˜åˆ°æ•°æ®åº“
                        boolean saved = snListItemService.saveBatch(entityList);
                        if (saved) {
                            System.out.println("成功保存 " + entityList.size() + " æ¡SN数据到数据库");
                        } else {
                            System.err.println("保存SN数据失败!");
                        }
                    } else {
                        System.out.println("响应中没有SN数据");
                    }
                } else {
                    System.err.println("BCS101接口调用失败: " + response.getErrorDesc());
                }
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }