commit ada75c98c83874faa9c325d20ad6894a4810acf1 Author: huzhengkao <562572218@qq.com> Date: Wed Jun 25 10:11:08 2025 +0800 企业数据上报服务 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6a555ee --- /dev/null +++ b/.gitignore @@ -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/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..269141c --- /dev/null +++ b/pom.xml @@ -0,0 +1,133 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.5.RELEASE + + + com.supervision.edh + supervision-edh + 1.0.0 + jar + supervision-edh + 药监企业数据上报服务 + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + + + com.alibaba + fastjson + 1.2.66 + + + commons-codec + commons-codec + 1.13 + + + + + cn.hutool + hutool-all + 4.0.12 + + + + org.bouncycastle + bcpkix-jdk15on + 1.70 + + + + org.projectlombok + lombok + 1.18.38 + + + + + mysql + mysql-connector-java + + + + + com.alibaba + druid-spring-boot-starter + 1.2.23 + + + + + com.baomidou + mybatis-plus-boot-starter + 3.5.1 + + + + + com.baomidou + mybatis-plus-generator + 3.5.1 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + + org.freemarker + freemarker + 2.3.32 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/sql/data.sql b/sql/data.sql new file mode 100644 index 0000000..b245371 --- /dev/null +++ b/sql/data.sql @@ -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='药监企业数据上报-库存上报信息表'; diff --git a/src/main/java/com/supervision/edh/SupervisionEdhApplication.java b/src/main/java/com/supervision/edh/SupervisionEdhApplication.java new file mode 100644 index 0000000..e149927 --- /dev/null +++ b/src/main/java/com/supervision/edh/SupervisionEdhApplication.java @@ -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); + } +} diff --git a/src/main/java/com/supervision/edh/SupervisionEdhClient.java b/src/main/java/com/supervision/edh/SupervisionEdhClient.java new file mode 100644 index 0000000..c2cfd4f --- /dev/null +++ b/src/main/java/com/supervision/edh/SupervisionEdhClient.java @@ -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-1019、9001-9002) 应用信息(2011-2020、2051-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 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 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)); + + } + + +} diff --git a/src/main/java/com/supervision/edh/common/AjaxResult.java b/src/main/java/com/supervision/edh/common/AjaxResult.java new file mode 100644 index 0000000..9c3b571 --- /dev/null +++ b/src/main/java/com/supervision/edh/common/AjaxResult.java @@ -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 { + 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; + } +} diff --git a/src/main/java/com/supervision/edh/config/CertConfig.java b/src/main/java/com/supervision/edh/config/CertConfig.java new file mode 100644 index 0000000..1aeafed --- /dev/null +++ b/src/main/java/com/supervision/edh/config/CertConfig.java @@ -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; +} diff --git a/src/main/java/com/supervision/edh/constant/HttpStatus.java b/src/main/java/com/supervision/edh/constant/HttpStatus.java new file mode 100644 index 0000000..433d0d0 --- /dev/null +++ b/src/main/java/com/supervision/edh/constant/HttpStatus.java @@ -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; +} diff --git a/src/main/java/com/supervision/edh/controller/SupervisionEdhServerController.java b/src/main/java/com/supervision/edh/controller/SupervisionEdhServerController.java new file mode 100644 index 0000000..01e3a1f --- /dev/null +++ b/src/main/java/com/supervision/edh/controller/SupervisionEdhServerController.java @@ -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 paramsTemp = JSON.parseObject(body); + System.out.println(paramsTemp); + Map 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); + } + + } + + +} diff --git a/src/main/java/com/supervision/edh/domain/EdhDomesticDrugBaseInfo.java b/src/main/java/com/supervision/edh/domain/EdhDomesticDrugBaseInfo.java new file mode 100644 index 0000000..1ff9f8f --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/EdhDomesticDrugBaseInfo.java @@ -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; + +/** + *

+ * 药监企业数据上报-药品基本信息数据子集 + *

+ * + * @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; + + +} diff --git a/src/main/java/com/supervision/edh/domain/EdhDrugDeliveryNoteApplyInfo.java b/src/main/java/com/supervision/edh/domain/EdhDrugDeliveryNoteApplyInfo.java new file mode 100644 index 0000000..7a3dbeb --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/EdhDrugDeliveryNoteApplyInfo.java @@ -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; + +/** + *

+ * 药监企业数据上报-药品收货单信息表 + *

+ * + * @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 itemList; // 非数据库集合字段 + +} diff --git a/src/main/java/com/supervision/edh/domain/EdhDrugInvoiceApplyInfo.java b/src/main/java/com/supervision/edh/domain/EdhDrugInvoiceApplyInfo.java new file mode 100644 index 0000000..b1543ce --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/EdhDrugInvoiceApplyInfo.java @@ -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; + +/** + *

+ * 药监企业数据上报-发货单信息数据子集 + *

+ * + * @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 itemList; // 非数据库集合字段 +} diff --git a/src/main/java/com/supervision/edh/domain/EdhDrugOperateLicenseBaseInfo.java b/src/main/java/com/supervision/edh/domain/EdhDrugOperateLicenseBaseInfo.java new file mode 100644 index 0000000..b3c2c15 --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/EdhDrugOperateLicenseBaseInfo.java @@ -0,0 +1,127 @@ +package com.supervision.edh.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDate; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.supervision.edh.utils.LocalDateDeserializer; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 药监企业数据上报-药品经营许可证基本信息 + *

+ * + * @author Jason + * @since 2025-06-19 + */ +@Data +@TableName("edh_drug_operate_license_base_info") +public class EdhDrugOperateLicenseBaseInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private String eventId; + + /** + * 经营许可证编号 + */ + private String jyxkzbh; + + /** + * 企业名称 + */ + private String qymc; + + /** + * 统一社会信用代码 + */ + private String tyshxydm; + + /** + * 注册地址 + */ + private String zcdz; + + /** + * 法定代表人 + */ + private String fddbr; + + /** + * 企业负责人 + */ + private String qyfzr; + + /** + * 质量负责人 + */ + private String zlfzr; + + /** + * 仓库地址 + */ + private String ckdz; + + /** + * 经营方式 + */ + private String jyfs; + + /** + * 经营范围 + */ + private String jyfw; + + /** + * 有效期 + */ + @JsonDeserialize(using = LocalDateDeserializer.class) + private LocalDate yxq; + + /** + * 发证机关 + */ + private String fzjg; + + /** + * 签发人 + */ + private String qfr; + + /** + * 签发日期 + */ + @JsonDeserialize(using = LocalDateDeserializer.class) + private LocalDate qfrq; + + /** + * 日常监督管 理机构 + */ + private String rcjdgljg; + + /** + * 投诉举报电 话 + */ + private String tsjbdh; + + /** + * 企业类型 + */ + private String qylx; + + /** + * 企业小类 + */ + private String qyxl; + + +} diff --git a/src/main/java/com/supervision/edh/domain/EdhDrugOperatorsBaseInfo.java b/src/main/java/com/supervision/edh/domain/EdhDrugOperatorsBaseInfo.java new file mode 100644 index 0000000..c3214df --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/EdhDrugOperatorsBaseInfo.java @@ -0,0 +1,143 @@ +package com.supervision.edh.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDate; +import java.time.LocalDateTime; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.supervision.edh.utils.LocalDateDeserializer; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 药监企业数据上报-药品经营企业基本信息 + *

+ * + * @author Jason + * @since 2025-06-18 + */ +@Getter +@Setter +@TableName("edh_drug_operators_base_info") +public class EdhDrugOperatorsBaseInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 事件流水号 + */ + private String eventId; + + /** + * 统一社会信用代码 + */ + private String tyshxydm; + + /** + * 企业名称 + */ + private String qymc; + + /** + * 企业类型 + */ + private String qylx; + + /** + * 企业小类 + */ + private String qyxl; + + /** + * 住所地址 + */ + private String zsdz; + + /** + * 行政区划代码 + */ + private String xzqhdm; + + /** + * 法定代表人 + */ + private String fddbr; + + /** + * 注册资本 + */ + private String zczb; + + /** + * 成立日期 + */ + @JsonDeserialize(using = LocalDateDeserializer.class) + private LocalDate clrq; + + /** + * 营业期限 + */ + private String yyqx; + + /** + * 经营范围 + */ + private String jyfw; + + /** + * 登记机关 + */ + private String djjg; + + /** + * 固定电话号码 + */ + private String gddhhm; + + /** + * 传真号码 + */ + private String czhm; + + /** + * 电子信箱 + */ + private String dzxx; + + /** + * 联系人 + */ + private String lxr; + + /** + * 联系电话 + */ + private String lxdh; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 是否删除(0-否 1-是) + */ + private Integer isDeleted; + + +} diff --git a/src/main/java/com/supervision/edh/domain/EdhReceiveDataLog.java b/src/main/java/com/supervision/edh/domain/EdhReceiveDataLog.java new file mode 100644 index 0000000..c8e93b3 --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/EdhReceiveDataLog.java @@ -0,0 +1,47 @@ +package com.supervision.edh.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + * @author Jason 药监企业上报数据日志 + * @date 2025年06月03日 15:28:25 + */ +@Data +@TableName("edh_receive_data_log") +public class EdhReceiveDataLog { + + @TableId(value = "event_id", type = IdType.AUTO) + private String eventId; + + private String tyshxydm; + + private String processId; + + + private String eventType; + + private String eventTypeName; + + + private String subType; + + private String subTypeName; + + + private String data; + + private String ver; + + private Date createTime; + + private Date updateTime; + + private Date isDeleted; + + +} diff --git a/src/main/java/com/supervision/edh/domain/EdhWarehouseStockApplyInfo.java b/src/main/java/com/supervision/edh/domain/EdhWarehouseStockApplyInfo.java new file mode 100644 index 0000000..a6b385d --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/EdhWarehouseStockApplyInfo.java @@ -0,0 +1,188 @@ +package com.supervision.edh.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.supervision.edh.domain.vo.DrugVO; +import com.supervision.edh.domain.vo.StockVO; +import com.supervision.edh.utils.LocalDateDeserializer; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 药监企业数据上报-库存上报信息表 + *

+ * + * @author Jason + * @since 2025-06-23 + */ +@Getter +@Setter +@TableName("edh_warehouse_stock_apply_info") +public class EdhWarehouseStockApplyInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 事件流水号 + */ + private String eventId; + + /** + * 统一社会信用代码(库存单位) + */ + private String tyshxydmkcdw; + + /** + * 库存单位名称 + */ + private String kcdwmc; + + /** + * 库存统计日期 + */ + @JsonDeserialize(using = LocalDateDeserializer.class) + private LocalDate kctjrq; + + /** + * 库存地址 + */ + private String kcdz; + + /** + * 药品通用名称 + */ + private String yptymc; + + /** + * 国家药品标识码 + */ + private String gjypbsm; + + /** + * 药品生产批号 + */ + private String ypscph; + + /** + * 药品生产日期 + */ + private LocalDate ypscrq; + + /** + * 药品有效期截止日期 + */ + private LocalDate ypyxqjzrq; + + /** + * 库存制剂数量 + */ + private Integer kcsl; + + /** + * 实际库存数量 + */ + private Integer sjkcsl; + + /** + * 库存单位类型 + */ + private String kcdwlx; + + /** + * 库存单位类型小类 + */ + private String kcdwlxxl; + + /** + * 药品批准文号 + */ + private String yppzwh; + + /** + * 药品上市许可持有人 + */ + private String ypssxkcyrmc; + + /** + * 药品上市许可持有人代码 + */ + private String ypssxkcyrdm; + + /** + * 药品生产企业名称 + */ + private String ypscqymc; + + /** + * 药品生产企业统一社会信用代码 + */ + private String ypscqytyshxydm; + + /** + * 剂型 + */ + private String jx; + + /** + * 制剂规格 + */ + private String zjgg; + + /** + * 包装规格 + */ + private String bzgg; + + /** + * 包装转换比 + */ + private Integer bzzhb; + + /** + * 包装转换比单位 + */ + private String bzzhbdw; + + /** + * 药品注册分类 + */ + private String ypzcfl; + + /** + * 特殊药品管理分类 + */ + private String tsypglfl; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 是否删除(0-否 1-是) + */ + private Integer isDeleted; + + @TableField(exist = false) + private List itemList; // 非数据库集合字段 +} diff --git a/src/main/java/com/supervision/edh/domain/EdhWhTempHumidityApplyInfo.java b/src/main/java/com/supervision/edh/domain/EdhWhTempHumidityApplyInfo.java new file mode 100644 index 0000000..3c5ca09 --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/EdhWhTempHumidityApplyInfo.java @@ -0,0 +1,126 @@ +package com.supervision.edh.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 药监企业数据上报-仓库存储温湿度信息表 + *

