企业数据上报服务

This commit is contained in:
huzhengkao 2025-06-25 10:11:08 +08:00
commit ada75c98c8
96 changed files with 6170 additions and 0 deletions

48
.gitignore vendored Normal file
View File

@ -0,0 +1,48 @@
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
!*/build/*.java
!*/build/*.html
!*/build/*.xml
/d2d/

133
pom.xml Normal file
View File

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.supervision.edh</groupId>
<artifactId>supervision-edh</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>supervision-edh</name>
<description>药监企业数据上报服务</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.66</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.13</version>
</dependency>
<!--糊涂工具-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.0.12</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.70</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.23</version>
</dependency>
<!-- mybatis-plus 增强CRUD -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!--代码生成-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<!-- JPA 支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--Jackson XML-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.32</version> <!-- 使用最新版本 -->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

324
sql/data.sql Normal file
View File

@ -0,0 +1,324 @@
CREATE TABLE `edh_receive_data_log` (
`event_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '事件流水号',
`tyshxydm` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '上报企业统一社会信用代码',
`process_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '传输标记号',
`event_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '数据文件内容主业务类型',
`event_type_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '数据文件内容主业务类型名称',
`sub_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '数据文件内容子业务类型',
`sub_type_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '数据文件内容子业务类型名称',
`data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '数据文件内容',
`ver` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'API协议版本',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint DEFAULT '0' COMMENT '是否删除(0-否 1-是)',
PRIMARY KEY (`event_id`) USING BTREE,
KEY `idx_process_id` (`process_id`) USING BTREE,
KEY `idx_event_type` (`event_type`) USING BTREE,
KEY `idx_sub_type` (`sub_type`) USING BTREE,
KEY `idx_tyshxydm` (`tyshxydm`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='药监企业数据上报日志信息表';
CREATE TABLE `edh_drug_operators_base_info` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`event_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '事件流水号',
`tyshxydm` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '统一社会信用代码',
`qymc` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业名称',
`qylx` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业类型',
`qyxl` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业小类',
`zsdz` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '住所地址',
`xzqhdm` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '行政区划代码',
`fddbr` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '法定代表人',
`zczb` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '注册资本',
`clrq` date NOT NULL COMMENT '成立日期',
`yyqx` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '营业期限',
`jyfw` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '经营范围',
`djjg` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '登记机关',
`gddhhm` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '固定电话号码',
`czhm` varchar(18) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '传真号码',
`dzxx` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '电子信箱',
`lxr` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '联系人',
`lxdh` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '联系电话',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint DEFAULT '0' COMMENT '是否删除(0-否 1-是)',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_event_id` (`event_id`) USING BTREE,
KEY `idx_tyshxydm` (`tyshxydm`) USING BTREE,
KEY `idx_qymc` (`qymc`) USING BTREE,
KEY `idx_qylx` (`qylx`) USING BTREE,
KEY `idx_qyxl` (`qyxl`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='药监企业数据上报-药品经营企业基本信息';
CREATE TABLE `edh_drug_operate_license_base_info` (
`id` bigint NOT NULL AUTO_INCREMENT,
`event_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
`jyxkzbh` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '经营许可证编号',
`qymc` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业名称',
`tyshxydm` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '统一社会信用代码',
`zcdz` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '注册地址',
`fddbr` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '法定代表人',
`qyfzr` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业负责人',
`zlfzr` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '质量负责人',
`ckdz` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '仓库地址',
`jyfs` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '经营方式',
`jyfw` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '经营范围',
`yxq` date NOT NULL COMMENT '有效期',
`fzjg` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '发证机关',
`qfr` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '签发人',
`qfrq` date NOT NULL COMMENT '签发日期',
`rcjdgljg` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '日常监督管理机构',
`tsjbdh` varchar(18) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '投诉举报电话',
`qylx` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业类型',
`qyxl` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '企业小类',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint DEFAULT '0' COMMENT '是否删除(0-否 1-是)',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_event_id` (`event_id`) USING BTREE,
UNIQUE KEY (`jyxkzbh`) USING BTREE,
KEY `idx_qymc` (`qymc`) USING BTREE,
KEY `idx_tyshxydm` (`tyshxydm`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='药监企业数据上报-药品经营许可证基本信息';
CREATE TABLE `edh_domestic_drug_base_info` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`event_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '事件流水号',
`gjypbsm` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '国家药品标识码',
`yptymc` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '药品通用名称',
`ypywmc` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '药品英文名称',
`ypspmc` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '药品商品名称',
`ypbwm` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '药品本位码',
`jx` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '剂型',
`zjgg` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '制剂规格',
`bzgg` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '包装规格',
`bzzhb` int NOT NULL COMMENT '包装转换比',
`ypyxq` int NOT NULL COMMENT '药品有效期',
`ypyxqdw` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '药品有效期单位',
`yppzwh` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '药品批准文号',
`yppzwhyxq` date NOT NULL COMMENT '药品批准文号有效期',
`ypzcfl` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '药品注册分类',
`gjjbywbs` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '国家基本药物标识',
`tsypglfl` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '特殊药品管理分类',
`cfybs` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '处方药标识',
`ypscqymc` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '药品生产企业名称',
`tyshxydmypscqyscdz` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '统一社会信用代码(药品生产企业)生产地址',
`ypssxkcyrmc` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '药品上市许可持有人名称',
`tyshxydmypssxkcyr` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '统一社会信用代码(药品上市许可持有人)',
`bzbl` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '包装比例',
`bzjb` int NOT NULL COMMENT '包装级别',
`bzggbs` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '包装规格标识',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint DEFAULT '0' COMMENT '是否删除(0-否 1-是)',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_event_id` (`event_id`) USING BTREE,
KEY `idx_gjypbsm` (`gjypbsm`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='药监企业数据上报-药品基本信息数据子集';
CREATE TABLE `edh_drug_invoice_apply_info` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`event_id` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '事件流水号',
`fhdbh` varchar(50) NOT NULL COMMENT '发货单编号',
`dhdbh` varchar(50) NOT NULL COMMENT '订货单编号',
`fhjgmc` varchar(200) NOT NULL COMMENT '发货机构名称',
`tyshxydmfhjg` varchar(50) NOT NULL COMMENT '统一社会信用代码(发货机构)',
`fhdz` varchar(500) NOT NULL COMMENT '发货地址',
`fhlx` varchar(10) NOT NULL COMMENT '发货类型',
`fhr` varchar(60) NOT NULL COMMENT '发货人',
`fhsj` datetime NOT NULL COMMENT '发货时间',
`shjgmc` varchar(200) NOT NULL COMMENT '收货机构名称',
`tyshxydmshjg` varchar(50) NOT NULL COMMENT '统一社会信用代码(收货机构)',
`shdz` varchar(500) NOT NULL COMMENT '收货地址',
`yppsqymc` varchar(200) NOT NULL COMMENT '药品配送企业名称',
`tyshxydmyppsqy` varchar(50) NOT NULL COMMENT '统一社会信用代码(药品配送企业)',
`djyzzt` varchar(10) NOT NULL COMMENT '单据验证状态',
`djyzrq` date NOT NULL COMMENT '单据验证日期',
`djyswtgyy` varchar(200) DEFAULT NULL COMMENT '单据验收未通过原因',
`gjypbsm` varchar(20) NOT NULL COMMENT '国家药品标识码',
`yptymc` varchar(100) NOT NULL COMMENT '药品通用名称',
`ypywmc` varchar(100) DEFAULT NULL COMMENT '药品英文名称',
`ypsymc` varchar(100) DEFAULT NULL COMMENT '药品商用名称',
`ypbwm` varchar(20) DEFAULT NULL COMMENT '药品本位码',
`ypyxq` int NOT NULL COMMENT '药品有效期',
`ypyxqdw` varchar(10) NOT NULL COMMENT '药品有效期单位(D:天; M:月Y:年)',
`yppzwh` varchar(100) NOT NULL COMMENT '药品批准文号',
`yppzwhyxq` date NOT NULL COMMENT '药品批准文号有效期',
`ypzcfl` varchar(10) NOT NULL COMMENT '药品注册分类',
`gjjbywbs` varchar(10) NOT NULL COMMENT '国家基本药物标识(true或者false)',
`tsypglfl` varchar(10) DEFAULT NULL COMMENT '特殊药品管理分类',
`cfybs` varchar(10) NOT NULL COMMENT '处方药标识',
`ypssxkcyrmc` varchar(200) DEFAULT NULL COMMENT '药品上市许可持有人名称',
`tyshxydmypssxkcyr` varchar(50) NOT NULL COMMENT '统一社会信用代码(药品上市许可持有人)',
`ypscqy` varchar(200) NOT NULL COMMENT '药品生产企业名称',
`tyshxydmypscqy` varchar(50) NOT NULL COMMENT '统一社会信用代码(药品生产企业)',
`fbzcmc` varchar(200) DEFAULT NULL COMMENT '分包装厂名称',
`tyshxydmfbzc` varchar(50) DEFAULT NULL COMMENT '统一社会信用代码(分包装厂)',
`ypscrq` date NOT NULL COMMENT '药品生产日期',
`ypyxqjzrq` date NOT NULL COMMENT '药品有效期截止日期',
`ypscph` varchar(20) NOT NULL COMMENT '药品生产批号',
`fhsl` int NOT NULL COMMENT '发货数量',
`ypzsm` varchar(200) NOT NULL COMMENT '药品追溯码',
`syjbzypzsm` varchar(200) NOT NULL COMMENT '上一级包装药品追溯码',
`bzcj` varchar(200) NOT NULL COMMENT '包装层级',
`fhjglx` varchar(10) NOT NULL COMMENT '发货机构类型',
`shjglx` varchar(10) NOT NULL COMMENT '收货机构类型',
`fhjgxl` varchar(10) NOT NULL COMMENT '发货机构小类',
`shjgxl` varchar(10) NOT NULL COMMENT '收货机构小类',
`jx` varchar(10) NOT NULL COMMENT '剂型',
`zjgg` varchar(200) NOT NULL COMMENT '制剂规格',
`bzgg` varchar(100) NOT NULL COMMENT '包装规格',
`bzzhb` int NOT NULL COMMENT '包装转换比',
`bzzhbdw` varchar(20) DEFAULT NULL COMMENT '包装转换比单位',
`fhdczr` varchar(60) NOT NULL COMMENT '发货单操作人',
`fhdscsj` datetime NOT NULL COMMENT '发货单上传时间',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint DEFAULT '0' COMMENT '是否删除(0-否 1-是)',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_event_id` (`event_id`) USING BTREE,
KEY `idx_dhdbh` (`dhdbh`) USING BTREE,
KEY `idx_gjypbsm` (`gjypbsm`) USING BTREE,
KEY `idx_ypzsm` (`ypzsm`) USING BTREE,
KEY `idx_fhsj` (`fhsj`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='药监企业数据上报-发货单信息数据子集';
CREATE TABLE `edh_drug_delivery_note_apply_info` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`event_id` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '事件流水号',
`shdbh` varchar(50) NOT NULL COMMENT '收货单编号',
`fhdbh` varchar(50) NOT NULL COMMENT '发货单编号',
`dhdbh` varchar(50) NOT NULL COMMENT '订货单编号',
`fhjgmc` varchar(200) NOT NULL COMMENT '发货机构名称',
`tyshxydmfhjg` varchar(50) NOT NULL COMMENT '统一社会信用代码(发货机构)',
`fhdz` varchar(500) NOT NULL COMMENT '发货地址',
`shdzjg` varchar(200) NOT NULL COMMENT '收货机构名称',
`tyshxydmshjg` varchar(50) NOT NULL COMMENT '统一社会信用代码(收货机构)',
`shdz` varchar(500) NOT NULL COMMENT '收货地址',
`shlx` varchar(10) NOT NULL COMMENT '收货类型',
`shrmc` varchar(60) NOT NULL COMMENT '收货人名称',
`shsj` datetime NOT NULL COMMENT '收货时间',
`djyzzt` varchar(10) NOT NULL COMMENT '单据验证状态',
`djyzrq` date NOT NULL COMMENT '单据验证日期',
`djyzwtgyy` varchar(200) DEFAULT NULL COMMENT '单据验证未通过原因',
`gjypbsm` varchar(20) NOT NULL COMMENT '国家药品标识码',
`yptymc` varchar(200) NOT NULL COMMENT '药品通用名称',
`ypywmc` varchar(200) DEFAULT NULL COMMENT '药品英文名称',
`ypsymc` varchar(200) DEFAULT NULL COMMENT '药品商品名称',
`ypbwm` varchar(20) NOT NULL COMMENT '药品本位码',
`ypyxq` int NOT NULL COMMENT '药品有效期',
`ypyxqdw` varchar(10) NOT NULL COMMENT '药品有效期单位',
`yppzwh` varchar(100) NOT NULL COMMENT '药品批准文号',
`yppzwhyxq` date NOT NULL COMMENT '药品批准文号有效期',
`ypzcfl` varchar(10) NOT NULL COMMENT '药品注册分类',
`gjjbywbs` varchar(10) NOT NULL COMMENT '国家基本药物标识',
`tsypglfl` varchar(10) DEFAULT NULL COMMENT '特殊药品管理分类',
`cfybs` varchar(10) NOT NULL COMMENT '处方药标识',
`ypssxkcyrmc` varchar(60) NOT NULL COMMENT '药品上市许可持有人名称',
`tyshxydmypssxkcyr` varchar(50) NOT NULL COMMENT '统一社会信用代码(药品上市许可持有人)',
`ypscqymc` varchar(200) NOT NULL COMMENT '药品生产企业名称',
`tyshxydmypscqy` varchar(50) NOT NULL COMMENT '统一社会信用代码(药品生产企业)',
`fbzcmc` varchar(200) DEFAULT NULL COMMENT '分包装厂名称',
`tyshxydmfbzc` varchar(50) DEFAULT NULL COMMENT '统一社会信用代码(分包装厂)',
`ypscrq` date NOT NULL COMMENT '药品生产日期',
`ypyxqjzrq` date NOT NULL COMMENT '药品有效期截止日期',
`ypscph` varchar(20) NOT NULL COMMENT '药品生产批号',
`yshsl` int NOT NULL COMMENT '应收货数量',
`sjshsl` int NOT NULL COMMENT '实际收货数量',
`ypzsm` varchar(200) NOT NULL COMMENT '药品追溯码',
`syjbzypzsm` varchar(200) NOT NULL COMMENT '上一级包装药品追溯码',
`bzcj` varchar(200) NOT NULL COMMENT '包装层级',
`bhzxxsbzdysl` int NOT NULL COMMENT '包含最小销售包装单元数量',
`zsmyzzt` varchar(10) NOT NULL COMMENT '追溯码验证状态',
`fhjglx` varchar(10) NOT NULL COMMENT '发货机构类型',
`shjglx` varchar(10) NOT NULL COMMENT '收货机构类型',
`fhjgxl` varchar(10) NOT NULL COMMENT '发货机构小类',
`shjgxl` varchar(10) NOT NULL COMMENT '收货机构小类',
`jx` varchar(10) NOT NULL COMMENT '剂型',
`zjgg` varchar(200) NOT NULL COMMENT '制剂规格',
`bzgg` varchar(100) NOT NULL COMMENT '包装规格',
`bzzhb` int NOT NULL COMMENT '包装转换比',
`bzzhdw` varchar(10) DEFAULT NULL COMMENT '包装转换比单位',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint DEFAULT '0' COMMENT '是否删除(0-否 1-是)',
PRIMARY KEY (`id`),
KEY `idx_event_id` (`event_id`) USING BTREE,
KEY `idx_fhdbh` (`fhdbh`) USING BTREE,
KEY `idx_dhdbh` (`dhdbh`) USING BTREE,
KEY `idx_gjypbsm` (`gjypbsm`) USING BTREE,
KEY `idx_ypzsm` (`ypzsm`) USING BTREE,
KEY `idx_shsj` (`shsj`) USING BTREE,
KEY `idx_ypscph` (`ypscph`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='药监企业数据上报-药品收货单信息表';
CREATE TABLE `edh_wh_temp_humidity_apply_info` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`event_id` varchar(32) NOT NULL COMMENT '事件流水号',
`qytyshxydm` varchar(50) NOT NULL COMMENT '企业统一社会信用代码',
`qymc` varchar(200) NOT NULL COMMENT '企业名称',
`ckbh` varchar(50) NOT NULL COMMENT '仓库编号',
`ckdz` varchar(200) NOT NULL COMMENT '仓库地址',
`ckmj` varchar(20) NOT NULL COMMENT '仓库面积',
`cklx` varchar(10) NOT NULL COMMENT '仓库类型',
`wdsx` varchar(10) NOT NULL COMMENT '温度上限',
`wdxx` varchar(10) NOT NULL COMMENT '温度下限',
`sdsx` varchar(10) NOT NULL COMMENT '湿度上限',
`sdxx` varchar(10) NOT NULL COMMENT '湿度下限',
`hjwd` varchar(10) NOT NULL COMMENT '环境温度',
`hjsd` varchar(10) NOT NULL COMMENT '环境湿度',
`sjlx` varchar(10) NOT NULL COMMENT '数据类型(1正常记录2报警记录)',
`sjscsj` datetime NOT NULL COMMENT '数据上传时间',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint DEFAULT '0' COMMENT '是否删除(0-否 1-是)',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_event_id` (`event_id`) USING BTREE,
KEY `idx_qytyshxydm` (`qytyshxydm`) USING BTREE,
KEY `idx_ckbh` (`ckbh`) USING BTREE,
KEY `idx_sjscsj` (`sjscsj`) USING BTREE,
KEY `idx_sjlx` (`sjlx`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='药监企业数据上报-仓库存储温湿度信息表';
CREATE TABLE `edh_warehouse_stock_apply_info` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`event_id` varchar(32) NOT NULL COMMENT '事件流水号',
`tyshxydmkcdw` varchar(50) NOT NULL COMMENT '统一社会信用代码(库存单位)',
`kcdwmc` varchar(200) NOT NULL COMMENT '库存单位名称',
`kctjrq` date NOT NULL COMMENT '库存统计日期',
`kcdz` varchar(500) NOT NULL COMMENT '库存地址',
`yptymc` varchar(200) NOT NULL COMMENT '药品通用名称',
`gjypbsm` varchar(20) NOT NULL COMMENT '国家药品标识码',
`ypscph` varchar(20) NOT NULL COMMENT '药品生产批号',
`ypscrq` date NOT NULL COMMENT '药品生产日期',
`ypyxqjzrq` date NOT NULL COMMENT '药品有效期截止日期',
`kcsl` int NOT NULL COMMENT '库存制剂数量',
`sjkcsl` int NOT NULL COMMENT '实际库存数量',
`kcdwlx` varchar(10) NOT NULL COMMENT '库存单位类型',
`kcdwlxxl` varchar(10) NOT NULL COMMENT '库存单位类型小类',
`pzwh` varchar(200) NOT NULL COMMENT '批准文号',
`ypssxkcyr` varchar(60) NOT NULL COMMENT '药品上市许可持有人',
`ypssxkcyrdm` varchar(50) NOT NULL COMMENT '药品上市许可持有人代码',
`ypscqymc` varchar(200) NOT NULL COMMENT '药品生产企业名称',
`ypscqytyshxydm` varchar(50) NOT NULL COMMENT '药品生产企业统一社会信用代码',
`jx` varchar(10) NOT NULL COMMENT '剂型',
`zjgg` varchar(200) NOT NULL COMMENT '制剂规格',
`bzgg` varchar(200) NOT NULL COMMENT '包装规格',
`bzzhb` int NOT NULL COMMENT '包装转换比',
`bzzhbdw` varchar(20) DEFAULT NULL COMMENT '包装转换比单位',
`ypzcfl` varchar(10) NOT NULL COMMENT '药品注册分类',
`tsypglfl` varchar(10) DEFAULT NULL COMMENT '特殊药品管理分类',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint DEFAULT '0' COMMENT '是否删除(0-否 1-是)',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_gjypbsm` (`gjypbsm`) USING BTREE,
KEY `idx_ypscph` (`ypscph`) USING BTREE,
KEY `idx_kctjrq` (`kctjrq`) USING BTREE,
KEY `idx_ypyxqjzrq` (`ypyxqjzrq`) USING BTREE,
KEY `idx_yptymc` (`yptymc`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='药监企业数据上报-库存上报信息表';

View File

@ -0,0 +1,21 @@
package com.supervision.edh;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* @author Jason
* @date 2025年06月17日 11:40:18
*/
@SpringBootApplication
// 指定要扫描的Mapper类的包的路径
@MapperScan("com.supervision.edh")
@EnableAsync
public class SupervisionEdhApplication {
public static void main(String[] args) {
SpringApplication.run(SupervisionEdhApplication.class, args);
}
}

