啊鑫
2025-04-10 22a8875b365c568790f6115ceb6acf0f49bb8c47
测试写入数据库
已修改5个文件
已添加21个文件
1457 ■■■■ 文件已修改
src/main/java/com/gs/xiaomi/XiaomiApplication.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/dto/EtHeader.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/entity/DeliveryDetail.java 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/entity/DeliveryMain.java 308 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/entity/LogisticsPackage.java 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/entity/PackageDetail.java 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/mapper/DeliveryDetailMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/mapper/DeliveryMainMapper.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/mapper/LogisticsPackageMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/mapper/PackageDetailMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/DeliveryDetailService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/DeliveryMainService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/LogisticsPackageService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/PackageDetailService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/SoapApiService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/XM104Service.java 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/impl/DeliveryDetailServiceImpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/impl/DeliveryMainServiceImpl.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/impl/LogisticsPackageServiceImpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/service/impl/PackageDetailServiceImpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/DeliveryDetailMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/DeliveryMainMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LogisticsPackageMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/PackageDetailMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/gs/xiaomi/XiaomiApplicationTests.java 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xiaomi/XiaomiApplication.java
@@ -1,9 +1,13 @@
package com.gs.xiaomi;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@MapperScan(value = " com.gs.xiaomi.mapper")
@EnableScheduling
public class XiaomiApplication {
    public static void main(String[] args) {
src/main/java/com/gs/xiaomi/dto/EtHeader.java
@@ -199,13 +199,13 @@
    /* é™„件信息块 */
    @XmlElementWrapper(name = "items")
    @XmlElement(name = "item")
    private List<Item> items;// è¡Œé¡¹ç›®æ˜Žç»†
    private List<Item> items;// è¡Œé¡¹ç›®æ˜Žç»†  å¯¹åº”表DELIVERY_DETAIL
    @XmlElementWrapper(name = "box_items")
    @XmlElement(name = "boxItems")
    private List<BoxItem> boxItems; // ç®±å•明细
    private List<BoxItem> boxItems; // ç®±å•明细  å¯¹åº”表PACKAGE_DETAIL
    @XmlElementWrapper(name = "box_sums")
    @XmlElement(name = "boxSum")
    private List<BoxSum> boxSums; // ç®±æ•°æ±‡æ€»
    private List<BoxSum> boxSums; // ç®±æ•°æ±‡æ€»  å¯¹åº”表LOGISTICS_PACKAGE
}
src/main/java/com/gs/xiaomi/entity/DeliveryDetail.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,196 @@
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;
/**
 * @TableName DELIVERY_DETAIL
 */
@TableName(value = "DELIVERY_DETAIL")
@Data
@KeySequence(value = "SEQ_DELIVERY_DETAIL", dbType = DbType.ORACLE)
public class DeliveryDetail {
    /**
     * SEQ_DELIVERY_DETAIL
     */
    @TableId
    private Long id;
    /**
     * DELIVERY_MAIN的id
     */
    private Long pid;
    /**
     * é€è´§å•号(主业务标识)
     */
    private String zzasn;
    /**
     * é€è´§å•行号
     */
    private String zzitemId;
    /**
     * é‡‡è´­å‡­è¯å·ï¼ˆPO单号)
     */
    private String zzpoNo;
    /**
     * é‡‡è´­è®¢å•行项目
     */
    private String zzpoItemId;
    /**
     * å°ç±³é€€æ¢è´§å•号
     */
    private String zzreqnr;
    /**
     * é€€æ¢è´§ç”³è¯·å•行号
     */
    private String zzreqln;
    /**
     * å°ç±³å†…部物料编码
     */
    private String zzproductId;
    /**
     * å·¥åŽ‚å®žé™…ä½¿ç”¨æ–™å·
     */
    private String zzvproductId;
    /**
     * åº“存单位编码
     */
    private String zzsku;
    /**
     * ç‰©æ–™æè¿°ï¼ˆå¦‚:手机屏幕组件)
     */
    private String maktx;
    /**
     * äº§å“åž‹å·ï¼ˆç¤ºä¾‹ï¼šXiaomi 14 Ultra)
     */
    private String modelnumber;
    /**
     * è®¢å•需求数量
     */
    private String zzquantity;
    /**
     * è®¡é‡å•位(如:个/箱)
     */
    private String zzunit;
    /**
     * æœªå®Œæˆæ•°é‡ï¼ˆå¾…补货量)
     */
    private String zzopenQty;
    /**
     * å®žé™…收货数量
     */
    private String actGrQty;
    /**
     * Shipment批次数量
     */
    private String shipmentidNum;
    /**
     * å“ç‰Œåç§°ï¼ˆå¦‚:Xiaomi)
     */
    private String brand;
    /**
     * ç”Ÿäº§åœ°ï¼ˆç¤ºä¾‹ï¼šä¸­å›½æ·±åœ³ï¼‰
     */
    private String place;
    /**
     * å“ç‰Œç±»åž‹ï¼ˆè‡ªæœ‰/ODM/OEM)
     */
    private String brandType;
    /**
     * ç‰©æµæ‰¹æ¬¡å”¯ä¸€æ ‡è¯†
     */
    private String zshipmentId;
    /**
     * è¯¦ç»†é…é€åœ°å€ï¼ˆçœå¸‚区街道门牌号)
     */
    private String addressDetail;
    /**
     * è°ƒå‡ºé¡¹ç›®å·ï¼ˆè°ƒæ‹¨æ¥æºæ ‡è¯†ï¼‰
     */
    private String bednr;
    /**
     * è°ƒå‡ºä»“类型(成品仓/原料仓)
     */
    private String wareTypeFrom;
    /**
     * è°ƒå…¥ä»“类型
     */
    private String wareTypeTo;
    /**
     * ç‰©æŽ§è°ƒæ‹¨å•号
     */
    private String xmstoNo;
    /**
     * è°ƒæ‹¨å•行项
     */
    private String xmstoItemNo;
    /**
     * æœ€åŽä¿®æ”¹æ—¶é—´ï¼ˆæ ¼å¼ï¼šyyyyMMddHHmmss)
     */
    private String changedAt;
    /**
     * æ•°æ®åˆ›å»ºæ—¶é—´ï¼ˆæ ¼å¼ï¼šyyyyMMddHHmmss)
     */
    private String createdAt;
    /**
     * å…³è”项目机型(多值逗号分隔)
     */
    private String appModels;
    /**
     * å¤–部系统凭证号(如ERP单号)
     */
    private String extDocNo;
    /**
     * å¤–部凭证行项目
     */
    private String extDocItem;
    /**
     * æµ·å…³HS编码(进出口报关用)
     */
    private String batchId;
    /**
     * ä¼˜å…ˆé‡‡è´­æ ‡è¯†ï¼ˆç´§æ€¥å¤‡æ–™æ ‡è®°ï¼‰
     */
    private String batchRow;
    /**
     * ä¸²å·ç®¡ç†æ ‡è¯†ï¼ˆY/N,控制序列号采集)
     */
    private String isIdentification;
}
src/main/java/com/gs/xiaomi/entity/DeliveryMain.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,308 @@
package com.gs.xiaomi.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
 * @TableName DELIVERY_MAIN
 */
@TableName(value = "DELIVERY_MAIN")
@Data
public class DeliveryMain {
    /**
     * SEQ_DELIVERY_MAIN
     */
    @TableId
    private Long id;
    /**
     * é€è´§å•号
     */
    private String zzasn;
    /**
     * å•据类型(普通/紧急)
     */
    private String zzasnType;
    /**
     * æ”¶è´§ç±»åž‹(标准/退货)
     */
    private String migoType;
    /**
     * é¡¹ç›®è°ƒæ‹¨ç¼–号
     */
    private String zrproject;
    /**
     * é‡‡è´­ç»„织编码
     */
    private String ekorg;
    /**
     * é‡‡è´­ç»„织描述
     */
    private String ekotx;
    /**
     * è°ƒå‡ºåº“存组织编码
     */
    private String stockOrgFrom;
    /**
     * è°ƒå‡ºåº“存描述
     */
    private String stockOrgFromDesc;
    /**
     * è°ƒå…¥åº“存组织编码
     */
    private String stockOrgTo;
    /**
     * è°ƒå…¥åº“存描述
     */
    private String stockOrgToDesc;
    /**
     * ä¾›åº”商编码(示例值:130479)
     */
    private String lifnr;
    /**
     * ä¾›åº”商全称
     */
    private String vendorName;
    /**
     * ä¾›åº”商简称
     */
    private String shortName;
    /**
     * HUB供应商编码
     */
    private String hubLifnr;
    /**
     * æ‰¿è¿å•†åç§°
     */
    private String zzcarrier;
    /**
     * æ‰¿è¿å•号
     */
    private String zzcarrierNo;
    /**
     * è¿è¾“单据号
     */
    private String roadTransportNo;
    /**
     * è¿è¾“车型
     */
    private String zztransModel;
    /**
     * è½¦ç‰Œå·
     */
    private String zzlicenseNumb;
    /**
     * é“…封号
     */
    private String zzsealNo;
    /**
     * ç‰©æµå•号
     */
    private String logisticsNo;
    /**
     * ç‰©æµå…¬å¸ç¼–码
     */
    private String logisticsCompany;
    /**
     * ç‰©æµå…¬å¸å…¨ç§°
     */
    private String logisticsCompanyName;
    /**
     * å‘货人姓名
     */
    private String zzshipName;
    /**
     * å‘货人电话
     */
    private String zzshipPhon;
    /**
     * å¸æœºå§“名
     */
    private String zzdriverName;
    /**
     * å¸æœºç”µè¯
     */
    private String zzdriverPhon;
    /**
     * æ‰‹æœºå°¾å·
     */
    private String last4PhoneNumber;
    /**
     * æ”¶è´§äºº
     */
    private String receiver;
    /**
     * æ”¶è´§ç”µè¯
     */
    private String receivePhone;
    /**
     * æœ€ç»ˆæ”¶è´§äºº
     */
    private String finalContact;
    /**
     * æœ€ç»ˆè”系电话
     */
    private String finalPhone;
    /**
     * å‘货地址
     */
    private String zzshipAddr;
    /**
     * æ ‡å‡†æ”¶è´§åœ°å€
     */
    private String zzreceiveAddr;
    /**
     * å®žé™…收货地址
     */
    private String receiveAddr;
    /**
     * æœ€ç»ˆé…é€åœ°å€
     */
    private String finalAddr;
    /**
     * æœ€ç»ˆæ”¶è´§å•位
     */
    private String finalCompany;
    /**
     * å‘货日期(yyyyMMdd)
     */
    private String zzshipDate;
    /**
     * é¢„计到货日期(yyyyMMdd)
     */
    private String zzarriveTime;
    /**
     * é¢„计到货时间(HHmm)
     */
    private String zzarriveTime1;
    /**
     * é¢„约日期(yyyyMMdd)
     */
    private String reserveDate;
    /**
     * é¢„约时间段
     */
    private String reserveTime;
    /**
     * ä»“库唯一标识
     */
    private String zzwarehouseId;
    /**
     * æ”¶è´§ä»“库ID
     */
    private String receiveWarehouseId;
    /**
     * ä»“库简称
     */
    private String receiveWarehouseShort;
    /**
     * å…¬å¸ä»£ç 
     */
    private String bukrs;
    /**
     * å•据状态(新建/已发货/已完成)
     */
    private String status;
    /**
     * æ¡ç çŠ¶æ€(已上传/未上传)
     */
    private String statusSn;
    /**
     * ä½œåºŸæ ‡è¯†(Y/N)
     */
    private String zzcanceled;
    /**
     * ä»·æ ¼å®¡æ ¸çŠ¶æ€
     */
    private String priceStat;
    /**
     * ä»“库作业指导类型
     */
    private String purchaseMode;
    /**
     * é‡‡è´­æ¨¡å¼(VMI/JIT)
     */
    private String purchaseMode2;
    /**
     * äº¤æ–™æ¨¡å¼(自提/配送)
     */
    private String businessModel;
    /**
     * å•据描述
     */
    private String asnDesc;
    /**
     * è¿›å£æŠ¥å…³æ ‡è¯†(Y/N)
     */
    private String imclr;
    /**
     * å¤–部工厂代码
     */
    private String lifnrDg;
    /**
     * ç”Ÿäº§ç±»åž‹(自制/外购)
     */
    private String productType;
    /**
     * é©¾é©¶è¯å·
     */
    private String zzdriverLicense;
}
src/main/java/com/gs/xiaomi/entity/LogisticsPackage.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,171 @@
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;
/**
 * @TableName LOGISTICS_PACKAGE
 */
@TableName(value = "LOGISTICS_PACKAGE")
@Data
@KeySequence(value = "LOGISTICS_PACKAGE_SEQ", dbType = DbType.ORACLE)
public class LogisticsPackage {
    /**
     * LOGISTICS_PACKAGE_SEQ
     */
    @TableId
    private Long id;
    /**
     * DELIVERY_MAIN的id
     */
    private Long pid;
    /**
     * ç®±å•流水号
     */
    private String boxSeq;
    /**
     * ç‰©ç†åŒ…装标识
     */
    private String boxNo;
    /**
     * å°ç±³ä¸“用加密箱号(AES-256加密存储)
     */
    private String cartonid;
    /**
     * å…¨çƒç»Ÿä¸€é€è´§å•号(关联物流系统)
     */
    private String zzasn;
    /**
     * SAP标准物料编码
     */
    private String matnr;
    /**
     * å¤šè¯­è¨€ç‰©æ–™æè¿°
     */
    private String maktx;
    /**
     * å®žé™…发货件数(最小销售单位统计)
     */
    private String pcQty;
    /**
     * ç‰©æµæ‰˜ç›˜ç¼–号
     */
    private String lotNo;
    /**
     * å•件净重
     */
    private String ntgewP;
    /**
     * å•箱毛重
     */
    private String brgewP;
    /**
     * æ‰˜ç›˜è£…载规格
     */
    private String lotSize;
    /**
     * æ ‡å‡†ç®±ä½“尺寸
     */
    private String boxSize;
    /**
     * å«æ‰˜ç›˜æ€»ä½“积
     */
    private String totalVlume;
    /**
     * æ‰˜ç›˜é•¿åº¦
     */
    private String lM;
    /**
     * æ‰˜ç›˜å®½åº¦
     */
    private String wM;
    /**
     * æ‰˜ç›˜å †é«˜ï¼ˆå®‰å…¨é™é«˜ï¼Œé˜²å€¾å€’控制)
     */
    private String hM;
    /**
     * é‡‡è´­è®¢å•号(关联SAP采购凭证)
     */
    private String ebeln;
    /**
     * é‡‡è´­è®¢å•行号(精确到物料层级)
     */
    private String ebelp;
    /**
     * å•箱容量规格(防超装校验)
     */
    private String boxSpec;
    /**
     * æ€»åŒ…装箱数(与采购订单匹配校验)
     */
    private String boxQty;
    /**
     * æ€»å‡€é‡ï¼ˆå…¬å¼ï¼šntgew_p Ã— pc_qty)
     */
    private String ntgew;
    /**
     * æ€»æ¯›é‡ï¼ˆå…¬å¼ï¼šbrgew_p Ã— box_qty)
     */
    private String brgew;
    /**
     * å›½é™…计量单位(UN/CEFACT标准)
     */
    private String meins;
    /**
     * å“ç‰Œè®¤è¯æ ‡è¯†ï¼ˆéœ€æµ·å…³å¤‡æ¡ˆï¼‰
     */
    private String brand;
    /**
     * åŽŸäº§åœ°ç¼–ç ï¼ˆè”åˆå›½UN/LOCODE标准)
     */
    private String place;
    /**
     * æŠ¥å…³æ ‡è¯†ï¼ˆæŽ§åˆ¶æŠ¥å…³æµç¨‹è§¦å‘)
     */
    private String imclr;
    /**
     * å›½é™…型号编码(全球市场唯一标识)
     */
    private String modelnumber;
    /**
     * æµ·å…³ç›‘管条件(如3C/能效标识)
     */
    private String matnrJg;
    /**
     * æ£€éªŒæ£€ç–«ä»£ç ï¼ˆå¦‚FDA/CE认证)
     */
    private String matnrJyjy;
}
src/main/java/com/gs/xiaomi/entity/PackageDetail.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,171 @@
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;
/**
 * @TableName PACKAGE_DETAIL
 */
@TableName(value = "PACKAGE_DETAIL")
@Data
@KeySequence(value = "PACKAGE_DETAIL_SEQ", dbType = DbType.ORACLE)
public class PackageDetail {
    /**
     * PACKAGE_DETAIL_SEQ
     */
    @TableId
    private Long id;
    /**
     * DELIVERY_MAIN的id
     */
    private Long pid;
    /**
     * ç®±å•流水号(按年月日+序列生成)
     */
    private String boxSeq;
    /**
     * åŒ…装箱唯一标识(规则:项目+日期+流水)
     */
    private String boxNo;
    /**
     * å°ç±³ä¸“用加密箱号(SHA-256算法加密)
     */
    private String cartonid;
    /**
     * å…¨çƒç»Ÿä¸€é€è´§å•号(主业务标识)
     */
    private String zzasn;
    /**
     * å›½é™…物料编码(全球唯一性保障)
     */
    private String matnr;
    /**
     * å¤šè¯­è¨€ç‰©æ–™æè¿°ï¼ˆæ”¯æŒä¸­/英/西语)
     */
    private String maktx;
    /**
     * å®žé™…发货件数(按最小销售单位统计)
     */
    private String pcQty;
    /**
     * æ‰˜ç›˜å”¯ä¸€ç¼–号(与物流系统联动)
     */
    private String lotNo;
    /**
     * å•件净重(精确到克,用于报关)
     */
    private String ntgewP;
    /**
     * å•箱毛重(含包装材料重量)
     */
    private String brgewP;
    /**
     * æ‰˜ç›˜è£…载规格(最大承载箱数)
     */
    private String lotSize;
    /**
     * æ ‡å‡†åŒ–箱体尺寸(长x宽x高)
     */
    private String boxSize;
    /**
     * å«æ‰˜ç›˜æ€»ä½“积(用于运输成本计算)
     */
    private String totalVlume;
    /**
     * æ€»ç®±æ•°ï¼ˆä¸Žé‡‡è´­è®¢å•校验)
     */
    private String boxQty;
    /**
     * é‡‡è´­è®¢å•号(关联ERP系统)
     */
    private String ebeln;
    /**
     * é‡‡è´­è®¢å•行号(精确到物料层级)
     */
    private String ebelp;
    /**
     * å•箱容量(件/箱,防超装控制)
     */
    private String boxSpec;
    /**
     * æ€»å‡€é‡ï¼ˆè‡ªåŠ¨è®¡ç®—ï¼šå•ä»¶å‡€é‡Ã—æ€»ä»¶æ•°ï¼‰
     */
    private String ntgew;
    /**
     * æ€»æ¯›é‡ï¼ˆå«æ‰˜ç›˜å’ŒåŒ…装材料)
     */
    private String brgew;
    /**
     * å›½é™…计量单位(UN/CEFACT标准)
     */
    private String meins;
    /**
     * æ‰˜ç›˜é•¿åº¦ï¼ˆç¬¦åˆISO 6780标准)
     */
    private String lM;
    /**
     * æ‰˜ç›˜å®½åº¦ï¼ˆæ¬§æ´²æ ‡å‡†ï¼š1.0m)
     */
    private String wM;
    /**
     * æ‰˜ç›˜å †é«˜ï¼ˆå®‰å…¨é™é«˜æ ‡è¯†ï¼‰
     */
    private String hM;
    /**
     * å“ç‰Œè®¤è¯æ ‡è¯†ï¼ˆéœ€æµ·å…³å¤‡æ¡ˆï¼‰
     */
    private String brand;
    /**
     * åŽŸäº§åœ°ç¼–ç ï¼ˆè”åˆå›½UN/LOCODE)
     */
    private String place;
    /**
     * æµ·å…³æŠ¥å…³æ ‡è¯†ï¼ˆY-需报关/N-免报关)
     */
    private String imclr;
    /**
     * å›½é™…型号编码(全球市场唯一)
     */
    private String modelnumber;
    /**
     * æµ·å…³ç›‘管条件(如3C/能效标识)
     */
    private String matnrJg;
    /**
     * æ£€éªŒæ£€ç–«ä»£ç ï¼ˆå¦‚FDA/CE认证)
     */
    private String matnrJyjy;
}
src/main/java/com/gs/xiaomi/mapper/DeliveryDetailMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.gs.xiaomi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gs.xiaomi.entity.DeliveryDetail;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€DELIVERY_DETAIL】的数据库操作Mapper
 * @createDate 2025-04-10 14:16:44
 * @Entity generator.domain.DeliveryDetail
 */
public interface DeliveryDetailMapper extends BaseMapper<DeliveryDetail> {
}
src/main/java/com/gs/xiaomi/mapper/DeliveryMainMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.gs.xiaomi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gs.xiaomi.entity.DeliveryMain;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€DELIVERY_MAIN】的数据库操作Mapper
 * @createDate 2025-04-10 14:16:52
 * @Entity generator.domain.DeliveryMain
 */
public interface DeliveryMainMapper extends BaseMapper<DeliveryMain> {
    long getNextVal();
}
src/main/java/com/gs/xiaomi/mapper/LogisticsPackageMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.gs.xiaomi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gs.xiaomi.entity.LogisticsPackage;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€LOGISTICS_PACKAGE】的数据库操作Mapper
 * @createDate 2025-04-10 14:17:13
 * @Entity generator.domain.LogisticsPackage
 */
public interface LogisticsPackageMapper extends BaseMapper<LogisticsPackage> {
}
src/main/java/com/gs/xiaomi/mapper/PackageDetailMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.gs.xiaomi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gs.xiaomi.entity.PackageDetail;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€PACKAGE_DETAIL】的数据库操作Mapper
 * @createDate 2025-04-10 14:17:48
 * @Entity generator.domain.PackageDetail
 */
public interface PackageDetailMapper extends BaseMapper<PackageDetail> {
}
src/main/java/com/gs/xiaomi/service/DeliveryDetailService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.gs.xiaomi.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gs.xiaomi.entity.DeliveryDetail;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€DELIVERY_DETAIL】的数据库操作Service
 * @createDate 2025-04-10 14:16:44
 */
public interface DeliveryDetailService extends IService<DeliveryDetail> {
}
src/main/java/com/gs/xiaomi/service/DeliveryMainService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.gs.xiaomi.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gs.xiaomi.entity.DeliveryMain;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€DELIVERY_MAIN】的数据库操作Service
 * @createDate 2025-04-10 14:16:52
 */
public interface DeliveryMainService extends IService<DeliveryMain> {
    long getId();
}
src/main/java/com/gs/xiaomi/service/LogisticsPackageService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.gs.xiaomi.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gs.xiaomi.entity.LogisticsPackage;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€LOGISTICS_PACKAGE】的数据库操作Service
 * @createDate 2025-04-10 14:17:13
 */
public interface LogisticsPackageService extends IService<LogisticsPackage> {
}
src/main/java/com/gs/xiaomi/service/PackageDetailService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.gs.xiaomi.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gs.xiaomi.entity.PackageDetail;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€PACKAGE_DETAIL】的数据库操作Service
 * @createDate 2025-04-10 14:17:48
 */
public interface PackageDetailService extends IService<PackageDetail> {
}
src/main/java/com/gs/xiaomi/service/SoapApiService.java
@@ -12,11 +12,19 @@
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.util.concurrent.TimeUnit;
@Service
public class SoapApiService {
    private static final OkHttpClient client = new OkHttpClient.Builder().build();
    private final OkHttpClient client;
    public SoapApiService() {
        this.client = new OkHttpClient.Builder().connectTimeout(3000, TimeUnit.SECONDS) // Set connection timeout
                .readTimeout(90, TimeUnit.SECONDS)    // Set read timeout
                .build();
    }
    public BizDocumentResult callAndParse(String url, ZfmWsApiRequest request) throws Exception {
        String soapXml = SoapXmlBuilder.build(request);
@@ -53,13 +61,10 @@
        Request request = new Request.Builder()
                .url(url)
                .method("POST", body)
//                .addHeader("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
                .addHeader("Content-Type", "application/xml")
                .addHeader("Authorization", "Basic " + auth)
                .addHeader("Accept", "*/*")
//                .addHeader("Host", "mipoq.p.mi.com")
                .addHeader("Connection", "keep-alive")
//                .addHeader("Cookie", "saplb_*=(J2EE4281420)4281450; MYSAPSSO2=AjExMDAgABJwb3J0YWw6UkZDWkpYSUFPQlWIAAdkZWZhdWx0AQALUkZDWkpYSUFPQlUCAAMwMDADAANQT1EEAAwyMDI1MDQwOTAwMTcFAAQAAAAICgALUkZDWkpYSUFPQlX%2FAQUwggEBBgkqhkiG9w0BBwKggfMwgfACAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGB0DCBzQIBATAiMB0xDDAKBgNVBAMTA1BPUTENMAsGA1UECxMESjJFRQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjUwNDA5MDAxNzU2WjAjBgkqhkiG9w0BCQQxFgQUvvJ1HSnOLckboGYaMR9Wiaem6z4wCQYHKoZIzjgEAwQvMC0CFQDKLPrpUC19VM2gcslWaHAnh7dfxQIUNs2dTxwGcKdNU%2FdAQPs4f08yaw4%3D; JSESSIONID=_6bPldDq9mFJPXEd11bc-GvrWMAVlgFqVEEA_SAPF-GrpRbcuqxMK_gShBYGdmdp; JSESSIONMARKID=QPmRVwktCDxMazp0fUbEMC40LWvmuqOMUbIGpUQQA")
                .build();
        return client.newCall(request).execute();
src/main/java/com/gs/xiaomi/service/XM104Service.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,167 @@
package com.gs.xiaomi.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.gs.xiaomi.config.DataAcquisitionConfiguration;
import com.gs.xiaomi.dto.*;
import com.gs.xiaomi.entity.DeliveryDetail;
import com.gs.xiaomi.entity.DeliveryMain;
import com.gs.xiaomi.entity.LogisticsPackage;
import com.gs.xiaomi.entity.PackageDetail;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class XM104Service {
    private static final Logger log = LoggerFactory.getLogger(XM104Service.class);
    private final SoapApiService soapApiService;
    private final DeliveryMainService deliveryMainService;
    private final PackageDetailService packageDetailService;
    private final DeliveryDetailService deliveryDetailService;
    private final LogisticsPackageService logisticsPackageService;
    public void getDb() {
        String format = DateUtil.format(new Date(), "yyyy-MM-dd");
        ZfmWsApiRequest req = new ZfmWsApiRequest();
        req.setIvCode(DataAcquisitionConfiguration.IV_CODEXM104);
        req.setIvEvent("");
        req.setIvFlag("");
        BizDocument doc = new BizDocument();
        doc.setBizDate(format);
        doc.setLifnr(DataAcquisitionConfiguration.LIFNR);
        req.setIvInfo(doc);
        req.setIvPass(DataAcquisitionConfiguration.getIvPass(DataAcquisitionConfiguration.IV_CODEXM104));
        req.setIvUser(DataAcquisitionConfiguration.IV_USER);
        try {
            BizDocumentResult deliveryNo = getDeliveryNo(req);
            if (CollUtil.isNotEmpty(deliveryNo.getEtHeaders())) {
                log.info("【BizDocumentResult】返回列表为空,跳过处理");
                log.info("获取接口列表返回: {}", deliveryNo.getEvMessage());
                return;
            }
            //获取所有的ASN号
            List<EtHeader> etHeaders = deliveryNo.getEtHeaders();
            etHeaders.forEach(etHeader -> {
                log.info("1.获取到送货单号: {}", etHeader.getZzasn());
                //根据每行ASN号获取详细的明细
                doc.setZzasn(etHeader.getZzasn());
                req.setIvInfo(doc);
                try {
                    BizDocumentResult result = getDeliveryNo(req);
                    if (result == null) {
                        log.info("【BizDocumentResult】获取送货单详情信息为空,跳过处理");
                        return;
                    }
                    log.info("2.写入数据库: {}", etHeader.getZzasn());
                    //写入到数据库中
                    setDeliveryMain(result);
                } catch (Exception e) {
                    log.error("【写入数据库异常】送货单: {}, å¼‚常: {}", etHeader.getZzasn(), e.getMessage(), e);
                    throw new RuntimeException(e);
                }
            });
        } catch (Exception e) {
            log.error("【读取列表异常】参数: {} å¼‚常: {}", JSON.toJSONString(req), e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }
    private BizDocumentResult getDeliveryNo(ZfmWsApiRequest request) throws Exception {
        BizDocumentResult bizDocumentResult = soapApiService.callAndParse(DataAcquisitionConfiguration.XM104_URL, request);
        return bizDocumentResult;
    }
    private void setDeliveryMain(BizDocumentResult result) {
        List<EtHeader> etHeaders = result.getEtHeaders();
        etHeaders.forEach(etHeader -> {
            DeliveryMain deliveryMain = new DeliveryMain();
            BeanUtil.copyProperties(etHeader, deliveryMain);
            long id = deliveryMainService.getId();
            deliveryMain.setId(id);
            deliveryMainService.save(deliveryMain);
            List<Item> items = etHeader.getItems();
            if (CollUtil.isNotEmpty(items)) {
                List<DeliveryDetail> deliveryDetails = new ArrayList<>();
                for (Item item : items) {
                    DeliveryDetail deliveryDetail = new DeliveryDetail();
                    BeanUtil.copyProperties(item, deliveryDetail);
                    deliveryDetail.setPid(deliveryMain.getId());
                    deliveryDetails.add(deliveryDetail);
                }
                deliveryDetailService.saveBatch(deliveryDetails);
            }
            List<BoxItem> boxItems = etHeader.getBoxItems();
            if (CollUtil.isNotEmpty(boxItems)) {
                List<PackageDetail> list = new ArrayList<>();
                for (BoxItem boxItem : boxItems) {
                    PackageDetail packageDetail = new PackageDetail();
                    BeanUtil.copyProperties(boxItem, packageDetail);
                    packageDetail.setPid(deliveryMain.getId());
                    list.add(packageDetail);
                }
                packageDetailService.saveBatch(list);
            }
            List<BoxSum> boxSums = etHeader.getBoxSums();
            if (CollUtil.isNotEmpty(boxSums)) {
                List<LogisticsPackage> list = new ArrayList<>();
                for (BoxSum boxSum : boxSums) {
                    LogisticsPackage logisticsPackage = new LogisticsPackage();
                    BeanUtil.copyProperties(boxSum, logisticsPackage);
                    logisticsPackage.setPid(deliveryMain.getId());
                    list.add(logisticsPackage);
                }
                logisticsPackageService.saveBatch(list);
            }
        });
    }
}
src/main/java/com/gs/xiaomi/service/impl/DeliveryDetailServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.gs.xiaomi.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gs.xiaomi.entity.DeliveryDetail;
import com.gs.xiaomi.mapper.DeliveryDetailMapper;
import com.gs.xiaomi.service.DeliveryDetailService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€DELIVERY_DETAIL】的数据库操作Service实现
 * @createDate 2025-04-10 14:16:44
 */
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class DeliveryDetailServiceImpl extends ServiceImpl<DeliveryDetailMapper, DeliveryDetail>
        implements DeliveryDetailService {
}
src/main/java/com/gs/xiaomi/service/impl/DeliveryMainServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.gs.xiaomi.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gs.xiaomi.entity.DeliveryMain;
import com.gs.xiaomi.mapper.DeliveryMainMapper;
import com.gs.xiaomi.service.DeliveryMainService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€DELIVERY_MAIN】的数据库操作Service实现
 * @createDate 2025-04-10 14:16:52
 */
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class DeliveryMainServiceImpl extends ServiceImpl<DeliveryMainMapper, DeliveryMain>
        implements DeliveryMainService {
    @Override
    public long getId() {
        return baseMapper.getNextVal();
    }
}
src/main/java/com/gs/xiaomi/service/impl/LogisticsPackageServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.gs.xiaomi.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gs.xiaomi.entity.LogisticsPackage;
import com.gs.xiaomi.mapper.LogisticsPackageMapper;
import com.gs.xiaomi.service.LogisticsPackageService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€LOGISTICS_PACKAGE】的数据库操作Service实现
 * @createDate 2025-04-10 14:17:13
 */
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class LogisticsPackageServiceImpl extends ServiceImpl<LogisticsPackageMapper, LogisticsPackage>
        implements LogisticsPackageService {
}
src/main/java/com/gs/xiaomi/service/impl/PackageDetailServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.gs.xiaomi.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gs.xiaomi.entity.PackageDetail;
import com.gs.xiaomi.mapper.PackageDetailMapper;
import com.gs.xiaomi.service.PackageDetailService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * @author 28567
 * @description é’ˆå¯¹è¡¨ã€PACKAGE_DETAIL】的数据库操作Service实现
 * @createDate 2025-04-10 14:17:48
 */
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class PackageDetailServiceImpl extends ServiceImpl<PackageDetailMapper, PackageDetail>
        implements PackageDetailService {
}
src/main/resources/application.yml
@@ -6,8 +6,8 @@
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: oracle.jdbc.OracleDriver
    url: jdbc:oracle:thin:@122.226.249.238:5936/ORCL
    username: zmz_prd
    password: zmzprd
    username: xb_prd
    password: xbprd
    druid:
      initialSize: 5
      minIdle: 5
@@ -37,15 +37,15 @@
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
    jdbc-type-for-null: 'null'
  type-aliases-package: com.gs.xky.entity.*
  type-aliases-package: com.gs.xiaomi.entity.*
  mapper-locations: classpath:mapper/*.xml
logging:
  level:
    root: info
    com.gs.xky.service.XkyService: debug  # æŒ‡å®š XkyService è®°å½• debug çº§åˆ«çš„æ—¥å¿—
    com.gs.xiaomi.service.XM104Service: debug  # æŒ‡å®š XkyService è®°å½• debug çº§åˆ«çš„æ—¥å¿—
  file:
    name: logs/xky_service.log  # æŒ‡å®šæ—¥å¿—文件路径
    name: logs/xm104_service.log  # æŒ‡å®šæ—¥å¿—文件路径
  pattern:
    file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
src/main/resources/mapper/DeliveryDetailMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
<?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.DeliveryDetailMapper">
</mapper>
src/main/resources/mapper/DeliveryMainMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
<?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.DeliveryMainMapper">
    <select id="getNextVal" resultType="java.lang.Long">
        SELECT SEQ_DELIVERY_MAIN.NEXTVAL
        FROM DUAL
    </select>
</mapper>
src/main/resources/mapper/LogisticsPackageMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
<?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.LogisticsPackageMapper">
</mapper>
src/main/resources/mapper/PackageDetailMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
<?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.PackageDetailMapper">
</mapper>
src/test/java/com/gs/xiaomi/XiaomiApplicationTests.java
@@ -1,156 +1,18 @@
package com.gs.xiaomi;
import com.alibaba.fastjson.JSON;
import com.gs.xiaomi.config.DataAcquisitionConfiguration;
import com.gs.xiaomi.dto.BizDocument;
import com.gs.xiaomi.dto.BizDocumentResult;
import com.gs.xiaomi.dto.ZfmWsApiRequest;
import com.gs.xiaomi.service.SoapApiService;
import com.gs.xiaomi.util.SoapXmlBuilder;
import okhttp3.*;
import com.gs.xiaomi.service.XM104Service;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.IOException;
import java.io.StringReader;
@SpringBootTest
class XiaomiApplicationTests {
    @Autowired
    private SoapApiService service;
    private XM104Service xm104Service;
    @Test
    void contextLoads() throws Exception {
        ZfmWsApiRequest req = new ZfmWsApiRequest();
        req.setIvCode(DataAcquisitionConfiguration.IV_CODEXM104);
        req.setIvEvent("");
        req.setIvFlag("");
        BizDocument doc = new BizDocument();
        doc.setBizDate("2025-04-01");
        doc.setLifnr(DataAcquisitionConfiguration.LIFNR);
        req.setIvInfo(doc);
        req.setIvPass(DataAcquisitionConfiguration.getIvPass(DataAcquisitionConfiguration.IV_CODEXM104));
        req.setIvUser(DataAcquisitionConfiguration.IV_USER);
        String soapXml = SoapXmlBuilder.build(req);
        System.out.println(soapXml);
        xm104Service.getDb();
    }
    @Test
    void testService() throws Exception {
        ZfmWsApiRequest req = new ZfmWsApiRequest();
        req.setIvCode(DataAcquisitionConfiguration.IV_CODEXM104);
        req.setIvEvent("");
        req.setIvFlag("");
        BizDocument doc = new BizDocument();
        doc.setBizDate("2025-04-01");
        doc.setLifnr(DataAcquisitionConfiguration.LIFNR);
        req.setIvInfo(doc);
        req.setIvPass(DataAcquisitionConfiguration.getIvPass(DataAcquisitionConfiguration.IV_CODEXM104));
        req.setIvUser(DataAcquisitionConfiguration.IV_USER);
        BizDocumentResult bizDocumentResult = service.callAndParse(DataAcquisitionConfiguration.XM104_URL, req);
        System.out.println(JSON.toJSONString(bizDocumentResult));
    }
    @Test
    void sta() throws IOException, JAXBException {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/xml");
        RequestBody body = RequestBody.create(mediaType, "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:sap-com:document:sap:rfc:functions\">\r\n    <soapenv:Header/>\r\n    <soapenv:Body>\r\n        <urn:ZFM_WS_API>\r\n            <IV_CODE>VDATA.XM104</IV_CODE>\r\n            <IV_EVENT></IV_EVENT>\r\n            <IV_FLAG></IV_FLAG>\r\n            <IV_INFO><![CDATA[<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<document>\r\n    <BIZ_DATE>2025-04-01</BIZ_DATE>\r\n    <I_LIFNR>177301</I_LIFNR>\r\n</document>]]></IV_INFO>\r\n            <IV_PASS>D25932DF5772D0A2DF9620A2A0AB121A</IV_PASS>\r\n            <IV_USER>V177301</IV_USER>\r\n        </urn:ZFM_WS_API>\r\n    </soapenv:Body>\r\n</soapenv:Envelope>");
        Request request = new Request.Builder()
                .url("https://mipoq.p.mi.com/XISOAPAdapter/MessageServlet?p=ic/9e8a118fb0b7379aa11c2a5c2860982a&senderParty=&senderService=ZJ_XIAOBU_QAS&receiverParty=&receiverService=&interface=SI_ZFM_WS_API_OUT&interfaceNamespace=http://xiaomi.com/srm/b2b")
                .method("POST", body)
//                .addHeader("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
                .addHeader("Content-Type", "application/xml")
                .addHeader("Authorization", "Basic UkZDWkpYSUFPQlU6cHBCOVIhSGU=")
                .addHeader("Accept", "*/*")
//                .addHeader("Host", "mipoq.p.mi.com")
                .addHeader("Connection", "keep-alive")
//                .addHeader("Cookie", "saplb_*=(J2EE4281420)4281450; MYSAPSSO2=AjExMDAgABJwb3J0YWw6UkZDWkpYSUFPQlWIAAdkZWZhdWx0AQALUkZDWkpYSUFPQlUCAAMwMDADAANQT1EEAAwyMDI1MDQwOTAwMTcFAAQAAAAICgALUkZDWkpYSUFPQlX%2FAQUwggEBBgkqhkiG9w0BBwKggfMwgfACAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGB0DCBzQIBATAiMB0xDDAKBgNVBAMTA1BPUTENMAsGA1UECxMESjJFRQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjUwNDA5MDAxNzU2WjAjBgkqhkiG9w0BCQQxFgQUvvJ1HSnOLckboGYaMR9Wiaem6z4wCQYHKoZIzjgEAwQvMC0CFQDKLPrpUC19VM2gcslWaHAnh7dfxQIUNs2dTxwGcKdNU%2FdAQPs4f08yaw4%3D; JSESSIONID=_6bPldDq9mFJPXEd11bc-GvrWMAVlgFqVEEA_SAPF-GrpRbcuqxMK_gShBYGdmdp; JSESSIONMARKID=nUs7PQMlYui9UqFCm4Z-ZRqUiI8YQ_hLJPJWpUQQA")
                .build();
        Response response = client.newCall(request).execute();
        if (response.isSuccessful() && response.body() != null) {
            String bodyStr = response.body().string();
            String evCode = extractEvCode(bodyStr);
            if (!"Y".equalsIgnoreCase(evCode)) {
                throw new RuntimeException("SOAP business failed, EV_CODE: " + evCode);
            }
            String decodedXml = decodeXmlEntities(bodyStr);
            String innerXml = extractCdata(decodedXml);
            if (innerXml == null) throw new RuntimeException("No CDATA <document> found in response");
//            JAXBContext context = JAXBContext.newInstance(BizDocumentResult.class);
//            Unmarshaller unmarshaller = context.createUnmarshaller();
            //BizDocumentResult unmarshal = (BizDocumentResult) unmarshaller.unmarshal(new StringReader(decodedXml));
            System.out.println(JSON.toJSONString(innerXml));
        } else {
            throw new RuntimeException("SOAP request failed: " + response.code() + " - " + response.message());
        }
    }
    @Test
    void contextLoads2() throws Exception {
        String bodyStr = "<SOAP:Envelope xmlns:SOAP='http://schemas.xmlsoap.org/soap/envelope/'>" +
                "  <SOAP:Header/>" +
                "  <SOAP:Body xmlns:urn='urn:sap-com:document:sap:rfc:functions'>" +
                "    <n0:ZFM_WS_APIResponse xmlns:n0='urn:sap-com:document:sap:rfc:functions' xmlns:prx='urn:sap.com:proxy:FRD:/1SAI/TAS82FD47019F21003C052D:752'>" +
                "      <EV_CODE>Y</EV_CODE>" +
                "      <EV_EVENT/>" +
                "      <EV_FLAG/>" +
                "      <EV_RESULT>&#60;?xml version=\"1.0\" encoding=\"utf-8\"?&#62;&#60;document&#62;&#60;et_headers type=\"h\"&#62;&#60;et_header idx=\"1\"&#62;&#60;zzasn&#62;9311031471&#60;/zzasn&#62;&#60;zzasn_type&#62;BL&#60;/zzasn_type&#62;&#60;imclr&#62;&#60;/imclr&#62;&#60;lifnr&#62;0000177301&#60;/lifnr&#62;&#60;vendor_name&#62;浙江小步出行有限公司&#60;/vendor_name&#62;&#60;zzship_addr&#62;测试&#60;/zzship_addr&#62;&#60;zzship_name&#62;11&#60;/zzship_name&#62;&#60;zzship_phon&#62;1111&#60;/zzship_phon&#62;&#60;zzship_date&#62;2025-04-01&#60;/zzship_date&#62;&#60;zzwarehouse_id&#62;0000017560&#60;/zzwarehouse_id&#62;&#60;zzwarehouse&#62;中小件-北京中心仓&#60;/zzwarehouse&#62;&#60;zzreceive_addr&#62;北京市大兴区经济开发区科创十街十五号(亦庄小米产业园)T1楼1层&#60;/zzreceive_addr&#62;&#60;zzcarrier&#62;&#60;/zzcarrier&#62;&#60;zzdriver_name&#62;&#60;/zzdriver_name&#62;&#60;zzdriver_phon&#62;&#60;/zzdriver_phon&#62;&#60;zzarrive_time&#62;20250402&#60;/zzarrive_time&#62;&#60;zzarrive_time1&#62;00:00:00&#60;/zzarrive_time1&#62;&#60;zzcarrier_no&#62;&#60;/zzcarrier_no&#62;&#60;road_transport_no&#62;&#60;/road_transport_no&#62;&#60;zztrans_model&#62;&#60;/zztrans_model&#62;&#60;zzdriver_license&#62;&#60;/zzdriver_license&#62;&#60;zzlicense_numb&#62;&#60;/zzlicense_numb&#62;&#60;zzseal_no&#62;&#60;/zzseal_no&#62;&#60;zzcanceled&#62;&#60;/zzcanceled&#62;&#60;ship_email&#62;11@163.com&#60;/ship_email&#62;&#60;lifnr_dg&#62;&#60;/lifnr_dg&#62;&#60;short_name&#62;&#60;/short_name&#62;&#60;reserve_date&#62;&#60;/reserve_date&#62;&#60;reserve_time&#62;&#60;/reserve_time&#62;&#60;bukrs&#62;1110&#60;/bukrs&#62;&#60;asn_desc&#62;&#60;/asn_desc&#62;&#60;price_stat&#62;&#60;/price_stat&#62;&#60;final_contact&#62;&#60;/final_contact&#62;&#60;final_phone&#62;&#60;/final_phone&#62;&#60;final_addr&#62;&#60;/final_addr&#62;&#60;final_company&#62;&#60;/final_company&#62;&#60;status&#62;S002&#60;/status&#62;&#60;status_sn&#62;&#60;/status_sn&#62;&#60;purchase_mode&#62;&#60;/purchase_mode&#62;&#60;hub_lifnr&#62;&#60;/hub_lifnr&#62;&#60;items type=\"h\"&#62;&#60;item idx=\"1\"&#62;&#60;zzasn&#62;9311031471&#60;/zzasn&#62;&#60;zzitem_id&#62;0000000010&#60;/zzitem_id&#62;&#60;zzpo_no&#62;4500173648&#60;/zzpo_no&#62;&#60;zzpo_item_id&#62;0000000010&#60;/zzpo_item_id&#62;&#60;zzreqnr&#62;&#60;/zzreqnr&#62;&#60;zzreqln&#62;&#60;/zzreqln&#62;&#60;zzproduct_id&#62;950102000010&#60;/zzproduct_id&#62;&#60;zzvproduct_id&#62;&#60;/zzvproduct_id&#62;&#60;zzsku&#62;BHR4008CN&#60;/zzsku&#62;&#60;zzquantity&#62;5.000&#60;/zzquantity&#62;&#60;zzunit&#62;ST&#60;/zzunit&#62;&#60;brand&#62;&#60;/brand&#62;&#60;place&#62;&#60;/place&#62;&#60;brand_type&#62;&#60;/brand_type&#62;&#60;is_identification&#62;&#60;/is_identification&#62;&#60;zzopen_qty&#62;5.000&#60;/zzopen_qty&#62;&#60;changed_at&#62;20250401071304&#60;/changed_at&#62;&#60;created_at&#62;20250401071304&#60;/created_at&#62;&#60;app_models&#62;11-AD&#60;/app_models&#62;&#60;ext_doc_no&#62;8897300&#60;/ext_doc_no&#62;&#60;ext_doc_item&#62;2884654&#60;/ext_doc_item&#62;&#60;address_detail&#62;北京市大兴区经济开发区科创十街十五号(亦庄小米产业园)T1楼1层&#60;/address_detail&#62;&#60;batch_id&#62;&#60;/batch_id&#62;&#60;batch_row&#62;&#60;/batch_row&#62;&#60;xmsto_no&#62;&#60;/xmsto_no&#62;&#60;xmsto_item_no&#62;&#60;/xmsto_item_no&#62;&#60;modelnumber&#62;&#60;/modelnumber&#62;&#60;shipment_id&#62;&#60;/shipment_id&#62;&#60;shipmentid_num&#62;0&#60;/shipmentid_num&#62;&#60;maktx&#62;米家智能侧吸油烟机&#60;/maktx&#62;&#60;bednr&#62;&#60;/bednr&#62;&#60;ware_type_from&#62;&#60;/ware_type_from&#62;&#60;ware_type_to&#62;&#60;/ware_type_to&#62;&#60;act_gr_qty&#62;0.000&#60;/act_gr_qty&#62;&#60;pn_matnr_l&#62;&#60;/pn_matnr_l&#62;&#60;pn_matnr_name&#62;&#60;/pn_matnr_name&#62;&#60;/item&#62;&#60;/items&#62;&#60;box_items type=\"h\"&#62;&#60;/box_items&#62;&#60;box_sums type=\"h\"&#62;&#60;/box_sums&#62;&#60;purchase_mode2&#62;&#60;/purchase_mode2&#62;&#60;receiver&#62;杨丹丹,周晨光&#60;/receiver&#62;&#60;receive_phone&#62;18811578183,13002157815&#60;/receive_phone&#62;&#60;receive_addr&#62;北京市大兴区经济开发区科创十街十五号(亦庄小米产业园)T1楼1层&#60;/receive_addr&#62;&#60;receive_warehouse_id&#62;0000017560&#60;/receive_warehouse_id&#62;&#60;receive_warehouse_short&#62;中小件-北京中心仓&#60;/receive_warehouse_short&#62;&#60;product_type&#62;GM&#60;/product_type&#62;&#60;ekorg&#62;2120&#60;/ekorg&#62;&#60;ekotx&#62;&#60;/ekotx&#62;&#60;stock_org_from&#62;&#60;/stock_org_from&#62;&#60;stock_org_from_desc&#62;&#60;/stock_org_from_desc&#62;&#60;stock_org_to&#62;MI_IOT&#60;/stock_org_to&#62;&#60;stock_org_to_desc&#62;生态链库存组织(IOT)&#60;/stock_org_to_desc&#62;&#60;migo_type&#62;&#60;/migo_type&#62;&#60;zrproject&#62;A1&#60;/zrproject&#62;&#60;logistics_no&#62;&#60;/logistics_no&#62;&#60;logistics_company&#62;&#60;/logistics_company&#62;&#60;last4_phone_number&#62;&#60;/last4_phone_number&#62;&#60;logistics_company_name&#62;&#60;/logistics_company_name&#62;&#60;business_model&#62;&#60;/business_model&#62;&#60;/et_header&#62;&#60;/et_headers&#62;&#60;ev_message&#62;&#60;/ev_message&#62;&#60;ev_msgty&#62;S&#60;/ev_msgty&#62;&#60;/document&#62;</EV_RESULT>" +
                "    </n0:ZFM_WS_APIResponse>" +
                "  </SOAP:Body>" +
                "</SOAP:Envelope>";
        String evCode = extractEvCode(bodyStr);
        if (!"Y".equalsIgnoreCase(evCode)) {
            throw new RuntimeException("SOAP business failed, EV_CODE: " + evCode);
        }
        String decodedXml = decodeXmlEntities(bodyStr);
        String innerXml = extractCdata(decodedXml);
        if (innerXml == null) throw new RuntimeException("No CDATA <document> found in response");
        JAXBContext context = JAXBContext.newInstance(BizDocumentResult.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        BizDocumentResult unmarshal = (BizDocumentResult) unmarshaller.unmarshal(new StringReader(innerXml));
        System.out.println(JSON.toJSONString(unmarshal));
    }
    private String extractEvCode(String xml) {
        int start = xml.indexOf("<EV_CODE>");
        int end = xml.indexOf("</EV_CODE>", start);
        if (start == -1 || end == -1) return null;
        return xml.substring(start + 9, end).trim();
    }
    private String decodeXmlEntities(String xml) {
        return xml.replace("&#60;", "<")
                .replace("&#62;", ">")
                .replace("&lt;", "<")
                .replace("&gt;", ">")
                .replace("&amp;", "&");
    }
    private String extractCdata(String xml) {
        int cdataStart = xml.indexOf("<EV_RESULT>");
        int cdataEnd = xml.indexOf("</EV_RESULT>", cdataStart);
        if (cdataStart == -1 || cdataEnd == -1) return null;
        return xml.substring(cdataStart + 11, cdataEnd).trim();
    }
}