+ * + * @author Jason + * @since 2025-06-21 + */ +@Getter +@Setter +@TableName("edh_wh_temp_humidity_apply_info") +public class EdhWhTempHumidityApplyInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 事件流水号 + */ + private String eventId; + + /** + * 企业统一社会信用代码 + */ + private String qytyshxydm; + + /** + * 企业名称 + */ + private String qymc; + + /** + * 仓库编号 + */ + private String ckbh; + + /** + * 仓库地址 + */ + private String ckdz; + + /** + * 仓库面积 + */ + private String ckmj; + + /** + * 仓库类型 + */ + private String cklx; + + /** + * 温度上限 + */ + private String wdsx; + + /** + * 温度下限 + */ + private String wdxx; + + /** + * 湿度上限 + */ + private String sdsx; + + /** + * 湿度下限 + */ + private String sdxx; + + /** + * 环境温度 + */ + private String hjwd; + + /** + * 环境湿度 + */ + private String hjsd; + + /** + * 数据类型(1:正常记录;2:报警记录) + */ + private String sjlx; + + /** + * 数据上传时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime sjscsj; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 是否删除(0-否 1-是) + */ + private Integer isDeleted; + + +} diff --git a/src/main/java/com/supervision/edh/domain/vo/BaseInfo.java b/src/main/java/com/supervision/edh/domain/vo/BaseInfo.java new file mode 100644 index 0000000..e8983aa --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/vo/BaseInfo.java @@ -0,0 +1,12 @@ +package com.supervision.edh.domain.vo; + +import lombok.Data; + +/** + * @author Jason + * @date 2025年06月18日 16:49:47 + */ +@Data +public class BaseInfo { + private String datasetName; +} diff --git a/src/main/java/com/supervision/edh/domain/vo/DrugVO.java b/src/main/java/com/supervision/edh/domain/vo/DrugVO.java new file mode 100644 index 0000000..ea5d509 --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/vo/DrugVO.java @@ -0,0 +1,86 @@ +package com.supervision.edh.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.supervision.edh.utils.LocalDateDeserializer; +import lombok.Data; + +import java.time.LocalDate; +import java.util.List; + +/** + * @author Jason 药品信息 + * @date 2025年06月20日 16:28:35 + */ +@Data +public class DrugVO { + //药品通用名称 + private String yptymc; + //国家药品标识码 + private String gjypbsm; + //药品生产日期 + @JsonDeserialize(using = LocalDateDeserializer.class) + private LocalDate ypscrq; + //发货数量 + private Integer fhsl; + //剂型 + private String jx; + //包装规格 + private String bzgg; + //制剂规格 + private String zjgg; + //包装转换比 + private Integer bzzhb; + //包装转换比单位 + private String bzzhbdw; + //药品注册分类 + private String ypzcfl; + //特殊药品管理分类 + private String tsypglfl; + //药品批准文号 + private String yppzwh; + //药品有效期 + private Integer ypyxq; + //药品有效期单位 + private String ypyxqdw; + //药品生产批号 + private String ypscph; + //药品批准文号有效期 + @JsonDeserialize(using = LocalDateDeserializer.class) + private LocalDate yppzwhyxq; + //药品有效期截止日期 + @JsonDeserialize(using = LocalDateDeserializer.class) + private LocalDate ypyxqjzrq; + //国家基本药物标识 + private String gjjbywbs; + //处方药标识 + private String cfybs; + //药品上市许可持有人名称 + private String ypssxkcyrmc; + //统一社会信用代码(药品上市许可持有人) + private String tyshxydmypssxkcyr; + //药品生产企业名称 + private String ypscqymc; + //统一社会信用代码(药品生产企业) + private String tyshxydmypscqy; + + //分包装厂名称 + private String fbzcmc; + //统一社会信用代码(分包装厂) + private String tyshxydmfbzc; + + //#################(收货单字段) + //药品英文名称 + private String ypywmc; + //药品商用名称 + private String ypsymc; + //药品本位码 + private String ypbwm; + //应收货数量 + private Integer yshsl; + //实际收货数量 + private Integer sjshsl; + + + private List instanceList; + +} diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhDomesticDrugBaseInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhDomesticDrugBaseInfoVO.java new file mode 100644 index 0000000..7e51c65 --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/vo/EdhDomesticDrugBaseInfoVO.java @@ -0,0 +1,17 @@ +package com.supervision.edh.domain.vo; + +import com.supervision.edh.domain.EdhDomesticDrugBaseInfo; +import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo; +import lombok.Data; + +import java.util.List; + +/** + * @author Jason 药品信息上报体 + * @date 2025年06月20日 15:07:37 + */ +@Data +public class EdhDomesticDrugBaseInfoVO extends BaseInfo{ + + private List dataSet; +} diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhDrugDeliveryNoteApplyInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhDrugDeliveryNoteApplyInfoVO.java new file mode 100644 index 0000000..d7ed55a --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/vo/EdhDrugDeliveryNoteApplyInfoVO.java @@ -0,0 +1,16 @@ +package com.supervision.edh.domain.vo; + +import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo; +import lombok.Data; + +import java.util.List; + +/** + * @author Jason + * @date 2025年06月21日 15:55:59 + */ +@Data +public class EdhDrugDeliveryNoteApplyInfoVO extends BaseInfo{ + + private List dataSet; +} diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhDrugInvoiceApplyInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhDrugInvoiceApplyInfoVO.java new file mode 100644 index 0000000..59f5580 --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/vo/EdhDrugInvoiceApplyInfoVO.java @@ -0,0 +1,16 @@ +package com.supervision.edh.domain.vo; + +import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo; +import lombok.Data; + +import java.util.List; + +/** + * @author Jason 发货信息上报体 + * @date 2025年06月20日 16:16:15 + */ +@Data +public class EdhDrugInvoiceApplyInfoVO extends BaseInfo{ + + private List dataSet; +} diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperateLicenseBaseInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperateLicenseBaseInfoVO.java new file mode 100644 index 0000000..2563e1c --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperateLicenseBaseInfoVO.java @@ -0,0 +1,16 @@ +package com.supervision.edh.domain.vo; + +import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo; +import lombok.Data; + +import java.util.List; + +/** + * @author Jason 药品经营企业基本信息上报体 + * @date 2025年06月19日 16:17:08 + */ +@Data +public class EdhDrugOperateLicenseBaseInfoVO extends BaseInfo{ + + private List dataSet; +} diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperatorsBaseInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperatorsBaseInfoVO.java new file mode 100644 index 0000000..085e8c1 --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/vo/EdhDrugOperatorsBaseInfoVO.java @@ -0,0 +1,16 @@ +package com.supervision.edh.domain.vo; + +import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo; +import lombok.Data; + +import java.util.List; + +/** + * @author Jason 药品经营许可证基本信息上报体 + * @date 2025年06月18日 15:53:20 + */ +@Data +public class EdhDrugOperatorsBaseInfoVO extends BaseInfo{ + + private List dataSet; +} diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhWarehouseStockApplyInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhWarehouseStockApplyInfoVO.java new file mode 100644 index 0000000..fec665a --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/vo/EdhWarehouseStockApplyInfoVO.java @@ -0,0 +1,18 @@ +package com.supervision.edh.domain.vo; + +import com.supervision.edh.domain.EdhWarehouseStockApplyInfo; +import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo; +import lombok.Data; + +import java.util.List; + +/** + * @author Jason 库存信息上报体 + * @date 2025年06月23日 11:26:09 + */ +@Data +public class EdhWarehouseStockApplyInfoVO extends BaseInfo{ + + + private List dataSet; +} diff --git a/src/main/java/com/supervision/edh/domain/vo/EdhWhTempHumidityApplyInfoVO.java b/src/main/java/com/supervision/edh/domain/vo/EdhWhTempHumidityApplyInfoVO.java new file mode 100644 index 0000000..a582e1b --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/vo/EdhWhTempHumidityApplyInfoVO.java @@ -0,0 +1,15 @@ +package com.supervision.edh.domain.vo; + +import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo; +import lombok.Data; + +import java.util.List; + +/** + * @author Jason 仓库存储温湿度信息数据上报体 + * @date 2025年06月21日 16:53:58 + */ +@Data +public class EdhWhTempHumidityApplyInfoVO extends BaseInfo{ + List dataSet; +} diff --git a/src/main/java/com/supervision/edh/domain/vo/InstanceVO.java b/src/main/java/com/supervision/edh/domain/vo/InstanceVO.java new file mode 100644 index 0000000..09ad996 --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/vo/InstanceVO.java @@ -0,0 +1,23 @@ +package com.supervision.edh.domain.vo; + +import lombok.Data; + +/** + * @author Jason + * @date 2025年06月20日 16:38:08 + */ +@Data +public class InstanceVO { + //药品追溯码 + private String ypzsm; + //上一级包装药品追溯码 + private String syjbzypzsm; + //包装层级 + private String bzcj; + + //######(收货单字段) + //追溯码验证状态 + private String zsmyzzt; + //包含最小销售包装单元数量 + private Integer bhzxxsbzdysl; +} diff --git a/src/main/java/com/supervision/edh/domain/vo/StockVO.java b/src/main/java/com/supervision/edh/domain/vo/StockVO.java new file mode 100644 index 0000000..0f5b482 --- /dev/null +++ b/src/main/java/com/supervision/edh/domain/vo/StockVO.java @@ -0,0 +1,49 @@ +package com.supervision.edh.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.supervision.edh.utils.LocalDateDeserializer; +import lombok.Data; + +import java.time.LocalDate; + +/** + * @author Jason 库存信息 + * @date 2025年06月23日 14:45:43 + */ +@Data +public class StockVO { + //药品通用名称 + private String yptymc; + private String gjypbsm; + private String ypscph; + + @JsonDeserialize(using = LocalDateDeserializer.class) + private LocalDate ypscrq; + + @JsonDeserialize(using = LocalDateDeserializer.class) + private LocalDate ypyxqjzrq; + + private Integer kcsl; + private Integer sjkcsl; + private String yppzwh; + private String ypssxkcyrmc; + + //药品生产企业名称 + private String ypscqymc; + //药品生产企业代码 + private String ypscqydm; + + //药品上市许可持有人代码 + private String ypssxkcyrdm; + //药品生产企业统一社会信用代码 + private String ypscqytyshxydm; + private String jx; + private String zjgg; + private String bzgg; + private Integer bzzhb; + private String bzzhbdw; + private String ypzcfl; + private String tsypglfl; + + +} diff --git a/src/main/java/com/supervision/edh/enums/BuzStatusEnum.java b/src/main/java/com/supervision/edh/enums/BuzStatusEnum.java new file mode 100644 index 0000000..7b602b3 --- /dev/null +++ b/src/main/java/com/supervision/edh/enums/BuzStatusEnum.java @@ -0,0 +1,40 @@ +package com.supervision.edh.enums; + +/** + * @ClassName BuzStatusEnum + * @Desc 回执给协同的 + * @Author houduo.wk + * @Date 2020/2/14 + **/ +public enum BuzStatusEnum { + SUCCESS(0,"执行成功"), + PARAM_NULL_ERR(1001,"缺少必填参数"), + SIGN_CHECK_ERR(1002,"签名认证失败"), + DATA_PARSE_ERR(1003,"数据解析错误"), + NO_ACCESS_AUTH_ERR(1004,"无接口访问权限"), + SYS_ERR(999,"系统开小差,请稍后重试"); + + int buzStatus; + String buzMessage; + + public int getBuzStatus() { + return buzStatus; + } + + public void setBuzStatus(int buzStatus) { + this.buzStatus = buzStatus; + } + + public String getBuzMessage() { + return buzMessage; + } + + public void setBuzMessage(String buzMessage) { + this.buzMessage = buzMessage; + } + + BuzStatusEnum(int buzStatus, String buzMessage) { + this.buzStatus = buzStatus; + this.buzMessage = buzMessage; + } +} diff --git a/src/main/java/com/supervision/edh/enums/EventTypeEnum.java b/src/main/java/com/supervision/edh/enums/EventTypeEnum.java new file mode 100644 index 0000000..3b7a75d --- /dev/null +++ b/src/main/java/com/supervision/edh/enums/EventTypeEnum.java @@ -0,0 +1,38 @@ +package com.supervision.edh.enums; + +public enum EventTypeEnum { + EVENTTYPE_10("10", "基础信息数据"), + EVENTTYPE_20("20", "应用信息数据"); + + private final String type; + private final String name; + + EventTypeEnum(String type, String name) { + this.type = type; + this.name = name; + } + + public String getType() { + return type; + } + + public String getName() { + return name; + } + + // 根据类型获取枚举实例 + public static EventTypeEnum getByType(String type) { + for (EventTypeEnum typeEnum : values()) { + if (typeEnum.type.equals(type)) { + return typeEnum; + } + } + return null; + } + + // 根据类型获取名称 + public static String getNameByType(String type) { + EventTypeEnum typeEnum = getByType(type); + return typeEnum != null ? typeEnum.getName() : "未知类型"; + } +} diff --git a/src/main/java/com/supervision/edh/enums/StatusEnum.java b/src/main/java/com/supervision/edh/enums/StatusEnum.java new file mode 100644 index 0000000..705486c --- /dev/null +++ b/src/main/java/com/supervision/edh/enums/StatusEnum.java @@ -0,0 +1,29 @@ +package com.supervision.edh.enums; + +public enum StatusEnum { + SUCCESS(0,"OK"),FAILED(1,"FAILED"),BUZ_ERROR(-1,"BUZ_ERROR"); + + StatusEnum(Integer status, String msg) { + this.status = status; + this.msg = msg; + } + + private Integer status; + private String msg; + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } +} diff --git a/src/main/java/com/supervision/edh/enums/SubTypeEnum.java b/src/main/java/com/supervision/edh/enums/SubTypeEnum.java new file mode 100644 index 0000000..617cfb8 --- /dev/null +++ b/src/main/java/com/supervision/edh/enums/SubTypeEnum.java @@ -0,0 +1,64 @@ +package com.supervision.edh.enums; + +/** + * @author Jason 数据文件内容子业务类型 + * @date 2025年06月04日 11:08:40 + */ +public enum SubTypeEnum { + SUBTYPE_1011("1011", "境内药品生产企业基本信息数据子集"), + SUBTYPE_1012("1012", "境外药品生产企业基本信息数据子集"), + SUBTYPE_1013("1013", "药品生产许可证基本信息数据子集"), + SUBTYPE_1014("1014", "药品经营企业基本信息数据子集"), + SUBTYPE_1015("1015", "药品经营许可证基本信息数据子集"), + SUBTYPE_1016("1016", "药品配送企业基本信息数据子集"), + SUBTYPE_1017("1017", "药品使用单位基本信息数据子集"), + SUBTYPE_1018("1018", "国产药品基本信息数据子集"), + SUBTYPE_1019("1019", "进口药品基本信息数据子集"), + SUBTYPE_9001("9001", "药检报告基础信息数据子集"), + SUBTYPE_9002("9002", "药检报告概览回传基础信息数据子集"), + SUBTYPE_2011("2011", "国产药品生产信息数据子集"), + SUBTYPE_2012("2012", "药品进口信息数据子集"), + SUBTYPE_2013("2013", "药品自检信息数据子集"), + SUBTYPE_2015("2015", "发货单信息数据子集"), + SUBTYPE_2016("2016", "收货单信息数据子集"), + SUBTYPE_2017("2017", "药品零售与药品使用信息数据子集"), + SUBTYPE_2018("2018", "药品召回信息数据子集"), + SUBTYPE_2019("2019", "库存上报基本信息数据子集"), + SUBTYPE_2020("2020", "撤销单"), + SUBTYPE_2051("2051", "温度信息子集-单据与存储设备关系信息"), + SUBTYPE_2052("2052", "温度信息子集-存储设备温度信息"), + SUBTYPE_2053("2053", "温度信息子集-运输温度信息"); + + + private final String type; + private final String name; + + SubTypeEnum(String type, String name) { + this.type = type; + this.name = name; + } + + public String getType() { + return type; + } + + public String getName() { + return name; + } + + // 根据类型获取枚举实例 + public static SubTypeEnum getByType(String type) { + for (SubTypeEnum typeEnum : values()) { + if (typeEnum.type.equals(type)) { + return typeEnum; + } + } + return null; + } + + // 根据类型获取名称 + public static String getNameByType(String type) { + SubTypeEnum typeEnum = getByType(type); + return typeEnum != null ? typeEnum.getName() : "未知类型"; + } +} diff --git a/src/main/java/com/supervision/edh/exception/GlobalExceptionHandler.java b/src/main/java/com/supervision/edh/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..f48bc20 --- /dev/null +++ b/src/main/java/com/supervision/edh/exception/GlobalExceptionHandler.java @@ -0,0 +1,127 @@ +package com.supervision.edh.exception; + + +import cn.hutool.core.convert.Convert; +import com.supervision.edh.common.AjaxResult; +import com.supervision.edh.constant.HttpStatus; +import com.supervision.edh.utils.EscapeUtil; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; +import org.springframework.validation.BindException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.MissingPathVariableException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; + +import javax.servlet.http.HttpServletRequest; +import java.nio.file.AccessDeniedException; + +/** + * 全局异常处理器 + * + * @author tcctyn + */ +@RestControllerAdvice +public class GlobalExceptionHandler { + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + /** + * 权限校验异常 + */ + @ExceptionHandler(AccessDeniedException.class) + public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage()); + return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权"); + } + + /** + * 请求方式不支持 + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, + HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); + return AjaxResult.error(e.getMessage()); + } + + /** + * 业务异常 + */ + @ExceptionHandler(ServiceException.class) + public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) { + log.error(e.getMessage(), e); + Integer code = e.getCode(); + return StringUtils.isEmpty(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); + } + + /** + * 请求路径中缺少必需的路径变量 + */ + @ExceptionHandler(MissingPathVariableException.class) + public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName())); + } + + /** + * 请求参数类型不匹配 + */ + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + String value = Convert.toStr(e.getValue()); + if (!StringUtils.isEmpty(value)) { + value = EscapeUtil.clean(value); + } + log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value)); + } + + /** + * 拦截未知的运行时异常 + */ + @ExceptionHandler(RuntimeException.class) + public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生未知异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 系统异常 + */ + @ExceptionHandler(Exception.class) + public AjaxResult handleException(Exception e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(BindException.class) + public AjaxResult handleBindException(BindException e) { + log.error(e.getMessage(), e); + String message = e.getAllErrors().get(0).getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { + log.error(e.getMessage(), e); + String message = e.getBindingResult().getFieldError().getDefaultMessage(); + return AjaxResult.error(message); + } + +} diff --git a/src/main/java/com/supervision/edh/exception/ServiceException.java b/src/main/java/com/supervision/edh/exception/ServiceException.java new file mode 100644 index 0000000..8b3e715 --- /dev/null +++ b/src/main/java/com/supervision/edh/exception/ServiceException.java @@ -0,0 +1,73 @@ +package com.supervision.edh.exception; + +/** + * 业务异常 + * + * @author tcctyn + */ +public final class ServiceException extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + /** + * 错误码 + */ + private Integer code; + + /** + * 错误提示 + */ + private String message; + + /** + * 错误明细,内部调试错误 + * + */ + private String detailMessage; + + /** + * 空构造方法,避免反序列化问题 + */ + public ServiceException() + { + } + + public ServiceException(String message) + { + this.message = message; + } + + public ServiceException(String message, Integer code) + { + this.message = message; + this.code = code; + } + + public String getDetailMessage() + { + return detailMessage; + } + + @Override + public String getMessage() + { + return message; + } + + public Integer getCode() + { + return code; + } + + public ServiceException setMessage(String message) + { + this.message = message; + return this; + } + + public ServiceException setDetailMessage(String detailMessage) + { + this.detailMessage = detailMessage; + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/supervision/edh/factory/EventHandlerFactory.java b/src/main/java/com/supervision/edh/factory/EventHandlerFactory.java new file mode 100644 index 0000000..d534713 --- /dev/null +++ b/src/main/java/com/supervision/edh/factory/EventHandlerFactory.java @@ -0,0 +1,25 @@ +package com.supervision.edh.factory; + +import com.supervision.edh.service.handle.EventDataHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * @author Jason 事件处理器工厂 + * @date 2025年06月05日 11:29:54 + */ +@Service +public class EventHandlerFactory { + @Autowired + private Map handlerMap; + + public EventDataHandler getHandler(String subType) { + EventDataHandler handler = handlerMap.get(subType); + if (handler == null) { + throw new IllegalArgumentException("未找到对应的处理器: " + subType); + } + return handler; + } +} diff --git a/src/main/java/com/supervision/edh/generator/CodeGenerator.java b/src/main/java/com/supervision/edh/generator/CodeGenerator.java new file mode 100644 index 0000000..1271a34 --- /dev/null +++ b/src/main/java/com/supervision/edh/generator/CodeGenerator.java @@ -0,0 +1,41 @@ +package com.supervision.edh.generator; + + +import com.baomidou.mybatisplus.generator.FastAutoGenerator; +import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; + +import java.nio.file.Paths; + +/** + * @author Jason + * @date 2025年06月06日 09:35:59 + */ +public class CodeGenerator { + + public static void main(String[] args) { + String tables="edh_warehouse_stock_apply_info";// 单表生成 + FastAutoGenerator.create("jdbc:mysql://47.109.202.121:3306/supervisionx_trace_data", "root", "TCCT3.1415926") + .globalConfig(builder -> builder + .author("Jason") + .outputDir(Paths.get(System.getProperty("user.dir")) + "/src/main/java") + .commentDate("yyyy-MM-dd") + .fileOverride() // 显式启用覆盖(默认行为) + ) + .packageConfig(builder -> builder + .parent("com.supervision.edh") + .entity("domain") + .mapper("mapper") + .service("service") + .serviceImpl("service.impl") + .xml("mapper.xml") + ) + .strategyConfig(builder -> builder + .addInclude(tables) + .entityBuilder() + .enableLombok() + ) + .templateEngine(new FreemarkerTemplateEngine()) + .execute(); + System.out.println("数据表"+tables+"--------生成实体成功!!"); + } +} diff --git a/src/main/java/com/supervision/edh/mapper/EdhDomesticDrugBaseInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhDomesticDrugBaseInfoMapper.java new file mode 100644 index 0000000..c47eb37 --- /dev/null +++ b/src/main/java/com/supervision/edh/mapper/EdhDomesticDrugBaseInfoMapper.java @@ -0,0 +1,16 @@ +package com.supervision.edh.mapper; + +import com.supervision.edh.domain.EdhDomesticDrugBaseInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 药监企业数据上报-药品基本信息数据子集 Mapper 接口 + *

+ * + * @author Jason + * @since 2025-06-20 + */ +public interface EdhDomesticDrugBaseInfoMapper extends BaseMapper { + +} diff --git a/src/main/java/com/supervision/edh/mapper/EdhDrugDeliveryNoteApplyInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhDrugDeliveryNoteApplyInfoMapper.java new file mode 100644 index 0000000..0c694eb --- /dev/null +++ b/src/main/java/com/supervision/edh/mapper/EdhDrugDeliveryNoteApplyInfoMapper.java @@ -0,0 +1,16 @@ +package com.supervision.edh.mapper; + +import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 药监企业数据上报-药品收货单信息表 Mapper 接口 + *

+ * + * @author Jason + * @since 2025-06-21 + */ +public interface EdhDrugDeliveryNoteApplyInfoMapper extends BaseMapper { + +} diff --git a/src/main/java/com/supervision/edh/mapper/EdhDrugInvoiceApplyInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhDrugInvoiceApplyInfoMapper.java new file mode 100644 index 0000000..c85dea6 --- /dev/null +++ b/src/main/java/com/supervision/edh/mapper/EdhDrugInvoiceApplyInfoMapper.java @@ -0,0 +1,16 @@ +package com.supervision.edh.mapper; + +import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 药监企业数据上报-发货单信息数据子集 Mapper 接口 + *

+ * + * @author Jason + * @since 2025-06-20 + */ +public interface EdhDrugInvoiceApplyInfoMapper extends BaseMapper { + +} diff --git a/src/main/java/com/supervision/edh/mapper/EdhDrugOperateLicenseBaseInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhDrugOperateLicenseBaseInfoMapper.java new file mode 100644 index 0000000..8c0f156 --- /dev/null +++ b/src/main/java/com/supervision/edh/mapper/EdhDrugOperateLicenseBaseInfoMapper.java @@ -0,0 +1,20 @@ +package com.supervision.edh.mapper; + +import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import java.util.List; +import java.util.Set; + +/** + *

+ * 药监企业数据上报-药品经营许可证基本信息 Mapper 接口 + *

+ * + * @author Jason + * @since 2025-06-19 + */ +public interface EdhDrugOperateLicenseBaseInfoMapper extends BaseMapper { + + List listByJyxkzbhIn(Set jyxkzbhSet); +} diff --git a/src/main/java/com/supervision/edh/mapper/EdhDrugOperatorsBaseInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhDrugOperatorsBaseInfoMapper.java new file mode 100644 index 0000000..e70a174 --- /dev/null +++ b/src/main/java/com/supervision/edh/mapper/EdhDrugOperatorsBaseInfoMapper.java @@ -0,0 +1,20 @@ +package com.supervision.edh.mapper; + +import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import java.util.List; +import java.util.Set; + +/** + *

+ * 药监企业数据上报-药品经营企业基本信息 Mapper 接口 + *

+ * + * @author Jason + * @since 2025-06-18 + */ +public interface EdhDrugOperatorsBaseInfoMapper extends BaseMapper { + + List listByTyshxydmIn(Set tyshxydmSet); +} diff --git a/src/main/java/com/supervision/edh/mapper/EdhReceiveDataLogMapper.java b/src/main/java/com/supervision/edh/mapper/EdhReceiveDataLogMapper.java new file mode 100644 index 0000000..089df37 --- /dev/null +++ b/src/main/java/com/supervision/edh/mapper/EdhReceiveDataLogMapper.java @@ -0,0 +1,11 @@ +package com.supervision.edh.mapper; + +import com.supervision.edh.domain.EdhReceiveDataLog; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @author Jason + * @date 2025年06月03日 15:35:00 + */ +public interface EdhReceiveDataLogMapper extends BaseMapper { +} diff --git a/src/main/java/com/supervision/edh/mapper/EdhWarehouseStockApplyInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhWarehouseStockApplyInfoMapper.java new file mode 100644 index 0000000..3e931fe --- /dev/null +++ b/src/main/java/com/supervision/edh/mapper/EdhWarehouseStockApplyInfoMapper.java @@ -0,0 +1,16 @@ +package com.supervision.edh.mapper; + +import com.supervision.edh.domain.EdhWarehouseStockApplyInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 药监企业数据上报-库存上报信息表 Mapper 接口 + *

+ * + * @author Jason + * @since 2025-06-23 + */ +public interface EdhWarehouseStockApplyInfoMapper extends BaseMapper { + +} diff --git a/src/main/java/com/supervision/edh/mapper/EdhWhTempHumidityApplyInfoMapper.java b/src/main/java/com/supervision/edh/mapper/EdhWhTempHumidityApplyInfoMapper.java new file mode 100644 index 0000000..92ca620 --- /dev/null +++ b/src/main/java/com/supervision/edh/mapper/EdhWhTempHumidityApplyInfoMapper.java @@ -0,0 +1,16 @@ +package com.supervision.edh.mapper; + +import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 药监企业数据上报-仓库存储温湿度信息表 Mapper 接口 + *

+ * + * @author Jason + * @since 2025-06-21 + */ +public interface EdhWhTempHumidityApplyInfoMapper extends BaseMapper { + +} diff --git a/src/main/java/com/supervision/edh/service/IEdhDomesticDrugBaseInfoService.java b/src/main/java/com/supervision/edh/service/IEdhDomesticDrugBaseInfoService.java new file mode 100644 index 0000000..4f7036d --- /dev/null +++ b/src/main/java/com/supervision/edh/service/IEdhDomesticDrugBaseInfoService.java @@ -0,0 +1,16 @@ +package com.supervision.edh.service; + +import com.supervision.edh.domain.EdhDomesticDrugBaseInfo; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 药监企业数据上报-药品基本信息数据子集 服务类 + *

+ * + * @author Jason + * @since 2025-06-20 + */ +public interface IEdhDomesticDrugBaseInfoService extends IService { + +} diff --git a/src/main/java/com/supervision/edh/service/IEdhDrugDeliveryNoteApplyInfoService.java b/src/main/java/com/supervision/edh/service/IEdhDrugDeliveryNoteApplyInfoService.java new file mode 100644 index 0000000..68bd1db --- /dev/null +++ b/src/main/java/com/supervision/edh/service/IEdhDrugDeliveryNoteApplyInfoService.java @@ -0,0 +1,16 @@ +package com.supervision.edh.service; + +import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 药监企业数据上报-药品收货单信息表 服务类 + *

+ * + * @author Jason + * @since 2025-06-21 + */ +public interface IEdhDrugDeliveryNoteApplyInfoService extends IService { + +} diff --git a/src/main/java/com/supervision/edh/service/IEdhDrugInvoiceApplyInfoService.java b/src/main/java/com/supervision/edh/service/IEdhDrugInvoiceApplyInfoService.java new file mode 100644 index 0000000..52417c6 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/IEdhDrugInvoiceApplyInfoService.java @@ -0,0 +1,16 @@ +package com.supervision.edh.service; + +import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 药监企业数据上报-发货单信息数据子集 服务类 + *

+ * + * @author Jason + * @since 2025-06-20 + */ +public interface IEdhDrugInvoiceApplyInfoService extends IService { + +} diff --git a/src/main/java/com/supervision/edh/service/IEdhDrugOperateLicenseBaseInfoService.java b/src/main/java/com/supervision/edh/service/IEdhDrugOperateLicenseBaseInfoService.java new file mode 100644 index 0000000..554b121 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/IEdhDrugOperateLicenseBaseInfoService.java @@ -0,0 +1,22 @@ +package com.supervision.edh.service; + +import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo; +import com.baomidou.mybatisplus.extension.service.IService; +import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +/** + *

+ * 药监企业数据上报-药品经营许可证基本信息 服务类 + *

+ * + * @author Jason + * @since 2025-06-19 + */ +public interface IEdhDrugOperateLicenseBaseInfoService extends IService { + + List listByJyxkzbhIn(Set jyxkzbhSet); +} diff --git a/src/main/java/com/supervision/edh/service/IEdhDrugOperatorsBaseInfoService.java b/src/main/java/com/supervision/edh/service/IEdhDrugOperatorsBaseInfoService.java new file mode 100644 index 0000000..0ee146b --- /dev/null +++ b/src/main/java/com/supervision/edh/service/IEdhDrugOperatorsBaseInfoService.java @@ -0,0 +1,23 @@ +package com.supervision.edh.service; + +import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +/** + *

+ * 药监企业数据上报-药品经营企业基本信息 服务类 + *

+ * + * @author Jason + * @since 2025-06-18 + */ +public interface IEdhDrugOperatorsBaseInfoService extends IService { + + + List listByTyshxydmIn(Set tyshxydmSet); + +} diff --git a/src/main/java/com/supervision/edh/service/IEdhReceiveDataLogService.java b/src/main/java/com/supervision/edh/service/IEdhReceiveDataLogService.java new file mode 100644 index 0000000..9c1f9b5 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/IEdhReceiveDataLogService.java @@ -0,0 +1,7 @@ +package com.supervision.edh.service; + +import com.supervision.edh.domain.EdhReceiveDataLog; +import com.baomidou.mybatisplus.extension.service.IService; + +public interface IEdhReceiveDataLogService extends IService { +} diff --git a/src/main/java/com/supervision/edh/service/IEdhWarehouseStockApplyInfoService.java b/src/main/java/com/supervision/edh/service/IEdhWarehouseStockApplyInfoService.java new file mode 100644 index 0000000..8806888 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/IEdhWarehouseStockApplyInfoService.java @@ -0,0 +1,16 @@ +package com.supervision.edh.service; + +import com.supervision.edh.domain.EdhWarehouseStockApplyInfo; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 药监企业数据上报-库存上报信息表 服务类 + *

+ * + * @author Jason + * @since 2025-06-23 + */ +public interface IEdhWarehouseStockApplyInfoService extends IService { + +} diff --git a/src/main/java/com/supervision/edh/service/IEdhWhTempHumidityApplyInfoService.java b/src/main/java/com/supervision/edh/service/IEdhWhTempHumidityApplyInfoService.java new file mode 100644 index 0000000..580da54 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/IEdhWhTempHumidityApplyInfoService.java @@ -0,0 +1,16 @@ +package com.supervision.edh.service; + +import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 药监企业数据上报-仓库存储温湿度信息表 服务类 + *

+ * + * @author Jason + * @since 2025-06-21 + */ +public interface IEdhWhTempHumidityApplyInfoService extends IService { + +} diff --git a/src/main/java/com/supervision/edh/service/IEventProcessingService.java b/src/main/java/com/supervision/edh/service/IEventProcessingService.java new file mode 100644 index 0000000..47a2471 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/IEventProcessingService.java @@ -0,0 +1,13 @@ +package com.supervision.edh.service; + +import com.supervision.edh.utils.EventPojo; + +public interface IEventProcessingService { + + /** + * 处理事件数据 + * @param data JSON数据 + * @param eventId 事件ID(用于日志追踪) + */ + void processEvent(EventPojo eventPojo, String data, String eventId); +} diff --git a/src/main/java/com/supervision/edh/service/handle/AbstractEventDataHandler.java b/src/main/java/com/supervision/edh/service/handle/AbstractEventDataHandler.java new file mode 100644 index 0000000..5cfb1fd --- /dev/null +++ b/src/main/java/com/supervision/edh/service/handle/AbstractEventDataHandler.java @@ -0,0 +1,24 @@ +package com.supervision.edh.service.handle; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Jason + * @date 2025年06月05日 11:11:15 + */ +public abstract class AbstractEventDataHandler implements EventDataHandler { + + protected final Logger log = LoggerFactory.getLogger(getClass()); + + protected abstract Class getEntityClass(); + + //protected abstract IService getService(); + + + +} diff --git a/src/main/java/com/supervision/edh/service/handle/EventDataHandler.java b/src/main/java/com/supervision/edh/service/handle/EventDataHandler.java new file mode 100644 index 0000000..60b6923 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/handle/EventDataHandler.java @@ -0,0 +1,12 @@ +package com.supervision.edh.service.handle; + + +/** + * 事件处理接口 + */ +public interface EventDataHandler { + //String getSubType(); // 返回业务subType + + //处理数据 + void handleData(String data,String eventId); +} diff --git a/src/main/java/com/supervision/edh/service/handle/EventSubType.java b/src/main/java/com/supervision/edh/service/handle/EventSubType.java new file mode 100644 index 0000000..f4ad6c1 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/handle/EventSubType.java @@ -0,0 +1,19 @@ +package com.supervision.edh.service.handle; + +import org.springframework.stereotype.Component; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Jason + * @date 2025年06月05日 15:05:31 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Component +public @interface EventSubType { + String value(); // 如 "2011" +} diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType1014Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType1014Handler.java new file mode 100644 index 0000000..f4cfea5 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/handle/core/SubType1014Handler.java @@ -0,0 +1,109 @@ +package com.supervision.edh.service.handle.core; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.extension.service.IService; +import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo; +import com.supervision.edh.domain.vo.EdhDrugOperatorsBaseInfoVO; +import com.supervision.edh.service.IEdhDrugOperatorsBaseInfoService; +import com.supervision.edh.service.IEdhReceiveDataLogService; +import com.supervision.edh.service.handle.AbstractEventDataHandler; +import com.supervision.edh.service.handle.EventSubType; +import com.supervision.edh.utils.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + + +/** + * @author Jason 企业上报-药品经营企业基本信息数据子集 + * @date 2025年06月18日 11:14:43 + */ +@Service +@EventSubType("1014") +public class SubType1014Handler extends AbstractEventDataHandler { + protected final Logger log = LoggerFactory.getLogger(getClass()); + + @Autowired + private IEdhDrugOperatorsBaseInfoService edhDrugOperatorsBaseInfoService; + + + @Override + protected Class getEntityClass() { + return EdhDrugOperatorsBaseInfoVO.class; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void handleData(String data, String eventId) { + EdhDrugOperatorsBaseInfoVO VO= JsonUtils.parseJson(data,getEntityClass()); + // 1. 数据校验与去重 + if (CollectionUtils.isEmpty(VO.getDataSet())) { + log.info("数据为空,跳过处理"); + return; + } + + // 使用Stream去重(按tyshxydm字段) + List uniqueList = VO.getDataSet().stream() + .filter(Objects::nonNull) + .collect(Collectors.toMap( + EdhDrugOperatorsBaseInfo::getTyshxydm, + Function.identity(), + (oldVal, newVal) -> oldVal + )) + .values() + .stream() + .peek(item -> item.setEventId(eventId)) // 统一设置eventId + .collect(Collectors.toList()); + + // 2. 批量查询已存在的数据 + Set tyshxydmSet = uniqueList.stream() + .map(EdhDrugOperatorsBaseInfo::getTyshxydm) + .collect(Collectors.toSet()); + + // 自定义批量查询方法 + Map existingMap = edhDrugOperatorsBaseInfoService + .listByTyshxydmIn(tyshxydmSet) + .stream() + .collect(Collectors.toMap( + EdhDrugOperatorsBaseInfo::getTyshxydm, + Function.identity() + )); + + // 3. 分离新增和更新数据 + List insertList = new ArrayList<>(); + List updateList = new ArrayList<>(); + + uniqueList.forEach(item -> { + EdhDrugOperatorsBaseInfo existing = existingMap.get(item.getTyshxydm()); + if (existing == null) { + insertList.add(item); + } else { + Long existingId = existing.getId(); + BeanUtils.copyProperties(item, existing); + existing.setId(existingId); // 保护原有ID + updateList.add(existing); + } + }); + + // 4. 批量操作 + if (!insertList.isEmpty()) { + edhDrugOperatorsBaseInfoService.saveBatch(insertList); + } + if (!updateList.isEmpty()) { + edhDrugOperatorsBaseInfoService.updateBatchById(updateList); + } + } + +} diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType1015Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType1015Handler.java new file mode 100644 index 0000000..489cf00 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/handle/core/SubType1015Handler.java @@ -0,0 +1,107 @@ +package com.supervision.edh.service.handle.core; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo; +import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo; +import com.supervision.edh.domain.vo.EdhDrugOperateLicenseBaseInfoVO; +import com.supervision.edh.domain.vo.EdhDrugOperatorsBaseInfoVO; +import com.supervision.edh.service.IEdhDrugOperateLicenseBaseInfoService; +import com.supervision.edh.service.IEdhDrugOperatorsBaseInfoService; +import com.supervision.edh.service.handle.AbstractEventDataHandler; +import com.supervision.edh.service.handle.EventSubType; +import com.supervision.edh.utils.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + + +/** + * @author Jason 药监企业数据上报-药品经营许可证基本信息 + * @date 2025年06月19日 10:14:43 + */ +@Service +@EventSubType("1015") +public class SubType1015Handler extends AbstractEventDataHandler { + protected final Logger log = LoggerFactory.getLogger(getClass()); + + @Autowired + private IEdhDrugOperateLicenseBaseInfoService drugOperateLicenseBaseInfoService; + + + @Override + protected Class getEntityClass() { + return EdhDrugOperateLicenseBaseInfoVO.class; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void handleData(String data, String eventId) { + EdhDrugOperateLicenseBaseInfoVO VO= JsonUtils.parseJson(data,getEntityClass()); + // 1. 数据校验与去重 + if (CollectionUtils.isEmpty(VO.getDataSet())) { + log.info("数据为空,跳过处理"); + return; + } + + // 使用Stream去重(按jyxkzbh字段) + List uniqueList = VO.getDataSet().stream() + .filter(Objects::nonNull) + .collect(Collectors.toMap( + EdhDrugOperateLicenseBaseInfo::getJyxkzbh, + Function.identity(), + (oldVal, newVal) -> oldVal + )) + .values() + .stream() + .peek(item -> item.setEventId(eventId)) // 统一设置eventId + .collect(Collectors.toList()); + + // 2. 批量查询已存在的数据 + Set jyxkzbhSet = uniqueList.stream() + .map(EdhDrugOperateLicenseBaseInfo::getJyxkzbh) + .collect(Collectors.toSet()); + + // 自定义批量查询方法 + Map existingMap = drugOperateLicenseBaseInfoService + .listByJyxkzbhIn(jyxkzbhSet) + .stream() + .collect(Collectors.toMap( + EdhDrugOperateLicenseBaseInfo::getJyxkzbh, + Function.identity() + )); + + // 3. 分离新增和更新数据 + List insertList = new ArrayList<>(); + List updateList = new ArrayList<>(); + + uniqueList.forEach(item -> { + EdhDrugOperateLicenseBaseInfo existing = existingMap.get(item.getJyxkzbh()); + if (existing == null) { + insertList.add(item); + } else { + Long existingId = existing.getId(); + BeanUtils.copyProperties(item, existing); + existing.setId(existingId); // 保护原有ID + updateList.add(existing); + } + }); + + // 4. 批量操作 + if (!insertList.isEmpty()) { + drugOperateLicenseBaseInfoService.saveBatch(insertList); + } + if (!updateList.isEmpty()) { + drugOperateLicenseBaseInfoService.updateBatchById(updateList); + } + } + +} diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType1018Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType1018Handler.java new file mode 100644 index 0000000..6291552 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/handle/core/SubType1018Handler.java @@ -0,0 +1,50 @@ +package com.supervision.edh.service.handle.core; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.supervision.edh.domain.vo.EdhDomesticDrugBaseInfoVO; +import com.supervision.edh.domain.vo.EdhDrugOperateLicenseBaseInfoVO; +import com.supervision.edh.service.IEdhDomesticDrugBaseInfoService; +import com.supervision.edh.service.IEdhDrugOperateLicenseBaseInfoService; +import com.supervision.edh.service.handle.AbstractEventDataHandler; +import com.supervision.edh.service.handle.EventSubType; +import com.supervision.edh.utils.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + + +/** + * @author Jason 药监企业数据上报-药品基本信息数据子集 + * @date 2025年06月20日 10:14:43 + */ +@Service +@EventSubType("1018") +public class SubType1018Handler extends AbstractEventDataHandler { + protected final Logger log = LoggerFactory.getLogger(getClass()); + + @Autowired + private IEdhDomesticDrugBaseInfoService domesticDrugBaseInfoService; + + + @Override + protected Class getEntityClass() { + return EdhDomesticDrugBaseInfoVO.class; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void handleData(String data, String eventId) { + EdhDomesticDrugBaseInfoVO VO= JsonUtils.parseJson(data,getEntityClass()); + if (CollectionUtils.isEmpty(VO.getDataSet())) { + log.info("数据为空,跳过处理"); + return; + } + VO.getDataSet().forEach(item -> item.setEventId(eventId)); + domesticDrugBaseInfoService.saveBatch(VO.getDataSet()); + } + +} diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType2015Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType2015Handler.java new file mode 100644 index 0000000..b6840d4 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/handle/core/SubType2015Handler.java @@ -0,0 +1,90 @@ +package com.supervision.edh.service.handle.core; + +import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo; +import com.supervision.edh.domain.vo.EdhDrugInvoiceApplyInfoVO; +import com.supervision.edh.domain.vo.InstanceVO; +import com.supervision.edh.domain.vo.DrugVO; +import com.supervision.edh.service.IEdhDrugInvoiceApplyInfoService; +import com.supervision.edh.service.handle.AbstractEventDataHandler; +import com.supervision.edh.service.handle.EventSubType; +import com.supervision.edh.utils.DateUtils; +import com.supervision.edh.utils.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.stream.Collectors; + + +/** + * @author Jason 药监企业数据上报-发货单信息数据集 + * @date 2025年06月20日 10:14:43 + */ +@Service +@EventSubType("2015") +public class SubType2015Handler extends AbstractEventDataHandler { + protected final Logger log = LoggerFactory.getLogger(getClass()); + + @Autowired + private IEdhDrugInvoiceApplyInfoService drugInvoiceApplyInfoService; + + + @Override + protected Class getEntityClass() { + return EdhDrugInvoiceApplyInfoVO.class; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void handleData(String data, String eventId) { + EdhDrugInvoiceApplyInfoVO VO= JsonUtils.parseJson(data,getEntityClass()); + if (CollectionUtils.isEmpty(VO.getDataSet())) { + log.info("数据为空,跳过处理"); + return; + } + List infoList = VO.getDataSet().stream() // 第一层:发货单列表 + .flatMap(info -> info.getItemList().stream() // 第二层:药品列表 + .flatMap(item -> item.getInstanceList().stream() // 第三层:实例列表 + .map(instance -> buildFlatEntity(info, item, instance,eventId)))) // 合并三个层级的数据 + .collect(Collectors.toList()); + drugInvoiceApplyInfoService.saveBatch(infoList); + } + + // 构建扁平化实体对象 + private EdhDrugInvoiceApplyInfo buildFlatEntity(EdhDrugInvoiceApplyInfo info, DrugVO item, InstanceVO instance,String eventId) { + EdhDrugInvoiceApplyInfo entity = new EdhDrugInvoiceApplyInfo(); + // 1. 填充发货单级别字段 + BeanUtils.copyProperties(info, entity); + // 2. 填充药品级别字段 + BeanUtils.copyProperties(item, entity); + // 3. 填充实例级别字段 + BeanUtils.copyProperties(instance, entity); + //事件ID + entity.setEventId(eventId); + return entity; + } + + // 分批插入工具方法 + private void batchInsert(List list, int batchSize) { + // 如果数据量小于等于批处理大小,直接全量插入 + if (list.size() <= batchSize) { + if (!list.isEmpty()) { + drugInvoiceApplyInfoService.saveBatch(list); + } + return; + } + for (int i = 0; i < list.size(); i += batchSize) { + int end = Math.min(i + batchSize, list.size()); + drugInvoiceApplyInfoService.saveBatch(list.subList(i, end)); + } + } + +} diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType2016Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType2016Handler.java new file mode 100644 index 0000000..a3c6554 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/handle/core/SubType2016Handler.java @@ -0,0 +1,88 @@ +package com.supervision.edh.service.handle.core; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo; +import com.supervision.edh.domain.vo.DrugVO; +import com.supervision.edh.domain.vo.EdhDrugDeliveryNoteApplyInfoVO; +import com.supervision.edh.domain.vo.InstanceVO; +import com.supervision.edh.service.IEdhDrugDeliveryNoteApplyInfoService; +import com.supervision.edh.service.handle.AbstractEventDataHandler; +import com.supervision.edh.service.handle.EventSubType; +import com.supervision.edh.utils.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.stream.Collectors; + + +/** + * @author Jason 药监企业数据上报-药品收货单信息数据集 + * @date 2025年06月21日 10:14:43 + */ +@Service +@EventSubType("2016") +public class SubType2016Handler extends AbstractEventDataHandler { + protected final Logger log = LoggerFactory.getLogger(getClass()); + + @Autowired + private IEdhDrugDeliveryNoteApplyInfoService drugDeliveryNoteApplyInfoService; + + + @Override + protected Class getEntityClass() { + return EdhDrugDeliveryNoteApplyInfoVO.class; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void handleData(String data, String eventId) { + EdhDrugDeliveryNoteApplyInfoVO VO= JsonUtils.parseJson(data,getEntityClass()); + if (CollectionUtils.isEmpty(VO.getDataSet())) { + log.info("数据为空,跳过处理"); + return; + } + List infoList = VO.getDataSet().stream() // 第一层:发货单列表 + .flatMap(info -> info.getItemList().stream() // 第二层:药品列表 + .flatMap(item -> item.getInstanceList().stream() // 第三层:实例列表 + .map(instance -> buildFlatEntity(info, item, instance,eventId)))) // 合并三个层级的数据 + .collect(Collectors.toList()); + drugDeliveryNoteApplyInfoService.saveBatch(infoList); + } + + // 构建扁平化实体对象 + private EdhDrugDeliveryNoteApplyInfo buildFlatEntity(EdhDrugDeliveryNoteApplyInfo info, DrugVO item, InstanceVO instance,String eventId) { + EdhDrugDeliveryNoteApplyInfo entity = new EdhDrugDeliveryNoteApplyInfo(); + // 1. 填充发货单级别字段 + BeanUtils.copyProperties(info, entity); + // 2. 填充药品级别字段 + BeanUtils.copyProperties(item, entity); + // 3. 填充实例级别字段 + BeanUtils.copyProperties(instance, entity); + //事件ID + entity.setEventId(eventId); + return entity; + } + + // 分批插入工具方法 + private void batchInsert(List list, int batchSize) { + // 如果数据量小于等于批处理大小,直接全量插入 + if (list.size() <= batchSize) { + if (!list.isEmpty()) { + drugDeliveryNoteApplyInfoService.saveBatch(list); + } + return; + } + for (int i = 0; i < list.size(); i += batchSize) { + int end = Math.min(i + batchSize, list.size()); + drugDeliveryNoteApplyInfoService.saveBatch(list.subList(i, end)); + } + } + +} diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType2019Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType2019Handler.java new file mode 100644 index 0000000..48455ef --- /dev/null +++ b/src/main/java/com/supervision/edh/service/handle/core/SubType2019Handler.java @@ -0,0 +1,72 @@ +package com.supervision.edh.service.handle.core; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo; +import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo; +import com.supervision.edh.domain.EdhWarehouseStockApplyInfo; +import com.supervision.edh.domain.vo.*; +import com.supervision.edh.service.IEdhWarehouseStockApplyInfoService; +import com.supervision.edh.service.IEdhWhTempHumidityApplyInfoService; +import com.supervision.edh.service.handle.AbstractEventDataHandler; +import com.supervision.edh.service.handle.EventSubType; +import com.supervision.edh.utils.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.stream.Collectors; + + +/** + * @author Jason 药监企业数据上报-库存上报信息 + * @date 2025年06月23日 11:22:43 + */ +@Service +@EventSubType("2019") +public class SubType2019Handler extends AbstractEventDataHandler { + protected final Logger log = LoggerFactory.getLogger(getClass()); + + @Autowired + private IEdhWarehouseStockApplyInfoService warehouseStockApplyInfoService; + + + @Override + protected Class getEntityClass() { + return EdhWarehouseStockApplyInfoVO.class; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void handleData(String data, String eventId) { + EdhWarehouseStockApplyInfoVO VO= JsonUtils.parseJson(data,getEntityClass()); + if (CollectionUtils.isEmpty(VO.getDataSet())) { + log.info("数据为空,跳过处理"); + return; + } + List infoList = VO.getDataSet().stream() // 第一层:发货单列表 + .flatMap(info -> info.getItemList().stream() // 第二层:药品列表 + .map(stock -> buildFlatEntity(info,stock,eventId))) // 合并三个层级的数据 + .collect(Collectors.toList()); + warehouseStockApplyInfoService.saveBatch(infoList); + } + + // 构建扁平化实体对象 + private EdhWarehouseStockApplyInfo buildFlatEntity(EdhWarehouseStockApplyInfo info, StockVO stock, String eventId) { + EdhWarehouseStockApplyInfo entity = new EdhWarehouseStockApplyInfo(); + // 1. 填充库存基础信息 + BeanUtils.copyProperties(info, entity); + // 2. 填充库存药品信息 + BeanUtils.copyProperties(stock, entity); + //事件ID + entity.setEventId(eventId); + return entity; + } + + +} diff --git a/src/main/java/com/supervision/edh/service/handle/core/SubType2052Handler.java b/src/main/java/com/supervision/edh/service/handle/core/SubType2052Handler.java new file mode 100644 index 0000000..7d55975 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/handle/core/SubType2052Handler.java @@ -0,0 +1,50 @@ +package com.supervision.edh.service.handle.core; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.supervision.edh.domain.vo.EdhWhTempHumidityApplyInfoVO; +import com.supervision.edh.service.IEdhWhTempHumidityApplyInfoService; +import com.supervision.edh.service.handle.AbstractEventDataHandler; +import com.supervision.edh.service.handle.EventSubType; +import com.supervision.edh.utils.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + + +/** + * @author Jason 药监企业数据上报-仓库存储温湿度信息表 + * @date 2025年06月21日 16:14:43 + */ +@Service +@EventSubType("2052") +public class SubType2052Handler extends AbstractEventDataHandler { + protected final Logger log = LoggerFactory.getLogger(getClass()); + + @Autowired + private IEdhWhTempHumidityApplyInfoService whTempHumidityApplyInfoService; + + + @Override + protected Class getEntityClass() { + return EdhWhTempHumidityApplyInfoVO.class; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void handleData(String data, String eventId) { + EdhWhTempHumidityApplyInfoVO VO= JsonUtils.parseJson(data,getEntityClass()); + if (CollectionUtils.isEmpty(VO.getDataSet())) { + log.info("数据为空,跳过处理"); + return; + } + VO.getDataSet().forEach(item -> { + item.setEventId(eventId); + }); + whTempHumidityApplyInfoService.saveBatch(VO.getDataSet()); + } + +} diff --git a/src/main/java/com/supervision/edh/service/impl/EdhDomesticDrugBaseInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhDomesticDrugBaseInfoServiceImpl.java new file mode 100644 index 0000000..3be9d1a --- /dev/null +++ b/src/main/java/com/supervision/edh/service/impl/EdhDomesticDrugBaseInfoServiceImpl.java @@ -0,0 +1,20 @@ +package com.supervision.edh.service.impl; + +import com.supervision.edh.domain.EdhDomesticDrugBaseInfo; +import com.supervision.edh.mapper.EdhDomesticDrugBaseInfoMapper; +import com.supervision.edh.service.IEdhDomesticDrugBaseInfoService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 药监企业数据上报-药品基本信息数据子集 服务实现类 + *

+ * + * @author Jason + * @since 2025-06-20 + */ +@Service("domesticDrugBaseInfoService") +public class EdhDomesticDrugBaseInfoServiceImpl extends ServiceImpl implements IEdhDomesticDrugBaseInfoService { + +} diff --git a/src/main/java/com/supervision/edh/service/impl/EdhDrugDeliveryNoteApplyInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhDrugDeliveryNoteApplyInfoServiceImpl.java new file mode 100644 index 0000000..d99c722 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/impl/EdhDrugDeliveryNoteApplyInfoServiceImpl.java @@ -0,0 +1,20 @@ +package com.supervision.edh.service.impl; + +import com.supervision.edh.domain.EdhDrugDeliveryNoteApplyInfo; +import com.supervision.edh.mapper.EdhDrugDeliveryNoteApplyInfoMapper; +import com.supervision.edh.service.IEdhDrugDeliveryNoteApplyInfoService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 药监企业数据上报-药品收货单信息表 服务实现类 + *

+ * + * @author Jason + * @since 2025-06-21 + */ +@Service("drugDeliveryNoteApplyInfoService") +public class EdhDrugDeliveryNoteApplyInfoServiceImpl extends ServiceImpl implements IEdhDrugDeliveryNoteApplyInfoService { + +} diff --git a/src/main/java/com/supervision/edh/service/impl/EdhDrugInvoiceApplyInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhDrugInvoiceApplyInfoServiceImpl.java new file mode 100644 index 0000000..c8384c4 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/impl/EdhDrugInvoiceApplyInfoServiceImpl.java @@ -0,0 +1,20 @@ +package com.supervision.edh.service.impl; + +import com.supervision.edh.domain.EdhDrugInvoiceApplyInfo; +import com.supervision.edh.mapper.EdhDrugInvoiceApplyInfoMapper; +import com.supervision.edh.service.IEdhDrugInvoiceApplyInfoService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 药监企业数据上报-发货单信息数据子集 服务实现类 + *

+ * + * @author Jason + * @since 2025-06-20 + */ +@Service("drugInvoiceApplyInfoService") +public class EdhDrugInvoiceApplyInfoServiceImpl extends ServiceImpl implements IEdhDrugInvoiceApplyInfoService { + +} diff --git a/src/main/java/com/supervision/edh/service/impl/EdhDrugOperateLicenseBaseInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhDrugOperateLicenseBaseInfoServiceImpl.java new file mode 100644 index 0000000..b42c0af --- /dev/null +++ b/src/main/java/com/supervision/edh/service/impl/EdhDrugOperateLicenseBaseInfoServiceImpl.java @@ -0,0 +1,28 @@ +package com.supervision.edh.service.impl; + +import com.supervision.edh.domain.EdhDrugOperateLicenseBaseInfo; +import com.supervision.edh.mapper.EdhDrugOperateLicenseBaseInfoMapper; +import com.supervision.edh.service.IEdhDrugOperateLicenseBaseInfoService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +/** + *

+ * 药监企业数据上报-药品经营许可证基本信息 服务实现类 + *

+ * + * @author Jason + * @since 2025-06-19 + */ +@Service("drugOperateLicenseBaseInfoService") +public class EdhDrugOperateLicenseBaseInfoServiceImpl extends ServiceImpl implements IEdhDrugOperateLicenseBaseInfoService { + + @Override + public List listByJyxkzbhIn(Set jyxkzbhSet) { + return getBaseMapper().listByJyxkzbhIn(jyxkzbhSet); + } +} diff --git a/src/main/java/com/supervision/edh/service/impl/EdhDrugOperatorsBaseInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhDrugOperatorsBaseInfoServiceImpl.java new file mode 100644 index 0000000..5197b46 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/impl/EdhDrugOperatorsBaseInfoServiceImpl.java @@ -0,0 +1,33 @@ +package com.supervision.edh.service.impl; + +import com.supervision.edh.domain.EdhDrugOperatorsBaseInfo; +import com.supervision.edh.domain.EdhReceiveDataLog; +import com.supervision.edh.mapper.EdhDrugOperatorsBaseInfoMapper; +import com.supervision.edh.mapper.EdhReceiveDataLogMapper; +import com.supervision.edh.service.IEdhDrugOperatorsBaseInfoService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.supervision.edh.service.IEdhReceiveDataLogService; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +/** + *

+ * 药监企业数据上报-药品经营企业基本信息 服务实现类 + *

+ * + * @author Jason + * @since 2025-06-18 + */ +@Service("edhDrugOperatorsBaseInfoService") +public class EdhDrugOperatorsBaseInfoServiceImpl extends ServiceImpl implements IEdhDrugOperatorsBaseInfoService { + + + @Override + public List listByTyshxydmIn(Set tyshxydmSet) { + return getBaseMapper().listByTyshxydmIn(tyshxydmSet); + } +} diff --git a/src/main/java/com/supervision/edh/service/impl/EdhReceiveDataLogServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhReceiveDataLogServiceImpl.java new file mode 100644 index 0000000..f61d643 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/impl/EdhReceiveDataLogServiceImpl.java @@ -0,0 +1,15 @@ +package com.supervision.edh.service.impl; + +import com.supervision.edh.domain.EdhReceiveDataLog; +import com.supervision.edh.mapper.EdhReceiveDataLogMapper; +import com.supervision.edh.service.IEdhReceiveDataLogService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * @author Jason + * @date 2025年06月03日 15:37:17 + */ +@Service("receiveDataLogService") +public class EdhReceiveDataLogServiceImpl extends ServiceImpl implements IEdhReceiveDataLogService { +} diff --git a/src/main/java/com/supervision/edh/service/impl/EdhWarehouseStockApplyInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhWarehouseStockApplyInfoServiceImpl.java new file mode 100644 index 0000000..d27f15f --- /dev/null +++ b/src/main/java/com/supervision/edh/service/impl/EdhWarehouseStockApplyInfoServiceImpl.java @@ -0,0 +1,20 @@ +package com.supervision.edh.service.impl; + +import com.supervision.edh.domain.EdhWarehouseStockApplyInfo; +import com.supervision.edh.mapper.EdhWarehouseStockApplyInfoMapper; +import com.supervision.edh.service.IEdhWarehouseStockApplyInfoService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 药监企业数据上报-库存上报信息表 服务实现类 + *

+ * + * @author Jason + * @since 2025-06-23 + */ +@Service("warehouseStockApplyInfoService") +public class EdhWarehouseStockApplyInfoServiceImpl extends ServiceImpl implements IEdhWarehouseStockApplyInfoService { + +} diff --git a/src/main/java/com/supervision/edh/service/impl/EdhWhTempHumidityApplyInfoServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EdhWhTempHumidityApplyInfoServiceImpl.java new file mode 100644 index 0000000..8a84d62 --- /dev/null +++ b/src/main/java/com/supervision/edh/service/impl/EdhWhTempHumidityApplyInfoServiceImpl.java @@ -0,0 +1,20 @@ +package com.supervision.edh.service.impl; + +import com.supervision.edh.domain.EdhWhTempHumidityApplyInfo; +import com.supervision.edh.mapper.EdhWhTempHumidityApplyInfoMapper; +import com.supervision.edh.service.IEdhWhTempHumidityApplyInfoService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 药监企业数据上报-仓库存储温湿度信息表 服务实现类 + *

+ * + * @author Jason + * @since 2025-06-21 + */ +@Service("whTempHumidityApplyInfoService") +public class EdhWhTempHumidityApplyInfoServiceImpl extends ServiceImpl implements IEdhWhTempHumidityApplyInfoService { + +} diff --git a/src/main/java/com/supervision/edh/service/impl/EventProcessingServiceImpl.java b/src/main/java/com/supervision/edh/service/impl/EventProcessingServiceImpl.java new file mode 100644 index 0000000..b960f5d --- /dev/null +++ b/src/main/java/com/supervision/edh/service/impl/EventProcessingServiceImpl.java @@ -0,0 +1,31 @@ +package com.supervision.edh.service.impl; + +import com.supervision.edh.factory.EventHandlerFactory; +import com.supervision.edh.service.handle.EventDataHandler; +import com.supervision.edh.utils.EventPojo; +import lombok.RequiredArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * @author Jason + * @date 2025年06月18日 15:38:51 + */ +@Service("eventProcessingService") +@RequiredArgsConstructor +public class EventProcessingServiceImpl{ + + private static final Logger logger = LoggerFactory.getLogger(EventProcessingServiceImpl.class); + private final EventHandlerFactory handlerFactory; + + @Async + public void asyncProcessEvent(EventPojo eventPojo, String data,String eventId) { + EventDataHandler handler = handlerFactory.getHandler(eventPojo.getSubType()); + handler.handleData(data,eventId); + + } +} diff --git a/src/main/java/com/supervision/edh/utils/Base64.java b/src/main/java/com/supervision/edh/utils/Base64.java new file mode 100644 index 0000000..75b89eb --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/Base64.java @@ -0,0 +1,102 @@ +package com.supervision.edh.utils; + + +import java.io.UnsupportedEncodingException; + +public class Base64 { + private static char[] base64EncodeChars = new char[]{ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/'}; + private static byte[] base64DecodeChars = new byte[]{ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1}; + + public static String encode(byte[] data) { + StringBuffer sb = new StringBuffer(); + int len = data.length; + int i = 0; + int b1, b2, b3; + while (i < len) { + b1 = data[i++] & 0xff; + if (i == len) { + sb.append(base64EncodeChars[b1 >>> 2]); + sb.append(base64EncodeChars[(b1 & 0x3) << 4]); + sb.append("=="); + break; + } + b2 = data[i++] & 0xff; + if (i == len) { + sb.append(base64EncodeChars[b1 >>> 2]); + sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]); + sb.append(base64EncodeChars[(b2 & 0x0f) << 2]); + sb.append("="); + break; + } + b3 = data[i++] & 0xff; + sb.append(base64EncodeChars[b1 >>> 2]); + sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]); + sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]); + sb.append(base64EncodeChars[b3 & 0x3f]); + } + return sb.toString(); + } + + public static byte[] decode(String str) throws UnsupportedEncodingException { + StringBuffer sb = new StringBuffer(); + byte[] data = str.getBytes("US-ASCII"); + int len = data.length; + int i = 0; + int b1, b2, b3, b4; + while (i < len) { + + do { + b1 = base64DecodeChars[data[i++]]; + } while (i < len && b1 == -1); + if (b1 == -1) break; + + do { + b2 = base64DecodeChars + [data[i++]]; + } while (i < len && b2 == -1); + if (b2 == -1) break; + sb.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4))); + + do { + b3 = data[i++]; + if (b3 == 61) return sb.toString().getBytes("iso8859-1"); + b3 = base64DecodeChars[b3]; + } while (i < len && b3 == -1); + if (b3 == -1) break; + sb.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2))); + + do { + b4 = data[i++]; + if (b4 == 61) return sb.toString().getBytes("iso8859-1"); + b4 = base64DecodeChars[b4]; + } while (i < len && b4 == -1); + if (b4 == -1) break; + sb.append((char) (((b3 & 0x03) << 6) | b4)); + } + return sb.toString().getBytes("iso8859-1"); + } + public static void main(String[] args) throws UnsupportedEncodingException { + String s = "abcd"; + System.out.println("����ǰ��" + s); + String x = encode(s.getBytes()); + System.out.println("���ܺ�" + x); + String x1 = new String(decode(x)); + System.out.println("���ܺ�" + x1); + } +} diff --git a/src/main/java/com/supervision/edh/utils/BouncyCastlePFXGenerator.java b/src/main/java/com/supervision/edh/utils/BouncyCastlePFXGenerator.java new file mode 100644 index 0000000..b9784ca --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/BouncyCastlePFXGenerator.java @@ -0,0 +1,73 @@ +package com.supervision.edh.utils; + +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; + +import java.io.FileOutputStream; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.Security; +import java.security.cert.X509Certificate; +import java.util.Date; + +/** + * @author Jason + * @date 2025年05月28日 15:02:12 + */ +public class BouncyCastlePFXGenerator { + + static { + Security.addProvider(new BouncyCastleProvider()); + } + + public static void generatePFX(String pfxFilePath, String password) throws Exception { + // 1. 生成密钥对 + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + KeyPair keyPair = keyPairGenerator.generateKeyPair(); + + // 2. 创建自签名证书 + X500Name issuerName = new X500Name("CN=Test Certificate, OU=Test, O=Test Org, C=US"); + BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis()); + Date notBefore = new Date(); + Date notAfter = new Date(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000); // 1年有效期 + + X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder( + issuerName, serialNumber, notBefore, notAfter, issuerName, keyPair.getPublic()); + + ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSAEncryption") + .build(keyPair.getPrivate()); + + X509Certificate cert = new JcaX509CertificateConverter() + .getCertificate(certBuilder.build(signer)); + + // 3. 创建PKCS12密钥库 + KeyStore pkcs12 = KeyStore.getInstance("PKCS12"); + pkcs12.load(null, null); + + // 4. 添加证书和私钥 + pkcs12.setKeyEntry("alias", keyPair.getPrivate(), password.toCharArray(), + new java.security.cert.Certificate[]{cert}); + + // 5. 保存PFX文件 + try (FileOutputStream fos = new FileOutputStream(pfxFilePath)) { + pkcs12.store(fos, password.toCharArray()); + } + } + + public static void main(String[] args) { + try { + generatePFX("edh.pfx", "YnYp123456"); + System.out.println("使用Bouncy Castle生成的PFX证书成功!"); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/supervision/edh/utils/CertManager.java b/src/main/java/com/supervision/edh/utils/CertManager.java new file mode 100644 index 0000000..5e51568 --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/CertManager.java @@ -0,0 +1,173 @@ +package com.supervision.edh.utils; + +import com.supervision.edh.config.CertConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.*; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * @author Jason 证书管理 + * @date 2025年06月06日 14:24:09 + */ +@Component +public class CertManager { + + private static volatile String privateKey; + + private static volatile String publicKey; + + @Autowired + private CertConfig certConfig; + + + /** + * 私钥解密 + * @param key + * @param data + * @return + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + * @throws NoSuchPaddingException + * @throws InvalidKeySpecException + * @throws BadPaddingException + * @throws IllegalBlockSizeException + * @throws IOException + */ + public String keyDecrypt(String key,String data) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException, IOException{ + byte[] decode = java.util.Base64.getDecoder().decode(key); + RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(certConfig.getAlgorithm()).generatePrivate(new PKCS8EncodedKeySpec(decode)); + //RSA解密 + Cipher ci = Cipher.getInstance(certConfig.getAlgorithm()); + ci.init(Cipher.DECRYPT_MODE, priKey); + + + byte[] bytes = java.util.Base64.getDecoder().decode(data); + int inputLen = bytes.length; + int offLen = 0; + int i = 0; + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + while(inputLen - offLen > 0){ + byte[] cache; + if(inputLen - offLen > 256){ + cache = ci.doFinal(bytes,offLen,256); + }else{ + cache = ci.doFinal(bytes,offLen,inputLen - offLen); + } + byteArrayOutputStream.write(cache); + i++; + offLen = 256 * i; + + } + byteArrayOutputStream.close(); + byte[] byteArray = byteArrayOutputStream.toByteArray(); + return new String(byteArray); + } + + /** + * 公钥加密 + * + * @param key + * @param data + * @return + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + * @throws NoSuchPaddingException + * @throws IllegalBlockSizeException + * @throws BadPaddingException + * @throws InvalidKeyException + * @throws IOException + */ + public String keyEncrypt(String key, String data) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, IOException { + byte[] decode = java.util.Base64.getDecoder().decode(key); + RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(certConfig.getAlgorithm()).generatePublic(new X509EncodedKeySpec(decode)); + //RSA加密 + Cipher ci = Cipher.getInstance(certConfig.getAlgorithm()); + ci.init(Cipher.ENCRYPT_MODE, pubKey); + + + byte[] bytes = data.getBytes(); + int inputLen = bytes.length; + int offLen = 0;//偏移量 + int i = 0; + ByteArrayOutputStream bops = new ByteArrayOutputStream(); + while (inputLen - offLen > 0) { + byte[] cache; + //2048 位密钥:2048 / 8 - 11 = 245 字节 + if (inputLen - offLen > 245) { + cache = ci.doFinal(bytes, offLen, 245); + } else { + cache = ci.doFinal(bytes, offLen, inputLen - offLen); + } + bops.write(cache); + i++; + offLen = 245 * i; + } + bops.close(); + byte[] encryptedData = bops.toByteArray(); + String encodeToString = java.util.Base64.getEncoder().encodeToString(encryptedData); + return encodeToString; + } + + + + @PostConstruct + public synchronized void init() throws Exception { + if (privateKey == null) { + privateKey = initPrivateKey(); + } + if(publicKey == null) { + publicKey = initPublicKey(); + } + } + + + + + /** + * 获取私钥 + * @return + * @throws Exception + */ + public String initPrivateKey() throws Exception { + KeyStore keyStore = KeyStoreUtil.loadKetStore(certConfig.getPath(),certConfig.getPassword()); + return Base64.encode(KeyStoreUtil.getPrivateKey(keyStore, certConfig.getPassword()).getEncoded()); + } + + public String getPrivateKey() { + if (privateKey == null) { + throw new IllegalStateException("获取私钥失败,证书未初始化"); + } + return privateKey; + } + + /** + * 获取公钥 + * @return + * @throws Exception + */ + public String initPublicKey() throws Exception { + KeyStore keyStore = KeyStoreUtil.loadKetStore(certConfig.getPath(),certConfig.getPassword()); + PublicKey publicKey = KeyStoreUtil.getPublicKey(keyStore); + return Base64.encode(publicKey.getEncoded()); + } + + public String getPublicKey() { + if (publicKey == null) { + throw new IllegalStateException("获取公钥失败,证书未初始化"); + } + return publicKey; + } +} diff --git a/src/main/java/com/supervision/edh/utils/DateUtils.java b/src/main/java/com/supervision/edh/utils/DateUtils.java new file mode 100644 index 0000000..61258c1 --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/DateUtils.java @@ -0,0 +1,28 @@ +package com.supervision.edh.utils; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +/** + * @author Jason + * @date 2025年06月21日 13:59:07 + */ +public class DateUtils { + + public static String convertDateString(String strDate) { + return LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyyMMdd")) + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); + } + + public static LocalDate convertDate(String strDate) { + // 1. 定义原始格式 + DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyyMMdd"); + // 2. 转换为LocalDate + return LocalDate.parse(strDate, inputFormatter); + + } + + public static void main(String[] args) { + System.out.println(convertDate("20200301")); + } +} diff --git a/src/main/java/com/supervision/edh/utils/EscapeUtil.java b/src/main/java/com/supervision/edh/utils/EscapeUtil.java new file mode 100644 index 0000000..475cd18 --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/EscapeUtil.java @@ -0,0 +1,142 @@ +package com.supervision.edh.utils; + + +import cn.hutool.http.HTMLFilter; +import org.springframework.util.StringUtils; + +/** + * 转义和反转义工具类 + * + * @author tcctyn + */ +public class EscapeUtil { + public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; + + private static final char[][] TEXT = new char[64][]; + + static { + for (int i = 0; i < 64; i++) { + TEXT[i] = new char[]{(char) i}; + } + + // special HTML characters + TEXT['\''] = "'".toCharArray(); // 单引号 + TEXT['"'] = """.toCharArray(); // 双引号 + TEXT['&'] = "&".toCharArray(); // &符 + TEXT['<'] = "<".toCharArray(); // 小于号 + TEXT['>'] = ">".toCharArray(); // 大于号 + } + + /** + * 转义文本中的HTML字符为安全的字符 + * + * @param text 被转义的文本 + * @return 转义后的文本 + */ + public static String escape(String text) { + return encode(text); + } + + /** + * 还原被转义的HTML特殊字符 + * + * @param content 包含转义符的HTML内容 + * @return 转换后的字符串 + */ + public static String unescape(String content) { + return decode(content); + } + + /** + * 清除所有HTML标签,但是不删除标签内的内容 + * + * @param content 文本 + * @return 清除标签后的文本 + */ + public static String clean(String content) { + return new HTMLFilter().filter(content); + } + + /** + * Escape编码 + * + * @param text 被编码的文本 + * @return 编码后的字符 + */ + private static String encode(String text) { + if (StringUtils.isEmpty(text)) { + return ""; + } + + final StringBuilder tmp = new StringBuilder(text.length() * 6); + char c; + for (int i = 0; i < text.length(); i++) { + c = text.charAt(i); + if (c < 256) { + tmp.append("%"); + if (c < 16) { + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } else { + tmp.append("%u"); + if (c <= 0xfff) { + // issue#I49JU8@Gitee + tmp.append("0"); + } + tmp.append(Integer.toString(c, 16)); + } + } + return tmp.toString(); + } + + /** + * Escape解码 + * + * @param content 被转义的内容 + * @return 解码后的字符串 + */ + public static String decode(String content) { + if (StringUtils.isEmpty(content)) { + return content; + } + + StringBuilder tmp = new StringBuilder(content.length()); + int lastPos = 0, pos = 0; + char ch; + while (lastPos < content.length()) { + pos = content.indexOf("%", lastPos); + if (pos == lastPos) { + if (content.charAt(pos + 1) == 'u') { + ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16); + tmp.append(ch); + lastPos = pos + 6; + } else { + ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16); + tmp.append(ch); + lastPos = pos + 3; + } + } else { + if (pos == -1) { + tmp.append(content.substring(lastPos)); + lastPos = content.length(); + } else { + tmp.append(content.substring(lastPos, pos)); + lastPos = pos; + } + } + } + return tmp.toString(); + } + + public static void main(String[] args) { + String html = ""; + String escape = EscapeUtil.escape(html); + // String html = "ipt>alert(\"XSS\")ipt>"; + // String html = "<123"; + // String html = "123>"; + System.out.println("clean: " + EscapeUtil.clean(html)); + System.out.println("escape: " + escape); + System.out.println("unescape: " + EscapeUtil.unescape(escape)); + } +} diff --git a/src/main/java/com/supervision/edh/utils/EventPojo.java b/src/main/java/com/supervision/edh/utils/EventPojo.java new file mode 100644 index 0000000..7755a4c --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/EventPojo.java @@ -0,0 +1,33 @@ +package com.supervision.edh.utils; + + +import com.alibaba.fastjson.annotation.JSONField; + +public class EventPojo { + /** + *数据文件内容子业务类型 详见:数据类型字典表 + */ + private String subType; + /** + * 详见:疫苗追溯基本数据集 ZIP 压缩XML/JSON数据文件内容(BASE64编码) + */ + private String data; + + @JSONField( name = "sub_type") + public String getSubType() { + return subType; + } + + public void setSubType(String subType) { + this.subType = subType; + } + + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } +} diff --git a/src/main/java/com/supervision/edh/utils/JsonUtils.java b/src/main/java/com/supervision/edh/utils/JsonUtils.java new file mode 100644 index 0000000..891db8a --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/JsonUtils.java @@ -0,0 +1,28 @@ +package com.supervision.edh.utils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Jason + * @date 2025年06月18日 16:45:54 + */ +public class JsonUtils { + private static final ObjectMapper mapper = new ObjectMapper(); + protected static final Logger log = LoggerFactory.getLogger(JsonUtils.class); + + // 通用解析方法 + public static T parseJson(String json, Class clazz) { + mapper.registerModule(new JavaTimeModule()); // 必须添加! + try { + return mapper.readValue(json, clazz); + } catch (JsonProcessingException e) { + log.error("数据解析错误:"+e.getMessage()); + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/com/supervision/edh/utils/KeyStoreUtil.java b/src/main/java/com/supervision/edh/utils/KeyStoreUtil.java new file mode 100644 index 0000000..09ff9c5 --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/KeyStoreUtil.java @@ -0,0 +1,600 @@ +package com.supervision.edh.utils; + + +import javax.crypto.Cipher; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.security.*; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.util.Date; +import java.util.Enumeration; + +public class KeyStoreUtil { + /** + * 加载证书 pfxFilepath 证书路径 pfxPassword 密码 + * + * @throws Exception + */ + public static KeyStore loadKetStore(String pfxFilepath, String pfxPassword) + throws Exception { + KeyStore keyStore = null; + File fPkcs12 = null; + if (pfxFilepath != null) { + fPkcs12 = new File(pfxFilepath); + } + FileInputStream fis = new FileInputStream(fPkcs12); + + try { + keyStore = KeyStore.getInstance("PKCS12"); + } catch (KeyStoreException ex) { + throw new Exception("不能正确解释pfx文件! "); + } + + try { + keyStore.load(fis, pfxPassword.toCharArray()); + } catch (CertificateException ex) { + throw new Exception(" 证书格式问题! "); + } catch (NoSuchAlgorithmException ex) { + throw new Exception(" 算法不支持! "); + } catch (FileNotFoundException ex) { + throw new Exception(" pfx文件没找到 "); + } catch (IOException ex) { + throw new Exception(" 读取pfx有误! "); + } + return keyStore; + } + + // 证书别名可以作为证书的识别,所以加载证书别名积极关键。 + + /** + * 获取证书别名 + * + * @param keyStore + * @return + */ + // @SuppressWarnings("unchecked") + public static String getKeyAlias(KeyStore keyStore) { + String keyAlias = ""; + try { + Enumeration enums = keyStore.aliases(); + while (enums.hasMoreElements()) { + keyAlias = (String) enums.nextElement(); + } + } catch (KeyStoreException e) { + e.printStackTrace(); + } + return keyAlias; + } + + // 获取私钥,可以使用私钥进行数据加密后在网络上传输。 + + /** + * 获取私钥 + * + * @param keyStore + * @param pfxPassword + * @return + */ + public static PrivateKey getPrivateKey(KeyStore keyStore, String pfxPassword) { + PrivateKey privateKey = null; + try { + String keyAlias = getKeyAlias(keyStore); + privateKey = (PrivateKey) keyStore.getKey(keyAlias, pfxPassword + .toCharArray()); + } catch (UnrecoverableKeyException e) { + e.printStackTrace(); + } catch (KeyStoreException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return privateKey; + } + + // 使用公钥对私钥加密过的数据进行解密,可以得到相关的明文。 + + /** + * 获取公钥 + * + * @param keyStore + * @return + */ + public static PublicKey getPublicKey(KeyStore keyStore) { + PublicKey publicKey = null; + try { + String keyAlias = getKeyAlias(keyStore); + Certificate[] certs = keyStore.getCertificateChain(keyAlias); + if (certs != null && certs.length > 0) { + // 取得公钥 + publicKey = certs[0].getPublicKey(); + } + } catch (KeyStoreException e) { + e.printStackTrace(); + } + return publicKey; + } + + // 使用公钥加密的数据,需要使用私钥进行解密。 + + /** + * 公钥加密 + * + * @param data + * @param publicKey + * @return + * @throws Exception + */ + public static String encryptByPublicKey(byte[] data, PublicKey publicKey) + throws Exception { + // 对数据加密 + Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + byte[] encodedata = cipher.doFinal(data); + return byte2hex(encodedata); + } + + // 使用公钥对私钥加密过的数据进行解密。 + + /** + * 公钥解密 + * + * @param data + * @param publicKey + * @return + * @throws Exception + */ + public static String decryptByPublicKey(String data, PublicKey publicKey) + throws Exception { + // 对数据解密 + Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, publicKey); + byte[] decodedata = cipher.doFinal(hex2byte(data)); + return new String(decodedata); + } + + // 使用私钥加密的数据,需要使用公钥进行解密。 + + /** + * 私钥加密 + * + * @param data + * @param privateKey + * @return + * @throws Exception + */ + public static String encryptByPrivateKey(byte[] data, PrivateKey privateKey) + throws Exception { + // 对数据加密 + Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + byte[] encodedata = cipher.doFinal(data); + return byte2hex(encodedata); + } + + // 可以使用私钥对公钥加密过的数据进行解密。 + + /** + * 私钥解密 + * + * @param encodestr + * @param privateKey + * @return + * @throws Exception + */ + public static String decryptByPrivateKey(String encodestr, + PrivateKey privateKey) throws Exception { + // 对数据解密 + Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] data = cipher.doFinal(hex2byte(encodestr)); + return new String(data); + } + + /** + * 验证Certificate是否过期或无效 + * + * @param keyStore + * @param date + * 当前时间 + * @return + */ + public static boolean verifyCertificate(KeyStore keyStore, Date date) { + boolean status = true; + try { + // 取得证书 + String keyAlias = getKeyAlias(keyStore); + Certificate[] certs = keyStore.getCertificateChain(keyAlias); + if (certs != null && certs.length > 0) { + // 取得公钥 + X509Certificate x509Certificate = (X509Certificate) certs[0]; + // 验证证书是否过期或无效 + x509Certificate.checkValidity(date); + } + } catch (Exception e) { + status = false; + } + return status; + } + + /** + * 构造签名 + * + * @param keyStore + * @param pfxPassword + * @param dataStr + * 证书别名 + * @return + */ + public static String createSignature(KeyStore keyStore, String pfxPassword, + String dataStr) { + try { + // 取得证书 + String keyAlias = getKeyAlias(keyStore); + Certificate[] certs = keyStore.getCertificateChain(keyAlias); + X509Certificate x509Certificate = null; + if (certs != null && certs.length > 0) { + x509Certificate = (X509Certificate) certs[0]; + // 验证证书是否过期或无效 + } + if (x509Certificate != null) { + Signature signature = Signature.getInstance(x509Certificate + .getSigAlgName()); + PrivateKey privateKey = getPrivateKey(keyStore, pfxPassword); + signature.initSign(privateKey); + signature.update(dataStr.getBytes()); + byte[] data = signature.sign(); + return byte2hex(data); + } else { + return null; + } + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 验证签名 + * + * @param keyStore + * @param dataStr + * @param signStr + * @return + */ + public static boolean verfySignature(KeyStore keyStore, String dataStr, + String signStr) { + try { + // 取得证书 + String keyAlias = getKeyAlias(keyStore); + Certificate[] certs = keyStore.getCertificateChain(keyAlias); + X509Certificate x509Certificate = null; + if (certs != null && certs.length > 0) { + x509Certificate = (X509Certificate) certs[0]; + // 验证证书是否过期或无效 + } + Signature signature = Signature.getInstance(x509Certificate + .getSigAlgName()); + PublicKey publicKey = getPublicKey(keyStore); + signature.initVerify(publicKey); + signature.update(dataStr.getBytes()); + return signature.verify(hex2byte(signStr)); + } catch (Exception e) { + return false; + } + } + + /** + * 验证签名使用公钥 + * + * @param dataStr + * @param signStr + * @return + */ + public static boolean verfySignatureWithPublic(byte[] publicKeyArr, + String dataStr, String signStr) { + try { + Signature signature = Signature.getInstance("SHA1withRSA"); + java.security.spec.X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec( + publicKeyArr); + java.security.KeyFactory keyFactory = java.security.KeyFactory + .getInstance("RSA"); + PublicKey publicKey = keyFactory.generatePublic(bobPubKeySpec); + signature.initVerify(publicKey); + signature.update(dataStr.getBytes()); + return signature.verify(hex2byte(signStr)); + } catch (Exception e) { + return false; + } + } + + public static String decodeWithPrivate(byte[] privateKeyArr) { + // Signature signature = Signature.getInstance("SHA1withRSA"); + java.security.spec.X509EncodedKeySpec bobPriKeySpec = new java.security.spec.X509EncodedKeySpec(privateKeyArr); + KeyFactory keyFactory = null; + try { + keyFactory = KeyFactory.getInstance("RSA"); + PrivateKey privateKey = keyFactory.generatePrivate(bobPriKeySpec); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (InvalidKeySpecException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 公钥解密 + * @param publicKeyArr + * @return + */ + public static String decodeWithPublic(String data,byte[] publicKeyArr) { + // Signature signature = Signature.getInstance("SHA1withRSA"); + java.security.spec.X509EncodedKeySpec bobPriKeySpec = new java.security.spec.X509EncodedKeySpec(publicKeyArr); + KeyFactory keyFactory = null; + try { + keyFactory = KeyFactory.getInstance("RSA"); + //PrivateKey privateKey = keyFactory.generatePrivate(bobPriKeySpec); + PublicKey publickey = keyFactory.generatePublic(bobPriKeySpec); + return decryptByPublicKey(data,publickey); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (InvalidKeySpecException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 公钥加密 + * @param publicKeyArr + * @return + */ + public static String encodeWithPublic(String data,byte[] publicKeyArr) { + // Signature signature = Signature.getInstance("SHA1withRSA"); + java.security.spec.X509EncodedKeySpec bobPriKeySpec = new java.security.spec.X509EncodedKeySpec(publicKeyArr); + KeyFactory keyFactory = null; + try { + keyFactory = KeyFactory.getInstance("RSA"); + //PrivateKey privateKey = keyFactory.generatePrivate(bobPriKeySpec); + PublicKey publickey = keyFactory.generatePublic(bobPriKeySpec); + return encryptByPublicKey(data.getBytes(),publickey); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (InvalidKeySpecException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + + /** + * 私钥解密 + * @param privateKeyArr + * @return + */ + public static String decodeWithPrivate(String data,byte[] privateKeyArr) { + // Signature signature = Signature.getInstance("SHA1withRSA"); + java.security.spec.X509EncodedKeySpec bobPriKeySpec = new java.security.spec.X509EncodedKeySpec(privateKeyArr); + KeyFactory keyFactory = null; + try { + keyFactory = KeyFactory.getInstance("RSA"); + //PrivateKey privateKey = keyFactory.generatePrivate(bobPriKeySpec); + PrivateKey privatekey = keyFactory.generatePrivate(bobPriKeySpec); + return decryptByPrivateKey(data,privatekey); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (InvalidKeySpecException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + + + /** + * 将二进制转化为16进制字符串 + * + * @param b + * 二进制字节数组 + * @return String + */ + private static String byte2hex(byte[] b) { + String hs = ""; + String stmp = ""; + for (int n = 0; n < b.length; n++) { + stmp = (Integer.toHexString(b[n] & 0XFF)); + if (stmp.length() == 1) { + hs = hs + "0" + stmp; + } else { + hs = hs + stmp; + } + } + return hs.toUpperCase(); + } + + /** + * 十六进制字符串转化为2进制 + * + * @param hex + * @return + */ + private static byte[] hex2byte(String hex) { + byte[] ret = null; + // try { + byte[] tmp = hex.getBytes(); + int length = tmp.length / 2; + ret = new byte[length]; + for (int i = 0; i < length; i++) { + ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]); + } + // } catch (UnsupportedEncodingException e) { + // e.printStackTrace(); + // } + return ret; + } + + /** + * 将两个ASCII字符合成一个字节; 如:"EF"--> 0xEF + * + * @param src0 + * byte + * @param src1 + * byte + * @return byte + */ + private static byte uniteBytes(byte src0, byte src1) { + byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 })) + .byteValue(); + _b0 = (byte) (_b0 << 4); + byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 })) + .byteValue(); + byte ret = (byte) (_b0 ^ _b1); + return ret; + } + + // /** + // * 验证pkcs7格式的签名数据 + // * @param signedData pkcs7格式的签名数据 + // * @return 验证结果 + // * @throws Exception + // */ + // public boolean verify(byte[] signedData) throws Exception { + // CMSSignedData sign = new CMSSignedData(signedData); + // CertStore certs = sign.getCertificatesAndCRLs("Collection", "BC"); + // SignerInformationStore signers = sign.getSignerInfos(); + // Collection c = signers.getSigners(); + // Iterator it = c.iterator(); + // boolean bresult = true; + // //当有多个签名者信息时需要进行全部验证 + // while (it.hasNext()) ...{ + // SignerInformation signer = (SignerInformation) it.next(); + // Collection certCollection = certs.getCertificates(signer.getSID()); + // Iterator certIt = certCollection.iterator(); + // X509Certificate cert = (X509Certificate) certIt.next();//证书链???? + // byte[] data = signer.getSignature(); + // logger.debug("签名后数据:" + data.length); + // for (int i = 0; i < data.length; i++) ...{ + // System.out.print(" " + data[i]); + // } + // System.out.println(); + // logger.debug("签名后数据Base64: " + new String(Base64.encode(data),"utf8")); + // if (signer.verify(cert.getPublicKey(), "BC")) ...{//验证过程??? + // logger.info(" pkcs7 verifed success!"); + // }else...{ + // bresult = false; + // } + // } + // return bresult; + // } + // + // /** + // * 签名生成pkcs7结构数据 + // * @param signText 原始数据 + // * @param keystore 密钥库 + // * @param keyalias 密钥别名 + // * @param password 密钥库密码 + // * @return 签名后数据 + // * @throws Exception + // */ + // public byte[] sign(byte[] signText,KeyStore keystore,String + // keyalias,char[] password) throws Exception { + // CMSSignedDataStreamGenerator gen = new CMSSignedDataStreamGenerator(); + // Enumeration en = keystore.aliases(); + // //遍历密钥库的密钥别名 + // while(en.hasMoreElements()){ + // String alias = (String)en.nextElement(); + // logger.debug("keyalias:" + alias); + // if(!alias.equalsIgnoreCase(keyalias))continue; + // + // //根据别名从证书中获取私钥 + // PrivateKey prikey = (PrivateKey) keystore.getKey(keyalias,password); + // X509Certificate x509 = null; + // + // //获取该别名对应的证书链 + // Certificate[] certs = keystore.getCertificateChain(keyalias); + // if (certs[0] instanceof X509Certificate) {//user's certificate + // x509 = (X509Certificate) certs[0]; + // } + // if (certs[certs.length - 1] instanceof X509Certificate) {//root + // certificate + // x509 = (X509Certificate) certs[certs.length - 1]; + // } + // gen.addSigner(prikey, x509, CMSSignedDataStreamGenerator.DIGEST_SHA1, + // "BC"); + // CertStore certstore = CertStore.getInstance("Collection", new + // CollectionCertStoreParameters(Arrays.asList(certs)),"BC"); + // gen.addCertificatesAndCRLs(certstore); + // } + // //输出字节流 + // ByteArrayOutputStream bOut = new + // ByteArrayOutputStream();//"e:/JavaSignedData.txt" + // OutputStream sigOut = gen.open(bOut,true);//false,不含原始数据,减轻传输负担 + // sigOut.write(signText);//对原始数据进行签名 + // sigOut.close(); + // logger.info("pkcs7 signed success!"); + // byte[] signedData = bOut.toByteArray();//签名后数据 + // bOut.close(); + // byte[] signedDataBase64 = Base64.encode(signedData); + // logger.debug("签名后数据: " + new String(signedData,CHARSET) + " "); + // logger.debug("签名后数据Base64: " + new String(signedDataBase64,CHARSET) + + // " "); + // return signedData; + // } + // + + public static void main(String args[]) { + try { + // 加载证书 + KeyStore keyStore = loadKetStore("C:\\Users\\houduo.wk\\Desktop\\pfx证书制作工具\\output\\GUIZHOUD2D.pfx","12345678"); + String alias = getKeyAlias(keyStore); + System.out.println("证收别名:" + alias); + // 获取公钥 + PublicKey publicKey = getPublicKey(keyStore); + System.out.println("公钥:"+Base64.encode(publicKey.getEncoded())); + //公钥加密 + String en = encryptByPublicKey("test".getBytes(), publicKey); + System.out.println("公钥加密后en:" + en); + + // 获取私钥 + PrivateKey privateKey = getPrivateKey(keyStore, "12345678"); + System.out.println("私钥:" + Base64.encode(privateKey.getEncoded())); + + //私钥解密 + String de = decryptByPrivateKey(en, privateKey); + System.out.println("私钥解密后de:" + de); + +/* + // 签名 + String sign = createSignature(keyStore, "88888888", "test"); + System.out.println("sign:" + sign); + // 验签 + System.out + .println(verfySignature( + keyStore, + "test", + "2FFBD4D36985621E1FA6E4A70E318651F861F7D348B7034031B38781F62F9E2DE3BC2C3B6BB6DA5A96C795417BF55789A96B5B05548F9F2D99BE0AEA5396189CBB5F333825C32631D93125F9EB5470142F5E489D89EBCEF53AD0DAE8E1B2C6E561122A1174D07D78F972590F5665BBFC8FB8D182EDA4F2ECFE1A4A2FBE077603")); +*/ + +/* String publickey = "30819F300D06092A864886F70D010101050003818D0030818902818100D4823C41CA161F451F1A979ABE62A1140305BD882B597BC36D8460F81C4EE31CF2D3A96CC834CC05F7FF296B53EA607603919419172C6558D25558DC1ACDDE013F995B32B69CF869A8F8F6818B0953BE61552E8A32068FACE1A0227A4CB3E7AC615F053B553E53A6E6B083108DA5BC31D5DFCF59B13B2D4167F777F2E32A3C0F0203010001"; + String privatekey = "30820277020100300D06092A864886F70D0101010500048202613082025D02010002818100D4823C41CA161F451F1A979ABE62A1140305BD882B597BC36D8460F81C4EE31CF2D3A96CC834CC05F7FF296B53EA607603919419172C6558D25558DC1ACDDE013F995B32B69CF869A8F8F6818B0953BE61552E8A32068FACE1A0227A4CB3E7AC615F053B553E53A6E6B083108DA5BC31D5DFCF59B13B2D4167F777F2E32A3C0F02030100010281806FD1FBCD0E7E6783E2A30685298B12814A39DA0A6DED0F1FBD5FFBFA7242DC64DE2D9C281E8D11924E7598A0DE2E2505D448E529F2B4ACBB7929E9B11FF595CC125BBA927078B69AD062261D2936056251E259E9EDA1BB99EC3860D311C028613F616B26EAEDAA1177231B2A8E7E9C262FEDFD22912D03785A0666ED9FF60CC9024100F96E689B306286F81C99BBEA7D465375D19A26C5CC23852041ABBB198CD425455160AEE760E8F92224E9D60C4AF518E3EE2C39598735BBE1656B15CA54DC87F5024100DA1AE7EA66708D76A22EBC193350E1E3979A19E2CB126A9704E1F2D8FFB13E1EB32669AF9CAC15232E4255A4F3D60E19BD4C0CB6A1C405A469FB68EF96AFE57302406F0DDC5F3424BA091FDAC6D2F961E568F0A09CA0B66A1E2CA5708B862DB08AC3991EDDE0C0C219A23D232B9D1F868EC574D695D629A01FFD93C520D78BFF003D024100AAA6CEBAFAB82A179EC24E6EB15621C88000152CFC93464F2F84D30CB2D3ADB53B9B5CAA093E23B3C92821F6D4CAB171B64960D12D3540ECE9F7CA9D5C1BF8BD024100A4FE9F3CF0EAADC1C00C8B7986BAA7BA0CC0DC389EFD854761896C5AC924A77AD8EE84A6A62465504CBB77D5DCF813809A9160E23E5982280C4147337B60CAC0"; + + String cont = encodeWithPublic("test",hex2byte(publickey)); + System.out.println(decodeWithPrivate(cont, hex2byte(privatekey)));*/ + + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/supervision/edh/utils/LocalDateDeserializer.java b/src/main/java/com/supervision/edh/utils/LocalDateDeserializer.java new file mode 100644 index 0000000..9c217d2 --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/LocalDateDeserializer.java @@ -0,0 +1,23 @@ +package com.supervision.edh.utils; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +/** + * @author Jason + * @date 2025年06月06日 15:06:07 + */ +public class LocalDateDeserializer extends JsonDeserializer { + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd"); + + @Override + public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + String dateStr = p.getText(); + return LocalDate.parse(dateStr, FORMATTER); + } +} \ No newline at end of file diff --git a/src/main/java/com/supervision/edh/utils/RequestWrapper.java b/src/main/java/com/supervision/edh/utils/RequestWrapper.java new file mode 100644 index 0000000..c142647 --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/RequestWrapper.java @@ -0,0 +1,118 @@ +package com.supervision.edh.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.*; +import java.nio.charset.Charset; + +public class RequestWrapper extends HttpServletRequestWrapper { + private Logger logger = LoggerFactory.getLogger(RequestWrapper.class); + + /** + * 存储body数据的容器 + */ + private final byte[] body; + + public RequestWrapper(HttpServletRequest request) throws IOException { + super(request); + + // 将body数据存储起来 + String bodyStr = getBodyString(request); + body = bodyStr.getBytes(Charset.defaultCharset()); + } + + /** + * 获取请求Body + * + * @param request request + * @return String + */ + public String getBodyString(final ServletRequest request) { + try { + return inputStream2String(request.getInputStream()); + } catch (IOException e) { + logger.error("Get body string error.{}",e); + throw new RuntimeException(e); + } + } + + /** + * 获取请求Body + * + * @return String + */ + public String getBodyString() { + final InputStream inputStream = new ByteArrayInputStream(body); + + return inputStream2String(inputStream); + } + + /** + * 将inputStream里的数据读取出来并转换成字符串 + * + * @param inputStream inputStream + * @return String + */ + private String inputStream2String(InputStream inputStream) { + StringBuilder sb = new StringBuilder(); + BufferedReader reader = null; + + try { + reader = new BufferedReader(new InputStreamReader(inputStream, Charset.defaultCharset())); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + logger.error("close stream error.{}", e); + } + } + } + + return sb.toString(); + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + @Override + public ServletInputStream getInputStream() throws IOException { + + final ByteArrayInputStream inputStream = new ByteArrayInputStream(body); + + return new ServletInputStream() { + @Override + public int read() throws IOException { + return inputStream.read(); + } + + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) { + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/com/supervision/edh/utils/ResponseBuilder.java b/src/main/java/com/supervision/edh/utils/ResponseBuilder.java new file mode 100644 index 0000000..985398d --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/ResponseBuilder.java @@ -0,0 +1,70 @@ +package com.supervision.edh.utils; + + +import com.alibaba.fastjson.JSON; +import com.supervision.edh.enums.BuzStatusEnum; +import com.supervision.edh.enums.StatusEnum; + +import java.util.HashMap; +import java.util.Map; + +public class ResponseBuilder extends HashMap{ + + public void status(Integer status){ + this.put("status", status); + } + + public void message(String message){ + this.put("message", message); + } + + public void body(BuzStatusEnum buzStatusEnum){ + Map body = new HashMap<>(); + body.put("buz_status", buzStatusEnum.getBuzStatus()); + body.put("buz_message", buzStatusEnum.getBuzMessage()); + this.put("body", body); + } + + public void body(Integer buzStatus,String buzMsg){ + Map body = new HashMap<>(); + body.put("buz_status", buzStatus); + body.put("buz_message", buzMsg); + this.put("body", body); + } + + public static String fail(BuzStatusEnum buzStatusEnumg){ + ResponseBuilder builder = new ResponseBuilder(); + builder.status(StatusEnum.FAILED.getStatus()); + builder.message(StatusEnum.FAILED.getMsg()); + builder.body(buzStatusEnumg); + return JSON.toJSONString(builder.build()); + } + + public static String success(){ + ResponseBuilder builder = new ResponseBuilder(); + builder.status(StatusEnum.SUCCESS.getStatus()); + builder.message(StatusEnum.SUCCESS.getMsg()); + builder.body(BuzStatusEnum.SUCCESS); + return JSON.toJSONString(builder.build()); + } + + public static Map buzError(Integer buzStatus,String buzMessage){ + ResponseBuilder builder = new ResponseBuilder(); + builder.status(StatusEnum.BUZ_ERROR.getStatus()); + builder.message(StatusEnum.BUZ_ERROR.getMsg()); + builder.body(buzStatus,buzMessage); + return builder.build(); + } + + public Map build(){ + Map responseMap = new HashMap<>(); + responseMap.put("resp", this); + + return responseMap; + } + + public static void main(String[] args){ + System.out.println(JSON.toJSONString(fail(BuzStatusEnum.SIGN_CHECK_ERR))); + } +} + diff --git a/src/main/java/com/supervision/edh/utils/StreamUtil.java b/src/main/java/com/supervision/edh/utils/StreamUtil.java new file mode 100644 index 0000000..c719d52 --- /dev/null +++ b/src/main/java/com/supervision/edh/utils/StreamUtil.java @@ -0,0 +1,91 @@ +package com.supervision.edh.utils; + + +import org.apache.commons.codec.binary.Base64; +import org.springframework.util.StringUtils; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + +/** + * + * @author xuwangyu + * + */ +public class StreamUtil { + /** + * 将文件内容压缩并转为base64格式 + * @param fileName 文件名称 + * @param fileContent 文件内容 + * @return 压缩后Base64内容 + * @throws Exception + */ + public static String getStreamContent(String fileName ,String fileContent) throws Exception { + if(StringUtils.isEmpty(fileName) || StringUtils.isEmpty(fileContent)) { + throw new NullPointerException(); + } + ByteArrayOutputStream bos = new ByteArrayOutputStream(5 * 1024 * 1024); + ZipOutputStream zos = new ZipOutputStream(bos); + InputStream is = new ByteArrayInputStream(fileContent.getBytes()); + BufferedInputStream fileReader = new BufferedInputStream(is); + zos.putNextEntry(new ZipEntry(fileName)); + byte[] b = new byte[1024]; + int i; + while ((i = fileReader.read(b)) != -1) { + zos.write(b, 0, i); + } + is.close(); + zos.closeEntry(); + zos.flush(); + zos.close(); + fileReader.close(); + bos.close(); + byte[] bytes = bos.toByteArray(); + return Base64.encodeBase64String(bytes); + } + + /** + * 先base64解密 后解压缩 + * @param s + * @return + */ + public static String getUnStreamContent(String s){ + byte[] bytes = Base64.decodeBase64(s); + return new String(unZip(bytes)); + } + + /*** + * 解压Zip + * @param data + * @return + */ + public static byte[] unZip(byte[] data) { + byte[] b = null; + try { + ByteArrayInputStream bis = new ByteArrayInputStream(data); + ZipInputStream zip = new ZipInputStream(bis); + while (zip.getNextEntry() != null) { + byte[] buf = new byte[1024]; + int num ; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + while ((num = zip.read(buf, 0, buf.length)) != -1) { + bos.write(buf, 0, num); + } + b = bos.toByteArray(); + bos.flush(); + bos.close(); + } + zip.close(); + bis.close(); + } catch (Exception ex) { + ex.printStackTrace(); + } + return b; + } + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..bdaea0b --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,42 @@ +server: + port: 1788 + +# spring配置 +spring: + datasource: + driverClassName: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://47.109.202.121:3306/supervisionx_trace_data?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true + username: root + password: TCCT3.1415926 + + +mybatis-plus: + # 搜索指定包别名 + type-aliases-package: com.supervision.edh + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + #mapper-locations: classpath*:mapper/**/*Mapper.xml + mapper-locations: classpath:mapper/*.xml + # 加载全局的配置文件 + config-location: classpath:mybatis/mybatis-config.xml + #逻辑删除配置 + global-config: + db-config: + logic-not-delete-value: 0 + logic-delete-value: 1 + logic-delete-field: del_flag + +logging: + level: + root: INFO + org.springframework: WARN + com.supervision.edh: DEBUG + mybatis: DEBUG + com.baomidou.mybatisplus: DEBUG + +cert: + #本地 + path: D:\ynyp\药品追溯\d2d\edh.pfx + #服务器 + #path: d2d\yunnan.pfx + password: YnYp123456 + algorithm: RSA diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..77c5090 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/info.log + + + + ${log.path}/info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/error.log + + + + ${log.path}/error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/EdhDomesticDrugBaseInfoMapper.xml b/src/main/resources/mapper/EdhDomesticDrugBaseInfoMapper.xml new file mode 100644 index 0000000..4e17534 --- /dev/null +++ b/src/main/resources/mapper/EdhDomesticDrugBaseInfoMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/resources/mapper/EdhDrugDeliveryNoteApplyInfoMapper.xml b/src/main/resources/mapper/EdhDrugDeliveryNoteApplyInfoMapper.xml new file mode 100644 index 0000000..aa1cd7f --- /dev/null +++ b/src/main/resources/mapper/EdhDrugDeliveryNoteApplyInfoMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/resources/mapper/EdhDrugInvoiceApplyInfoMapper.xml b/src/main/resources/mapper/EdhDrugInvoiceApplyInfoMapper.xml new file mode 100644 index 0000000..39d6bd9 --- /dev/null +++ b/src/main/resources/mapper/EdhDrugInvoiceApplyInfoMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/resources/mapper/EdhDrugOperateLicenseBaseInfoMapper.xml b/src/main/resources/mapper/EdhDrugOperateLicenseBaseInfoMapper.xml new file mode 100644 index 0000000..11d987a --- /dev/null +++ b/src/main/resources/mapper/EdhDrugOperateLicenseBaseInfoMapper.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/src/main/resources/mapper/EdhDrugOperatorsBaseInfoMapper.xml b/src/main/resources/mapper/EdhDrugOperatorsBaseInfoMapper.xml new file mode 100644 index 0000000..1b8e3bb --- /dev/null +++ b/src/main/resources/mapper/EdhDrugOperatorsBaseInfoMapper.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/src/main/resources/mapper/EdhReceiveDataLogMapper.xml b/src/main/resources/mapper/EdhReceiveDataLogMapper.xml new file mode 100644 index 0000000..e5917b0 --- /dev/null +++ b/src/main/resources/mapper/EdhReceiveDataLogMapper.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/EdhWarehouseStockApplyInfoMapper.xml b/src/main/resources/mapper/EdhWarehouseStockApplyInfoMapper.xml new file mode 100644 index 0000000..4567882 --- /dev/null +++ b/src/main/resources/mapper/EdhWarehouseStockApplyInfoMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/resources/mapper/EdhWhTempHumidityApplyInfoMapper.xml b/src/main/resources/mapper/EdhWhTempHumidityApplyInfoMapper.xml new file mode 100644 index 0000000..ee44ac6 --- /dev/null +++ b/src/main/resources/mapper/EdhWhTempHumidityApplyInfoMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/resources/mybatis/mybatis-config.xml b/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..ac47c03 --- /dev/null +++ b/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/com/supervision/edh/SupervisionEdhApplicationTests.java b/src/test/java/com/supervision/edh/SupervisionEdhApplicationTests.java new file mode 100644 index 0000000..da875e9 --- /dev/null +++ b/src/test/java/com/supervision/edh/SupervisionEdhApplicationTests.java @@ -0,0 +1,32 @@ +package com.supervision.edh; + +import com.supervision.edh.utils.CertManager; +import com.supervision.edh.utils.StreamUtil; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; + +@SpringBootTest +class SupervisionEdhApplicationTests { + + + @Autowired + private CertManager certManager; + + @Test + void testCode() throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, InvalidKeySpecException, BadPaddingException, IOException, InvalidKeyException { + String privateKey="MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6qV2TEiVq3zo0V3zbD4EQJetoeG8WMJxrwzymx6LflOnRTNmO0OJWpNOcKTWWRu7RQwxx4OweZBVr+jH3dmP/kLTgF/nfrdwqjtdUwawbSK+v3TQs3h5Zo8oir6p5h288TYaY48UfAyFxGpCdwcvwp0RWkwWwaEiS9tksyuIuQ/HsFfCseSKrM0VLB/U4VGWK0uwlO7LgSrkBDABoOnzSFTsGZFjYyrz079bIWSIFA66VX/DgrKs0wtC5nDbfoc2Wg7U2UvlBJR6UgT/eS6FKC+JEpiI1C8SL6hWAeyc3WAnIjKNVjyn14SOsAI/701HvHfhPbk/BUDWKk+RMobInAgMBAAECggEBAK3ZtpSXDxCFzmEXpuskepF+r82CdfxV1CouEdxIDbNtr4RHrk1s0ZHfPFOysf1AHYf7iai600/O6YDC6yzPMH3D2iLpUcn51RgyJ+4B3/kdbrw+Ky0qx1u3yDkcIYvFD1472oOliF/E+62rD0xPRlHiiCyWDHNr/UQb8tPcNmLdPWgFAv6I3XitQEist7dwjCjSeBcvxm2gr9x98bqfw4dxrjtfTidzxMaEJvyAGYYHQzOZZCKTZEAmJMpz69F8k8A45cCKWYHqjrvuu2rnjumF4nMHX6OntYtJl1jbOLCNC63XSdSRep4+H80DfstnKpnGRZp4HY+ivY//vME5giECgYEA9lCTWehgN3v5oRjKvNpyEkidzLHISO+CQ1PeVe3wwmAy068mkAA896sD+iDD0EJsgr3Cg5uxUbvSj53tvbuW0H+ggXKqIuvVl1HvgD+AJtSr3JXcLcYtkFaTUwW5W+dcQz+1lOLccMAfOc4qMUR8e7poWAd/NCOKGOCQJ5E9wXcCgYEAwgBQ+S9sZIQJx3frPekcze21IjqXwb24Wj4VUY/I2mtad8KefQ+FbYGdQmL/bsP73F2jH5q35+doaN14+Q+9+xouaf3L//djmSqhygxWzQnu2sLmaatAl1FWdqQZds/XBJtXEXwxMJT4vfZ3vZxmq1J0QqmoBM5TtuniZlwvQNECgYBRl11IIfaFSpblKz41ErNIpS9IV/e9WUEwJj72/euLp6wOfO1sM/f+HnMhzuquOOKS6GLfj5pMNchI9IqFF/ecNzqmxqHfEXneNzD7rY04z6fiWO3nZ8c+Eb+Zd8Lv05K3YAo5OHDHFI0Da+yEB2io35Wi21Dip4ceOHzn7m+jfwKBgQCmdbEE7w0ZfjYJ4jqGB8SAact3EEFwqsJJJGYUcsRLrbuVcPeepTe+i22NLfawaxdrsSirkIzmPifXetk3E6vWjlNu/KcS/YmHPg5OmKHOEwzQxlUALEIi1FbVO97hlFqRiFyAE0j9v4VjMdzyZAWwUPKS1JHndcZc93gcjlK5UQKBgBJ28+ZVBoG/L/NeNqXXGxMgtQ7gphkXZ7RaoY4Ut1L2qa09E5htUkqwyX3HjuO/YMMVADvbAlaI1FDa/mS1qwYSSWji40x8vU39v3jE06avKWEiy9XPv9iozyDYvcPxRg5FjvjgVxeqLTWWLN79Jy+ZfrNZuNezvPspv7c1Y043"; + String de = certManager.keyDecrypt(privateKey, "EtI59GVaEMZJ17DvHVoD5iG6h+dH7LS9NEH3hq9ItP7NW6xgez70lUJWJNO4I7CRS0O66WFRvyAVYPpsi0VY647aFy19v7yr/62vm00EuKhhiguw7v2cnh5p0vgRQT5BGW4zMmxl/2nGXuVQKjdr8NX/y+KE6bM5bRKnz5oLRK1JR8tJ9ESMYRftAvysSB5SyeRK3FqBDj43QU5S5jS4LI6iCGuEVYBg1V6dEfACLKPktQu0AHE6OQbZPS1nI8EVj0pcXDpTLBnGZs/NVyHY6nwacEBHnATbXPbrJN1wk/J0ZlOcv16oCVbZx1l8ef4vlvvz29t8y9JjCmLOXgGHCAR/ip7qdDaQBGe2g/R5JAN3NEYwv5gOQ7zghAgJL2OWeMT+0VkIeXWkrML4M1pg4L4U1+DCW/XUNGhodMK78ilBX7xQApxM1ld/HqV/xAq7leLdeafw+BxZxvcsgoR4L3GxXKyei9zaNwkqPjgyvtfWC5OIXasDJcFmK2P4Ud6hXxwrcqp7/OKiPniH/QxOuPoCcalrAmYfdAMxjP8Vum9k2sMinp6JuHoVa4YR+KJ0Vsk5QONQMlzS1ac5gtPa+twBB+9J2UE6gaaRbNye+/975BDKHDVZtWOmA44SG+mQl6+UKnURCdNhVgeZtEeZ+lR44oowrS+nRhMoPX6xwl2g7XWcf75JAPIrY4EXkyOaqD7cYTwiRkqZinAzI6bdEn1zHvzx/tWcabBQOrNaCq4yk5R4FWsYMs6OfTEMGdjDXS3FVJBSqumGqW3X/YTGfQQ5/4aOeeUSm9mysOYTKVZAbko3pwoyJim6c1lPlrFKOkkiuu+B6XNTVApDuVZV7Bk5OLX1Lv8Fk4jByUE/p7+Bs8ssp2nzD80YOjqJFlWIqdvLHyoky3TibsJGUXYnEbCJACD2q3NF/GL3akocJ8EdBKyd0Cjv7qAIpYp8kewgUrfopVG46T29xdUu8mre/LYhE+roDcSKwM/p0mwqIjXGpHka0FLeuuARWEevcTeDCoHBLiOPz77C7F+Rp+R3QTubcxjkGzxVb3Kq7gMy38RB4s3H+ue8qns5pydqg4QHMy6OBWdZh/jVOdZ5byl2pTanjA3U+TcW93tlRebJT9ZpOJB1w7aBupUPqtw1ZOAUOmc2BT+00Bzbpa8ZkdOpUXhTiBEpcto1JZrtTModwh+TO/By3QF5jxNkWApw+QBFLbp16PJoyjzPI5dXFikoJN7FZzUuh3sebWHPA/A+VyN6uKWRfPMx1A5UWqvwruMAAIcmMrlhtPTlpT2WSGunpJFXlnR/4sSUrQW6SKahewFLO38qBDVEp9jfqpBD9UiwJnPPKwzXAjHXKDjvnNzTVD6Zh9skM4cLCgRNXfBqS9z70PzLkea/MzNjYKUdcSKG74MxbMlABPQHoov6J6aehQYCBdpkk4kXgeSTqDapgtipUScSqfvTkLPi4bfHkXD3nIgY0Wr6opknan1CGyYayt0Veuggv7TLscfSjKlhIkLG/gphKr6ld+S+hdzOb994if6X+QRtSFRDVrQYYyEz8hu+ajEU024L4GC6OvKpR5UfaY6bKAdFsr54PGudrcmuKo3djqzdOywmlEaXmMvPM6M5SqhSsb5+H5Hew+p6+uQ+VRoQLqpCioN+7J509sOrUmX0v3cDLqZKeLyVhimcKNByFpKwyvlo2sXiT4OCl9Y="); + String data = StreamUtil.getUnStreamContent(de); + System.out.println("解析后的数据:"+data); + } + +}