View File

@ -0,0 +1,218 @@
package com.supervision.edh;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import com.supervision.edh.utils.Base64;
import com.supervision.edh.utils.EventPojo;
import com.supervision.edh.utils.KeyStoreUtil;
import com.supervision.edh.utils.StreamUtil;
import org.springframework.util.ResourceUtils;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.*;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 请求客户端
*/
public class SupervisionEdhClient {
/**
* 请求url
*/
private static final String url = "http://localhost:1788/supervision/edh/receive";
//private static final String url = "http://222.221.246.3:1788/supervision/edh/receive";
/**
* 证书地址
*/
private static final String PFX_FILE_PATH = "D:\\ynyp\\药品追溯\\d2d\\edh.pfx";
/**
* 证书密码
*/
private static final String PFX_PASSWORD = "YnYp123456";
/**
* 加密算法
*/
private static final String algorithm = "RSA";
private static final String JSON_DIRECTORY = "D:\\ynyp\\药品追溯\\省市对接药品v0.19-通用版\\企业上报\\json数据报文\\";
public static void main(String[] args) throws Exception {
//数据文件内容主业务类型 10基础信息数据 20应用信息数据
//subType数据文件内容子业务类型 详见数据类型字典表 基本信息(1011-10199001-9002) 应用信息2011-20202051-2053
testProv("1015");
}
public static void testProv(String subType) throws Exception {
//入参
String fileName = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 20);
//需要同步的xml(10-基本信息集 20-应用信息集)
String data = StreamUtil.getStreamContent(fileName, getData(subType));
//流水号
String processId = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 20);
//事件编号
String eventId = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 20);
//数据文件内容主业务类型 10基础信息数据 20应用信息数据
//subType数据文件内容子业务类型 详见数据类型字典表
//获取公钥
String publicKey = getPublicKey();
System.out.println("publicKey:" + publicKey);
String privateKey = getPrivateKey();
System.out.println("privateKey:" + privateKey);
//公钥加密
String en = keyEncrypt(publicKey, data);
System.out.println("publicKey加密后en:" + en);
EventPojo eventPojo = new EventPojo();
eventPojo.setData(en);
eventPojo.setSubType(subType);
//请求时间戳
String timestamp = formatDateToyyyyMMddHHmm(new Date());
//请求时间戳
String ver = "1.0";
Map<String, String> paramMap = new HashMap<>();
paramMap.put("process_id", processId);
paramMap.put("event_id", eventId);
String eventType = "10";
if (subType.startsWith("20")) {//20开头
eventType = "20";
}
paramMap.put("event_type", eventType);
paramMap.put("event", JSONObject.toJSONString(eventPojo));
paramMap.put("timestamp", timestamp);
paramMap.put("ver", ver);
paramMap.put("tyshxydm", "12345678");
Map<String, Object> requestMap = new HashMap<>(4);
requestMap.put("req", paramMap);
System.out.println(JSONObject.toJSONString(requestMap));
String body = HttpRequest.post(url).body(JSONObject.toJSONString(requestMap)).timeout(10000).execute().body();
System.out.println(body);
}
/**
* 公钥加密
*
* @param key
* @param data
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws NoSuchPaddingException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
* @throws InvalidKeyException
* @throws IOException
*/
public static 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(algorithm).generatePublic(new X509EncodedKeySpec(decode));
//RSA加密
Cipher ci = Cipher.getInstance(algorithm);
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;
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;
}
/**
* 获取私钥
*
* @return
* @throws Exception
*/
private static String getPrivateKey() throws Exception {
KeyStore keyStore = KeyStoreUtil.loadKetStore(PFX_FILE_PATH, PFX_PASSWORD);
return Base64.encode(KeyStoreUtil.getPrivateKey(keyStore, PFX_PASSWORD).getEncoded());
}
/**
* 获取公钥
*
* @return
* @throws Exception
*/
private static String getPublicKey() throws Exception {
KeyStore keyStore = KeyStoreUtil.loadKetStore(PFX_FILE_PATH, PFX_PASSWORD);
PublicKey publicKey = KeyStoreUtil.getPublicKey(keyStore);
return Base64.encode(publicKey.getEncoded());
}
/**
* 返回时间字符串, 可读形式的, yy年M月d日HH:mm 格式.
*
* @return - String 格式化后的时间
*/
public static String formatDateToyyyyMMddHHmm(Date date) {
if (date == null) {
return "";
}
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyyMMddHHmmss");
return dateFormat.format(date);
}
/**
* 动态获取文件内容
*
* @param subType
* @return
* @throws IOException
*/
private static String getData(String subType) throws IOException {
// 构建文件名
String fileName = subType + ".json";
// 获取文件路径
File file = ResourceUtils.getFile(JSON_DIRECTORY + fileName);
Path path = Paths.get(file.getAbsolutePath());
// 读取文件内容并返回
return new String(Files.readAllBytes(path));
}
}

