itemList; // 非数据库集合字段
+}
diff --git a/src/main/java/com/supervision/edh/domain/EdhDrugOperateLicenseBaseInfo.java b/src/main/java/com/supervision/edh/domain/EdhDrugOperateLicenseBaseInfo.java
new file mode 100644
index 0000000..b3c2c15
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/EdhDrugOperateLicenseBaseInfo.java
@@ -0,0 +1,127 @@
+package com.supervision.edh.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDate;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.supervision.edh.utils.LocalDateDeserializer;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * 药监企业数据上报-药品经营许可证基本信息
+ *
+ *
+ * @author Jason
+ * @since 2025-06-19
+ */
+@Data
+@TableName("edh_drug_operate_license_base_info")
+public class EdhDrugOperateLicenseBaseInfo implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ private String eventId;
+
+ /**
+ * 经营许可证编号
+ */
+ private String jyxkzbh;
+
+ /**
+ * 企业名称
+ */
+ private String qymc;
+
+ /**
+ * 统一社会信用代码
+ */
+ private String tyshxydm;
+
+ /**
+ * 注册地址
+ */
+ private String zcdz;
+
+ /**
+ * 法定代表人
+ */
+ private String fddbr;
+
+ /**
+ * 企业负责人
+ */
+ private String qyfzr;
+
+ /**
+ * 质量负责人
+ */
+ private String zlfzr;
+
+ /**
+ * 仓库地址
+ */
+ private String ckdz;
+
+ /**
+ * 经营方式
+ */
+ private String jyfs;
+
+ /**
+ * 经营范围
+ */
+ private String jyfw;
+
+ /**
+ * 有效期
+ */
+ @JsonDeserialize(using = LocalDateDeserializer.class)
+ private LocalDate yxq;
+
+ /**
+ * 发证机关
+ */
+ private String fzjg;
+
+ /**
+ * 签发人
+ */
+ private String qfr;
+
+ /**
+ * 签发日期
+ */
+ @JsonDeserialize(using = LocalDateDeserializer.class)
+ private LocalDate qfrq;
+
+ /**
+ * 日常监督管 理机构
+ */
+ private String rcjdgljg;
+
+ /**
+ * 投诉举报电 话
+ */
+ private String tsjbdh;
+
+ /**
+ * 企业类型
+ */
+ private String qylx;
+
+ /**
+ * 企业小类
+ */
+ private String qyxl;
+
+
+}
diff --git a/src/main/java/com/supervision/edh/domain/EdhDrugOperatorsBaseInfo.java b/src/main/java/com/supervision/edh/domain/EdhDrugOperatorsBaseInfo.java
new file mode 100644
index 0000000..c3214df
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/EdhDrugOperatorsBaseInfo.java
@@ -0,0 +1,143 @@
+package com.supervision.edh.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.supervision.edh.utils.LocalDateDeserializer;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * 药监企业数据上报-药品经营企业基本信息
+ *
+ *
+ * @author Jason
+ * @since 2025-06-18
+ */
+@Getter
+@Setter
+@TableName("edh_drug_operators_base_info")
+public class EdhDrugOperatorsBaseInfo implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键ID
+ */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 事件流水号
+ */
+ private String eventId;
+
+ /**
+ * 统一社会信用代码
+ */
+ private String tyshxydm;
+
+ /**
+ * 企业名称
+ */
+ private String qymc;
+
+ /**
+ * 企业类型
+ */
+ private String qylx;
+
+ /**
+ * 企业小类
+ */
+ private String qyxl;
+
+ /**
+ * 住所地址
+ */
+ private String zsdz;
+
+ /**
+ * 行政区划代码
+ */
+ private String xzqhdm;
+
+ /**
+ * 法定代表人
+ */
+ private String fddbr;
+
+ /**
+ * 注册资本
+ */
+ private String zczb;
+
+ /**
+ * 成立日期
+ */
+ @JsonDeserialize(using = LocalDateDeserializer.class)
+ private LocalDate clrq;
+
+ /**
+ * 营业期限
+ */
+ private String yyqx;
+
+ /**
+ * 经营范围
+ */
+ private String jyfw;
+
+ /**
+ * 登记机关
+ */
+ private String djjg;
+
+ /**
+ * 固定电话号码
+ */
+ private String gddhhm;
+
+ /**
+ * 传真号码
+ */
+ private String czhm;
+
+ /**
+ * 电子信箱
+ */
+ private String dzxx;
+
+ /**
+ * 联系人
+ */
+ private String lxr;
+
+ /**
+ * 联系电话
+ */
+ private String lxdh;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private LocalDateTime updateTime;
+
+ /**
+ * 是否删除(0-否 1-是)
+ */
+ private Integer isDeleted;
+
+
+}
diff --git a/src/main/java/com/supervision/edh/domain/EdhReceiveDataLog.java b/src/main/java/com/supervision/edh/domain/EdhReceiveDataLog.java
new file mode 100644
index 0000000..c8e93b3
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/EdhReceiveDataLog.java
@@ -0,0 +1,47 @@
+package com.supervision.edh.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author Jason 药监企业上报数据日志
+ * @date 2025年06月03日 15:28:25
+ */
+@Data
+@TableName("edh_receive_data_log")
+public class EdhReceiveDataLog {
+
+ @TableId(value = "event_id", type = IdType.AUTO)
+ private String eventId;
+
+ private String tyshxydm;
+
+ private String processId;
+
+
+ private String eventType;
+
+ private String eventTypeName;
+
+
+ private String subType;
+
+ private String subTypeName;
+
+
+ private String data;
+
+ private String ver;
+
+ private Date createTime;
+
+ private Date updateTime;
+
+ private Date isDeleted;
+
+
+}
diff --git a/src/main/java/com/supervision/edh/domain/EdhWarehouseStockApplyInfo.java b/src/main/java/com/supervision/edh/domain/EdhWarehouseStockApplyInfo.java
new file mode 100644
index 0000000..a6b385d
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/EdhWarehouseStockApplyInfo.java
@@ -0,0 +1,188 @@
+package com.supervision.edh.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.supervision.edh.domain.vo.DrugVO;
+import com.supervision.edh.domain.vo.StockVO;
+import com.supervision.edh.utils.LocalDateDeserializer;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * 药监企业数据上报-库存上报信息表
+ *
+ *
+ * @author Jason
+ * @since 2025-06-23
+ */
+@Getter
+@Setter
+@TableName("edh_warehouse_stock_apply_info")
+public class EdhWarehouseStockApplyInfo implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键ID
+ */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 事件流水号
+ */
+ private String eventId;
+
+ /**
+ * 统一社会信用代码(库存单位)
+ */
+ private String tyshxydmkcdw;
+
+ /**
+ * 库存单位名称
+ */
+ private String kcdwmc;
+
+ /**
+ * 库存统计日期
+ */
+ @JsonDeserialize(using = LocalDateDeserializer.class)
+ private LocalDate kctjrq;
+
+ /**
+ * 库存地址
+ */
+ private String kcdz;
+
+ /**
+ * 药品通用名称
+ */
+ private String yptymc;
+
+ /**
+ * 国家药品标识码
+ */
+ private String gjypbsm;
+
+ /**
+ * 药品生产批号
+ */
+ private String ypscph;
+
+ /**
+ * 药品生产日期
+ */
+ private LocalDate ypscrq;
+
+ /**
+ * 药品有效期截止日期
+ */
+ private LocalDate ypyxqjzrq;
+
+ /**
+ * 库存制剂数量
+ */
+ private Integer kcsl;
+
+ /**
+ * 实际库存数量
+ */
+ private Integer sjkcsl;
+
+ /**
+ * 库存单位类型
+ */
+ private String kcdwlx;
+
+ /**
+ * 库存单位类型小类
+ */
+ private String kcdwlxxl;
+
+ /**
+ * 药品批准文号
+ */
+ private String yppzwh;
+
+ /**
+ * 药品上市许可持有人
+ */
+ private String ypssxkcyrmc;
+
+ /**
+ * 药品上市许可持有人代码
+ */
+ private String ypssxkcyrdm;
+
+ /**
+ * 药品生产企业名称
+ */
+ private String ypscqymc;
+
+ /**
+ * 药品生产企业统一社会信用代码
+ */
+ private String ypscqytyshxydm;
+
+ /**
+ * 剂型
+ */
+ private String jx;
+
+ /**
+ * 制剂规格
+ */
+ private String zjgg;
+
+ /**
+ * 包装规格
+ */
+ private String bzgg;
+
+ /**
+ * 包装转换比
+ */
+ private Integer bzzhb;
+
+ /**
+ * 包装转换比单位
+ */
+ private String bzzhbdw;
+
+ /**
+ * 药品注册分类
+ */
+ private String ypzcfl;
+
+ /**
+ * 特殊药品管理分类
+ */
+ private String tsypglfl;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private LocalDateTime updateTime;
+
+ /**
+ * 是否删除(0-否 1-是)
+ */
+ private Integer isDeleted;
+
+ @TableField(exist = false)
+ private List itemList; // 非数据库集合字段
+}
diff --git a/src/main/java/com/supervision/edh/domain/EdhWhTempHumidityApplyInfo.java b/src/main/java/com/supervision/edh/domain/EdhWhTempHumidityApplyInfo.java
new file mode 100644
index 0000000..3c5ca09
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/EdhWhTempHumidityApplyInfo.java
@@ -0,0 +1,126 @@
+package com.supervision.edh.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * 药监企业数据上报-仓库存储温湿度信息表
+ *
+ *
+ * @author Jason
+ * @since 2025-06-21
+ */
+@Getter
+@Setter
+@TableName("edh_wh_temp_humidity_apply_info")
+public class EdhWhTempHumidityApplyInfo implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键ID
+ */
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 事件流水号
+ */
+ private String eventId;
+
+ /**
+ * 企业统一社会信用代码
+ */
+ private String qytyshxydm;
+
+ /**
+ * 企业名称
+ */
+ private String qymc;
+
+ /**
+ * 仓库编号
+ */
+ private String ckbh;
+
+ /**
+ * 仓库地址
+ */
+ private String ckdz;
+
+ /**
+ * 仓库面积
+ */
+ private String ckmj;
+
+ /**
+ * 仓库类型
+ */
+ private String cklx;
+
+ /**
+ * 温度上限
+ */
+ private String wdsx;
+
+ /**
+ * 温度下限
+ */
+ private String wdxx;
+
+ /**
+ * 湿度上限
+ */
+ private String sdsx;
+
+ /**
+ * 湿度下限
+ */
+ private String sdxx;
+
+ /**
+ * 环境温度
+ */
+ private String hjwd;
+
+ /**
+ * 环境湿度
+ */
+ private String hjsd;
+
+ /**
+ * 数据类型(1:正常记录;2:报警记录)
+ */
+ private String sjlx;
+
+ /**
+ * 数据上传时间
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private LocalDateTime sjscsj;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+
+ /**
+ * 更新时间
+ */
+ private LocalDateTime updateTime;
+
+ /**
+ * 是否删除(0-否 1-是)
+ */
+ private Integer isDeleted;
+
+
+}
diff --git a/src/main/java/com/supervision/edh/domain/vo/BaseInfo.java b/src/main/java/com/supervision/edh/domain/vo/BaseInfo.java
new file mode 100644
index 0000000..e8983aa
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/vo/BaseInfo.java
@@ -0,0 +1,12 @@
+package com.supervision.edh.domain.vo;
+
+import lombok.Data;
+
+/**
+ * @author Jason
+ * @date 2025年06月18日 16:49:47
+ */
+@Data
+public class BaseInfo {
+ private String datasetName;
+}
diff --git a/src/main/java/com/supervision/edh/domain/vo/DrugVO.java b/src/main/java/com/supervision/edh/domain/vo/DrugVO.java
new file mode 100644
index 0000000..ea5d509
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/vo/DrugVO.java
@@ -0,0 +1,86 @@
+package com.supervision.edh.domain.vo;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.supervision.edh.utils.LocalDateDeserializer;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.util.List;
+
+/**
+ * @author Jason 药品信息
+ * @date 2025年06月20日 16:28:35
+ */
+@Data
+public class DrugVO {
+ //药品通用名称
+ private String yptymc;
+ //国家药品标识码
+ private String gjypbsm;
+ //药品生产日期
+ @JsonDeserialize(using = LocalDateDeserializer.class)
+ private LocalDate ypscrq;
+ //发货数量
+ private Integer fhsl;
+ //剂型
+ private String jx;
+ //包装规格
+ private String bzgg;
+ //制剂规格
+ private String zjgg;
+ //包装转换比
+ private Integer bzzhb;
+ //包装转换比单位
+ private String bzzhbdw;
+ //药品注册分类
+ private String ypzcfl;
+ //特殊药品管理分类
+ private String tsypglfl;
+ //药品批准文号
+ private String yppzwh;
+ //药品有效期
+ private Integer ypyxq;
+ //药品有效期单位
+ private String ypyxqdw;
+ //药品生产批号
+ private String ypscph;
+ //药品批准文号有效期
+ @JsonDeserialize(using = LocalDateDeserializer.class)
+ private LocalDate yppzwhyxq;
+ //药品有效期截止日期
+ @JsonDeserialize(using = LocalDateDeserializer.class)
+ private LocalDate ypyxqjzrq;
+ //国家基本药物标识
+ private String gjjbywbs;
+ //处方药标识
+ private String cfybs;
+ //药品上市许可持有人名称
+ private String ypssxkcyrmc;
+ //统一社会信用代码(药品上市许可持有人)
+ private String tyshxydmypssxkcyr;
+ //药品生产企业名称
+ private String ypscqymc;
+ //统一社会信用代码(药品生产企业)
+ private String tyshxydmypscqy;
+
+ //分包装厂名称
+ private String fbzcmc;
+ //统一社会信用代码(分包装厂)
+ private String tyshxydmfbzc;
+
+ //#################(收货单字段)
+ //药品英文名称
+ private String ypywmc;
+ //药品商用名称
+ private String ypsymc;
+ //药品本位码
+ private String ypbwm;
+ //应收货数量
+ private Integer yshsl;
+ //实际收货数量
+ private Integer sjshsl;
+
+
+ private List instanceList;
+
+}
diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhDomesticDrugBaseInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhDomesticDrugBaseInfoVO.java
new file mode 100644
index 0000000..7e51c65
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/vo/EdhDomesticDrugBaseInfoVO.java
@@ -0,0 +1,17 @@
+package com.supervision.edh.domain.vo;
+
+import com.supervision.edh.domain.EdhDomesticDrugBaseInfo;
+import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Jason 药品信息上报体
+ * @date 2025年06月20日 15:07:37
+ */
+@Data
+public class EdhDomesticDrugBaseInfoVO extends BaseInfo{
+
+ private List dataSet;
+}
diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhDrugDeliveryNoteApplyInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhDrugDeliveryNoteApplyInfoVO.java
new file mode 100644
index 0000000..d7ed55a
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/vo/EdhDrugDeliveryNoteApplyInfoVO.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.domain.vo;
+
+import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Jason
+ * @date 2025年06月21日 15:55:59
+ */
+@Data
+public class EdhDrugDeliveryNoteApplyInfoVO extends BaseInfo{
+
+ private List dataSet;
+}
diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhDrugInvoiceApplyInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhDrugInvoiceApplyInfoVO.java
new file mode 100644
index 0000000..59f5580
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/vo/EdhDrugInvoiceApplyInfoVO.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.domain.vo;
+
+import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Jason 发货信息上报体
+ * @date 2025年06月20日 16:16:15
+ */
+@Data
+public class EdhDrugInvoiceApplyInfoVO extends BaseInfo{
+
+ private List dataSet;
+}
diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperateLicenseBaseInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperateLicenseBaseInfoVO.java
new file mode 100644
index 0000000..2563e1c
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperateLicenseBaseInfoVO.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.domain.vo;
+
+import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Jason 药品经营企业基本信息上报体
+ * @date 2025年06月19日 16:17:08
+ */
+@Data
+public class EdhDrugOperateLicenseBaseInfoVO extends BaseInfo{
+
+ private List dataSet;
+}
diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperatorsBaseInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperatorsBaseInfoVO.java
new file mode 100644
index 0000000..085e8c1
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperatorsBaseInfoVO.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.domain.vo;
+
+import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Jason 药品经营许可证基本信息上报体
+ * @date 2025年06月18日 15:53:20
+ */
+@Data
+public class EdhDrugOperatorsBaseInfoVO extends BaseInfo{
+
+ private List dataSet;
+}
diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhWarehouseStockApplyInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhWarehouseStockApplyInfoVO.java
new file mode 100644
index 0000000..fec665a
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/vo/EdhWarehouseStockApplyInfoVO.java
@@ -0,0 +1,18 @@
+package com.supervision.edh.domain.vo;
+
+import com.supervision.edh.domain.EdhWarehouseStockApplyInfo;
+import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Jason 库存信息上报体
+ * @date 2025年06月23日 11:26:09
+ */
+@Data
+public class EdhWarehouseStockApplyInfoVO extends BaseInfo{
+
+
+ private List dataSet;
+}
diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhWhTempHumidityApplyInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhWhTempHumidityApplyInfoVO.java
new file mode 100644
index 0000000..a582e1b
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/vo/EdhWhTempHumidityApplyInfoVO.java
@@ -0,0 +1,15 @@
+package com.supervision.edh.domain.vo;
+
+import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Jason 仓库存储温湿度信息数据上报体
+ * @date 2025年06月21日 16:53:58
+ */
+@Data
+public class EdhWhTempHumidityApplyInfoVO extends BaseInfo{
+ List dataSet;
+}
diff --git a/src/main/java/com/supervision/edh/domain/vo/InstanceVO.java b/src/main/java/com/supervision/edh/domain/vo/InstanceVO.java
new file mode 100644
index 0000000..09ad996
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/vo/InstanceVO.java
@@ -0,0 +1,23 @@
+package com.supervision.edh.domain.vo;
+
+import lombok.Data;
+
+/**
+ * @author Jason
+ * @date 2025年06月20日 16:38:08
+ */
+@Data
+public class InstanceVO {
+ //药品追溯码
+ private String ypzsm;
+ //上一级包装药品追溯码
+ private String syjbzypzsm;
+ //包装层级
+ private String bzcj;
+
+ //######(收货单字段)
+ //追溯码验证状态
+ private String zsmyzzt;
+ //包含最小销售包装单元数量
+ private Integer bhzxxsbzdysl;
+}
diff --git a/src/main/java/com/supervision/edh/domain/vo/StockVO.java b/src/main/java/com/supervision/edh/domain/vo/StockVO.java
new file mode 100644
index 0000000..0f5b482
--- /dev/null
+++ b/src/main/java/com/supervision/edh/domain/vo/StockVO.java
@@ -0,0 +1,49 @@
+package com.supervision.edh.domain.vo;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.supervision.edh.utils.LocalDateDeserializer;
+import lombok.Data;
+
+import java.time.LocalDate;
+
+/**
+ * @author Jason 库存信息
+ * @date 2025年06月23日 14:45:43
+ */
+@Data
+public class StockVO {
+ //药品通用名称
+ private String yptymc;
+ private String gjypbsm;
+ private String ypscph;
+
+ @JsonDeserialize(using = LocalDateDeserializer.class)
+ private LocalDate ypscrq;
+
+ @JsonDeserialize(using = LocalDateDeserializer.class)
+ private LocalDate ypyxqjzrq;
+
+ private Integer kcsl;
+ private Integer sjkcsl;
+ private String yppzwh;
+ private String ypssxkcyrmc;
+
+ //药品生产企业名称
+ private String ypscqymc;
+ //药品生产企业代码
+ private String ypscqydm;
+
+ //药品上市许可持有人代码
+ private String ypssxkcyrdm;
+ //药品生产企业统一社会信用代码
+ private String ypscqytyshxydm;
+ private String jx;
+ private String zjgg;
+ private String bzgg;
+ private Integer bzzhb;
+ private String bzzhbdw;
+ private String ypzcfl;
+ private String tsypglfl;
+
+
+}
diff --git a/src/main/java/com/supervision/edh/enums/BuzStatusEnum.java b/src/main/java/com/supervision/edh/enums/BuzStatusEnum.java
new file mode 100644
index 0000000..7b602b3
--- /dev/null
+++ b/src/main/java/com/supervision/edh/enums/BuzStatusEnum.java
@@ -0,0 +1,40 @@
+package com.supervision.edh.enums;
+
+/**
+ * @ClassName BuzStatusEnum
+ * @Desc 回执给协同的
+ * @Author houduo.wk
+ * @Date 2020/2/14
+ **/
+public enum BuzStatusEnum {
+ SUCCESS(0,"执行成功"),
+ PARAM_NULL_ERR(1001,"缺少必填参数"),
+ SIGN_CHECK_ERR(1002,"签名认证失败"),
+ DATA_PARSE_ERR(1003,"数据解析错误"),
+ NO_ACCESS_AUTH_ERR(1004,"无接口访问权限"),
+ SYS_ERR(999,"系统开小差,请稍后重试");
+
+ int buzStatus;
+ String buzMessage;
+
+ public int getBuzStatus() {
+ return buzStatus;
+ }
+
+ public void setBuzStatus(int buzStatus) {
+ this.buzStatus = buzStatus;
+ }
+
+ public String getBuzMessage() {
+ return buzMessage;
+ }
+
+ public void setBuzMessage(String buzMessage) {
+ this.buzMessage = buzMessage;
+ }
+
+ BuzStatusEnum(int buzStatus, String buzMessage) {
+ this.buzStatus = buzStatus;
+ this.buzMessage = buzMessage;
+ }
+}
diff --git a/src/main/java/com/supervision/edh/enums/EventTypeEnum.java b/src/main/java/com/supervision/edh/enums/EventTypeEnum.java
new file mode 100644
index 0000000..3b7a75d
--- /dev/null
+++ b/src/main/java/com/supervision/edh/enums/EventTypeEnum.java
@@ -0,0 +1,38 @@
+package com.supervision.edh.enums;
+
+public enum EventTypeEnum {
+ EVENTTYPE_10("10", "基础信息数据"),
+ EVENTTYPE_20("20", "应用信息数据");
+
+ private final String type;
+ private final String name;
+
+ EventTypeEnum(String type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ // 根据类型获取枚举实例
+ public static EventTypeEnum getByType(String type) {
+ for (EventTypeEnum typeEnum : values()) {
+ if (typeEnum.type.equals(type)) {
+ return typeEnum;
+ }
+ }
+ return null;
+ }
+
+ // 根据类型获取名称
+ public static String getNameByType(String type) {
+ EventTypeEnum typeEnum = getByType(type);
+ return typeEnum != null ? typeEnum.getName() : "未知类型";
+ }
+}
diff --git a/src/main/java/com/supervision/edh/enums/StatusEnum.java b/src/main/java/com/supervision/edh/enums/StatusEnum.java
new file mode 100644
index 0000000..705486c
--- /dev/null
+++ b/src/main/java/com/supervision/edh/enums/StatusEnum.java
@@ -0,0 +1,29 @@
+package com.supervision.edh.enums;
+
+public enum StatusEnum {
+ SUCCESS(0,"OK"),FAILED(1,"FAILED"),BUZ_ERROR(-1,"BUZ_ERROR");
+
+ StatusEnum(Integer status, String msg) {
+ this.status = status;
+ this.msg = msg;
+ }
+
+ private Integer status;
+ private String msg;
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+}
diff --git a/src/main/java/com/supervision/edh/enums/SubTypeEnum.java b/src/main/java/com/supervision/edh/enums/SubTypeEnum.java
new file mode 100644
index 0000000..617cfb8
--- /dev/null
+++ b/src/main/java/com/supervision/edh/enums/SubTypeEnum.java
@@ -0,0 +1,64 @@
+package com.supervision.edh.enums;
+
+/**
+ * @author Jason 数据文件内容子业务类型
+ * @date 2025年06月04日 11:08:40
+ */
+public enum SubTypeEnum {
+ SUBTYPE_1011("1011", "境内药品生产企业基本信息数据子集"),
+ SUBTYPE_1012("1012", "境外药品生产企业基本信息数据子集"),
+ SUBTYPE_1013("1013", "药品生产许可证基本信息数据子集"),
+ SUBTYPE_1014("1014", "药品经营企业基本信息数据子集"),
+ SUBTYPE_1015("1015", "药品经营许可证基本信息数据子集"),
+ SUBTYPE_1016("1016", "药品配送企业基本信息数据子集"),
+ SUBTYPE_1017("1017", "药品使用单位基本信息数据子集"),
+ SUBTYPE_1018("1018", "国产药品基本信息数据子集"),
+ SUBTYPE_1019("1019", "进口药品基本信息数据子集"),
+ SUBTYPE_9001("9001", "药检报告基础信息数据子集"),
+ SUBTYPE_9002("9002", "药检报告概览回传基础信息数据子集"),
+ SUBTYPE_2011("2011", "国产药品生产信息数据子集"),
+ SUBTYPE_2012("2012", "药品进口信息数据子集"),
+ SUBTYPE_2013("2013", "药品自检信息数据子集"),
+ SUBTYPE_2015("2015", "发货单信息数据子集"),
+ SUBTYPE_2016("2016", "收货单信息数据子集"),
+ SUBTYPE_2017("2017", "药品零售与药品使用信息数据子集"),
+ SUBTYPE_2018("2018", "药品召回信息数据子集"),
+ SUBTYPE_2019("2019", "库存上报基本信息数据子集"),
+ SUBTYPE_2020("2020", "撤销单"),
+ SUBTYPE_2051("2051", "温度信息子集-单据与存储设备关系信息"),
+ SUBTYPE_2052("2052", "温度信息子集-存储设备温度信息"),
+ SUBTYPE_2053("2053", "温度信息子集-运输温度信息");
+
+
+ private final String type;
+ private final String name;
+
+ SubTypeEnum(String type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ // 根据类型获取枚举实例
+ public static SubTypeEnum getByType(String type) {
+ for (SubTypeEnum typeEnum : values()) {
+ if (typeEnum.type.equals(type)) {
+ return typeEnum;
+ }
+ }
+ return null;
+ }
+
+ // 根据类型获取名称
+ public static String getNameByType(String type) {
+ SubTypeEnum typeEnum = getByType(type);
+ return typeEnum != null ? typeEnum.getName() : "未知类型";
+ }
+}
diff --git a/src/main/java/com/supervision/edh/exception/GlobalExceptionHandler.java b/src/main/java/com/supervision/edh/exception/GlobalExceptionHandler.java
new file mode 100644
index 0000000..f48bc20
--- /dev/null
+++ b/src/main/java/com/supervision/edh/exception/GlobalExceptionHandler.java
@@ -0,0 +1,127 @@
+package com.supervision.edh.exception;
+
+
+import cn.hutool.core.convert.Convert;
+import com.supervision.edh.common.AjaxResult;
+import com.supervision.edh.constant.HttpStatus;
+import com.supervision.edh.utils.EscapeUtil;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+import org.springframework.validation.BindException;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.MissingPathVariableException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
+
+import javax.servlet.http.HttpServletRequest;
+import java.nio.file.AccessDeniedException;
+
+/**
+ * 全局异常处理器
+ *
+ * @author tcctyn
+ */
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+ private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
+
+ /**
+ * 权限校验异常
+ */
+ @ExceptionHandler(AccessDeniedException.class)
+ public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) {
+ String requestURI = request.getRequestURI();
+ log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage());
+ return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权");
+ }
+
+ /**
+ * 请求方式不支持
+ */
+ @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
+ public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
+ HttpServletRequest request) {
+ String requestURI = request.getRequestURI();
+ log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
+ return AjaxResult.error(e.getMessage());
+ }
+
+ /**
+ * 业务异常
+ */
+ @ExceptionHandler(ServiceException.class)
+ public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) {
+ log.error(e.getMessage(), e);
+ Integer code = e.getCode();
+ return StringUtils.isEmpty(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
+ }
+
+ /**
+ * 请求路径中缺少必需的路径变量
+ */
+ @ExceptionHandler(MissingPathVariableException.class)
+ public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) {
+ String requestURI = request.getRequestURI();
+ log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);
+ return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));
+ }
+
+ /**
+ * 请求参数类型不匹配
+ */
+ @ExceptionHandler(MethodArgumentTypeMismatchException.class)
+ public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) {
+ String requestURI = request.getRequestURI();
+ String value = Convert.toStr(e.getValue());
+ if (!StringUtils.isEmpty(value)) {
+ value = EscapeUtil.clean(value);
+ }
+ log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);
+ return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value));
+ }
+
+ /**
+ * 拦截未知的运行时异常
+ */
+ @ExceptionHandler(RuntimeException.class)
+ public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) {
+ String requestURI = request.getRequestURI();
+ log.error("请求地址'{}',发生未知异常.", requestURI, e);
+ return AjaxResult.error(e.getMessage());
+ }
+
+ /**
+ * 系统异常
+ */
+ @ExceptionHandler(Exception.class)
+ public AjaxResult handleException(Exception e, HttpServletRequest request) {
+ String requestURI = request.getRequestURI();
+ log.error("请求地址'{}',发生系统异常.", requestURI, e);
+ return AjaxResult.error(e.getMessage());
+ }
+
+ /**
+ * 自定义验证异常
+ */
+ @ExceptionHandler(BindException.class)
+ public AjaxResult handleBindException(BindException e) {
+ log.error(e.getMessage(), e);
+ String message = e.getAllErrors().get(0).getDefaultMessage();
+ return AjaxResult.error(message);
+ }
+
+ /**
+ * 自定义验证异常
+ */
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
+ log.error(e.getMessage(), e);
+ String message = e.getBindingResult().getFieldError().getDefaultMessage();
+ return AjaxResult.error(message);
+ }
+
+}
diff --git a/src/main/java/com/supervision/edh/exception/ServiceException.java b/src/main/java/com/supervision/edh/exception/ServiceException.java
new file mode 100644
index 0000000..8b3e715
--- /dev/null
+++ b/src/main/java/com/supervision/edh/exception/ServiceException.java
@@ -0,0 +1,73 @@
+package com.supervision.edh.exception;
+
+/**
+ * 业务异常
+ *
+ * @author tcctyn
+ */
+public final class ServiceException extends RuntimeException
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 错误码
+ */
+ private Integer code;
+
+ /**
+ * 错误提示
+ */
+ private String message;
+
+ /**
+ * 错误明细,内部调试错误
+ *
+ */
+ private String detailMessage;
+
+ /**
+ * 空构造方法,避免反序列化问题
+ */
+ public ServiceException()
+ {
+ }
+
+ public ServiceException(String message)
+ {
+ this.message = message;
+ }
+
+ public ServiceException(String message, Integer code)
+ {
+ this.message = message;
+ this.code = code;
+ }
+
+ public String getDetailMessage()
+ {
+ return detailMessage;
+ }
+
+ @Override
+ public String getMessage()
+ {
+ return message;
+ }
+
+ public Integer getCode()
+ {
+ return code;
+ }
+
+ public ServiceException setMessage(String message)
+ {
+ this.message = message;
+ return this;
+ }
+
+ public ServiceException setDetailMessage(String detailMessage)
+ {
+ this.detailMessage = detailMessage;
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/supervision/edh/factory/EventHandlerFactory.java b/src/main/java/com/supervision/edh/factory/EventHandlerFactory.java
new file mode 100644
index 0000000..d534713
--- /dev/null
+++ b/src/main/java/com/supervision/edh/factory/EventHandlerFactory.java
@@ -0,0 +1,25 @@
+package com.supervision.edh.factory;
+
+import com.supervision.edh.service.handle.EventDataHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @author Jason 事件处理器工厂
+ * @date 2025年06月05日 11:29:54
+ */
+@Service
+public class EventHandlerFactory {
+ @Autowired
+ private Map handlerMap;
+
+ public EventDataHandler getHandler(String subType) {
+ EventDataHandler handler = handlerMap.get(subType);
+ if (handler == null) {
+ throw new IllegalArgumentException("未找到对应的处理器: " + subType);
+ }
+ return handler;
+ }
+}
diff --git a/src/main/java/com/supervision/edh/generator/CodeGenerator.java b/src/main/java/com/supervision/edh/generator/CodeGenerator.java
new file mode 100644
index 0000000..1271a34
--- /dev/null
+++ b/src/main/java/com/supervision/edh/generator/CodeGenerator.java
@@ -0,0 +1,41 @@
+package com.supervision.edh.generator;
+
+
+import com.baomidou.mybatisplus.generator.FastAutoGenerator;
+import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
+
+import java.nio.file.Paths;
+
+/**
+ * @author Jason
+ * @date 2025年06月06日 09:35:59
+ */
+public class CodeGenerator {
+
+ public static void main(String[] args) {
+ String tables="edh_warehouse_stock_apply_info";// 单表生成
+ FastAutoGenerator.create("jdbc:mysql://47.109.202.121:3306/supervisionx_trace_data", "root", "TCCT3.1415926")
+ .globalConfig(builder -> builder
+ .author("Jason")
+ .outputDir(Paths.get(System.getProperty("user.dir")) + "/src/main/java")
+ .commentDate("yyyy-MM-dd")
+ .fileOverride() // 显式启用覆盖(默认行为)
+ )
+ .packageConfig(builder -> builder
+ .parent("com.supervision.edh")
+ .entity("domain")
+ .mapper("mapper")
+ .service("service")
+ .serviceImpl("service.impl")
+ .xml("mapper.xml")
+ )
+ .strategyConfig(builder -> builder
+ .addInclude(tables)
+ .entityBuilder()
+ .enableLombok()
+ )
+ .templateEngine(new FreemarkerTemplateEngine())
+ .execute();
+ System.out.println("数据表"+tables+"--------生成实体成功!!");
+ }
+}
diff --git a/src/main/java/com/supervision/edh/mapper/EdhDomesticDrugBaseInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhDomesticDrugBaseInfoMapper.java
new file mode 100644
index 0000000..c47eb37
--- /dev/null
+++ b/src/main/java/com/supervision/edh/mapper/EdhDomesticDrugBaseInfoMapper.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.mapper;
+
+import com.supervision.edh.domain.EdhDomesticDrugBaseInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ *
+ * 药监企业数据上报-药品基本信息数据子集 Mapper 接口
+ *
+ *
+ * @author Jason
+ * @since 2025-06-20
+ */
+public interface EdhDomesticDrugBaseInfoMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/supervision/edh/mapper/EdhDrugDeliveryNoteApplyInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhDrugDeliveryNoteApplyInfoMapper.java
new file mode 100644
index 0000000..0c694eb
--- /dev/null
+++ b/src/main/java/com/supervision/edh/mapper/EdhDrugDeliveryNoteApplyInfoMapper.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.mapper;
+
+import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ *
+ * 药监企业数据上报-药品收货单信息表 Mapper 接口
+ *
+ *
+ * @author Jason
+ * @since 2025-06-21
+ */
+public interface EdhDrugDeliveryNoteApplyInfoMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/supervision/edh/mapper/EdhDrugInvoiceApplyInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhDrugInvoiceApplyInfoMapper.java
new file mode 100644
index 0000000..c85dea6
--- /dev/null
+++ b/src/main/java/com/supervision/edh/mapper/EdhDrugInvoiceApplyInfoMapper.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.mapper;
+
+import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ *
+ * 药监企业数据上报-发货单信息数据子集 Mapper 接口
+ *
+ *
+ * @author Jason
+ * @since 2025-06-20
+ */
+public interface EdhDrugInvoiceApplyInfoMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/supervision/edh/mapper/EdhDrugOperateLicenseBaseInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhDrugOperateLicenseBaseInfoMapper.java
new file mode 100644
index 0000000..8c0f156
--- /dev/null
+++ b/src/main/java/com/supervision/edh/mapper/EdhDrugOperateLicenseBaseInfoMapper.java
@@ -0,0 +1,20 @@
+package com.supervision.edh.mapper;
+
+import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * 药监企业数据上报-药品经营许可证基本信息 Mapper 接口
+ *
+ *
+ * @author Jason
+ * @since 2025-06-19
+ */
+public interface EdhDrugOperateLicenseBaseInfoMapper extends BaseMapper {
+
+ List listByJyxkzbhIn(Set jyxkzbhSet);
+}
diff --git a/src/main/java/com/supervision/edh/mapper/EdhDrugOperatorsBaseInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhDrugOperatorsBaseInfoMapper.java
new file mode 100644
index 0000000..e70a174
--- /dev/null
+++ b/src/main/java/com/supervision/edh/mapper/EdhDrugOperatorsBaseInfoMapper.java
@@ -0,0 +1,20 @@
+package com.supervision.edh.mapper;
+
+import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * 药监企业数据上报-药品经营企业基本信息 Mapper 接口
+ *
+ *
+ * @author Jason
+ * @since 2025-06-18
+ */
+public interface EdhDrugOperatorsBaseInfoMapper extends BaseMapper {
+
+ List listByTyshxydmIn(Set tyshxydmSet);
+}
diff --git a/src/main/java/com/supervision/edh/mapper/EdhReceiveDataLogMapper.java b/src/main/java/com/supervision/edh/mapper/EdhReceiveDataLogMapper.java
new file mode 100644
index 0000000..089df37
--- /dev/null
+++ b/src/main/java/com/supervision/edh/mapper/EdhReceiveDataLogMapper.java
@@ -0,0 +1,11 @@
+package com.supervision.edh.mapper;
+
+import com.supervision.edh.domain.EdhReceiveDataLog;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @author Jason
+ * @date 2025年06月03日 15:35:00
+ */
+public interface EdhReceiveDataLogMapper extends BaseMapper {
+}
diff --git a/src/main/java/com/supervision/edh/mapper/EdhWarehouseStockApplyInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhWarehouseStockApplyInfoMapper.java
new file mode 100644
index 0000000..3e931fe
--- /dev/null
+++ b/src/main/java/com/supervision/edh/mapper/EdhWarehouseStockApplyInfoMapper.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.mapper;
+
+import com.supervision.edh.domain.EdhWarehouseStockApplyInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ *
+ * 药监企业数据上报-库存上报信息表 Mapper 接口
+ *
+ *
+ * @author Jason
+ * @since 2025-06-23
+ */
+public interface EdhWarehouseStockApplyInfoMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/supervision/edh/mapper/EdhWhTempHumidityApplyInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhWhTempHumidityApplyInfoMapper.java
new file mode 100644
index 0000000..92ca620
--- /dev/null
+++ b/src/main/java/com/supervision/edh/mapper/EdhWhTempHumidityApplyInfoMapper.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.mapper;
+
+import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ *
+ * 药监企业数据上报-仓库存储温湿度信息表 Mapper 接口
+ *
+ *
+ * @author Jason
+ * @since 2025-06-21
+ */
+public interface EdhWhTempHumidityApplyInfoMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/supervision/edh/service/IEdhDomesticDrugBaseInfoService.java b/src/main/java/com/supervision/edh/service/IEdhDomesticDrugBaseInfoService.java
new file mode 100644
index 0000000..4f7036d
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/IEdhDomesticDrugBaseInfoService.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.service;
+
+import com.supervision.edh.domain.EdhDomesticDrugBaseInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 药监企业数据上报-药品基本信息数据子集 服务类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-20
+ */
+public interface IEdhDomesticDrugBaseInfoService extends IService {
+
+}
diff --git a/src/main/java/com/supervision/edh/service/IEdhDrugDeliveryNoteApplyInfoService.java b/src/main/java/com/supervision/edh/service/IEdhDrugDeliveryNoteApplyInfoService.java
new file mode 100644
index 0000000..68bd1db
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/IEdhDrugDeliveryNoteApplyInfoService.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.service;
+
+import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 药监企业数据上报-药品收货单信息表 服务类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-21
+ */
+public interface IEdhDrugDeliveryNoteApplyInfoService extends IService {
+
+}
diff --git a/src/main/java/com/supervision/edh/service/IEdhDrugInvoiceApplyInfoService.java b/src/main/java/com/supervision/edh/service/IEdhDrugInvoiceApplyInfoService.java
new file mode 100644
index 0000000..52417c6
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/IEdhDrugInvoiceApplyInfoService.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.service;
+
+import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 药监企业数据上报-发货单信息数据子集 服务类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-20
+ */
+public interface IEdhDrugInvoiceApplyInfoService extends IService {
+
+}
diff --git a/src/main/java/com/supervision/edh/service/IEdhDrugOperateLicenseBaseInfoService.java b/src/main/java/com/supervision/edh/service/IEdhDrugOperateLicenseBaseInfoService.java
new file mode 100644
index 0000000..554b121
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/IEdhDrugOperateLicenseBaseInfoService.java
@@ -0,0 +1,22 @@
+package com.supervision.edh.service;
+
+import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * 药监企业数据上报-药品经营许可证基本信息 服务类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-19
+ */
+public interface IEdhDrugOperateLicenseBaseInfoService extends IService {
+
+ List listByJyxkzbhIn(Set jyxkzbhSet);
+}
diff --git a/src/main/java/com/supervision/edh/service/IEdhDrugOperatorsBaseInfoService.java b/src/main/java/com/supervision/edh/service/IEdhDrugOperatorsBaseInfoService.java
new file mode 100644
index 0000000..0ee146b
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/IEdhDrugOperatorsBaseInfoService.java
@@ -0,0 +1,23 @@
+package com.supervision.edh.service;
+
+import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * 药监企业数据上报-药品经营企业基本信息 服务类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-18
+ */
+public interface IEdhDrugOperatorsBaseInfoService extends IService {
+
+
+ List listByTyshxydmIn(Set tyshxydmSet);
+
+}
diff --git a/src/main/java/com/supervision/edh/service/IEdhReceiveDataLogService.java b/src/main/java/com/supervision/edh/service/IEdhReceiveDataLogService.java
new file mode 100644
index 0000000..9c1f9b5
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/IEdhReceiveDataLogService.java
@@ -0,0 +1,7 @@
+package com.supervision.edh.service;
+
+import com.supervision.edh.domain.EdhReceiveDataLog;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+public interface IEdhReceiveDataLogService extends IService {
+}
diff --git a/src/main/java/com/supervision/edh/service/IEdhWarehouseStockApplyInfoService.java b/src/main/java/com/supervision/edh/service/IEdhWarehouseStockApplyInfoService.java
new file mode 100644
index 0000000..8806888
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/IEdhWarehouseStockApplyInfoService.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.service;
+
+import com.supervision.edh.domain.EdhWarehouseStockApplyInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 药监企业数据上报-库存上报信息表 服务类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-23
+ */
+public interface IEdhWarehouseStockApplyInfoService extends IService {
+
+}
diff --git a/src/main/java/com/supervision/edh/service/IEdhWhTempHumidityApplyInfoService.java b/src/main/java/com/supervision/edh/service/IEdhWhTempHumidityApplyInfoService.java
new file mode 100644
index 0000000..580da54
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/IEdhWhTempHumidityApplyInfoService.java
@@ -0,0 +1,16 @@
+package com.supervision.edh.service;
+
+import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 药监企业数据上报-仓库存储温湿度信息表 服务类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-21
+ */
+public interface IEdhWhTempHumidityApplyInfoService extends IService {
+
+}
diff --git a/src/main/java/com/supervision/edh/service/IEventProcessingService.java b/src/main/java/com/supervision/edh/service/IEventProcessingService.java
new file mode 100644
index 0000000..47a2471
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/IEventProcessingService.java
@@ -0,0 +1,13 @@
+package com.supervision.edh.service;
+
+import com.supervision.edh.utils.EventPojo;
+
+public interface IEventProcessingService {
+
+ /**
+ * 处理事件数据
+ * @param data JSON数据
+ * @param eventId 事件ID(用于日志追踪)
+ */
+ void processEvent(EventPojo eventPojo, String data, String eventId);
+}
diff --git a/src/main/java/com/supervision/edh/service/handle/AbstractEventDataHandler.java b/src/main/java/com/supervision/edh/service/handle/AbstractEventDataHandler.java
new file mode 100644
index 0000000..5cfb1fd
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/handle/AbstractEventDataHandler.java
@@ -0,0 +1,24 @@
+package com.supervision.edh.service.handle;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Jason
+ * @date 2025年06月05日 11:11:15
+ */
+public abstract class AbstractEventDataHandler implements EventDataHandler {
+
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ protected abstract Class getEntityClass();
+
+ //protected abstract IService getService();
+
+
+
+}
diff --git a/src/main/java/com/supervision/edh/service/handle/EventDataHandler.java b/src/main/java/com/supervision/edh/service/handle/EventDataHandler.java
new file mode 100644
index 0000000..60b6923
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/handle/EventDataHandler.java
@@ -0,0 +1,12 @@
+package com.supervision.edh.service.handle;
+
+
+/**
+ * 事件处理接口
+ */
+public interface EventDataHandler {
+ //String getSubType(); // 返回业务subType
+
+ //处理数据
+ void handleData(String data,String eventId);
+}
diff --git a/src/main/java/com/supervision/edh/service/handle/EventSubType.java b/src/main/java/com/supervision/edh/service/handle/EventSubType.java
new file mode 100644
index 0000000..f4ad6c1
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/handle/EventSubType.java
@@ -0,0 +1,19 @@
+package com.supervision.edh.service.handle;
+
+import org.springframework.stereotype.Component;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author Jason
+ * @date 2025年06月05日 15:05:31
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Component
+public @interface EventSubType {
+ String value(); // 如 "2011"
+}
diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType1014Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType1014Handler.java
new file mode 100644
index 0000000..f4cfea5
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/handle/core/SubType1014Handler.java
@@ -0,0 +1,109 @@
+package com.supervision.edh.service.handle.core;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo;
+import com.supervision.edh.domain.vo.EdhDrugOperatorsBaseInfoVO;
+import com.supervision.edh.service.IEdhDrugOperatorsBaseInfoService;
+import com.supervision.edh.service.IEdhReceiveDataLogService;
+import com.supervision.edh.service.handle.AbstractEventDataHandler;
+import com.supervision.edh.service.handle.EventSubType;
+import com.supervision.edh.utils.JsonUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+
+/**
+ * @author Jason 企业上报-药品经营企业基本信息数据子集
+ * @date 2025年06月18日 11:14:43
+ */
+@Service
+@EventSubType("1014")
+public class SubType1014Handler extends AbstractEventDataHandler {
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Autowired
+ private IEdhDrugOperatorsBaseInfoService edhDrugOperatorsBaseInfoService;
+
+
+ @Override
+ protected Class getEntityClass() {
+ return EdhDrugOperatorsBaseInfoVO.class;
+ }
+
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void handleData(String data, String eventId) {
+ EdhDrugOperatorsBaseInfoVO VO= JsonUtils.parseJson(data,getEntityClass());
+ // 1. 数据校验与去重
+ if (CollectionUtils.isEmpty(VO.getDataSet())) {
+ log.info("数据为空,跳过处理");
+ return;
+ }
+
+ // 使用Stream去重(按tyshxydm字段)
+ List uniqueList = VO.getDataSet().stream()
+ .filter(Objects::nonNull)
+ .collect(Collectors.toMap(
+ EdhDrugOperatorsBaseInfo::getTyshxydm,
+ Function.identity(),
+ (oldVal, newVal) -> oldVal
+ ))
+ .values()
+ .stream()
+ .peek(item -> item.setEventId(eventId)) // 统一设置eventId
+ .collect(Collectors.toList());
+
+ // 2. 批量查询已存在的数据
+ Set tyshxydmSet = uniqueList.stream()
+ .map(EdhDrugOperatorsBaseInfo::getTyshxydm)
+ .collect(Collectors.toSet());
+
+ // 自定义批量查询方法
+ Map existingMap = edhDrugOperatorsBaseInfoService
+ .listByTyshxydmIn(tyshxydmSet)
+ .stream()
+ .collect(Collectors.toMap(
+ EdhDrugOperatorsBaseInfo::getTyshxydm,
+ Function.identity()
+ ));
+
+ // 3. 分离新增和更新数据
+ List insertList = new ArrayList<>();
+ List updateList = new ArrayList<>();
+
+ uniqueList.forEach(item -> {
+ EdhDrugOperatorsBaseInfo existing = existingMap.get(item.getTyshxydm());
+ if (existing == null) {
+ insertList.add(item);
+ } else {
+ Long existingId = existing.getId();
+ BeanUtils.copyProperties(item, existing);
+ existing.setId(existingId); // 保护原有ID
+ updateList.add(existing);
+ }
+ });
+
+ // 4. 批量操作
+ if (!insertList.isEmpty()) {
+ edhDrugOperatorsBaseInfoService.saveBatch(insertList);
+ }
+ if (!updateList.isEmpty()) {
+ edhDrugOperatorsBaseInfoService.updateBatchById(updateList);
+ }
+ }
+
+}
diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType1015Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType1015Handler.java
new file mode 100644
index 0000000..489cf00
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/handle/core/SubType1015Handler.java
@@ -0,0 +1,107 @@
+package com.supervision.edh.service.handle.core;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo;
+import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo;
+import com.supervision.edh.domain.vo.EdhDrugOperateLicenseBaseInfoVO;
+import com.supervision.edh.domain.vo.EdhDrugOperatorsBaseInfoVO;
+import com.supervision.edh.service.IEdhDrugOperateLicenseBaseInfoService;
+import com.supervision.edh.service.IEdhDrugOperatorsBaseInfoService;
+import com.supervision.edh.service.handle.AbstractEventDataHandler;
+import com.supervision.edh.service.handle.EventSubType;
+import com.supervision.edh.utils.JsonUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+
+/**
+ * @author Jason 药监企业数据上报-药品经营许可证基本信息
+ * @date 2025年06月19日 10:14:43
+ */
+@Service
+@EventSubType("1015")
+public class SubType1015Handler extends AbstractEventDataHandler {
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Autowired
+ private IEdhDrugOperateLicenseBaseInfoService drugOperateLicenseBaseInfoService;
+
+
+ @Override
+ protected Class getEntityClass() {
+ return EdhDrugOperateLicenseBaseInfoVO.class;
+ }
+
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void handleData(String data, String eventId) {
+ EdhDrugOperateLicenseBaseInfoVO VO= JsonUtils.parseJson(data,getEntityClass());
+ // 1. 数据校验与去重
+ if (CollectionUtils.isEmpty(VO.getDataSet())) {
+ log.info("数据为空,跳过处理");
+ return;
+ }
+
+ // 使用Stream去重(按jyxkzbh字段)
+ List uniqueList = VO.getDataSet().stream()
+ .filter(Objects::nonNull)
+ .collect(Collectors.toMap(
+ EdhDrugOperateLicenseBaseInfo::getJyxkzbh,
+ Function.identity(),
+ (oldVal, newVal) -> oldVal
+ ))
+ .values()
+ .stream()
+ .peek(item -> item.setEventId(eventId)) // 统一设置eventId
+ .collect(Collectors.toList());
+
+ // 2. 批量查询已存在的数据
+ Set jyxkzbhSet = uniqueList.stream()
+ .map(EdhDrugOperateLicenseBaseInfo::getJyxkzbh)
+ .collect(Collectors.toSet());
+
+ // 自定义批量查询方法
+ Map existingMap = drugOperateLicenseBaseInfoService
+ .listByJyxkzbhIn(jyxkzbhSet)
+ .stream()
+ .collect(Collectors.toMap(
+ EdhDrugOperateLicenseBaseInfo::getJyxkzbh,
+ Function.identity()
+ ));
+
+ // 3. 分离新增和更新数据
+ List insertList = new ArrayList<>();
+ List updateList = new ArrayList<>();
+
+ uniqueList.forEach(item -> {
+ EdhDrugOperateLicenseBaseInfo existing = existingMap.get(item.getJyxkzbh());
+ if (existing == null) {
+ insertList.add(item);
+ } else {
+ Long existingId = existing.getId();
+ BeanUtils.copyProperties(item, existing);
+ existing.setId(existingId); // 保护原有ID
+ updateList.add(existing);
+ }
+ });
+
+ // 4. 批量操作
+ if (!insertList.isEmpty()) {
+ drugOperateLicenseBaseInfoService.saveBatch(insertList);
+ }
+ if (!updateList.isEmpty()) {
+ drugOperateLicenseBaseInfoService.updateBatchById(updateList);
+ }
+ }
+
+}
diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType1018Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType1018Handler.java
new file mode 100644
index 0000000..6291552
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/handle/core/SubType1018Handler.java
@@ -0,0 +1,50 @@
+package com.supervision.edh.service.handle.core;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.supervision.edh.domain.vo.EdhDomesticDrugBaseInfoVO;
+import com.supervision.edh.domain.vo.EdhDrugOperateLicenseBaseInfoVO;
+import com.supervision.edh.service.IEdhDomesticDrugBaseInfoService;
+import com.supervision.edh.service.IEdhDrugOperateLicenseBaseInfoService;
+import com.supervision.edh.service.handle.AbstractEventDataHandler;
+import com.supervision.edh.service.handle.EventSubType;
+import com.supervision.edh.utils.JsonUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+
+/**
+ * @author Jason 药监企业数据上报-药品基本信息数据子集
+ * @date 2025年06月20日 10:14:43
+ */
+@Service
+@EventSubType("1018")
+public class SubType1018Handler extends AbstractEventDataHandler {
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Autowired
+ private IEdhDomesticDrugBaseInfoService domesticDrugBaseInfoService;
+
+
+ @Override
+ protected Class getEntityClass() {
+ return EdhDomesticDrugBaseInfoVO.class;
+ }
+
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void handleData(String data, String eventId) {
+ EdhDomesticDrugBaseInfoVO VO= JsonUtils.parseJson(data,getEntityClass());
+ if (CollectionUtils.isEmpty(VO.getDataSet())) {
+ log.info("数据为空,跳过处理");
+ return;
+ }
+ VO.getDataSet().forEach(item -> item.setEventId(eventId));
+ domesticDrugBaseInfoService.saveBatch(VO.getDataSet());
+ }
+
+}
diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType2015Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType2015Handler.java
new file mode 100644
index 0000000..b6840d4
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/handle/core/SubType2015Handler.java
@@ -0,0 +1,90 @@
+package com.supervision.edh.service.handle.core;
+
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo;
+import com.supervision.edh.domain.vo.EdhDrugInvoiceApplyInfoVO;
+import com.supervision.edh.domain.vo.InstanceVO;
+import com.supervision.edh.domain.vo.DrugVO;
+import com.supervision.edh.service.IEdhDrugInvoiceApplyInfoService;
+import com.supervision.edh.service.handle.AbstractEventDataHandler;
+import com.supervision.edh.service.handle.EventSubType;
+import com.supervision.edh.utils.DateUtils;
+import com.supervision.edh.utils.JsonUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+/**
+ * @author Jason 药监企业数据上报-发货单信息数据集
+ * @date 2025年06月20日 10:14:43
+ */
+@Service
+@EventSubType("2015")
+public class SubType2015Handler extends AbstractEventDataHandler {
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Autowired
+ private IEdhDrugInvoiceApplyInfoService drugInvoiceApplyInfoService;
+
+
+ @Override
+ protected Class getEntityClass() {
+ return EdhDrugInvoiceApplyInfoVO.class;
+ }
+
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void handleData(String data, String eventId) {
+ EdhDrugInvoiceApplyInfoVO VO= JsonUtils.parseJson(data,getEntityClass());
+ if (CollectionUtils.isEmpty(VO.getDataSet())) {
+ log.info("数据为空,跳过处理");
+ return;
+ }
+ List infoList = VO.getDataSet().stream() // 第一层:发货单列表
+ .flatMap(info -> info.getItemList().stream() // 第二层:药品列表
+ .flatMap(item -> item.getInstanceList().stream() // 第三层:实例列表
+ .map(instance -> buildFlatEntity(info, item, instance,eventId)))) // 合并三个层级的数据
+ .collect(Collectors.toList());
+ drugInvoiceApplyInfoService.saveBatch(infoList);
+ }
+
+ // 构建扁平化实体对象
+ private EdhDrugInvoiceApplyInfo buildFlatEntity(EdhDrugInvoiceApplyInfo info, DrugVO item, InstanceVO instance,String eventId) {
+ EdhDrugInvoiceApplyInfo entity = new EdhDrugInvoiceApplyInfo();
+ // 1. 填充发货单级别字段
+ BeanUtils.copyProperties(info, entity);
+ // 2. 填充药品级别字段
+ BeanUtils.copyProperties(item, entity);
+ // 3. 填充实例级别字段
+ BeanUtils.copyProperties(instance, entity);
+ //事件ID
+ entity.setEventId(eventId);
+ return entity;
+ }
+
+ // 分批插入工具方法
+ private void batchInsert(List list, int batchSize) {
+ // 如果数据量小于等于批处理大小,直接全量插入
+ if (list.size() <= batchSize) {
+ if (!list.isEmpty()) {
+ drugInvoiceApplyInfoService.saveBatch(list);
+ }
+ return;
+ }
+ for (int i = 0; i < list.size(); i += batchSize) {
+ int end = Math.min(i + batchSize, list.size());
+ drugInvoiceApplyInfoService.saveBatch(list.subList(i, end));
+ }
+ }
+
+}
diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType2016Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType2016Handler.java
new file mode 100644
index 0000000..a3c6554
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/handle/core/SubType2016Handler.java
@@ -0,0 +1,88 @@
+package com.supervision.edh.service.handle.core;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo;
+import com.supervision.edh.domain.vo.DrugVO;
+import com.supervision.edh.domain.vo.EdhDrugDeliveryNoteApplyInfoVO;
+import com.supervision.edh.domain.vo.InstanceVO;
+import com.supervision.edh.service.IEdhDrugDeliveryNoteApplyInfoService;
+import com.supervision.edh.service.handle.AbstractEventDataHandler;
+import com.supervision.edh.service.handle.EventSubType;
+import com.supervision.edh.utils.JsonUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+/**
+ * @author Jason 药监企业数据上报-药品收货单信息数据集
+ * @date 2025年06月21日 10:14:43
+ */
+@Service
+@EventSubType("2016")
+public class SubType2016Handler extends AbstractEventDataHandler {
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Autowired
+ private IEdhDrugDeliveryNoteApplyInfoService drugDeliveryNoteApplyInfoService;
+
+
+ @Override
+ protected Class getEntityClass() {
+ return EdhDrugDeliveryNoteApplyInfoVO.class;
+ }
+
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void handleData(String data, String eventId) {
+ EdhDrugDeliveryNoteApplyInfoVO VO= JsonUtils.parseJson(data,getEntityClass());
+ if (CollectionUtils.isEmpty(VO.getDataSet())) {
+ log.info("数据为空,跳过处理");
+ return;
+ }
+ List infoList = VO.getDataSet().stream() // 第一层:发货单列表
+ .flatMap(info -> info.getItemList().stream() // 第二层:药品列表
+ .flatMap(item -> item.getInstanceList().stream() // 第三层:实例列表
+ .map(instance -> buildFlatEntity(info, item, instance,eventId)))) // 合并三个层级的数据
+ .collect(Collectors.toList());
+ drugDeliveryNoteApplyInfoService.saveBatch(infoList);
+ }
+
+ // 构建扁平化实体对象
+ private EdhDrugDeliveryNoteApplyInfo buildFlatEntity(EdhDrugDeliveryNoteApplyInfo info, DrugVO item, InstanceVO instance,String eventId) {
+ EdhDrugDeliveryNoteApplyInfo entity = new EdhDrugDeliveryNoteApplyInfo();
+ // 1. 填充发货单级别字段
+ BeanUtils.copyProperties(info, entity);
+ // 2. 填充药品级别字段
+ BeanUtils.copyProperties(item, entity);
+ // 3. 填充实例级别字段
+ BeanUtils.copyProperties(instance, entity);
+ //事件ID
+ entity.setEventId(eventId);
+ return entity;
+ }
+
+ // 分批插入工具方法
+ private void batchInsert(List list, int batchSize) {
+ // 如果数据量小于等于批处理大小,直接全量插入
+ if (list.size() <= batchSize) {
+ if (!list.isEmpty()) {
+ drugDeliveryNoteApplyInfoService.saveBatch(list);
+ }
+ return;
+ }
+ for (int i = 0; i < list.size(); i += batchSize) {
+ int end = Math.min(i + batchSize, list.size());
+ drugDeliveryNoteApplyInfoService.saveBatch(list.subList(i, end));
+ }
+ }
+
+}
diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType2019Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType2019Handler.java
new file mode 100644
index 0000000..48455ef
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/handle/core/SubType2019Handler.java
@@ -0,0 +1,72 @@
+package com.supervision.edh.service.handle.core;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo;
+import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo;
+import com.supervision.edh.domain.EdhWarehouseStockApplyInfo;
+import com.supervision.edh.domain.vo.*;
+import com.supervision.edh.service.IEdhWarehouseStockApplyInfoService;
+import com.supervision.edh.service.IEdhWhTempHumidityApplyInfoService;
+import com.supervision.edh.service.handle.AbstractEventDataHandler;
+import com.supervision.edh.service.handle.EventSubType;
+import com.supervision.edh.utils.JsonUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+/**
+ * @author Jason 药监企业数据上报-库存上报信息
+ * @date 2025年06月23日 11:22:43
+ */
+@Service
+@EventSubType("2019")
+public class SubType2019Handler extends AbstractEventDataHandler {
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Autowired
+ private IEdhWarehouseStockApplyInfoService warehouseStockApplyInfoService;
+
+
+ @Override
+ protected Class getEntityClass() {
+ return EdhWarehouseStockApplyInfoVO.class;
+ }
+
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void handleData(String data, String eventId) {
+ EdhWarehouseStockApplyInfoVO VO= JsonUtils.parseJson(data,getEntityClass());
+ if (CollectionUtils.isEmpty(VO.getDataSet())) {
+ log.info("数据为空,跳过处理");
+ return;
+ }
+ List infoList = VO.getDataSet().stream() // 第一层:发货单列表
+ .flatMap(info -> info.getItemList().stream() // 第二层:药品列表
+ .map(stock -> buildFlatEntity(info,stock,eventId))) // 合并三个层级的数据
+ .collect(Collectors.toList());
+ warehouseStockApplyInfoService.saveBatch(infoList);
+ }
+
+ // 构建扁平化实体对象
+ private EdhWarehouseStockApplyInfo buildFlatEntity(EdhWarehouseStockApplyInfo info, StockVO stock, String eventId) {
+ EdhWarehouseStockApplyInfo entity = new EdhWarehouseStockApplyInfo();
+ // 1. 填充库存基础信息
+ BeanUtils.copyProperties(info, entity);
+ // 2. 填充库存药品信息
+ BeanUtils.copyProperties(stock, entity);
+ //事件ID
+ entity.setEventId(eventId);
+ return entity;
+ }
+
+
+}
diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType2052Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType2052Handler.java
new file mode 100644
index 0000000..7d55975
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/handle/core/SubType2052Handler.java
@@ -0,0 +1,50 @@
+package com.supervision.edh.service.handle.core;
+
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.supervision.edh.domain.vo.EdhWhTempHumidityApplyInfoVO;
+import com.supervision.edh.service.IEdhWhTempHumidityApplyInfoService;
+import com.supervision.edh.service.handle.AbstractEventDataHandler;
+import com.supervision.edh.service.handle.EventSubType;
+import com.supervision.edh.utils.JsonUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+
+/**
+ * @author Jason 药监企业数据上报-仓库存储温湿度信息表
+ * @date 2025年06月21日 16:14:43
+ */
+@Service
+@EventSubType("2052")
+public class SubType2052Handler extends AbstractEventDataHandler {
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ @Autowired
+ private IEdhWhTempHumidityApplyInfoService whTempHumidityApplyInfoService;
+
+
+ @Override
+ protected Class getEntityClass() {
+ return EdhWhTempHumidityApplyInfoVO.class;
+ }
+
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void handleData(String data, String eventId) {
+ EdhWhTempHumidityApplyInfoVO VO= JsonUtils.parseJson(data,getEntityClass());
+ if (CollectionUtils.isEmpty(VO.getDataSet())) {
+ log.info("数据为空,跳过处理");
+ return;
+ }
+ VO.getDataSet().forEach(item -> {
+ item.setEventId(eventId);
+ });
+ whTempHumidityApplyInfoService.saveBatch(VO.getDataSet());
+ }
+
+}
diff --git a/src/main/java/com/supervision/edh/service/impl/EdhDomesticDrugBaseInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhDomesticDrugBaseInfoServiceImpl.java
new file mode 100644
index 0000000..3be9d1a
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/impl/EdhDomesticDrugBaseInfoServiceImpl.java
@@ -0,0 +1,20 @@
+package com.supervision.edh.service.impl;
+
+import com.supervision.edh.domain.EdhDomesticDrugBaseInfo;
+import com.supervision.edh.mapper.EdhDomesticDrugBaseInfoMapper;
+import com.supervision.edh.service.IEdhDomesticDrugBaseInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 药监企业数据上报-药品基本信息数据子集 服务实现类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-20
+ */
+@Service("domesticDrugBaseInfoService")
+public class EdhDomesticDrugBaseInfoServiceImpl extends ServiceImpl implements IEdhDomesticDrugBaseInfoService {
+
+}
diff --git a/src/main/java/com/supervision/edh/service/impl/EdhDrugDeliveryNoteApplyInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhDrugDeliveryNoteApplyInfoServiceImpl.java
new file mode 100644
index 0000000..d99c722
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/impl/EdhDrugDeliveryNoteApplyInfoServiceImpl.java
@@ -0,0 +1,20 @@
+package com.supervision.edh.service.impl;
+
+import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo;
+import com.supervision.edh.mapper.EdhDrugDeliveryNoteApplyInfoMapper;
+import com.supervision.edh.service.IEdhDrugDeliveryNoteApplyInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 药监企业数据上报-药品收货单信息表 服务实现类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-21
+ */
+@Service("drugDeliveryNoteApplyInfoService")
+public class EdhDrugDeliveryNoteApplyInfoServiceImpl extends ServiceImpl implements IEdhDrugDeliveryNoteApplyInfoService {
+
+}
diff --git a/src/main/java/com/supervision/edh/service/impl/EdhDrugInvoiceApplyInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhDrugInvoiceApplyInfoServiceImpl.java
new file mode 100644
index 0000000..c8384c4
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/impl/EdhDrugInvoiceApplyInfoServiceImpl.java
@@ -0,0 +1,20 @@
+package com.supervision.edh.service.impl;
+
+import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo;
+import com.supervision.edh.mapper.EdhDrugInvoiceApplyInfoMapper;
+import com.supervision.edh.service.IEdhDrugInvoiceApplyInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 药监企业数据上报-发货单信息数据子集 服务实现类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-20
+ */
+@Service("drugInvoiceApplyInfoService")
+public class EdhDrugInvoiceApplyInfoServiceImpl extends ServiceImpl implements IEdhDrugInvoiceApplyInfoService {
+
+}
diff --git a/src/main/java/com/supervision/edh/service/impl/EdhDrugOperateLicenseBaseInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhDrugOperateLicenseBaseInfoServiceImpl.java
new file mode 100644
index 0000000..b42c0af
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/impl/EdhDrugOperateLicenseBaseInfoServiceImpl.java
@@ -0,0 +1,28 @@
+package com.supervision.edh.service.impl;
+
+import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo;
+import com.supervision.edh.mapper.EdhDrugOperateLicenseBaseInfoMapper;
+import com.supervision.edh.service.IEdhDrugOperateLicenseBaseInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * 药监企业数据上报-药品经营许可证基本信息 服务实现类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-19
+ */
+@Service("drugOperateLicenseBaseInfoService")
+public class EdhDrugOperateLicenseBaseInfoServiceImpl extends ServiceImpl implements IEdhDrugOperateLicenseBaseInfoService {
+
+ @Override
+ public List listByJyxkzbhIn(Set jyxkzbhSet) {
+ return getBaseMapper().listByJyxkzbhIn(jyxkzbhSet);
+ }
+}
diff --git a/src/main/java/com/supervision/edh/service/impl/EdhDrugOperatorsBaseInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhDrugOperatorsBaseInfoServiceImpl.java
new file mode 100644
index 0000000..5197b46
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/impl/EdhDrugOperatorsBaseInfoServiceImpl.java
@@ -0,0 +1,33 @@
+package com.supervision.edh.service.impl;
+
+import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo;
+import com.supervision.edh.domain.EdhReceiveDataLog;
+import com.supervision.edh.mapper.EdhDrugOperatorsBaseInfoMapper;
+import com.supervision.edh.mapper.EdhReceiveDataLogMapper;
+import com.supervision.edh.service.IEdhDrugOperatorsBaseInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.supervision.edh.service.IEdhReceiveDataLogService;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * 药监企业数据上报-药品经营企业基本信息 服务实现类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-18
+ */
+@Service("edhDrugOperatorsBaseInfoService")
+public class EdhDrugOperatorsBaseInfoServiceImpl extends ServiceImpl implements IEdhDrugOperatorsBaseInfoService {
+
+
+ @Override
+ public List listByTyshxydmIn(Set tyshxydmSet) {
+ return getBaseMapper().listByTyshxydmIn(tyshxydmSet);
+ }
+}
diff --git a/src/main/java/com/supervision/edh/service/impl/EdhReceiveDataLogServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhReceiveDataLogServiceImpl.java
new file mode 100644
index 0000000..f61d643
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/impl/EdhReceiveDataLogServiceImpl.java
@@ -0,0 +1,15 @@
+package com.supervision.edh.service.impl;
+
+import com.supervision.edh.domain.EdhReceiveDataLog;
+import com.supervision.edh.mapper.EdhReceiveDataLogMapper;
+import com.supervision.edh.service.IEdhReceiveDataLogService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Jason
+ * @date 2025年06月03日 15:37:17
+ */
+@Service("receiveDataLogService")
+public class EdhReceiveDataLogServiceImpl extends ServiceImpl implements IEdhReceiveDataLogService {
+}
diff --git a/src/main/java/com/supervision/edh/service/impl/EdhWarehouseStockApplyInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhWarehouseStockApplyInfoServiceImpl.java
new file mode 100644
index 0000000..d27f15f
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/impl/EdhWarehouseStockApplyInfoServiceImpl.java
@@ -0,0 +1,20 @@
+package com.supervision.edh.service.impl;
+
+import com.supervision.edh.domain.EdhWarehouseStockApplyInfo;
+import com.supervision.edh.mapper.EdhWarehouseStockApplyInfoMapper;
+import com.supervision.edh.service.IEdhWarehouseStockApplyInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 药监企业数据上报-库存上报信息表 服务实现类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-23
+ */
+@Service("warehouseStockApplyInfoService")
+public class EdhWarehouseStockApplyInfoServiceImpl extends ServiceImpl implements IEdhWarehouseStockApplyInfoService {
+
+}
diff --git a/src/main/java/com/supervision/edh/service/impl/EdhWhTempHumidityApplyInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhWhTempHumidityApplyInfoServiceImpl.java
new file mode 100644
index 0000000..8a84d62
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/impl/EdhWhTempHumidityApplyInfoServiceImpl.java
@@ -0,0 +1,20 @@
+package com.supervision.edh.service.impl;
+
+import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo;
+import com.supervision.edh.mapper.EdhWhTempHumidityApplyInfoMapper;
+import com.supervision.edh.service.IEdhWhTempHumidityApplyInfoService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 药监企业数据上报-仓库存储温湿度信息表 服务实现类
+ *
+ *
+ * @author Jason
+ * @since 2025-06-21
+ */
+@Service("whTempHumidityApplyInfoService")
+public class EdhWhTempHumidityApplyInfoServiceImpl extends ServiceImpl implements IEdhWhTempHumidityApplyInfoService {
+
+}
diff --git a/src/main/java/com/supervision/edh/service/impl/EventProcessingServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EventProcessingServiceImpl.java
new file mode 100644
index 0000000..b960f5d
--- /dev/null
+++ b/src/main/java/com/supervision/edh/service/impl/EventProcessingServiceImpl.java
@@ -0,0 +1,31 @@
+package com.supervision.edh.service.impl;
+
+import com.supervision.edh.factory.EventHandlerFactory;
+import com.supervision.edh.service.handle.EventDataHandler;
+import com.supervision.edh.utils.EventPojo;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * @author Jason
+ * @date 2025年06月18日 15:38:51
+ */
+@Service("eventProcessingService")
+@RequiredArgsConstructor
+public class EventProcessingServiceImpl{
+
+ private static final Logger logger = LoggerFactory.getLogger(EventProcessingServiceImpl.class);
+ private final EventHandlerFactory handlerFactory;
+
+ @Async
+ public void asyncProcessEvent(EventPojo eventPojo, String data,String eventId) {
+ EventDataHandler handler = handlerFactory.getHandler(eventPojo.getSubType());
+ handler.handleData(data,eventId);
+
+ }
+}
diff --git a/src/main/java/com/supervision/edh/utils/Base64.java b/src/main/java/com/supervision/edh/utils/Base64.java
new file mode 100644
index 0000000..75b89eb
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/Base64.java
@@ -0,0 +1,102 @@
+package com.supervision.edh.utils;
+
+
+import java.io.UnsupportedEncodingException;
+
+public class Base64 {
+ private static char[] base64EncodeChars = new char[]{
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/'};
+ private static byte[] base64DecodeChars = new byte[]{
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1};
+
+ public static String encode(byte[] data) {
+ StringBuffer sb = new StringBuffer();
+ int len = data.length;
+ int i = 0;
+ int b1, b2, b3;
+ while (i < len) {
+ b1 = data[i++] & 0xff;
+ if (i == len) {
+ sb.append(base64EncodeChars[b1 >>> 2]);
+ sb.append(base64EncodeChars[(b1 & 0x3) << 4]);
+ sb.append("==");
+ break;
+ }
+ b2 = data[i++] & 0xff;
+ if (i == len) {
+ sb.append(base64EncodeChars[b1 >>> 2]);
+ sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
+ sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);
+ sb.append("=");
+ break;
+ }
+ b3 = data[i++] & 0xff;
+ sb.append(base64EncodeChars[b1 >>> 2]);
+ sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
+ sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);
+ sb.append(base64EncodeChars[b3 & 0x3f]);
+ }
+ return sb.toString();
+ }
+
+ public static byte[] decode(String str) throws UnsupportedEncodingException {
+ StringBuffer sb = new StringBuffer();
+ byte[] data = str.getBytes("US-ASCII");
+ int len = data.length;
+ int i = 0;
+ int b1, b2, b3, b4;
+ while (i < len) {
+
+ do {
+ b1 = base64DecodeChars[data[i++]];
+ } while (i < len && b1 == -1);
+ if (b1 == -1) break;
+
+ do {
+ b2 = base64DecodeChars
+ [data[i++]];
+ } while (i < len && b2 == -1);
+ if (b2 == -1) break;
+ sb.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4)));
+
+ do {
+ b3 = data[i++];
+ if (b3 == 61) return sb.toString().getBytes("iso8859-1");
+ b3 = base64DecodeChars[b3];
+ } while (i < len && b3 == -1);
+ if (b3 == -1) break;
+ sb.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2)));
+
+ do {
+ b4 = data[i++];
+ if (b4 == 61) return sb.toString().getBytes("iso8859-1");
+ b4 = base64DecodeChars[b4];
+ } while (i < len && b4 == -1);
+ if (b4 == -1) break;
+ sb.append((char) (((b3 & 0x03) << 6) | b4));
+ }
+ return sb.toString().getBytes("iso8859-1");
+ }
+ public static void main(String[] args) throws UnsupportedEncodingException {
+ String s = "abcd";
+ System.out.println("����ǰ��" + s);
+ String x = encode(s.getBytes());
+ System.out.println("���ܺ�" + x);
+ String x1 = new String(decode(x));
+ System.out.println("���ܺ�" + x1);
+ }
+}
diff --git a/src/main/java/com/supervision/edh/utils/BouncyCastlePFXGenerator.java b/src/main/java/com/supervision/edh/utils/BouncyCastlePFXGenerator.java
new file mode 100644
index 0000000..b9784ca
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/BouncyCastlePFXGenerator.java
@@ -0,0 +1,73 @@
+package com.supervision.edh.utils;
+
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+
+import java.io.FileOutputStream;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+/**
+ * @author Jason
+ * @date 2025年05月28日 15:02:12
+ */
+public class BouncyCastlePFXGenerator {
+
+ static {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public static void generatePFX(String pfxFilePath, String password) throws Exception {
+ // 1. 生成密钥对
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ keyPairGenerator.initialize(2048);
+ KeyPair keyPair = keyPairGenerator.generateKeyPair();
+
+ // 2. 创建自签名证书
+ X500Name issuerName = new X500Name("CN=Test Certificate, OU=Test, O=Test Org, C=US");
+ BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
+ Date notBefore = new Date();
+ Date notAfter = new Date(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000); // 1年有效期
+
+ X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
+ issuerName, serialNumber, notBefore, notAfter, issuerName, keyPair.getPublic());
+
+ ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSAEncryption")
+ .build(keyPair.getPrivate());
+
+ X509Certificate cert = new JcaX509CertificateConverter()
+ .getCertificate(certBuilder.build(signer));
+
+ // 3. 创建PKCS12密钥库
+ KeyStore pkcs12 = KeyStore.getInstance("PKCS12");
+ pkcs12.load(null, null);
+
+ // 4. 添加证书和私钥
+ pkcs12.setKeyEntry("alias", keyPair.getPrivate(), password.toCharArray(),
+ new java.security.cert.Certificate[]{cert});
+
+ // 5. 保存PFX文件
+ try (FileOutputStream fos = new FileOutputStream(pfxFilePath)) {
+ pkcs12.store(fos, password.toCharArray());
+ }
+ }
+
+ public static void main(String[] args) {
+ try {
+ generatePFX("edh.pfx", "YnYp123456");
+ System.out.println("使用Bouncy Castle生成的PFX证书成功!");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/com/supervision/edh/utils/CertManager.java b/src/main/java/com/supervision/edh/utils/CertManager.java
new file mode 100644
index 0000000..5e51568
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/CertManager.java
@@ -0,0 +1,173 @@
+package com.supervision.edh.utils;
+
+import com.supervision.edh.config.CertConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+/**
+ * @author Jason 证书管理
+ * @date 2025年06月06日 14:24:09
+ */
+@Component
+public class CertManager {
+
+ private static volatile String privateKey;
+
+ private static volatile String publicKey;
+
+ @Autowired
+ private CertConfig certConfig;
+
+
+ /**
+ * 私钥解密
+ * @param key
+ * @param data
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeyException
+ * @throws NoSuchPaddingException
+ * @throws InvalidKeySpecException
+ * @throws BadPaddingException
+ * @throws IllegalBlockSizeException
+ * @throws IOException
+ */
+ public String keyDecrypt(String key,String data) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException, IOException{
+ byte[] decode = java.util.Base64.getDecoder().decode(key);
+ RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(certConfig.getAlgorithm()).generatePrivate(new PKCS8EncodedKeySpec(decode));
+ //RSA解密
+ Cipher ci = Cipher.getInstance(certConfig.getAlgorithm());
+ ci.init(Cipher.DECRYPT_MODE, priKey);
+
+
+ byte[] bytes = java.util.Base64.getDecoder().decode(data);
+ int inputLen = bytes.length;
+ int offLen = 0;
+ int i = 0;
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ while(inputLen - offLen > 0){
+ byte[] cache;
+ if(inputLen - offLen > 256){
+ cache = ci.doFinal(bytes,offLen,256);
+ }else{
+ cache = ci.doFinal(bytes,offLen,inputLen - offLen);
+ }
+ byteArrayOutputStream.write(cache);
+ i++;
+ offLen = 256 * i;
+
+ }
+ byteArrayOutputStream.close();
+ byte[] byteArray = byteArrayOutputStream.toByteArray();
+ return new String(byteArray);
+ }
+
+ /**
+ * 公钥加密
+ *
+ * @param key
+ * @param data
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeySpecException
+ * @throws NoSuchPaddingException
+ * @throws IllegalBlockSizeException
+ * @throws BadPaddingException
+ * @throws InvalidKeyException
+ * @throws IOException
+ */
+ public String keyEncrypt(String key, String data) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, IOException {
+ byte[] decode = java.util.Base64.getDecoder().decode(key);
+ RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(certConfig.getAlgorithm()).generatePublic(new X509EncodedKeySpec(decode));
+ //RSA加密
+ Cipher ci = Cipher.getInstance(certConfig.getAlgorithm());
+ ci.init(Cipher.ENCRYPT_MODE, pubKey);
+
+
+ byte[] bytes = data.getBytes();
+ int inputLen = bytes.length;
+ int offLen = 0;//偏移量
+ int i = 0;
+ ByteArrayOutputStream bops = new ByteArrayOutputStream();
+ while (inputLen - offLen > 0) {
+ byte[] cache;
+ //2048 位密钥:2048 / 8 - 11 = 245 字节
+ if (inputLen - offLen > 245) {
+ cache = ci.doFinal(bytes, offLen, 245);
+ } else {
+ cache = ci.doFinal(bytes, offLen, inputLen - offLen);
+ }
+ bops.write(cache);
+ i++;
+ offLen = 245 * i;
+ }
+ bops.close();
+ byte[] encryptedData = bops.toByteArray();
+ String encodeToString = java.util.Base64.getEncoder().encodeToString(encryptedData);
+ return encodeToString;
+ }
+
+
+
+ @PostConstruct
+ public synchronized void init() throws Exception {
+ if (privateKey == null) {
+ privateKey = initPrivateKey();
+ }
+ if(publicKey == null) {
+ publicKey = initPublicKey();
+ }
+ }
+
+
+
+
+ /**
+ * 获取私钥
+ * @return
+ * @throws Exception
+ */
+ public String initPrivateKey() throws Exception {
+ KeyStore keyStore = KeyStoreUtil.loadKetStore(certConfig.getPath(),certConfig.getPassword());
+ return Base64.encode(KeyStoreUtil.getPrivateKey(keyStore, certConfig.getPassword()).getEncoded());
+ }
+
+ public String getPrivateKey() {
+ if (privateKey == null) {
+ throw new IllegalStateException("获取私钥失败,证书未初始化");
+ }
+ return privateKey;
+ }
+
+ /**
+ * 获取公钥
+ * @return
+ * @throws Exception
+ */
+ public String initPublicKey() throws Exception {
+ KeyStore keyStore = KeyStoreUtil.loadKetStore(certConfig.getPath(),certConfig.getPassword());
+ PublicKey publicKey = KeyStoreUtil.getPublicKey(keyStore);
+ return Base64.encode(publicKey.getEncoded());
+ }
+
+ public String getPublicKey() {
+ if (publicKey == null) {
+ throw new IllegalStateException("获取公钥失败,证书未初始化");
+ }
+ return publicKey;
+ }
+}
diff --git a/src/main/java/com/supervision/edh/utils/DateUtils.java b/src/main/java/com/supervision/edh/utils/DateUtils.java
new file mode 100644
index 0000000..61258c1
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/DateUtils.java
@@ -0,0 +1,28 @@
+package com.supervision.edh.utils;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * @author Jason
+ * @date 2025年06月21日 13:59:07
+ */
+public class DateUtils {
+
+ public static String convertDateString(String strDate) {
+ return LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyyMMdd"))
+ .format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+ }
+
+ public static LocalDate convertDate(String strDate) {
+ // 1. 定义原始格式
+ DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
+ // 2. 转换为LocalDate
+ return LocalDate.parse(strDate, inputFormatter);
+
+ }
+
+ public static void main(String[] args) {
+ System.out.println(convertDate("20200301"));
+ }
+}
diff --git a/src/main/java/com/supervision/edh/utils/EscapeUtil.java b/src/main/java/com/supervision/edh/utils/EscapeUtil.java
new file mode 100644
index 0000000..475cd18
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/EscapeUtil.java
@@ -0,0 +1,142 @@
+package com.supervision.edh.utils;
+
+
+import cn.hutool.http.HTMLFilter;
+import org.springframework.util.StringUtils;
+
+/**
+ * 转义和反转义工具类
+ *
+ * @author tcctyn
+ */
+public class EscapeUtil {
+ public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)";
+
+ private static final char[][] TEXT = new char[64][];
+
+ static {
+ for (int i = 0; i < 64; i++) {
+ TEXT[i] = new char[]{(char) i};
+ }
+
+ // special HTML characters
+ TEXT['\''] = "'".toCharArray(); // 单引号
+ TEXT['"'] = """.toCharArray(); // 双引号
+ TEXT['&'] = "&".toCharArray(); // &符
+ TEXT['<'] = "<".toCharArray(); // 小于号
+ TEXT['>'] = ">".toCharArray(); // 大于号
+ }
+
+ /**
+ * 转义文本中的HTML字符为安全的字符
+ *
+ * @param text 被转义的文本
+ * @return 转义后的文本
+ */
+ public static String escape(String text) {
+ return encode(text);
+ }
+
+ /**
+ * 还原被转义的HTML特殊字符
+ *
+ * @param content 包含转义符的HTML内容
+ * @return 转换后的字符串
+ */
+ public static String unescape(String content) {
+ return decode(content);
+ }
+
+ /**
+ * 清除所有HTML标签,但是不删除标签内的内容
+ *
+ * @param content 文本
+ * @return 清除标签后的文本
+ */
+ public static String clean(String content) {
+ return new HTMLFilter().filter(content);
+ }
+
+ /**
+ * Escape编码
+ *
+ * @param text 被编码的文本
+ * @return 编码后的字符
+ */
+ private static String encode(String text) {
+ if (StringUtils.isEmpty(text)) {
+ return "";
+ }
+
+ final StringBuilder tmp = new StringBuilder(text.length() * 6);
+ char c;
+ for (int i = 0; i < text.length(); i++) {
+ c = text.charAt(i);
+ if (c < 256) {
+ tmp.append("%");
+ if (c < 16) {
+ tmp.append("0");
+ }
+ tmp.append(Integer.toString(c, 16));
+ } else {
+ tmp.append("%u");
+ if (c <= 0xfff) {
+ // issue#I49JU8@Gitee
+ tmp.append("0");
+ }
+ tmp.append(Integer.toString(c, 16));
+ }
+ }
+ return tmp.toString();
+ }
+
+ /**
+ * Escape解码
+ *
+ * @param content 被转义的内容
+ * @return 解码后的字符串
+ */
+ public static String decode(String content) {
+ if (StringUtils.isEmpty(content)) {
+ return content;
+ }
+
+ StringBuilder tmp = new StringBuilder(content.length());
+ int lastPos = 0, pos = 0;
+ char ch;
+ while (lastPos < content.length()) {
+ pos = content.indexOf("%", lastPos);
+ if (pos == lastPos) {
+ if (content.charAt(pos + 1) == 'u') {
+ ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16);
+ tmp.append(ch);
+ lastPos = pos + 6;
+ } else {
+ ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16);
+ tmp.append(ch);
+ lastPos = pos + 3;
+ }
+ } else {
+ if (pos == -1) {
+ tmp.append(content.substring(lastPos));
+ lastPos = content.length();
+ } else {
+ tmp.append(content.substring(lastPos, pos));
+ lastPos = pos;
+ }
+ }
+ }
+ return tmp.toString();
+ }
+
+ public static void main(String[] args) {
+ String html = "";
+ String escape = EscapeUtil.escape(html);
+ // String html = "ipt>alert(\"XSS\")ipt>";
+ // String html = "<123";
+ // String html = "123>";
+ System.out.println("clean: " + EscapeUtil.clean(html));
+ System.out.println("escape: " + escape);
+ System.out.println("unescape: " + EscapeUtil.unescape(escape));
+ }
+}
diff --git a/src/main/java/com/supervision/edh/utils/EventPojo.java b/src/main/java/com/supervision/edh/utils/EventPojo.java
new file mode 100644
index 0000000..7755a4c
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/EventPojo.java
@@ -0,0 +1,33 @@
+package com.supervision.edh.utils;
+
+
+import com.alibaba.fastjson.annotation.JSONField;
+
+public class EventPojo {
+ /**
+ *数据文件内容子业务类型 详见:数据类型字典表
+ */
+ private String subType;
+ /**
+ * 详见:疫苗追溯基本数据集 ZIP 压缩XML/JSON数据文件内容(BASE64编码)
+ */
+ private String data;
+
+ @JSONField( name = "sub_type")
+ public String getSubType() {
+ return subType;
+ }
+
+ public void setSubType(String subType) {
+ this.subType = subType;
+ }
+
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+}
diff --git a/src/main/java/com/supervision/edh/utils/JsonUtils.java b/src/main/java/com/supervision/edh/utils/JsonUtils.java
new file mode 100644
index 0000000..891db8a
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/JsonUtils.java
@@ -0,0 +1,28 @@
+package com.supervision.edh.utils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Jason
+ * @date 2025年06月18日 16:45:54
+ */
+public class JsonUtils {
+ private static final ObjectMapper mapper = new ObjectMapper();
+ protected static final Logger log = LoggerFactory.getLogger(JsonUtils.class);
+
+ // 通用解析方法
+ public static T parseJson(String json, Class clazz) {
+ mapper.registerModule(new JavaTimeModule()); // 必须添加!
+ try {
+ return mapper.readValue(json, clazz);
+ } catch (JsonProcessingException e) {
+ log.error("数据解析错误:"+e.getMessage());
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/src/main/java/com/supervision/edh/utils/KeyStoreUtil.java b/src/main/java/com/supervision/edh/utils/KeyStoreUtil.java
new file mode 100644
index 0000000..09ff9c5
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/KeyStoreUtil.java
@@ -0,0 +1,600 @@
+package com.supervision.edh.utils;
+
+
+import javax.crypto.Cipher;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Date;
+import java.util.Enumeration;
+
+public class KeyStoreUtil {
+ /**
+ * 加载证书 pfxFilepath 证书路径 pfxPassword 密码
+ *
+ * @throws Exception
+ */
+ public static KeyStore loadKetStore(String pfxFilepath, String pfxPassword)
+ throws Exception {
+ KeyStore keyStore = null;
+ File fPkcs12 = null;
+ if (pfxFilepath != null) {
+ fPkcs12 = new File(pfxFilepath);
+ }
+ FileInputStream fis = new FileInputStream(fPkcs12);
+
+ try {
+ keyStore = KeyStore.getInstance("PKCS12");
+ } catch (KeyStoreException ex) {
+ throw new Exception("不能正确解释pfx文件! ");
+ }
+
+ try {
+ keyStore.load(fis, pfxPassword.toCharArray());
+ } catch (CertificateException ex) {
+ throw new Exception(" 证书格式问题! ");
+ } catch (NoSuchAlgorithmException ex) {
+ throw new Exception(" 算法不支持! ");
+ } catch (FileNotFoundException ex) {
+ throw new Exception(" pfx文件没找到 ");
+ } catch (IOException ex) {
+ throw new Exception(" 读取pfx有误! ");
+ }
+ return keyStore;
+ }
+
+ // 证书别名可以作为证书的识别,所以加载证书别名积极关键。
+
+ /**
+ * 获取证书别名
+ *
+ * @param keyStore
+ * @return
+ */
+ // @SuppressWarnings("unchecked")
+ public static String getKeyAlias(KeyStore keyStore) {
+ String keyAlias = "";
+ try {
+ Enumeration enums = keyStore.aliases();
+ while (enums.hasMoreElements()) {
+ keyAlias = (String) enums.nextElement();
+ }
+ } catch (KeyStoreException e) {
+ e.printStackTrace();
+ }
+ return keyAlias;
+ }
+
+ // 获取私钥,可以使用私钥进行数据加密后在网络上传输。
+
+ /**
+ * 获取私钥
+ *
+ * @param keyStore
+ * @param pfxPassword
+ * @return
+ */
+ public static PrivateKey getPrivateKey(KeyStore keyStore, String pfxPassword) {
+ PrivateKey privateKey = null;
+ try {
+ String keyAlias = getKeyAlias(keyStore);
+ privateKey = (PrivateKey) keyStore.getKey(keyAlias, pfxPassword
+ .toCharArray());
+ } catch (UnrecoverableKeyException e) {
+ e.printStackTrace();
+ } catch (KeyStoreException e) {
+ e.printStackTrace();
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ return privateKey;
+ }
+
+ // 使用公钥对私钥加密过的数据进行解密,可以得到相关的明文。
+
+ /**
+ * 获取公钥
+ *
+ * @param keyStore
+ * @return
+ */
+ public static PublicKey getPublicKey(KeyStore keyStore) {
+ PublicKey publicKey = null;
+ try {
+ String keyAlias = getKeyAlias(keyStore);
+ Certificate[] certs = keyStore.getCertificateChain(keyAlias);
+ if (certs != null && certs.length > 0) {
+ // 取得公钥
+ publicKey = certs[0].getPublicKey();
+ }
+ } catch (KeyStoreException e) {
+ e.printStackTrace();
+ }
+ return publicKey;
+ }
+
+ // 使用公钥加密的数据,需要使用私钥进行解密。
+
+ /**
+ * 公钥加密
+ *
+ * @param data
+ * @param publicKey
+ * @return
+ * @throws Exception
+ */
+ public static String encryptByPublicKey(byte[] data, PublicKey publicKey)
+ throws Exception {
+ // 对数据加密
+ Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
+ cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+ byte[] encodedata = cipher.doFinal(data);
+ return byte2hex(encodedata);
+ }
+
+ // 使用公钥对私钥加密过的数据进行解密。
+
+ /**
+ * 公钥解密
+ *
+ * @param data
+ * @param publicKey
+ * @return
+ * @throws Exception
+ */
+ public static String decryptByPublicKey(String data, PublicKey publicKey)
+ throws Exception {
+ // 对数据解密
+ Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
+ cipher.init(Cipher.DECRYPT_MODE, publicKey);
+ byte[] decodedata = cipher.doFinal(hex2byte(data));
+ return new String(decodedata);
+ }
+
+ // 使用私钥加密的数据,需要使用公钥进行解密。
+
+ /**
+ * 私钥加密
+ *
+ * @param data
+ * @param privateKey
+ * @return
+ * @throws Exception
+ */
+ public static String encryptByPrivateKey(byte[] data, PrivateKey privateKey)
+ throws Exception {
+ // 对数据加密
+ Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
+ cipher.init(Cipher.ENCRYPT_MODE, privateKey);
+ byte[] encodedata = cipher.doFinal(data);
+ return byte2hex(encodedata);
+ }
+
+ // 可以使用私钥对公钥加密过的数据进行解密。
+
+ /**
+ * 私钥解密
+ *
+ * @param encodestr
+ * @param privateKey
+ * @return
+ * @throws Exception
+ */
+ public static String decryptByPrivateKey(String encodestr,
+ PrivateKey privateKey) throws Exception {
+ // 对数据解密
+ Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
+ cipher.init(Cipher.DECRYPT_MODE, privateKey);
+ byte[] data = cipher.doFinal(hex2byte(encodestr));
+ return new String(data);
+ }
+
+ /**
+ * 验证Certificate是否过期或无效
+ *
+ * @param keyStore
+ * @param date
+ * 当前时间
+ * @return
+ */
+ public static boolean verifyCertificate(KeyStore keyStore, Date date) {
+ boolean status = true;
+ try {
+ // 取得证书
+ String keyAlias = getKeyAlias(keyStore);
+ Certificate[] certs = keyStore.getCertificateChain(keyAlias);
+ if (certs != null && certs.length > 0) {
+ // 取得公钥
+ X509Certificate x509Certificate = (X509Certificate) certs[0];
+ // 验证证书是否过期或无效
+ x509Certificate.checkValidity(date);
+ }
+ } catch (Exception e) {
+ status = false;
+ }
+ return status;
+ }
+
+ /**
+ * 构造签名
+ *
+ * @param keyStore
+ * @param pfxPassword
+ * @param dataStr
+ * 证书别名
+ * @return
+ */
+ public static String createSignature(KeyStore keyStore, String pfxPassword,
+ String dataStr) {
+ try {
+ // 取得证书
+ String keyAlias = getKeyAlias(keyStore);
+ Certificate[] certs = keyStore.getCertificateChain(keyAlias);
+ X509Certificate x509Certificate = null;
+ if (certs != null && certs.length > 0) {
+ x509Certificate = (X509Certificate) certs[0];
+ // 验证证书是否过期或无效
+ }
+ if (x509Certificate != null) {
+ Signature signature = Signature.getInstance(x509Certificate
+ .getSigAlgName());
+ PrivateKey privateKey = getPrivateKey(keyStore, pfxPassword);
+ signature.initSign(privateKey);
+ signature.update(dataStr.getBytes());
+ byte[] data = signature.sign();
+ return byte2hex(data);
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * 验证签名
+ *
+ * @param keyStore
+ * @param dataStr
+ * @param signStr
+ * @return
+ */
+ public static boolean verfySignature(KeyStore keyStore, String dataStr,
+ String signStr) {
+ try {
+ // 取得证书
+ String keyAlias = getKeyAlias(keyStore);
+ Certificate[] certs = keyStore.getCertificateChain(keyAlias);
+ X509Certificate x509Certificate = null;
+ if (certs != null && certs.length > 0) {
+ x509Certificate = (X509Certificate) certs[0];
+ // 验证证书是否过期或无效
+ }
+ Signature signature = Signature.getInstance(x509Certificate
+ .getSigAlgName());
+ PublicKey publicKey = getPublicKey(keyStore);
+ signature.initVerify(publicKey);
+ signature.update(dataStr.getBytes());
+ return signature.verify(hex2byte(signStr));
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * 验证签名使用公钥
+ *
+ * @param dataStr
+ * @param signStr
+ * @return
+ */
+ public static boolean verfySignatureWithPublic(byte[] publicKeyArr,
+ String dataStr, String signStr) {
+ try {
+ Signature signature = Signature.getInstance("SHA1withRSA");
+ java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(
+ publicKeyArr);
+ java.security.KeyFactory keyFactory = java.security.KeyFactory
+ .getInstance("RSA");
+ PublicKey publicKey = keyFactory.generatePublic(bobPubKeySpec);
+ signature.initVerify(publicKey);
+ signature.update(dataStr.getBytes());
+ return signature.verify(hex2byte(signStr));
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ public static String decodeWithPrivate(byte[] privateKeyArr) {
+ // Signature signature = Signature.getInstance("SHA1withRSA");
+ java.security.spec.X509EncodedKeySpec bobPriKeySpec = new java.security.spec.X509EncodedKeySpec(privateKeyArr);
+ KeyFactory keyFactory = null;
+ try {
+ keyFactory = KeyFactory.getInstance("RSA");
+ PrivateKey privateKey = keyFactory.generatePrivate(bobPriKeySpec);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } catch (InvalidKeySpecException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 公钥解密
+ * @param publicKeyArr
+ * @return
+ */
+ public static String decodeWithPublic(String data,byte[] publicKeyArr) {
+ // Signature signature = Signature.getInstance("SHA1withRSA");
+ java.security.spec.X509EncodedKeySpec bobPriKeySpec = new java.security.spec.X509EncodedKeySpec(publicKeyArr);
+ KeyFactory keyFactory = null;
+ try {
+ keyFactory = KeyFactory.getInstance("RSA");
+ //PrivateKey privateKey = keyFactory.generatePrivate(bobPriKeySpec);
+ PublicKey publickey = keyFactory.generatePublic(bobPriKeySpec);
+ return decryptByPublicKey(data,publickey);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } catch (InvalidKeySpecException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 公钥加密
+ * @param publicKeyArr
+ * @return
+ */
+ public static String encodeWithPublic(String data,byte[] publicKeyArr) {
+ // Signature signature = Signature.getInstance("SHA1withRSA");
+ java.security.spec.X509EncodedKeySpec bobPriKeySpec = new java.security.spec.X509EncodedKeySpec(publicKeyArr);
+ KeyFactory keyFactory = null;
+ try {
+ keyFactory = KeyFactory.getInstance("RSA");
+ //PrivateKey privateKey = keyFactory.generatePrivate(bobPriKeySpec);
+ PublicKey publickey = keyFactory.generatePublic(bobPriKeySpec);
+ return encryptByPublicKey(data.getBytes(),publickey);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } catch (InvalidKeySpecException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+
+ /**
+ * 私钥解密
+ * @param privateKeyArr
+ * @return
+ */
+ public static String decodeWithPrivate(String data,byte[] privateKeyArr) {
+ // Signature signature = Signature.getInstance("SHA1withRSA");
+ java.security.spec.X509EncodedKeySpec bobPriKeySpec = new java.security.spec.X509EncodedKeySpec(privateKeyArr);
+ KeyFactory keyFactory = null;
+ try {
+ keyFactory = KeyFactory.getInstance("RSA");
+ //PrivateKey privateKey = keyFactory.generatePrivate(bobPriKeySpec);
+ PrivateKey privatekey = keyFactory.generatePrivate(bobPriKeySpec);
+ return decryptByPrivateKey(data,privatekey);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } catch (InvalidKeySpecException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+
+
+ /**
+ * 将二进制转化为16进制字符串
+ *
+ * @param b
+ * 二进制字节数组
+ * @return String
+ */
+ private static String byte2hex(byte[] b) {
+ String hs = "";
+ String stmp = "";
+ for (int n = 0; n < b.length; n++) {
+ stmp = (Integer.toHexString(b[n] & 0XFF));
+ if (stmp.length() == 1) {
+ hs = hs + "0" + stmp;
+ } else {
+ hs = hs + stmp;
+ }
+ }
+ return hs.toUpperCase();
+ }
+
+ /**
+ * 十六进制字符串转化为2进制
+ *
+ * @param hex
+ * @return
+ */
+ private static byte[] hex2byte(String hex) {
+ byte[] ret = null;
+ // try {
+ byte[] tmp = hex.getBytes();
+ int length = tmp.length / 2;
+ ret = new byte[length];
+ for (int i = 0; i < length; i++) {
+ ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
+ }
+ // } catch (UnsupportedEncodingException e) {
+ // e.printStackTrace();
+ // }
+ return ret;
+ }
+
+ /**
+ * 将两个ASCII字符合成一个字节; 如:"EF"--> 0xEF
+ *
+ * @param src0
+ * byte
+ * @param src1
+ * byte
+ * @return byte
+ */
+ private static byte uniteBytes(byte src0, byte src1) {
+ byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 }))
+ .byteValue();
+ _b0 = (byte) (_b0 << 4);
+ byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 }))
+ .byteValue();
+ byte ret = (byte) (_b0 ^ _b1);
+ return ret;
+ }
+
+ // /**
+ // * 验证pkcs7格式的签名数据
+ // * @param signedData pkcs7格式的签名数据
+ // * @return 验证结果
+ // * @throws Exception
+ // */
+ // public boolean verify(byte[] signedData) throws Exception {
+ // CMSSignedData sign = new CMSSignedData(signedData);
+ // CertStore certs = sign.getCertificatesAndCRLs("Collection", "BC");
+ // SignerInformationStore signers = sign.getSignerInfos();
+ // Collection c = signers.getSigners();
+ // Iterator it = c.iterator();
+ // boolean bresult = true;
+ // //当有多个签名者信息时需要进行全部验证
+ // while (it.hasNext()) ...{
+ // SignerInformation signer = (SignerInformation) it.next();
+ // Collection certCollection = certs.getCertificates(signer.getSID());
+ // Iterator certIt = certCollection.iterator();
+ // X509Certificate cert = (X509Certificate) certIt.next();//证书链????
+ // byte[] data = signer.getSignature();
+ // logger.debug("签名后数据:" + data.length);
+ // for (int i = 0; i < data.length; i++) ...{
+ // System.out.print(" " + data[i]);
+ // }
+ // System.out.println();
+ // logger.debug("签名后数据Base64: " + new String(Base64.encode(data),"utf8"));
+ // if (signer.verify(cert.getPublicKey(), "BC")) ...{//验证过程???
+ // logger.info(" pkcs7 verifed success!");
+ // }else...{
+ // bresult = false;
+ // }
+ // }
+ // return bresult;
+ // }
+ //
+ // /**
+ // * 签名生成pkcs7结构数据
+ // * @param signText 原始数据
+ // * @param keystore 密钥库
+ // * @param keyalias 密钥别名
+ // * @param password 密钥库密码
+ // * @return 签名后数据
+ // * @throws Exception
+ // */
+ // public byte[] sign(byte[] signText,KeyStore keystore,String
+ // keyalias,char[] password) throws Exception {
+ // CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator();
+ // Enumeration en = keystore.aliases();
+ // //遍历密钥库的密钥别名
+ // while(en.hasMoreElements()){
+ // String alias = (String)en.nextElement();
+ // logger.debug("keyalias:" + alias);
+ // if(!alias.equalsIgnoreCase(keyalias))continue;
+ //
+ // //根据别名从证书中获取私钥
+ // PrivateKey prikey = (PrivateKey) keystore.getKey(keyalias,password);
+ // X509Certificate x509 = null;
+ //
+ // //获取该别名对应的证书链
+ // Certificate[] certs = keystore.getCertificateChain(keyalias);
+ // if (certs[0] instanceof X509Certificate) {//user's certificate
+ // x509 = (X509Certificate) certs[0];
+ // }
+ // if (certs[certs.length - 1] instanceof X509Certificate) {//root
+ // certificate
+ // x509 = (X509Certificate) certs[certs.length - 1];
+ // }
+ // gen.addSigner(prikey, x509, CMSSignedDataStreamGenerator.DIGEST_SHA1,
+ // "BC");
+ // CertStore certstore = CertStore.getInstance("Collection", new
+ // CollectionCertStoreParameters(Arrays.asList(certs)),"BC");
+ // gen.addCertificatesAndCRLs(certstore);
+ // }
+ // //输出字节流
+ // ByteArrayOutputStream bOut = new
+ // ByteArrayOutputStream();//"e:/JavaSignedData.txt"
+ // OutputStream sigOut = gen.open(bOut,true);//false,不含原始数据,减轻传输负担
+ // sigOut.write(signText);//对原始数据进行签名
+ // sigOut.close();
+ // logger.info("pkcs7 signed success!");
+ // byte[] signedData = bOut.toByteArray();//签名后数据
+ // bOut.close();
+ // byte[] signedDataBase64 = Base64.encode(signedData);
+ // logger.debug("签名后数据: " + new String(signedData,CHARSET) + " ");
+ // logger.debug("签名后数据Base64: " + new String(signedDataBase64,CHARSET) +
+ // " ");
+ // return signedData;
+ // }
+ //
+
+ public static void main(String args[]) {
+ try {
+ // 加载证书
+ KeyStore keyStore = loadKetStore("C:\\Users\\houduo.wk\\Desktop\\pfx证书制作工具\\output\\GUIZHOUD2D.pfx","12345678");
+ String alias = getKeyAlias(keyStore);
+ System.out.println("证收别名:" + alias);
+ // 获取公钥
+ PublicKey publicKey = getPublicKey(keyStore);
+ System.out.println("公钥:"+Base64.encode(publicKey.getEncoded()));
+ //公钥加密
+ String en = encryptByPublicKey("test".getBytes(), publicKey);
+ System.out.println("公钥加密后en:" + en);
+
+ // 获取私钥
+ PrivateKey privateKey = getPrivateKey(keyStore, "12345678");
+ System.out.println("私钥:" + Base64.encode(privateKey.getEncoded()));
+
+ //私钥解密
+ String de = decryptByPrivateKey(en, privateKey);
+ System.out.println("私钥解密后de:" + de);
+
+/*
+ // 签名
+ String sign = createSignature(keyStore, "88888888", "test");
+ System.out.println("sign:" + sign);
+ // 验签
+ System.out
+ .println(verfySignature(
+ keyStore,
+ "test",
+ "2FFBD4D36985621E1FA6E4A70E318651F861F7D348B7034031B38781F62F9E2DE3BC2C3B6BB6DA5A96C795417BF55789A96B5B05548F9F2D99BE0AEA5396189CBB5F333825C32631D93125F9EB5470142F5E489D89EBCEF53AD0DAE8E1B2C6E561122A1174D07D78F972590F5665BBFC8FB8D182EDA4F2ECFE1A4A2FBE077603"));
+*/
+
+/* String publickey = "30819F300D06092A864886F70D010101050003818D0030818902818100D4823C41CA161F451F1A979ABE62A1140305BD882B597BC36D8460F81C4EE31CF2D3A96CC834CC05F7FF296B53EA607603919419172C6558D25558DC1ACDDE013F995B32B69CF869A8F8F6818B0953BE61552E8A32068FACE1A0227A4CB3E7AC615F053B553E53A6E6B083108DA5BC31D5DFCF59B13B2D4167F777F2E32A3C0F0203010001";
+ String privatekey = "30820277020100300D06092A864886F70D0101010500048202613082025D02010002818100D4823C41CA161F451F1A979ABE62A1140305BD882B597BC36D8460F81C4EE31CF2D3A96CC834CC05F7FF296B53EA607603919419172C6558D25558DC1ACDDE013F995B32B69CF869A8F8F6818B0953BE61552E8A32068FACE1A0227A4CB3E7AC615F053B553E53A6E6B083108DA5BC31D5DFCF59B13B2D4167F777F2E32A3C0F02030100010281806FD1FBCD0E7E6783E2A30685298B12814A39DA0A6DED0F1FBD5FFBFA7242DC64DE2D9C281E8D11924E7598A0DE2E2505D448E529F2B4ACBB7929E9B11FF595CC125BBA927078B69AD062261D2936056251E259E9EDA1BB99EC3860D311C028613F616B26EAEDAA1177231B2A8E7E9C262FEDFD22912D03785A0666ED9FF60CC9024100F96E689B306286F81C99BBEA7D465375D19A26C5CC23852041ABBB198CD425455160AEE760E8F92224E9D60C4AF518E3EE2C39598735BBE1656B15CA54DC87F5024100DA1AE7EA66708D76A22EBC193350E1E3979A19E2CB126A9704E1F2D8FFB13E1EB32669AF9CAC15232E4255A4F3D60E19BD4C0CB6A1C405A469FB68EF96AFE57302406F0DDC5F3424BA091FDAC6D2F961E568F0A09CA0B66A1E2CA5708B862DB08AC3991EDDE0C0C219A23D232B9D1F868EC574D695D629A01FFD93C520D78BFF003D024100AAA6CEBAFAB82A179EC24E6EB15621C88000152CFC93464F2F84D30CB2D3ADB53B9B5CAA093E23B3C92821F6D4CAB171B64960D12D3540ECE9F7CA9D5C1BF8BD024100A4FE9F3CF0EAADC1C00C8B7986BAA7BA0CC0DC389EFD854761896C5AC924A77AD8EE84A6A62465504CBB77D5DCF813809A9160E23E5982280C4147337B60CAC0";
+
+ String cont = encodeWithPublic("test",hex2byte(publickey));
+ System.out.println(decodeWithPrivate(cont, hex2byte(privatekey)));*/
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/main/java/com/supervision/edh/utils/LocalDateDeserializer.java b/src/main/java/com/supervision/edh/utils/LocalDateDeserializer.java
new file mode 100644
index 0000000..9c217d2
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/LocalDateDeserializer.java
@@ -0,0 +1,23 @@
+package com.supervision.edh.utils;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+
+import java.io.IOException;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * @author Jason
+ * @date 2025年06月06日 15:06:07
+ */
+public class LocalDateDeserializer extends JsonDeserializer {
+ private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
+
+ @Override
+ public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
+ String dateStr = p.getText();
+ return LocalDate.parse(dateStr, FORMATTER);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/supervision/edh/utils/RequestWrapper.java b/src/main/java/com/supervision/edh/utils/RequestWrapper.java
new file mode 100644
index 0000000..c142647
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/RequestWrapper.java
@@ -0,0 +1,118 @@
+package com.supervision.edh.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.*;
+import java.nio.charset.Charset;
+
+public class RequestWrapper extends HttpServletRequestWrapper {
+ private Logger logger = LoggerFactory.getLogger(RequestWrapper.class);
+
+ /**
+ * 存储body数据的容器
+ */
+ private final byte[] body;
+
+ public RequestWrapper(HttpServletRequest request) throws IOException {
+ super(request);
+
+ // 将body数据存储起来
+ String bodyStr = getBodyString(request);
+ body = bodyStr.getBytes(Charset.defaultCharset());
+ }
+
+ /**
+ * 获取请求Body
+ *
+ * @param request request
+ * @return String
+ */
+ public String getBodyString(final ServletRequest request) {
+ try {
+ return inputStream2String(request.getInputStream());
+ } catch (IOException e) {
+ logger.error("Get body string error.{}",e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 获取请求Body
+ *
+ * @return String
+ */
+ public String getBodyString() {
+ final InputStream inputStream = new ByteArrayInputStream(body);
+
+ return inputStream2String(inputStream);
+ }
+
+ /**
+ * 将inputStream里的数据读取出来并转换成字符串
+ *
+ * @param inputStream inputStream
+ * @return String
+ */
+ private String inputStream2String(InputStream inputStream) {
+ StringBuilder sb = new StringBuilder();
+ BufferedReader reader = null;
+
+ try {
+ reader = new BufferedReader(new InputStreamReader(inputStream, Charset.defaultCharset()));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ logger.error("close stream error.{}", e);
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+
+ @Override
+ public BufferedReader getReader() throws IOException {
+ return new BufferedReader(new InputStreamReader(getInputStream()));
+ }
+
+ @Override
+ public ServletInputStream getInputStream() throws IOException {
+
+ final ByteArrayInputStream inputStream = new ByteArrayInputStream(body);
+
+ return new ServletInputStream() {
+ @Override
+ public int read() throws IOException {
+ return inputStream.read();
+ }
+
+ @Override
+ public boolean isFinished() {
+ return false;
+ }
+
+ @Override
+ public boolean isReady() {
+ return false;
+ }
+
+ @Override
+ public void setReadListener(ReadListener readListener) {
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/supervision/edh/utils/ResponseBuilder.java b/src/main/java/com/supervision/edh/utils/ResponseBuilder.java
new file mode 100644
index 0000000..985398d
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/ResponseBuilder.java
@@ -0,0 +1,70 @@
+package com.supervision.edh.utils;
+
+
+import com.alibaba.fastjson.JSON;
+import com.supervision.edh.enums.BuzStatusEnum;
+import com.supervision.edh.enums.StatusEnum;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ResponseBuilder extends HashMap{
+
+ public void status(Integer status){
+ this.put("status", status);
+ }
+
+ public void message(String message){
+ this.put("message", message);
+ }
+
+ public void body(BuzStatusEnum buzStatusEnum){
+ Map body = new HashMap<>();
+ body.put("buz_status", buzStatusEnum.getBuzStatus());
+ body.put("buz_message", buzStatusEnum.getBuzMessage());
+ this.put("body", body);
+ }
+
+ public void body(Integer buzStatus,String buzMsg){
+ Map body = new HashMap<>();
+ body.put("buz_status", buzStatus);
+ body.put("buz_message", buzMsg);
+ this.put("body", body);
+ }
+
+ public static String fail(BuzStatusEnum buzStatusEnumg){
+ ResponseBuilder builder = new ResponseBuilder();
+ builder.status(StatusEnum.FAILED.getStatus());
+ builder.message(StatusEnum.FAILED.getMsg());
+ builder.body(buzStatusEnumg);
+ return JSON.toJSONString(builder.build());
+ }
+
+ public static String success(){
+ ResponseBuilder builder = new ResponseBuilder();
+ builder.status(StatusEnum.SUCCESS.getStatus());
+ builder.message(StatusEnum.SUCCESS.getMsg());
+ builder.body(BuzStatusEnum.SUCCESS);
+ return JSON.toJSONString(builder.build());
+ }
+
+ public static Map buzError(Integer buzStatus,String buzMessage){
+ ResponseBuilder builder = new ResponseBuilder();
+ builder.status(StatusEnum.BUZ_ERROR.getStatus());
+ builder.message(StatusEnum.BUZ_ERROR.getMsg());
+ builder.body(buzStatus,buzMessage);
+ return builder.build();
+ }
+
+ public Map build(){
+ Map responseMap = new HashMap<>();
+ responseMap.put("resp", this);
+
+ return responseMap;
+ }
+
+ public static void main(String[] args){
+ System.out.println(JSON.toJSONString(fail(BuzStatusEnum.SIGN_CHECK_ERR)));
+ }
+}
+
diff --git a/src/main/java/com/supervision/edh/utils/StreamUtil.java b/src/main/java/com/supervision/edh/utils/StreamUtil.java
new file mode 100644
index 0000000..c719d52
--- /dev/null
+++ b/src/main/java/com/supervision/edh/utils/StreamUtil.java
@@ -0,0 +1,91 @@
+package com.supervision.edh.utils;
+
+
+import org.apache.commons.codec.binary.Base64;
+import org.springframework.util.StringUtils;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+/**
+ *
+ * @author xuwangyu
+ *
+ */
+public class StreamUtil {
+ /**
+ * 将文件内容压缩并转为base64格式
+ * @param fileName 文件名称
+ * @param fileContent 文件内容
+ * @return 压缩后Base64内容
+ * @throws Exception
+ */
+ public static String getStreamContent(String fileName ,String fileContent) throws Exception {
+ if(StringUtils.isEmpty(fileName) || StringUtils.isEmpty(fileContent)) {
+ throw new NullPointerException();
+ }
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(5 * 1024 * 1024);
+ ZipOutputStream zos = new ZipOutputStream(bos);
+ InputStream is = new ByteArrayInputStream(fileContent.getBytes());
+ BufferedInputStream fileReader = new BufferedInputStream(is);
+ zos.putNextEntry(new ZipEntry(fileName));
+ byte[] b = new byte[1024];
+ int i;
+ while ((i = fileReader.read(b)) != -1) {
+ zos.write(b, 0, i);
+ }
+ is.close();
+ zos.closeEntry();
+ zos.flush();
+ zos.close();
+ fileReader.close();
+ bos.close();
+ byte[] bytes = bos.toByteArray();
+ return Base64.encodeBase64String(bytes);
+ }
+
+ /**
+ * 先base64解密 后解压缩
+ * @param s
+ * @return
+ */
+ public static String getUnStreamContent(String s){
+ byte[] bytes = Base64.decodeBase64(s);
+ return new String(unZip(bytes));
+ }
+
+ /***
+ * 解压Zip
+ * @param data
+ * @return
+ */
+ public static byte[] unZip(byte[] data) {
+ byte[] b = null;
+ try {
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ ZipInputStream zip = new ZipInputStream(bis);
+ while (zip.getNextEntry() != null) {
+ byte[] buf = new byte[1024];
+ int num ;
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ while ((num = zip.read(buf, 0, buf.length)) != -1) {
+ bos.write(buf, 0, num);
+ }
+ b = bos.toByteArray();
+ bos.flush();
+ bos.close();
+ }
+ zip.close();
+ bis.close();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return b;
+ }
+
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..bdaea0b
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,42 @@
+server:
+ port: 1788
+
+# spring配置
+spring:
+ datasource:
+ driverClassName: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://47.109.202.121:3306/supervisionx_trace_data?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+ username: root
+ password: TCCT3.1415926
+
+
+mybatis-plus:
+ # 搜索指定包别名
+ type-aliases-package: com.supervision.edh
+ # 配置mapper的扫描,找到所有的mapper.xml映射文件
+ #mapper-locations: classpath*:mapper/**/*Mapper.xml
+ mapper-locations: classpath:mapper/*.xml
+ # 加载全局的配置文件
+ config-location: classpath:mybatis/mybatis-config.xml
+ #逻辑删除配置
+ global-config:
+ db-config:
+ logic-not-delete-value: 0
+ logic-delete-value: 1
+ logic-delete-field: del_flag
+
+logging:
+ level:
+ root: INFO
+ org.springframework: WARN
+ com.supervision.edh: DEBUG
+ mybatis: DEBUG
+ com.baomidou.mybatisplus: DEBUG
+
+cert:
+ #本地
+ path: D:\ynyp\药品追溯\d2d\edh.pfx
+ #服务器
+ #path: d2d\yunnan.pfx
+ password: YnYp123456
+ algorithm: RSA
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 0000000..77c5090
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+ ${log.pattern}
+
+
+
+
+
+ ${log.path}/info.log
+
+
+
+ ${log.path}/info.%d{yyyy-MM-dd}.log
+
+ 60
+
+
+ ${log.pattern}
+
+
+
+ INFO
+
+ ACCEPT
+
+ DENY
+
+
+
+
+ ${log.path}/error.log
+
+
+
+ ${log.path}/error.%d{yyyy-MM-dd}.log
+
+ 60
+
+
+ ${log.pattern}
+
+
+
+ ERROR
+
+ ACCEPT
+
+ DENY
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/mapper/EdhDomesticDrugBaseInfoMapper.xml b/src/main/resources/mapper/EdhDomesticDrugBaseInfoMapper.xml
new file mode 100644
index 0000000..4e17534
--- /dev/null
+++ b/src/main/resources/mapper/EdhDomesticDrugBaseInfoMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/resources/mapper/EdhDrugDeliveryNoteApplyInfoMapper.xml b/src/main/resources/mapper/EdhDrugDeliveryNoteApplyInfoMapper.xml
new file mode 100644
index 0000000..aa1cd7f
--- /dev/null
+++ b/src/main/resources/mapper/EdhDrugDeliveryNoteApplyInfoMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/resources/mapper/EdhDrugInvoiceApplyInfoMapper.xml b/src/main/resources/mapper/EdhDrugInvoiceApplyInfoMapper.xml
new file mode 100644
index 0000000..39d6bd9
--- /dev/null
+++ b/src/main/resources/mapper/EdhDrugInvoiceApplyInfoMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/resources/mapper/EdhDrugOperateLicenseBaseInfoMapper.xml b/src/main/resources/mapper/EdhDrugOperateLicenseBaseInfoMapper.xml
new file mode 100644
index 0000000..11d987a
--- /dev/null
+++ b/src/main/resources/mapper/EdhDrugOperateLicenseBaseInfoMapper.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/src/main/resources/mapper/EdhDrugOperatorsBaseInfoMapper.xml b/src/main/resources/mapper/EdhDrugOperatorsBaseInfoMapper.xml
new file mode 100644
index 0000000..1b8e3bb
--- /dev/null
+++ b/src/main/resources/mapper/EdhDrugOperatorsBaseInfoMapper.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
diff --git a/src/main/resources/mapper/EdhReceiveDataLogMapper.xml b/src/main/resources/mapper/EdhReceiveDataLogMapper.xml
new file mode 100644
index 0000000..e5917b0
--- /dev/null
+++ b/src/main/resources/mapper/EdhReceiveDataLogMapper.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/mapper/EdhWarehouseStockApplyInfoMapper.xml b/src/main/resources/mapper/EdhWarehouseStockApplyInfoMapper.xml
new file mode 100644
index 0000000..4567882
--- /dev/null
+++ b/src/main/resources/mapper/EdhWarehouseStockApplyInfoMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/resources/mapper/EdhWhTempHumidityApplyInfoMapper.xml b/src/main/resources/mapper/EdhWhTempHumidityApplyInfoMapper.xml
new file mode 100644
index 0000000..ee44ac6
--- /dev/null
+++ b/src/main/resources/mapper/EdhWhTempHumidityApplyInfoMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/resources/mybatis/mybatis-config.xml b/src/main/resources/mybatis/mybatis-config.xml
new file mode 100644
index 0000000..ac47c03
--- /dev/null
+++ b/src/main/resources/mybatis/mybatis-config.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/java/com/supervision/edh/SupervisionEdhApplicationTests.java b/src/test/java/com/supervision/edh/SupervisionEdhApplicationTests.java
new file mode 100644
index 0000000..da875e9
--- /dev/null
+++ b/src/test/java/com/supervision/edh/SupervisionEdhApplicationTests.java
@@ -0,0 +1,32 @@
+package com.supervision.edh;
+
+import com.supervision.edh.utils.CertManager;
+import com.supervision.edh.utils.StreamUtil;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+
+@SpringBootTest
+class SupervisionEdhApplicationTests {
+
+
+ @Autowired
+ private CertManager certManager;
+
+ @Test
+ void testCode() throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, InvalidKeySpecException, BadPaddingException, IOException, InvalidKeyException {
+ String privateKey="MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6qV2TEiVq3zo0V3zbD4EQJetoeG8WMJxrwzymx6LflOnRTNmO0OJWpNOcKTWWRu7RQwxx4OweZBVr+jH3dmP/kLTgF/nfrdwqjtdUwawbSK+v3TQs3h5Zo8oir6p5h288TYaY48UfAyFxGpCdwcvwp0RWkwWwaEiS9tksyuIuQ/HsFfCseSKrM0VLB/U4VGWK0uwlO7LgSrkBDABoOnzSFTsGZFjYyrz079bIWSIFA66VX/DgrKs0wtC5nDbfoc2Wg7U2UvlBJR6UgT/eS6FKC+JEpiI1C8SL6hWAeyc3WAnIjKNVjyn14SOsAI/701HvHfhPbk/BUDWKk+RMobInAgMBAAECggEBAK3ZtpSXDxCFzmEXpuskepF+r82CdfxV1CouEdxIDbNtr4RHrk1s0ZHfPFOysf1AHYf7iai600/O6YDC6yzPMH3D2iLpUcn51RgyJ+4B3/kdbrw+Ky0qx1u3yDkcIYvFD1472oOliF/E+62rD0xPRlHiiCyWDHNr/UQb8tPcNmLdPWgFAv6I3XitQEist7dwjCjSeBcvxm2gr9x98bqfw4dxrjtfTidzxMaEJvyAGYYHQzOZZCKTZEAmJMpz69F8k8A45cCKWYHqjrvuu2rnjumF4nMHX6OntYtJl1jbOLCNC63XSdSRep4+H80DfstnKpnGRZp4HY+ivY//vME5giECgYEA9lCTWehgN3v5oRjKvNpyEkidzLHISO+CQ1PeVe3wwmAy068mkAA896sD+iDD0EJsgr3Cg5uxUbvSj53tvbuW0H+ggXKqIuvVl1HvgD+AJtSr3JXcLcYtkFaTUwW5W+dcQz+1lOLccMAfOc4qMUR8e7poWAd/NCOKGOCQJ5E9wXcCgYEAwgBQ+S9sZIQJx3frPekcze21IjqXwb24Wj4VUY/I2mtad8KefQ+FbYGdQmL/bsP73F2jH5q35+doaN14+Q+9+xouaf3L//djmSqhygxWzQnu2sLmaatAl1FWdqQZds/XBJtXEXwxMJT4vfZ3vZxmq1J0QqmoBM5TtuniZlwvQNECgYBRl11IIfaFSpblKz41ErNIpS9IV/e9WUEwJj72/euLp6wOfO1sM/f+HnMhzuquOOKS6GLfj5pMNchI9IqFF/ecNzqmxqHfEXneNzD7rY04z6fiWO3nZ8c+Eb+Zd8Lv05K3YAo5OHDHFI0Da+yEB2io35Wi21Dip4ceOHzn7m+jfwKBgQCmdbEE7w0ZfjYJ4jqGB8SAact3EEFwqsJJJGYUcsRLrbuVcPeepTe+i22NLfawaxdrsSirkIzmPifXetk3E6vWjlNu/KcS/YmHPg5OmKHOEwzQxlUALEIi1FbVO97hlFqRiFyAE0j9v4VjMdzyZAWwUPKS1JHndcZc93gcjlK5UQKBgBJ28+ZVBoG/L/NeNqXXGxMgtQ7gphkXZ7RaoY4Ut1L2qa09E5htUkqwyX3HjuO/YMMVADvbAlaI1FDa/mS1qwYSSWji40x8vU39v3jE06avKWEiy9XPv9iozyDYvcPxRg5FjvjgVxeqLTWWLN79Jy+ZfrNZuNezvPspv7c1Y043";
+ String de = certManager.keyDecrypt(privateKey, "EtI59GVaEMZJ17DvHVoD5iG6h+dH7LS9NEH3hq9ItP7NW6xgez70lUJWJNO4I7CRS0O66WFRvyAVYPpsi0VY647aFy19v7yr/62vm00EuKhhiguw7v2cnh5p0vgRQT5BGW4zMmxl/2nGXuVQKjdr8NX/y+KE6bM5bRKnz5oLRK1JR8tJ9ESMYRftAvysSB5SyeRK3FqBDj43QU5S5jS4LI6iCGuEVYBg1V6dEfACLKPktQu0AHE6OQbZPS1nI8EVj0pcXDpTLBnGZs/NVyHY6nwacEBHnATbXPbrJN1wk/J0ZlOcv16oCVbZx1l8ef4vlvvz29t8y9JjCmLOXgGHCAR/ip7qdDaQBGe2g/R5JAN3NEYwv5gOQ7zghAgJL2OWeMT+0VkIeXWkrML4M1pg4L4U1+DCW/XUNGhodMK78ilBX7xQApxM1ld/HqV/xAq7leLdeafw+BxZxvcsgoR4L3GxXKyei9zaNwkqPjgyvtfWC5OIXasDJcFmK2P4Ud6hXxwrcqp7/OKiPniH/QxOuPoCcalrAmYfdAMxjP8Vum9k2sMinp6JuHoVa4YR+KJ0Vsk5QONQMlzS1ac5gtPa+twBB+9J2UE6gaaRbNye+/975BDKHDVZtWOmA44SG+mQl6+UKnURCdNhVgeZtEeZ+lR44oowrS+nRhMoPX6xwl2g7XWcf75JAPIrY4EXkyOaqD7cYTwiRkqZinAzI6bdEn1zHvzx/tWcabBQOrNaCq4yk5R4FWsYMs6OfTEMGdjDXS3FVJBSqumGqW3X/YTGfQQ5/4aOeeUSm9mysOYTKVZAbko3pwoyJim6c1lPlrFKOkkiuu+B6XNTVApDuVZV7Bk5OLX1Lv8Fk4jByUE/p7+Bs8ssp2nzD80YOjqJFlWIqdvLHyoky3TibsJGUXYnEbCJACD2q3NF/GL3akocJ8EdBKyd0Cjv7qAIpYp8kewgUrfopVG46T29xdUu8mre/LYhE+roDcSKwM/p0mwqIjXGpHka0FLeuuARWEevcTeDCoHBLiOPz77C7F+Rp+R3QTubcxjkGzxVb3Kq7gMy38RB4s3H+ue8qns5pydqg4QHMy6OBWdZh/jVOdZ5byl2pTanjA3U+TcW93tlRebJT9ZpOJB1w7aBupUPqtw1ZOAUOmc2BT+00Bzbpa8ZkdOpUXhTiBEpcto1JZrtTModwh+TO/By3QF5jxNkWApw+QBFLbp16PJoyjzPI5dXFikoJN7FZzUuh3sebWHPA/A+VyN6uKWRfPMx1A5UWqvwruMAAIcmMrlhtPTlpT2WSGunpJFXlnR/4sSUrQW6SKahewFLO38qBDVEp9jfqpBD9UiwJnPPKwzXAjHXKDjvnNzTVD6Zh9skM4cLCgRNXfBqS9z70PzLkea/MzNjYKUdcSKG74MxbMlABPQHoov6J6aehQYCBdpkk4kXgeSTqDapgtipUScSqfvTkLPi4bfHkXD3nIgY0Wr6opknan1CGyYayt0Veuggv7TLscfSjKlhIkLG/gphKr6ld+S+hdzOb994if6X+QRtSFRDVrQYYyEz8hu+ajEU024L4GC6OvKpR5UfaY6bKAdFsr54PGudrcmuKo3djqzdOywmlEaXmMvPM6M5SqhSsb5+H5Hew+p6+uQ+VRoQLqpCioN+7J509sOrUmX0v3cDLqZKeLyVhimcKNByFpKwyvlo2sXiT4OCl9Y=");
+ String data = StreamUtil.getUnStreamContent(de);
+ System.out.println("解析后的数据:"+data);
+ }
+
+}