View File

@ -0,0 +1,205 @@
package com.supervision.edh.common;
import com.supervision.edh.constant.HttpStatus;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Objects;
/**
* 操作消息提醒
*
* @author tcctyn
*/
public class AjaxResult extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
/**
* 状态码
*/
public static final String CODE_TAG = "code";
/**
* 返回内容
*/
public static final String MSG_TAG = "msg";
/**
* 数据对象
*/
public static final String DATA_TAG = "data";
/**
* 初始化一个新创建的 AjaxResult 对象使其表示一个空消息
*/
public AjaxResult() {
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param code 状态码
* @param msg 返回内容
*/
public AjaxResult(int code, String msg) {
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
}
/**
* 初始化一个新创建的 AjaxResult 对象
*
* @param code 状态码
* @param msg 返回内容
* @param data 数据对象
*/
public AjaxResult(int code, String msg, Object data) {
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
if (!StringUtils.isEmpty(data)) {
super.put(DATA_TAG, data);
}
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public static AjaxResult success() {
return AjaxResult.success("操作成功");
}
/**
* 返回成功数据
*
* @return 成功消息
*/
public static AjaxResult success(Object data) {
return AjaxResult.success("操作成功", data);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @return 成功消息
*/
public static AjaxResult success(String msg) {
return AjaxResult.success(msg, null);
}
/**
* 返回成功消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 成功消息
*/
public static AjaxResult success(String msg, Object data) {
return new AjaxResult(HttpStatus.SUCCESS, msg, data);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static AjaxResult warn(String msg) {
return AjaxResult.warn(msg, null);
}
/**
* 返回警告消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static AjaxResult warn(String msg, Object data) {
return new AjaxResult(HttpStatus.WARN, msg, data);
}
/**
* 返回错误消息
*
* @return 错误消息
*/
public static AjaxResult error() {
return AjaxResult.error("操作失败");
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @return 错误消息
*/
public static AjaxResult error(String msg) {
return AjaxResult.error(msg, null);
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 错误消息
*/
public static AjaxResult error(String msg, Object data) {
return new AjaxResult(HttpStatus.ERROR, msg, data);
}
/**
* 返回错误消息
*
* @param code 状态码
* @param msg 返回内容
* @return 错误消息
*/
public static AjaxResult error(int code, String msg) {
return new AjaxResult(code, msg, null);
}
/**
* 是否为成功消息
*
* @return 结果
*/
public boolean isSuccess() {
return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
}
/**
* 是否为警告消息
*
* @return 结果
*/
public boolean isWarn() {
return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
}
/**
* 是否为错误消息
*
* @return 结果
*/
public boolean isError() {
return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
}
/**
* 方便链式调用
*
* @param key
* @param value
* @return 数据对象
*/
@Override
public AjaxResult put(String key, Object value) {
super.put(key, value);
return this;
}
}

View File

@ -0,0 +1,18 @@
package com.supervision.edh.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author Jason 证书配置
* @date 2025年06月06日 14:09:26
*/
@Component
@ConfigurationProperties(prefix = "cert")
@Data
public class CertConfig {
private String path;
private String password;
private String algorithm;
}

View File

@ -0,0 +1,94 @@
package com.supervision.edh.constant;
/**
* 返回状态码
*
* @author tcctyn
*/
public class HttpStatus
{
/**
* 操作成功
*/
public static final int SUCCESS = 200;
/**
* 对象创建成功
*/
public static final int CREATED = 201;
/**
* 请求已经被接受
*/
public static final int ACCEPTED = 202;
/**
* 操作已经执行成功但是没有返回数据
*/
public static final int NO_CONTENT = 204;
/**
* 资源已被移除
*/
public static final int MOVED_PERM = 301;
/**
* 重定向
*/
public static final int SEE_OTHER = 303;
/**
* 资源没有被修改
*/
public static final int NOT_MODIFIED = 304;
/**
* 参数列表错误缺少格式不匹配
*/
public static final int BAD_REQUEST = 400;
/**
* 未授权
*/
public static final int UNAUTHORIZED = 401;
/**
* 访问受限授权过期
*/
public static final int FORBIDDEN = 403;
/**
* 资源服务未找到
*/
public static final int NOT_FOUND = 404;
/**
* 不允许的http方法
*/
public static final int BAD_METHOD = 405;
/**
* 资源冲突或者资源被锁
*/
public static final int CONFLICT = 409;
/**
* 不支持的数据媒体类型
*/
public static final int UNSUPPORTED_TYPE = 415;
/**
* 系统内部错误
*/
public static final int ERROR = 500;
/**
* 接口未实现
*/
public static final int NOT_IMPLEMENTED = 501;
/**
* 系统警告消息
*/
public static final int WARN = 601;
}

View File

@ -0,0 +1,110 @@
package com.supervision.edh.controller;
import com.alibaba.fastjson.JSON;
import com.supervision.edh.common.AjaxResult;
import com.supervision.edh.domain.EdhReceiveDataLog;
import com.supervision.edh.enums.BuzStatusEnum;
import com.supervision.edh.enums.EventTypeEnum;
import com.supervision.edh.enums.SubTypeEnum;
import com.supervision.edh.service.IEdhReceiveDataLogService;
import com.supervision.edh.service.IEventProcessingService;
import com.supervision.edh.service.impl.EventProcessingServiceImpl;
import com.supervision.edh.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;
/**
* @ClassName SupervisionEdhServerController
* @Desc 省局对接示例代码 服务端 接收端
* @Author houduo.wk
* @Date 2020/3/13
**/
@RestController
@RequestMapping("/supervision/edh")
public class SupervisionEdhServerController {
Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private CertManager certManager;
@Autowired
private IEdhReceiveDataLogService receiveDataLogService;
@Autowired
private EventProcessingServiceImpl processingService;
@RequestMapping("/receive")
public @ResponseBody
String receive(HttpServletRequest request) throws IOException {
RequestWrapper requestWrapper = new RequestWrapper(request);
String body = requestWrapper.getBodyString();
System.out.println(body);
Map<String, Object> paramsTemp = JSON.parseObject(body);
System.out.println(paramsTemp);
Map<String, Object> params = JSON.parseObject(paramsTemp.get("req").toString());
logger.info("ProvTestController.receive.in.params:{}", params);
try {
//传输流水号0
String processId = String.valueOf(params.get("process_id"));
//事件编号
String eventId = String.valueOf(params.get("event_id"));
//主数据类型
String eventType = String.valueOf(params.get("event_type"));
//主数据 包含子类型sub_type和数据data
String event = String.valueOf(params.get("event"));
//时间戳 YYMMddHHmmssSSS
String timeStamp = String.valueOf(params.get("timestamp"));
//版本号
String ver = String.valueOf(params.get("ver"));
//企业统一社会信用代码
String tyshxydm = String.valueOf(params.get("tyshxydm"));
logger.info("processId:{}|eventId:{}|eventType:{}|event:{}|timeStamp:{}|ver:{}"
, processId, eventId, eventType, event, timeStamp, ver);
EventPojo eventPojo = JSON.parseObject(event, EventPojo.class);
//获取私钥
String privateKey = certManager.getPrivateKey();
logger.info("privateKey:{}", privateKey);
String de = certManager.keyDecrypt(privateKey, eventPojo.getData());
String data = StreamUtil.getUnStreamContent(de);
logger.info("解密之后的文件内容:{}", data);
//保存数据日志
EdhReceiveDataLog dataLog = new EdhReceiveDataLog();
dataLog.setEventId(eventId);
dataLog.setTyshxydm(tyshxydm);
dataLog.setProcessId(processId);
dataLog.setEventType(eventType);
dataLog.setEventTypeName(EventTypeEnum.getNameByType(eventType));
dataLog.setSubType(eventPojo.getSubType());
dataLog.setSubTypeName(SubTypeEnum.getNameByType(eventPojo.getSubType()));
dataLog.setData(eventPojo.getData());
dataLog.setVer(ver);
receiveDataLogService.save(dataLog);
//解析并处理数据
processingService.asyncProcessEvent(eventPojo, data, eventId);
return ResponseBuilder.success();
} catch (Exception e) {
logger.error("数据解析错误,错误信息:{}", e.getMessage());
return ResponseBuilder.fail(BuzStatusEnum.SYS_ERR);
}
}
}

View File

@ -0,0 +1,178 @@
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;
/**
* <p>
* 药监企业数据上报-药品基本信息数据子集
* </p>
*
* @author Jason
* @since 2025-06-20
*/
@Getter
@Setter
@TableName("edh_domestic_drug_base_info")
public class EdhDomesticDrugBaseInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 事件流水号
*/
private String eventId;
/**
* 国家药品标识码
*/
private String gjypbsm;
/**
* 药品通用名称
*/
private String yptymc;
/**
* 药品英文名称
*/
private String ypywmc;
/**
* 药品商品名称
*/
private String ypspmc;
/**
* 药品本位码
*/
private String ypbwm;
/**
* 剂型
*/
private String jx;
/**
* 制剂规格
*/
private String zjgg;
/**
* 包装规格
*/
private String bzgg;
/**
* 包装转换比
*/
private Integer bzzhb;
/**
* 药品有效期
*/
private Integer ypyxq;
/**
* 药品有效期单位
*/
private String ypyxqdw;
/**
* 药品批准文号
*/
private String yppzwh;
/**
* 药品批准文号有效期
*/
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate yppzwhyxq;
/**
* 药品注册分类
*/
private String ypzcfl;
/**
* 国家基本药物标识
*/
private String gjjbywbs;
/**
* 特殊药品管理分类
*/
private String tsypglfl;
/**
* 处方药标识
*/
private String cfybs;
/**
* 药品生产企业名称
*/
private String ypscqymc;
/**
* 统一社会信用代码(药品生产企业)生产地址
*/
private String tyshxydmypscqyscdz;
/**
* 药品上市许可持有人名称
*/
private String ypssxkcyrmc;
/**
* 统一社会信用代码药品上市许可持有人
*/
private String tyshxydmypssxkcyr;
/**
* 包装比例
*/
private String bzbl;
/**
* 包装级别
*/
private Integer bzjb;
/**
* 包装规格标识
*/
private String bzggbs;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 是否删除(0- 1-)
*/
private Integer isDeleted;
}

View File

@ -0,0 +1,330 @@
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.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.supervision.edh.domain.vo.DrugVO;
import com.supervision.edh.utils.LocalDateDeserializer;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 药监企业数据上报-药品收货单信息表
* </p>
*
* @author Jason
* @since 2025-06-21
*/
@Getter
@Setter
@TableName("edh_drug_delivery_note_apply_info")
public class EdhDrugDeliveryNoteApplyInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 事件流水号
*/
private String eventId;
/**
* 收货单编号
*/
private String shdbh;
/**
* 发货单编号
*/
private String fhdbh;
/**
* 订货单编号
*/
private String dhdbh;
/**
* 发货机构名称
*/
private String fhjgmc;
/**
* 统一社会信用代码发货机构
*/
private String tyshxydmfhjg;
/**
* 发货地址
*/
private String fhdz;
/**
* 收货机构名称
*/
private String shjgmc;
/**
* 统一社会信用代码收货机构
*/
private String tyshxydmshjg;
/**
* 收货地址
*/
private String shdz;
/**
* 收货类型
*/
private String shlx;
/**
* 收货人名称
*/
private String shrmc;
/**
* 收货时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime shsj;
/**
* 单据验证状态
*/
private String djyzzt;
/**
* 单据验证日期
*/
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate djyzrq;
/**
* 单据验证未通过原因
*/
private String djyzwtgyy;
/**
* 国家药品标识码
*/
private String gjypbsm;
/**
* 药品通用名称
*/
private String yptymc;
/**
* 药品英文名称
*/
private String ypywmc;
/**
* 药品商品名称
*/
private String ypsymc;
/**
* 药品本位码
*/
private String ypbwm;
/**
* 药品有效期
*/
private Integer ypyxq;
/**
* 药品有效期单位
*/
private String ypyxqdw;
/**
* 药品批准文号
*/
private String yppzwh;
/**
* 药品批准文号有效期
*/
private LocalDate yppzwhyxq;
/**
* 药品注册分类
*/
private String ypzcfl;
/**
* 国家基本药物标识
*/
private String gjjbywbs;
/**
* 特殊药品管理分类
*/
private String tsypglfl;
/**
* 处方药标识
*/
private String cfybs;
/**
* 药品上市许可持有人名称
*/
private String ypssxkcyrmc;
/**
* 统一社会信用代码药品上市许可持有人
*/
private String tyshxydmypssxkcyr;
/**
* 药品生产企业名称
*/
private String ypscqymc;
/**
* 统一社会信用代码(药品生产企业)
*/
private String tyshxydmypscqy;
/**
* 分包装厂名称
*/
private String fbzcmc;
/**
* 统一社会信用代码分包装厂
*/
private String tyshxydmfbzc;
/**
* 药品生产日期
*/
private LocalDate ypscrq;
/**
* 药品有效期截止日期
*/
private LocalDate ypyxqjzrq;
/**
* 药品生产批号
*/
private String ypscph;
/**
* 应收货数量
*/
private Integer yshsl;
/**
* 实际收货数量
*/
private Integer sjshsl;
/**
* 药品追溯码
*/
private String ypzsm;
/**
* 上一级包装药品追溯码
*/
private String syjbzypzsm;
/**
* 包装层级
*/
private String bzcj;
/**
* 包含最小销售包装单元数量
*/
private Integer bhzxxsbzdysl;
/**
* 追溯码验证状态
*/
private String zsmyzzt;
/**
* 发货机构类型
*/
private String fhjglx;
/**
* 收货机构类型
*/
private String shjglx;
/**
* 发货机构小类
*/
private String fhjgxl;
/**
* 收货机构小类
*/
private String shjgxl;
/**
* 剂型
*/
private String jx;
/**
* 制剂规格
*/
private String zjgg;
/**
* 包装规格
*/
private String bzgg;
/**
* 包装转换比
*/
private Integer bzzhb;
/**
* 包装转换比单位
*/
private String bzzhbdw;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 是否删除(0- 1-)
*/
private Integer isDeleted;
@TableField(exist = false)
private List<DrugVO> itemList; // 非数据库集合字段
}

View File

@ -0,0 +1,330 @@
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.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.supervision.edh.domain.vo.DrugVO;
import com.supervision.edh.utils.LocalDateDeserializer;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 药监企业数据上报-发货单信息数据子集
* </p>
*
* @author Jason
* @since 2025-06-20
*/
@Getter
@Setter
@TableName("edh_drug_invoice_apply_info")
public class EdhDrugInvoiceApplyInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 事件流水号
*/
private String eventId;
/**
* 发货单编号
*/
private String fhdbh;
/**
* 订货单编号
*/
private String dhdbh;
/**
* 发货机构名称
*/
private String fhjgmc;
/**
* 统一社会信用代码发货机构
*/
private String tyshxydmfhjg;
/**
* 发货地址
*/
private String fhdz;
/**
* 发货类型
*/
private String fhlx;
/**
* 发货人
*/
private String fhr;
/**
* 发货时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime fhsj;
/**
* 收货机构名称
*/
private String shjgmc;
/**
* 统一社会信用代码收货机构
*/
private String tyshxydmshjg;
/**
* 收货地址
*/
private String shdz;
/**
* 药品配送企业名称
*/
private String yppsqymc;
/**
* 统一社会信用代码药品配送企业
*/
private String tyshxydmyppsqy;
/**
* 单据验证状态
*/
private String djyzzt;
/**
* 单据验证日期
*/
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate djyzrq;
/**
* 单据验收未通过原因
*/
private String djyswtgyy;
/**
* 国家药品标识码
*/
private String gjypbsm;
/**
* 药品通用名称
*/
private String yptymc;
/**
* 药品英文名称
*/
private String ypywmc;
/**
* 药品商用名称
*/
private String ypsymc;
/**
* 药品本位码
*/
private String ypbwm;
/**
* 药品有效期
*/
private Integer ypyxq;
/**
* 药品有效期单位(D: M:Y:)
*/
private String ypyxqdw;
/**
* 药品批准文号
*/
private String yppzwh;
/**
* 药品批准文号有效期
*/
private LocalDate yppzwhyxq;
/**
* 药品注册分类
*/
private String ypzcfl;
/**
* 国家基本药物标识(true或者false)
*/
private String gjjbywbs;
/**
* 特殊药品管理分类
*/
private String tsypglfl;
/**
* 处方药标识
*/
private String cfybs;
/**
* 药品上市许可持有人名称
*/
private String ypssxkcyrmc;
/**
* 统一社会信用代码药品上市许可持有人
*/
private String tyshxydmypssxkcyr;
/**
* 药品生产企业名称
*/
private String ypscqymc;
/**
* 统一社会信用代码药品生产企业
*/
private String tyshxydmypscqy;
/**
* 分包装厂名称
*/
private String fbzcmc;
/**
* 统一社会信用代码分包装厂
*/
private String tyshxydmfbzc;
/**
* 药品生产日期
*/
private LocalDate ypscrq;
/**
* 药品有效期截止日期
*/
private LocalDate ypyxqjzrq;
/**
* 药品生产批号
*/
private String ypscph;
/**
* 发货数量
*/
private Integer fhsl;
/**
* 药品追溯码
*/
private String ypzsm;
/**
* 上一级包装药品追溯码
*/
private String syjbzypzsm;
/**
* 包装层级
*/
private String bzcj;
/**
* 发货机构类型
*/
private String fhjglx;
/**
* 收货机构类型
*/
private String shjglx;
/**
* 发货机构小类
*/
private String fhjgxl;
/**
* 收货机构小类
*/
private String shjgxl;
/**
* 剂型
*/
private String jx;
/**
* 制剂规格
*/
private String zjgg;
/**
* 包装规格
*/
private String bzgg;
/**
* 包装转换比
*/
private Integer bzzhb;
/**
* 包装转换比单位
*/
private String bzzhbdw;
/**
* 发货单操作人
*/
private String fhdczr;
/**
* 发货单上传时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime fhdscsj;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 是否删除(0- 1-)
*/
private Integer isDeleted;
@TableField(exist = false)
private List<DrugVO> itemList; // 非数据库集合字段
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-药品经营许可证基本信息
* </p>
*
* @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;
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-药品经营企业基本信息
* </p>
*
* @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;
}

View File

@ -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;
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-库存上报信息表
* </p>
*
* @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<StockVO> itemList; // 非数据库集合字段
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-仓库存储温湿度信息表
* </p>
*
* @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;
}

View File

@ -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;
}

View File

@ -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<InstanceVO> instanceList;
}

View File

@ -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<EdhDomesticDrugBaseInfo> dataSet;
}

View File

@ -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<EdhDrugDeliveryNoteApplyInfo> dataSet;
}

View File

@ -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<EdhDrugInvoiceApplyInfo> dataSet;
}

View File

@ -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<EdhDrugOperateLicenseBaseInfo> dataSet;
}

View File

@ -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<EdhDrugOperatorsBaseInfo> dataSet;
}

View File

@ -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<EdhWarehouseStockApplyInfo> dataSet;
}

View File

@ -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<EdhWhTempHumidityApplyInfo> dataSet;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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() : "未知类型";
}
}

View File

@ -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;
}
}

View File

@ -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() : "未知类型";
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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<String, EventDataHandler> handlerMap;
public EventDataHandler getHandler(String subType) {
EventDataHandler handler = handlerMap.get(subType);
if (handler == null) {
throw new IllegalArgumentException("未找到对应的处理器: " + subType);
}
return handler;
}
}

View File

@ -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+"--------生成实体成功!!");
}
}

View File

@ -0,0 +1,16 @@
package com.supervision.edh.mapper;
import com.supervision.edh.domain.EdhDomesticDrugBaseInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 药监企业数据上报-药品基本信息数据子集 Mapper 接口
* </p>
*
* @author Jason
* @since 2025-06-20
*/
public interface EdhDomesticDrugBaseInfoMapper extends BaseMapper<EdhDomesticDrugBaseInfo> {
}

View File

@ -0,0 +1,16 @@
package com.supervision.edh.mapper;
import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 药监企业数据上报-药品收货单信息表 Mapper 接口
* </p>
*
* @author Jason
* @since 2025-06-21
*/
public interface EdhDrugDeliveryNoteApplyInfoMapper extends BaseMapper<EdhDrugDeliveryNoteApplyInfo> {
}

View File

@ -0,0 +1,16 @@
package com.supervision.edh.mapper;
import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 药监企业数据上报-发货单信息数据子集 Mapper 接口
* </p>
*
* @author Jason
* @since 2025-06-20
*/
public interface EdhDrugInvoiceApplyInfoMapper extends BaseMapper<EdhDrugInvoiceApplyInfo> {
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-药品经营许可证基本信息 Mapper 接口
* </p>
*
* @author Jason
* @since 2025-06-19
*/
public interface EdhDrugOperateLicenseBaseInfoMapper extends BaseMapper<EdhDrugOperateLicenseBaseInfo> {
List<EdhDrugOperateLicenseBaseInfo> listByJyxkzbhIn(Set<String> jyxkzbhSet);
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-药品经营企业基本信息 Mapper 接口
* </p>
*
* @author Jason
* @since 2025-06-18
*/
public interface EdhDrugOperatorsBaseInfoMapper extends BaseMapper<EdhDrugOperatorsBaseInfo> {
List<EdhDrugOperatorsBaseInfo> listByTyshxydmIn(Set<String> tyshxydmSet);
}

View File

@ -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<EdhReceiveDataLog> {
}

View File

@ -0,0 +1,16 @@
package com.supervision.edh.mapper;
import com.supervision.edh.domain.EdhWarehouseStockApplyInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 药监企业数据上报-库存上报信息表 Mapper 接口
* </p>
*
* @author Jason
* @since 2025-06-23
*/
public interface EdhWarehouseStockApplyInfoMapper extends BaseMapper<EdhWarehouseStockApplyInfo> {
}

View File

@ -0,0 +1,16 @@
package com.supervision.edh.mapper;
import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 药监企业数据上报-仓库存储温湿度信息表 Mapper 接口
* </p>
*
* @author Jason
* @since 2025-06-21
*/
public interface EdhWhTempHumidityApplyInfoMapper extends BaseMapper<EdhWhTempHumidityApplyInfo> {
}

View File

@ -0,0 +1,16 @@
package com.supervision.edh.service;
import com.supervision.edh.domain.EdhDomesticDrugBaseInfo;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 药监企业数据上报-药品基本信息数据子集 服务类
* </p>
*
* @author Jason
* @since 2025-06-20
*/
public interface IEdhDomesticDrugBaseInfoService extends IService<EdhDomesticDrugBaseInfo> {
}

View File

@ -0,0 +1,16 @@
package com.supervision.edh.service;
import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 药监企业数据上报-药品收货单信息表 服务类
* </p>
*
* @author Jason
* @since 2025-06-21
*/
public interface IEdhDrugDeliveryNoteApplyInfoService extends IService<EdhDrugDeliveryNoteApplyInfo> {
}

View File

@ -0,0 +1,16 @@
package com.supervision.edh.service;
import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 药监企业数据上报-发货单信息数据子集 服务类
* </p>
*
* @author Jason
* @since 2025-06-20
*/
public interface IEdhDrugInvoiceApplyInfoService extends IService<EdhDrugInvoiceApplyInfo> {
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-药品经营许可证基本信息 服务类
* </p>
*
* @author Jason
* @since 2025-06-19
*/
public interface IEdhDrugOperateLicenseBaseInfoService extends IService<EdhDrugOperateLicenseBaseInfo> {
List<EdhDrugOperateLicenseBaseInfo> listByJyxkzbhIn(Set<String> jyxkzbhSet);
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-药品经营企业基本信息 服务类
* </p>
*
* @author Jason
* @since 2025-06-18
*/
public interface IEdhDrugOperatorsBaseInfoService extends IService<EdhDrugOperatorsBaseInfo> {
List<EdhDrugOperatorsBaseInfo> listByTyshxydmIn(Set<String> tyshxydmSet);
}

View File

@ -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<EdhReceiveDataLog> {
}

View File

@ -0,0 +1,16 @@
package com.supervision.edh.service;
import com.supervision.edh.domain.EdhWarehouseStockApplyInfo;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 药监企业数据上报-库存上报信息表 服务类
* </p>
*
* @author Jason
* @since 2025-06-23
*/
public interface IEdhWarehouseStockApplyInfoService extends IService<EdhWarehouseStockApplyInfo> {
}

View File

@ -0,0 +1,16 @@
package com.supervision.edh.service;
import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 药监企业数据上报-仓库存储温湿度信息表 服务类
* </p>
*
* @author Jason
* @since 2025-06-21
*/
public interface IEdhWhTempHumidityApplyInfoService extends IService<EdhWhTempHumidityApplyInfo> {
}

View File

@ -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);
}

View File

@ -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<T> implements EventDataHandler {
protected final Logger log = LoggerFactory.getLogger(getClass());
protected abstract Class<T> getEntityClass();
//protected abstract IService<T> getService();
}

View File

@ -0,0 +1,12 @@
package com.supervision.edh.service.handle;
/**
* 事件处理接口
*/
public interface EventDataHandler {
//String getSubType(); // 返回业务subType
//处理数据
void handleData(String data,String eventId);
}

View File

@ -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"
}

View File

@ -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<EdhDrugOperatorsBaseInfoVO> {
protected final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
private IEdhDrugOperatorsBaseInfoService edhDrugOperatorsBaseInfoService;
@Override
protected Class<EdhDrugOperatorsBaseInfoVO> 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<EdhDrugOperatorsBaseInfo> 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<String> tyshxydmSet = uniqueList.stream()
.map(EdhDrugOperatorsBaseInfo::getTyshxydm)
.collect(Collectors.toSet());
// 自定义批量查询方法
Map<String, EdhDrugOperatorsBaseInfo> existingMap = edhDrugOperatorsBaseInfoService
.listByTyshxydmIn(tyshxydmSet)
.stream()
.collect(Collectors.toMap(
EdhDrugOperatorsBaseInfo::getTyshxydm,
Function.identity()
));
// 3. 分离新增和更新数据
List<EdhDrugOperatorsBaseInfo> insertList = new ArrayList<>();
List<EdhDrugOperatorsBaseInfo> 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);
}
}
}

View File

@ -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<EdhDrugOperateLicenseBaseInfoVO> {
protected final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
private IEdhDrugOperateLicenseBaseInfoService drugOperateLicenseBaseInfoService;
@Override
protected Class<EdhDrugOperateLicenseBaseInfoVO> 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<EdhDrugOperateLicenseBaseInfo> 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<String> jyxkzbhSet = uniqueList.stream()
.map(EdhDrugOperateLicenseBaseInfo::getJyxkzbh)
.collect(Collectors.toSet());
// 自定义批量查询方法
Map<String, EdhDrugOperateLicenseBaseInfo> existingMap = drugOperateLicenseBaseInfoService
.listByJyxkzbhIn(jyxkzbhSet)
.stream()
.collect(Collectors.toMap(
EdhDrugOperateLicenseBaseInfo::getJyxkzbh,
Function.identity()
));
// 3. 分离新增和更新数据
List<EdhDrugOperateLicenseBaseInfo> insertList = new ArrayList<>();
List<EdhDrugOperateLicenseBaseInfo> 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);
}
}
}

View File

@ -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<EdhDomesticDrugBaseInfoVO> {
protected final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
private IEdhDomesticDrugBaseInfoService domesticDrugBaseInfoService;
@Override
protected Class<EdhDomesticDrugBaseInfoVO> 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());
}
}

View File

@ -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<EdhDrugInvoiceApplyInfoVO> {
protected final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
private IEdhDrugInvoiceApplyInfoService drugInvoiceApplyInfoService;
@Override
protected Class<EdhDrugInvoiceApplyInfoVO> 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<EdhDrugInvoiceApplyInfo> 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<EdhDrugInvoiceApplyInfo> 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));
}
}
}

View File

@ -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<EdhDrugDeliveryNoteApplyInfoVO> {
protected final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
private IEdhDrugDeliveryNoteApplyInfoService drugDeliveryNoteApplyInfoService;
@Override
protected Class<EdhDrugDeliveryNoteApplyInfoVO> 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<EdhDrugDeliveryNoteApplyInfo> 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<EdhDrugDeliveryNoteApplyInfo> 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));
}
}
}

View File

@ -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<EdhWarehouseStockApplyInfoVO> {
protected final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
private IEdhWarehouseStockApplyInfoService warehouseStockApplyInfoService;
@Override
protected Class<EdhWarehouseStockApplyInfoVO> 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<EdhWarehouseStockApplyInfo> 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;
}
}

View File

@ -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<EdhWhTempHumidityApplyInfoVO> {
protected final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
private IEdhWhTempHumidityApplyInfoService whTempHumidityApplyInfoService;
@Override
protected Class<EdhWhTempHumidityApplyInfoVO> 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());
}
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-药品基本信息数据子集 服务实现类
* </p>
*
* @author Jason
* @since 2025-06-20
*/
@Service("domesticDrugBaseInfoService")
public class EdhDomesticDrugBaseInfoServiceImpl extends ServiceImpl<EdhDomesticDrugBaseInfoMapper, EdhDomesticDrugBaseInfo> implements IEdhDomesticDrugBaseInfoService {
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-药品收货单信息表 服务实现类
* </p>
*
* @author Jason
* @since 2025-06-21
*/
@Service("drugDeliveryNoteApplyInfoService")
public class EdhDrugDeliveryNoteApplyInfoServiceImpl extends ServiceImpl<EdhDrugDeliveryNoteApplyInfoMapper, EdhDrugDeliveryNoteApplyInfo> implements IEdhDrugDeliveryNoteApplyInfoService {
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-发货单信息数据子集 服务实现类
* </p>
*
* @author Jason
* @since 2025-06-20
*/
@Service("drugInvoiceApplyInfoService")
public class EdhDrugInvoiceApplyInfoServiceImpl extends ServiceImpl<EdhDrugInvoiceApplyInfoMapper, EdhDrugInvoiceApplyInfo> implements IEdhDrugInvoiceApplyInfoService {
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-药品经营许可证基本信息 服务实现类
* </p>
*
* @author Jason
* @since 2025-06-19
*/
@Service("drugOperateLicenseBaseInfoService")
public class EdhDrugOperateLicenseBaseInfoServiceImpl extends ServiceImpl<EdhDrugOperateLicenseBaseInfoMapper, EdhDrugOperateLicenseBaseInfo> implements IEdhDrugOperateLicenseBaseInfoService {
@Override
public List<EdhDrugOperateLicenseBaseInfo> listByJyxkzbhIn(Set<String> jyxkzbhSet) {
return getBaseMapper().listByJyxkzbhIn(jyxkzbhSet);
}
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-药品经营企业基本信息 服务实现类
* </p>
*
* @author Jason
* @since 2025-06-18
*/
@Service("edhDrugOperatorsBaseInfoService")
public class EdhDrugOperatorsBaseInfoServiceImpl extends ServiceImpl<EdhDrugOperatorsBaseInfoMapper, EdhDrugOperatorsBaseInfo> implements IEdhDrugOperatorsBaseInfoService {
@Override
public List<EdhDrugOperatorsBaseInfo> listByTyshxydmIn(Set<String> tyshxydmSet) {
return getBaseMapper().listByTyshxydmIn(tyshxydmSet);
}
}

View File

@ -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<EdhReceiveDataLogMapper, EdhReceiveDataLog> implements IEdhReceiveDataLogService {
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-库存上报信息表 服务实现类
* </p>
*
* @author Jason
* @since 2025-06-23
*/
@Service("warehouseStockApplyInfoService")
public class EdhWarehouseStockApplyInfoServiceImpl extends ServiceImpl<EdhWarehouseStockApplyInfoMapper, EdhWarehouseStockApplyInfo> implements IEdhWarehouseStockApplyInfoService {
}

View File

@ -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;
/**
* <p>
* 药监企业数据上报-仓库存储温湿度信息表 服务实现类
* </p>
*
* @author Jason
* @since 2025-06-21
*/
@Service("whTempHumidityApplyInfoService")
public class EdhWhTempHumidityApplyInfoServiceImpl extends ServiceImpl<EdhWhTempHumidityApplyInfoMapper, EdhWhTempHumidityApplyInfo> implements IEdhWhTempHumidityApplyInfoService {
}

View File

@ -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);
}
}

View File

@ -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("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD>" + s);
String x = encode(s.getBytes());
System.out.println("<EFBFBD><EFBFBD><EFBFBD>ܺ<EFBFBD>" + x);
String x1 = new String(decode(x));
System.out.println("<EFBFBD><EFBFBD><EFBFBD>ܺ<EFBFBD>" + x1);
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}

View File

@ -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"));
}
}

View File

@ -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['\''] = "&#039;".toCharArray(); // 单引号
TEXT['"'] = "&#34;".toCharArray(); // 双引号
TEXT['&'] = "&#38;".toCharArray(); // &
TEXT['<'] = "&#60;".toCharArray(); // 小于号
TEXT['>'] = "&#62;".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 = "<script>alert(1);</script>";
String escape = EscapeUtil.escape(html);
// String html = "<scr<script>ipt>alert(\"XSS\")</scr<script>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));
}
}

View File

@ -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;
}
}

View File

@ -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> T parseJson(String json, Class<T> clazz) {
mapper.registerModule(new JavaTimeModule()); // 必须添加
try {
return mapper.readValue(json, clazz);
} catch (JsonProcessingException e) {
log.error("数据解析错误:"+e.getMessage());
throw new RuntimeException(e);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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<LocalDate> {
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);
}
}

View File

@ -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) {
}
};
}
}

View File

@ -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<String, Object> 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<String, Object> 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<String,Object> 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<String,Object> build(){
Map<String, Object> 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)));
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/edh" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.supervision.edh" level="info" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
</configuration>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.edh.mapper.EdhDomesticDrugBaseInfoMapper">
</mapper>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.edh.mapper.EdhDrugDeliveryNoteApplyInfoMapper">
</mapper>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.edh.mapper.EdhDrugInvoiceApplyInfoMapper">
</mapper>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.edh.mapper.EdhDrugOperateLicenseBaseInfoMapper">
<select id="listByJyxkzbhIn" resultType="EdhDrugOperateLicenseBaseInfo">
SELECT * FROM edh_drug_operate_license_base_info
WHERE jyxkzbh IN
<foreach collection="jyxkzbhSet" item="dm" open="(" separator="," close=")">
#{dm}
</foreach>
</select>
</mapper>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.edh.mapper.EdhDrugOperatorsBaseInfoMapper">
<select id="listByTyshxydmIn" resultType="EdhDrugOperatorsBaseInfo">
SELECT * FROM edh_drug_operators_base_info
WHERE tyshxydm IN
<foreach collection="tyshxydmSet" item="dm" open="(" separator="," close=")">
#{dm}
</foreach>
</select>
</mapper>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.edh.mapper.EdhReceiveDataLogMapper">
</mapper>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.edh.mapper.EdhWarehouseStockApplyInfoMapper">
</mapper>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.edh.mapper.EdhWhTempHumidityApplyInfoMapper">
</mapper>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局参数 -->
<settings>
<!-- 使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 允许JDBC 支持自动生成主键 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
<setting name="defaultExecutorType" value="SIMPLE" />
<!-- 指定 MyBatis 所用日志的具体实现 -->
<setting name="logImpl" value="SLF4J" />
<!-- 使用驼峰命名法转换字段 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
</settings>
</configuration>

View File

@ -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);
}
}