From 796de974a52b45fd3cea4700595ed13d3bc0775b Mon Sep 17 00:00:00 2001 From: luotaiqian <1147642922@qq.com> Date: Mon, 3 Aug 2026 09:25:36 +0800 Subject: [PATCH] import --- ...alter_personnel_title_and_level_fields.sql | 57 +++ pom.xml | 7 + .../adapter/web/OrgPersonnelController.java | 9 + safety-eval-app/pom.xml | 6 + .../app/executor/OrgPersonnelExecutor.java | 11 + .../app/support/ImportEducationEnum.java | 70 ++++ .../app/support/ImportGenderEnum.java | 50 +++ .../support/ImportRegisterEngineerEnum.java | 44 ++ .../support/OrgPersonnelExcelImporter.java | 379 ++++++++++++++++++ .../app/support/OrgPersonnelImportRow.java | 82 ++++ .../client/api/OrgPersonnelApi.java | 10 + .../client/co/OrgPersonnelImportErrorCO.java | 35 ++ .../client/co/OrgPersonnelImportResultCO.java | 25 ++ .../request/BasicDisciplineMajorPageQry.java | 6 - .../domain/exception/ErrorCode.java | 5 + .../domain/gateway/OrgDepartmentGateway.java | 6 + .../domain/gateway/OrgPersonnelGateway.java | 7 + .../domain/gateway/OrgPositionGateway.java | 8 + .../gatewayimpl/OrgDepartmentGatewayImpl.java | 17 + .../gatewayimpl/OrgPersonnelGatewayImpl.java | 16 + .../gatewayimpl/OrgPositionGatewayImpl.java | 22 + .../BasicDisciplineMajorQueryServiceImpl.java | 3 +- .../BasicDisciplineMajorRepositoryImpl.java | 37 +- 23 files changed, 886 insertions(+), 26 deletions(-) create mode 100644 safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportEducationEnum.java create mode 100644 safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportGenderEnum.java create mode 100644 safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportRegisterEngineerEnum.java create mode 100644 safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelExcelImporter.java create mode 100644 safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelImportRow.java create mode 100644 safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/OrgPersonnelImportErrorCO.java create mode 100644 safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/OrgPersonnelImportResultCO.java diff --git a/docs/sql/alter_personnel_title_and_level_fields.sql b/docs/sql/alter_personnel_title_and_level_fields.sql index 1956a6d..9a512cc 100644 --- a/docs/sql/alter_personnel_title_and_level_fields.sql +++ b/docs/sql/alter_personnel_title_and_level_fields.sql @@ -30,3 +30,60 @@ ALTER TABLE `qual_filing_personnel` ALTER TABLE `qual_filing_personnel_change` DROP COLUMN `person_type_name`, CHANGE COLUMN `title_code` `title_code_arr` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '职称(多个逗号分隔)'; + + +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (142, 'COAL_MINING,METAL_NONMETAL_MINING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '矿业机械', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (172, 'ONSHORE_OIL_GAS', 'OIL_PRODUCTION', NULL, '钻井工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (173, 'ONSHORE_OIL_GAS', 'OIL_PRODUCTION', NULL, '采油工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (174, 'ONSHORE_OIL_GAS', 'OIL_PRODUCTION', NULL, '油藏工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (175, 'ONSHORE_OIL_GAS', 'OIL_PRODUCTION', NULL, '石油工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (176, 'ONSHORE_OIL_GAS', 'OIL_PRODUCTION', NULL, '石油钻井', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (180, 'ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE', 'OIL_GAS_STORAGE_TRANSPORT,STORAGE_AND_TRANSPORT', NULL, '石油储运', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (181, 'ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE', 'OIL_GAS_STORAGE_TRANSPORT,STORAGE_AND_TRANSPORT', NULL, '石油天然气储运工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (182, 'ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE', 'OIL_GAS_STORAGE_TRANSPORT,STORAGE_AND_TRANSPORT', NULL, '油气储运工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (183, 'ONSHORE_OIL_GAS_PIPELINE', 'OIL_GAS_STORAGE_TRANSPORT', NULL, '线路工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (184, 'ONSHORE_OIL_GAS_PIPELINE', 'OIL_GAS_STORAGE_TRANSPORT', NULL, '储运工艺', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (185, 'ONSHORE_OIL_GAS_PIPELINE', 'OIL_GAS_STORAGE_TRANSPORT', NULL, '设备与控制', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (192, 'ONSHORE_OIL_GAS_PIPELINE', 'AUTOMATION_INSTRUMENT', NULL, '自动化仪表和设备', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (193, 'ONSHORE_OIL_GAS_PIPELINE', 'AUTOMATION_INSTRUMENT', NULL, '智能监控系统', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (195, 'ONSHORE_OIL_GAS_PIPELINE', 'ELECTRICAL', NULL, '继电保护与自动远动技术', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (211, 'ONSHORE_OIL_GAS_PIPELINE', 'ANTICORROSION', NULL, '腐蚀与防护', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (230, 'ONSHORE_OIL_GAS,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'CHEMICAL_MECHANICAL,MECHANICAL', NULL, '高分子材料加工机械', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (232, 'ONSHORE_OIL_GAS,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'CHEMICAL_MECHANICAL,MECHANICAL', NULL, '化工设备与机械', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (234, 'ONSHORE_OIL_GAS,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'CHEMICAL_MECHANICAL,MECHANICAL', NULL, '化工机械', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (245, 'ONSHORE_OIL_GAS,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电力系统及其自动化', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (258, 'ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'AUTOMATION,AUTOMATION_INSTRUMENT', NULL, '计算机及应用', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (259, 'COAL_MINING,METAL_NONMETAL_MINING,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'AUTOMATION,AUTOMATION_INSTRUMENT,ELECTRICAL,PROCESS_EQUIPMENT_CONTROL', NULL, '自动控制', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (291, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '高压电技术及设备', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (292, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电气绝缘与电缆', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (296, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '高电压与绝缘技术', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (310, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'SAFETY,VENTILATION', NULL, '安全工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (311, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '机械制造工艺与设备', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (312, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '机械制造工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (313, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '机械设计及制造', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (318, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'CHEMICAL_MECHANICAL,MECHANICAL', NULL, '设备工程与管理', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (319, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '机械设计制造及其自动化', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (321, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '机械工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (322, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '机械电子工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (323, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '工业设计', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (324, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'CHEMICAL_MECHANICAL,MECHANICAL', NULL, '过程装备与控制工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (325, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '机械工程及自动化', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (326, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '工程机械', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (327, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '制造自动化与测控技术', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (328, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS', 'MECHANICAL', NULL, '制造工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (329, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电气技术', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (330, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电机', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (331, 'FIREWORKS_FIRECRACKERS,METAL_SMELTING,ONSHORE_OIL_GAS,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电器', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (332, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电机电器及其控制', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (333, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'AUTOMATION,AUTOMATION_INSTRUMENT,ELECTRICAL', NULL, '工业自动化', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (334, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'AUTOMATION,ELECTRICAL', NULL, '工业电气自动化', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (336, 'FIREWORKS_FIRECRACKERS,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'AUTOMATION,AUTOMATION_INSTRUMENT,ELECTRICAL', NULL, '生产过程自动化', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (337, 'FIREWORKS_FIRECRACKERS,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电力牵引与传动控制', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (338, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE', 'ELECTRICAL', NULL, '电气工程及其自动化', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (339, 'FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'AUTOMATION,AUTOMATION_INSTRUMENT,ELECTRICAL', NULL, '自动化', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (340, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电气工程与自动化', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (341, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电气信息工程', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (342, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电力工程与管理', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (343, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电气技术教育', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (344, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电机电器智能化', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); +INSERT INTO `safety-eval-service`.`basic_discipline_major` (`id`, `industry_code`, `professional_capability_code`, `professional_code`, `professional_name`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `org_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`) VALUES (345, 'COAL_MINING,FIREWORKS_FIRECRACKERS,METAL_NONMETAL_MINING,METAL_SMELTING,ONSHORE_OIL_GAS,ONSHORE_OIL_GAS_PIPELINE,PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL', 'ELECTRICAL', NULL, '电气工程与智能控制', 'false', NULL, NULL, NULL, NULL, NULL, 0, '2026-07-14 11:41:48', '2026-07-14 11:41:48', NULL, NULL, 'prod'); \ No newline at end of file diff --git a/pom.xml b/pom.xml index 6c2f662..f7a55ef 100644 --- a/pom.xml +++ b/pom.xml @@ -225,6 +225,13 @@ aliyun-sdk-oss ${aliyun-oss.version} + + + + com.alibaba + easyexcel + ${easyexcel.version} + diff --git a/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/OrgPersonnelController.java b/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/OrgPersonnelController.java index 43e4907..267a138 100644 --- a/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/OrgPersonnelController.java +++ b/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/OrgPersonnelController.java @@ -5,10 +5,12 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.qinan.safetyeval.client.api.OrgPersonnelApi; import org.qinan.safetyeval.client.co.OrgPersonnelCO; +import org.qinan.safetyeval.client.co.OrgPersonnelImportResultCO; import org.qinan.safetyeval.client.dto.*; import org.qinan.safetyeval.infrastructure.dataobject.base.Req; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; @@ -60,4 +62,11 @@ public class OrgPersonnelController { public SingleResponse resetPassword(@ApiParam("主键ID") @RequestBody Req req) { return orgPersonnelApi.resetPassword(req.getData()); } + + @ApiOperation("导入人员信息") + @PostMapping("/import") + public SingleResponse importPersonnel( + @ApiParam("导入文件") @RequestParam("file") MultipartFile file) { + return orgPersonnelApi.importPersonnel(file); + } } diff --git a/safety-eval-app/pom.xml b/safety-eval-app/pom.xml index ec3e0cb..66f2c5f 100644 --- a/safety-eval-app/pom.xml +++ b/safety-eval-app/pom.xml @@ -40,6 +40,12 @@ lombok provided + + + + com.alibaba + easyexcel + diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/OrgPersonnelExecutor.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/OrgPersonnelExecutor.java index 172961e..d1266b9 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/OrgPersonnelExecutor.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/OrgPersonnelExecutor.java @@ -7,9 +7,11 @@ import com.zcloud.gbscommon.utils.MD5; import com.zcloud.gbscommon.utils.Sm2Util; import org.qinan.safetyeval.app.convertor.OrgPersonnelConvertor; import org.qinan.safetyeval.app.support.OrgPersonnelChangeRecorder; +import org.qinan.safetyeval.app.support.OrgPersonnelExcelImporter; import org.qinan.safetyeval.app.support.OrgPersonnelViewEnricher; import org.qinan.safetyeval.client.api.OrgPersonnelApi; import org.qinan.safetyeval.client.co.OrgPersonnelCO; +import org.qinan.safetyeval.client.co.OrgPersonnelImportResultCO; import org.qinan.safetyeval.client.dto.*; import org.qinan.safetyeval.domain.entity.OrgPersonnelEntity; import org.qinan.safetyeval.domain.entity.OrgPositionEntity; @@ -32,6 +34,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; import java.math.BigDecimal; import java.util.Collections; @@ -71,6 +74,9 @@ public class OrgPersonnelExecutor implements OrgPersonnelApi { @Autowired(required = false) private FaceCompareGateway faceCompareGateway; + @Autowired + private OrgPersonnelExcelImporter orgPersonnelExcelImporter; + @Value("${def.password:a123456}") private String defPassword; @Value("${def.publicKey:0402df2195296d4062ac85ad766994d73e871b887e18efb9a9a06b4cebc72372869b7da6c347c129dee2b46a0f279ff066b01c76208c2a052af75977c722a2ccee}") @@ -259,4 +265,9 @@ public class OrgPersonnelExecutor implements OrgPersonnelApi { BigDecimal score = faceCompareGateway.compare(entity.getOriginFaceUrl(), cmd.getImageBase64()); return SingleResponse.success(score); } + + @Override + public SingleResponse importPersonnel(MultipartFile file) { + return SingleResponse.success(orgPersonnelExcelImporter.importPersonnel(file)); + } } diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportEducationEnum.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportEducationEnum.java new file mode 100644 index 0000000..8bc4bde --- /dev/null +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportEducationEnum.java @@ -0,0 +1,70 @@ +package org.qinan.safetyeval.app.support; + +import org.springframework.util.StringUtils; + +/** + * 导入学历枚举转换。 + *

+ * 学历为前端字典,此处提供常见学历名称的兜底映射;如与实际字典不一致可在此调整。 + *

+ * + * @author safety-eval + */ +public enum ImportEducationEnum { + + DOCTOR(new String[]{"博士"}, "06", "博士研究生", "04", "博士"), + MASTER(new String[]{"硕士", "研究生"}, "05", "硕士研究生", "03", "硕士"), + BACHELOR(new String[]{"本科"}, "04", "大学本科", "02", "本科"), + COLLEGE(new String[]{"专科", "大专", "高职"}, "03", "大学专科", "01", "专科"), + SECONDARY(new String[]{"中专", "中技", "技校"}, "02", "中专", "00", "中专"), + HIGH_SCHOOL(new String[]{"高中"}, "01", "高中", "00", "高中"); + + private final String[] keywords; + private final String educationCode; + private final String educationName; + private final String educationLevelCode; + private final String educationLevelName; + + ImportEducationEnum(String[] keywords, String educationCode, String educationName, + String educationLevelCode, String educationLevelName) { + this.keywords = keywords; + this.educationCode = educationCode; + this.educationName = educationName; + this.educationLevelCode = educationLevelCode; + this.educationLevelName = educationLevelName; + } + + public String getEducationCode() { + return educationCode; + } + + public String getEducationName() { + return educationName; + } + + public String getEducationLevelCode() { + return educationLevelCode; + } + + public String getEducationLevelName() { + return educationLevelName; + } + + /** + * 按包含关键字匹配学历枚举,无法识别返回 null。 + */ + public static ImportEducationEnum match(String text) { + if (!StringUtils.hasText(text)) { + return null; + } + String trimmed = text.trim(); + for (ImportEducationEnum e : values()) { + for (String kw : e.keywords) { + if (trimmed.contains(kw)) { + return e; + } + } + } + return null; + } +} diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportGenderEnum.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportGenderEnum.java new file mode 100644 index 0000000..c5ea7d0 --- /dev/null +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportGenderEnum.java @@ -0,0 +1,50 @@ +package org.qinan.safetyeval.app.support; + +import org.springframework.util.StringUtils; + +/** + * 导入性别枚举转换(性别编码 1男 2女)。 + * + * @author safety-eval + */ +public enum ImportGenderEnum { + + MALE(1, "男", new String[]{"男", "男性"}), + FEMALE(2, "女", new String[]{"女", "女性"}); + + private final Integer code; + private final String name; + private final String[] aliases; + + ImportGenderEnum(Integer code, String name, String[] aliases) { + this.code = code; + this.name = name; + this.aliases = aliases; + } + + public Integer getCode() { + return code; + } + + public String getName() { + return name; + } + + /** + * 按文本匹配性别枚举,无法识别返回 null。 + */ + public static ImportGenderEnum fromText(String text) { + if (!StringUtils.hasText(text)) { + return null; + } + String trimmed = text.trim(); + for (ImportGenderEnum e : values()) { + for (String alias : e.aliases) { + if (alias.equals(trimmed)) { + return e; + } + } + } + return null; + } +} diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportRegisterEngineerEnum.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportRegisterEngineerEnum.java new file mode 100644 index 0000000..bb08d96 --- /dev/null +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/ImportRegisterEngineerEnum.java @@ -0,0 +1,44 @@ +package org.qinan.safetyeval.app.support; + +import org.springframework.util.StringUtils; + +/** + * 导入“是否注册安全工程师”枚举转换(1是 2否)。 + * + * @author safety-eval + */ +public enum ImportRegisterEngineerEnum { + + YES(1, new String[]{"是", "Y", "y", "yes", "true"}), + NO(2, new String[]{"否", "N", "n", "no", "false"}); + + private final Integer code; + private final String[] aliases; + + ImportRegisterEngineerEnum(Integer code, String[] aliases) { + this.code = code; + this.aliases = aliases; + } + + public Integer getCode() { + return code; + } + + /** + * 按文本匹配枚举,无法识别返回 null。 + */ + public static ImportRegisterEngineerEnum fromText(String text) { + if (!StringUtils.hasText(text)) { + return null; + } + String trimmed = text.trim(); + for (ImportRegisterEngineerEnum e : values()) { + for (String alias : e.aliases) { + if (alias.equalsIgnoreCase(trimmed)) { + return e; + } + } + } + return null; + } +} diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelExcelImporter.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelExcelImporter.java new file mode 100644 index 0000000..08f8b2d --- /dev/null +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelExcelImporter.java @@ -0,0 +1,379 @@ +package org.qinan.safetyeval.app.support; + +import com.alibaba.excel.EasyExcel; +import org.qinan.safetyeval.client.co.OrgPersonnelImportErrorCO; +import org.qinan.safetyeval.client.co.OrgPersonnelImportResultCO; +import org.qinan.safetyeval.domain.entity.OrgDepartmentEntity; +import org.qinan.safetyeval.domain.entity.OrgPersonnelEntity; +import org.qinan.safetyeval.domain.entity.OrgPositionEntity; +import org.qinan.safetyeval.domain.entity.TitleCodeCo; +import org.qinan.safetyeval.domain.exception.BizException; +import org.qinan.safetyeval.domain.exception.ErrorCode; +import org.qinan.safetyeval.domain.gateway.OrgDepartmentGateway; +import org.qinan.safetyeval.domain.gateway.OrgPersonnelGateway; +import org.qinan.safetyeval.domain.gateway.OrgPositionGateway; +import org.qinan.safetyeval.domain.service.OrgPersonnelDomainService; +import org.qinan.safetyeval.infrastructure.adapter.ThreadLocalUserInfoAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 基于 EasyExcel 的人员信息批量导入器。 + *

+ * 解析 Excel -> 批量校验部门/岗位名称并回填ID -> 校验账号重复并收集异常 -> 逐行落库。 + *

+ * + * @author safety-eval + */ +@Component +public class OrgPersonnelExcelImporter { + + private static final Logger LOGGER = LoggerFactory.getLogger(OrgPersonnelExcelImporter.class); + + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + @Resource + private OrgDepartmentGateway orgDepartmentGateway; + + @Resource + private OrgPositionGateway orgPositionGateway; + + @Resource + private OrgPersonnelGateway orgPersonnelGateway; + + @Resource + private OrgPersonnelDomainService orgPersonnelDomainService; + + public OrgPersonnelImportResultCO importPersonnel(MultipartFile file) { + if (file == null || file.isEmpty()) { + throw new BizException(ErrorCode.FILE_UPLOAD_EMPTY); + } + + List errors = new ArrayList<>(); + List rows = parseRows(file, errors); + if (rows.isEmpty()) { + throw new BizException(ErrorCode.ORG_PERSONNEL_IMPORT_EMPTY); + } + + Long orgId = ThreadLocalUserInfoAdapter.getOrgId(); + + OrgPersonnelImportResultCO result = new OrgPersonnelImportResultCO(); + result.setSuccessCount(0); + result.setFailCount(0); + + // 1. 批量校验并回填部门ID + validateAndFillDept(rows, orgId); + + // 2. 批量校验并回填岗位ID + validateAndFillPosition(rows, orgId); + + // 3. 批量查询库中已存在的账号(未删除) + Set existingAccounts = batchQueryExistingAccounts(rows, orgId); + + // 4. 逐行转换、落库 + int successCount = 0; + + for (OrgPersonnelImportRow row : rows) { + String account = trim(row.getAccount()); + + // 账号在库中已存在 -> 跳过该行,记录异常 + if (existingAccounts.contains(account)) { + errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), account, trim(row.getUserName()), + "账号已存在,跳过该行")); + continue; + } + + try { + OrgPersonnelEntity entity = buildEntity(row, orgId, errors); + if (entity == null) { + // 行内枚举/数据校验未通过,已记录异常 + continue; + } + orgPersonnelDomainService.add(entity); + successCount++; + } catch (Exception ex) { + LOGGER.warn("导入人员落库失败, rowIndex={}, account={}", row.getRowIndex(), account, ex); + errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), account, trim(row.getUserName()), + "保存失败:" + ex.getMessage())); + } + } + + result.setSuccessCount(successCount); + result.setFailCount(errors.size()); + result.setErrors(errors); + return result; + } + + /** + * 解析 Excel,过滤空行,并回填物理行号(从1开始,含表头,首条数据为第2行)。 + *

+ * 文件内手机号重复的行在此剔除,并生成提示放入 errors(空账号不参与去重)。 + *

+ */ + private List parseRows(MultipartFile file, List errors) { + List raw; + try { + raw = EasyExcel.read(file.getInputStream()) + .head(OrgPersonnelImportRow.class) + .sheet() + .headRowNumber(1) + .doReadSync(); + } catch (Exception ex) { + LOGGER.error("解析人员导入Excel失败", ex); + throw new BizException(ErrorCode.ORG_PERSONNEL_IMPORT_PARSE_ERROR); + } + if (raw == null || raw.isEmpty()) { + return new ArrayList<>(); + } + List rows = new ArrayList<>(raw.size()); + Set seenAccounts = new HashSet<>(); + for (int i = 0; i < raw.size(); i++) { + OrgPersonnelImportRow row = raw.get(i); + if (row == null) { + continue; + } + // 空行:账号与姓名均为空 + if (!StringUtils.hasText(trim(row.getAccount())) && !StringUtils.hasText(trim(row.getUserName()))) { + continue; + } + row.setRowIndex(i + 2); + + // 文件内手机号重复:剔除该行并记录提示(空账号不参与去重) + String account = trim(row.getAccount()); + if (StringUtils.hasText(account) && !seenAccounts.add(account)) { + errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), account, trim(row.getUserName()), + "账号在文件内重复,已剔除该行")); + continue; + } + rows.add(row); + } + return rows; + } + + /** + * 批量校验部门名称是否在当前机构下存在,校验通过的同时回填 deptId;不存在则抛出异常。 + */ + private void validateAndFillDept(List rows, Long orgId) { + Set deptNames = rows.stream() + .map(r -> trim(r.getDeptName())) + .filter(StringUtils::hasText) + .collect(Collectors.toCollection(LinkedHashSet::new)); + + Map deptMap = new HashMap<>(); + if (!deptNames.isEmpty()) { + for (OrgDepartmentEntity dept : orgDepartmentGateway.listByOrgIdAndNames(orgId, deptNames)) { + if (dept.getDeptName() != null) { + deptMap.putIfAbsent(dept.getDeptName().trim(), dept); + } + } + } + + // 收集所有缺失部门(保留出现顺序,附带首个出现行号) + Map missingDeptRows = new LinkedHashMap<>(); + for (OrgPersonnelImportRow row : rows) { + String name = trim(row.getDeptName()); + if (!StringUtils.hasText(name)) { + missingDeptRows.putIfAbsent("(空)", row.getRowIndex()); + continue; + } + if (!deptMap.containsKey(name)) { + missingDeptRows.putIfAbsent(name, row.getRowIndex()); + } + } + if (!missingDeptRows.isEmpty()) { + String detail = missingDeptRows.entrySet().stream() + .map(e -> e.getKey() + "(第" + e.getValue() + "行)") + .collect(Collectors.joining("; ")); + throw new BizException(ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_NOT_FOUND, + ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_NOT_FOUND.getMessage() + ":" + detail); + } + + // 校验通过,回填部门ID + for (OrgPersonnelImportRow row : rows) { + row.setDeptId(deptMap.get(trim(row.getDeptName())).getId()); + } + } + + /** + * 批量校验岗位名称在所属部门下是否存在(dept_id + org_id),校验通过的同时回填 postId;不存在则抛出异常。 + */ + private void validateAndFillPosition(List rows, Long orgId) { + Set deptIds = new HashSet<>(); + Set positionNames = new HashSet<>(); + for (OrgPersonnelImportRow row : rows) { + if (row.getDeptId() != null) { + deptIds.add(row.getDeptId()); + } + String posName = trim(row.getPositionName()); + if (StringUtils.hasText(posName)) { + positionNames.add(posName); + } + } + + // key: deptId|positionName -> position + Map positionMap = new HashMap<>(); + if (!deptIds.isEmpty() || !positionNames.isEmpty()) { + for (OrgPositionEntity pos : orgPositionGateway.listByOrgIdAndDeptIdsAndNames(orgId, deptIds, positionNames)) { + String key = pos.getDeptId() + "|" + (pos.getPositionName() == null ? "" : pos.getPositionName().trim()); + positionMap.putIfAbsent(key, pos); + } + } + + // 收集缺失岗位 + Map missingPositionRows = new LinkedHashMap<>(); + Map missingDeptName = new LinkedHashMap<>(); + for (OrgPersonnelImportRow row : rows) { + String posName = trim(row.getPositionName()); + if (!StringUtils.hasText(posName)) { + missingPositionRows.putIfAbsent("(空)", row.getRowIndex()); + missingDeptName.putIfAbsent("(空)", trim(row.getDeptName())); + continue; + } + String key = row.getDeptId() + "|" + posName; + if (!positionMap.containsKey(key)) { + missingPositionRows.putIfAbsent(posName, row.getRowIndex()); + missingDeptName.putIfAbsent(posName, trim(row.getDeptName())); + } + } + if (!missingPositionRows.isEmpty()) { + String detail = missingPositionRows.entrySet().stream() + .map(e -> e.getKey() + "(部门:" + missingDeptName.get(e.getKey()) + ",第" + e.getValue() + "行)") + .collect(Collectors.joining("; ")); + throw new BizException(ErrorCode.ORG_PERSONNEL_IMPORT_POSITION_NOT_FOUND, + ErrorCode.ORG_PERSONNEL_IMPORT_POSITION_NOT_FOUND.getMessage() + ":" + detail); + } + + // 校验通过,回填岗位ID + for (OrgPersonnelImportRow row : rows) { + String key = row.getDeptId() + "|" + trim(row.getPositionName()); + row.setPostId(positionMap.get(key).getId()); + } + } + + private Set batchQueryExistingAccounts(List rows, Long orgId) { + Set accounts = rows.stream() + .map(r -> trim(r.getAccount())) + .filter(StringUtils::hasText) + .collect(Collectors.toSet()); + if (accounts.isEmpty()) { + return new HashSet<>(); + } + return orgPersonnelGateway.listByOrgIdAndAccounts(orgId, accounts).stream() + .map(OrgPersonnelEntity::getAccount) + .filter(StringUtils::hasText) + .collect(Collectors.toSet()); + } + + /** + * 行数据转换为实体;枚举无法识别等校验失败时记录异常并返回 null。 + */ + private OrgPersonnelEntity buildEntity(OrgPersonnelImportRow row, Long orgId, List errors) { + OrgPersonnelEntity entity = new OrgPersonnelEntity(); + entity.setOrgId(orgId); + entity.setDeptId(row.getDeptId()); + entity.setPostId(row.getPostId()); + entity.setUserName(trim(row.getUserName())); + entity.setAccount(trim(row.getAccount())); + entity.setIdCardNo(trim(row.getIdCardNo())); + entity.setBirthDate(parseDate(trim(row.getBirthDate()))); + entity.setJoinWorkDate(parseDate(trim(row.getJoinWorkDate()))); + entity.setGraduateSchool(trim(row.getGraduateSchool())); + entity.setMajor(trim(row.getMajor())); + entity.setCurrentAddress(trim(row.getCurrentAddress())); + entity.setOfficeAddress(trim(row.getOfficeAddress())); + entity.setWorkExperience(trim(row.getWorkExperience())); + entity.setPublications(trim(row.getPublications())); + entity.setAbilityDeclaration(trim(row.getAbilityDeclaration())); + + // 性别:严格转换 + String genderText = trim(row.getGender()); + if (StringUtils.hasText(genderText)) { + ImportGenderEnum gender = ImportGenderEnum.fromText(genderText); + if (gender == null) { + errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), entity.getAccount(), entity.getUserName(), + "性别[" + genderText + "]无法识别,跳过该行")); + return null; + } + entity.setGenderCode(gender.getCode()); + entity.setGenderName(gender.getName()); + } + + // 是否注册安全工程师:严格转换 + String registerText = trim(row.getRegisterEngineer()); + if (StringUtils.hasText(registerText)) { + ImportRegisterEngineerEnum register = ImportRegisterEngineerEnum.fromText(registerText); + if (register == null) { + errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), entity.getAccount(), entity.getUserName(), + "是否注册安全工程师[" + registerText + "]无法识别,跳过该行")); + return null; + } + entity.setRegisterEngineerFlag(register.getCode()); + } + + // 学历:兜底字典映射,匹配不到则原样存名称 + String educationText = trim(row.getEducation()); + if (StringUtils.hasText(educationText)) { + ImportEducationEnum education = ImportEducationEnum.match(educationText); + if (education != null) { + entity.setEducationCode(education.getEducationCode()); + entity.setEducationName(education.getEducationName()); + entity.setEducationLevelCode(education.getEducationLevelCode()); + entity.setEducationLevelName(education.getEducationLevelName()); + } else { + entity.setEducationName(educationText); + } + } + + // 职称:无字典,按分隔符拆分后原样存入(保留信息,待后续字典完善) + entity.setTitleCodeArr(parseTitles(trim(row.getTitle()))); + return entity; + } + + private List parseTitles(String title) { + if (!StringUtils.hasText(title)) { + return null; + } + List list = Arrays.stream(title.split("[,,;;、]")) + .map(String::trim) + .filter(StringUtils::hasText) + .map(t -> { + TitleCodeCo co = new TitleCodeCo(); + co.setTitleCode(t); + return co; + }) + .collect(Collectors.toList()); + return list.isEmpty() ? null : list; + } + + private LocalDate parseDate(String text) { + if (!StringUtils.hasText(text)) { + return null; + } + try { + return LocalDate.parse(text, DATE_FORMATTER); + } catch (Exception ex) { + return null; + } + } + + private String trim(String text) { + return text == null ? null : text.trim(); + } +} diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelImportRow.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelImportRow.java new file mode 100644 index 0000000..ab453f9 --- /dev/null +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelImportRow.java @@ -0,0 +1,82 @@ +package org.qinan.safetyeval.app.support; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +/** + * 人员导入 Excel 行模型(按列下标映射,避免表头存在重名列)。 + *

+ * 列顺序:部门 / 岗位 / 账号(手机号) / 姓名 / 性别 / 出生日期 / 身份证号 / + * 学历 / 毕业院校 / 所学专业 / 职称 / 参加工作时间 / 是否注册安全工程师 / + * 现住地址 / 办公地址 / 主要学习工作经历 / 出版学术专著、专利、获奖、发表学术论文等 / + * 自我申报的专业能力及认定方式。 + *

+ * + * @author safety-eval + */ +@Data +public class OrgPersonnelImportRow { + + @ExcelProperty(value = "部门", index = 0) + private String deptName; + + @ExcelProperty(value = "岗位", index = 1) + private String positionName; + + @ExcelProperty(value = "账号", index = 2) + private String account; + + @ExcelProperty(value = "姓名", index = 3) + private String userName; + + @ExcelProperty(value = "性别", index = 4) + private String gender; + + @ExcelProperty(value = "出生日期", index = 5) + private String birthDate; + + @ExcelProperty(value = "身份证号", index = 6) + private String idCardNo; + + @ExcelProperty(value = "学历", index = 7) + private String education; + + @ExcelProperty(value = "毕业院校", index = 8) + private String graduateSchool; + + @ExcelProperty(value = "所学专业", index = 9) + private String major; + + @ExcelProperty(value = "职称", index = 10) + private String title; + + @ExcelProperty(value = "参加工作时间", index = 11) + private String joinWorkDate; + + @ExcelProperty(value = "是否注册安全工程师", index = 12) + private String registerEngineer; + + @ExcelProperty(value = "现住地址", index = 13) + private String currentAddress; + + @ExcelProperty(value = "办公地址", index = 14) + private String officeAddress; + + @ExcelProperty(value = "主要学习工作经历", index = 15) + private String workExperience; + + @ExcelProperty(value = "出版学术专著、专利、获奖、发表学术论文等", index = 16) + private String publications; + + @ExcelProperty(value = "自我申报的专业能力及认定方式", index = 17) + private String abilityDeclaration; + + /** EasyExcel 解析时记录的物理行号(从1开始,含表头),由导入器填充。 */ + private Integer rowIndex; + + /** 校验通过后回填的部门ID(非Excel列)。 */ + private Long deptId; + + /** 校验通过后回填的岗位ID(非Excel列)。 */ + private Long postId; +} diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/OrgPersonnelApi.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/OrgPersonnelApi.java index d7830b7..929b855 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/OrgPersonnelApi.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/OrgPersonnelApi.java @@ -1,6 +1,7 @@ package org.qinan.safetyeval.client.api; import org.qinan.safetyeval.client.co.OrgPersonnelCO; +import org.qinan.safetyeval.client.co.OrgPersonnelImportResultCO; import org.qinan.safetyeval.client.dto.PageResponse; import org.qinan.safetyeval.client.dto.SingleResponse; import org.qinan.safetyeval.client.dto.OrgPersonnelAddCmd; @@ -8,6 +9,7 @@ import org.qinan.safetyeval.client.dto.OrgPersonnelCompareFaceCmd; import org.qinan.safetyeval.client.dto.OrgPersonnelModifyCmd; import org.qinan.safetyeval.client.dto.OrgPersonnelPageQuery; import org.qinan.safetyeval.client.dto.OrgPersonnelUpdateOriginFaceCmd; +import org.springframework.web.multipart.MultipartFile; import java.math.BigDecimal; @@ -33,4 +35,12 @@ public interface OrgPersonnelApi { SingleResponse updateOriginFace(OrgPersonnelUpdateOriginFaceCmd cmd); SingleResponse compareFace(OrgPersonnelCompareFaceCmd cmd); + + /** + * 通过 EasyExcel 批量导入人员信息。 + * + * @param file Excel 文件 + * @return 导入结果(成功条数与异常明细) + */ + SingleResponse importPersonnel(MultipartFile file); } diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/OrgPersonnelImportErrorCO.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/OrgPersonnelImportErrorCO.java new file mode 100644 index 0000000..09a13df --- /dev/null +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/OrgPersonnelImportErrorCO.java @@ -0,0 +1,35 @@ +package org.qinan.safetyeval.client.co; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 人员导入异常消息 + * + * @author safety-eval + */ +@Data +public class OrgPersonnelImportErrorCO { + + @ApiModelProperty(value = "Excel行号(从1开始的物理行号)") + private Integer rowIndex; + + @ApiModelProperty(value = "账号(手机号)") + private String account; + + @ApiModelProperty(value = "姓名") + private String userName; + + @ApiModelProperty(value = "异常原因") + private String errorMessage; + + public OrgPersonnelImportErrorCO() { + } + + public OrgPersonnelImportErrorCO(Integer rowIndex, String account, String userName, String errorMessage) { + this.rowIndex = rowIndex; + this.account = account; + this.userName = userName; + this.errorMessage = errorMessage; + } +} diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/OrgPersonnelImportResultCO.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/OrgPersonnelImportResultCO.java new file mode 100644 index 0000000..b89d77b --- /dev/null +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/OrgPersonnelImportResultCO.java @@ -0,0 +1,25 @@ +package org.qinan.safetyeval.client.co; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +/** + * 人员导入结果 + * + * @author safety-eval + */ +@Data +public class OrgPersonnelImportResultCO { + + @ApiModelProperty(value = "成功导入条数") + private Integer successCount; + + @ApiModelProperty(value = "失败/跳过条数") + private Integer failCount; + + @ApiModelProperty(value = "异常明细") + private List errors = new ArrayList<>(); +} diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/major/request/BasicDisciplineMajorPageQry.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/major/request/BasicDisciplineMajorPageQry.java index 65432de..a928f01 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/major/request/BasicDisciplineMajorPageQry.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/major/request/BasicDisciplineMajorPageQry.java @@ -40,10 +40,4 @@ public class BasicDisciplineMajorPageQry extends PageQuery { */ @ApiModelProperty(value = "专业名称") private String professionalName; - /** - * 环境 - */ - @ApiModelProperty(value = "环境") - private String env; - } diff --git a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java index fcb1599..e84c413 100644 --- a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java +++ b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java @@ -29,6 +29,11 @@ public enum ErrorCode { ORG_PERSONNEL_FACE_ORIGIN_EMPTY("01-05-004", "人员未配置原始人像,无法比对"), ORG_PERSONNEL_FACE_COMPARE_EMPTY("01-05-005", "待比对图片不能为空"), ORG_PERSONNEL_FACE_COMPARE_FAILED("01-05-006", "人脸比对失败"), + // ---- 人员导入 ---- + ORG_PERSONNEL_IMPORT_EMPTY("01-05-007", "导入文件没有有效数据"), + ORG_PERSONNEL_IMPORT_PARSE_ERROR("01-05-008", "导入文件解析失败"), + ORG_PERSONNEL_IMPORT_DEPT_NOT_FOUND("01-05-009", "导入文件中存在不存在的部门"), + ORG_PERSONNEL_IMPORT_POSITION_NOT_FOUND("01-05-010", "导入文件中存在不存在的岗位"), // ---- 人员证书 ---- ORG_PERSONNEL_CERT_NOT_FOUND("01-06-001", "人员证书不存在"), diff --git a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgDepartmentGateway.java b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgDepartmentGateway.java index c59f59a..f810d7f 100644 --- a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgDepartmentGateway.java +++ b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgDepartmentGateway.java @@ -4,6 +4,7 @@ import org.qinan.safetyeval.domain.entity.OrgDepartmentEntity; import org.qinan.safetyeval.domain.query.OrgDepartmentQuery; import org.qinan.safetyeval.domain.query.PageResult; +import java.util.Collection; import java.util.List; /** @@ -24,4 +25,9 @@ public interface OrgDepartmentGateway { PageResult page(OrgDepartmentQuery query); List list(OrgDepartmentQuery query); + + /** + * 按机构ID + 部门名称集合批量精确查询未删除部门(用于导入名称解析)。 + */ + List listByOrgIdAndNames(Long orgId, Collection deptNames); } diff --git a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgPersonnelGateway.java b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgPersonnelGateway.java index 4fb37cd..48bff96 100644 --- a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgPersonnelGateway.java +++ b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgPersonnelGateway.java @@ -4,6 +4,8 @@ import org.qinan.safetyeval.domain.entity.OrgPersonnelEntity; import org.qinan.safetyeval.domain.query.OrgPersonnelQuery; import org.qinan.safetyeval.domain.query.PageResult; +import java.util.Collection; + /** * 人员信息Gateway接口(Domain层定义) * @@ -35,4 +37,9 @@ public interface OrgPersonnelGateway { * 查询岗位下未删除人员(post_id = positionId)。 */ java.util.List listByPostId(Long postId); + + /** + * 按机构ID + 账号集合批量查询未删除人员(用于导入手机号重复校验)。 + */ + java.util.List listByOrgIdAndAccounts(Long orgId, Collection accounts); } diff --git a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgPositionGateway.java b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgPositionGateway.java index 030d2d5..841c685 100644 --- a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgPositionGateway.java +++ b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/gateway/OrgPositionGateway.java @@ -4,6 +4,9 @@ import org.qinan.safetyeval.domain.entity.OrgPositionEntity; import org.qinan.safetyeval.domain.query.OrgPositionQuery; import org.qinan.safetyeval.domain.query.PageResult; +import java.util.Collection; +import java.util.List; + /** * 岗位Gateway接口(Domain层定义) * @@ -20,4 +23,9 @@ public interface OrgPositionGateway { void delete(Long id); PageResult page(OrgPositionQuery query); + + /** + * 按机构ID + 部门ID集合 + 岗位名称集合批量精确查询未删除岗位(用于导入名称解析)。 + */ + List listByOrgIdAndDeptIdsAndNames(Long orgId, Collection deptIds, Collection positionNames); } diff --git a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgDepartmentGatewayImpl.java b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgDepartmentGatewayImpl.java index 238aa77..9cf38af 100644 --- a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgDepartmentGatewayImpl.java +++ b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgDepartmentGatewayImpl.java @@ -15,6 +15,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.annotation.Resource; +import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -80,6 +81,22 @@ public class OrgDepartmentGatewayImpl implements OrgDepartmentGateway { .collect(Collectors.toList()); } + @Override + public List listByOrgIdAndNames(Long orgId, Collection deptNames) { + if (deptNames == null || deptNames.isEmpty()) { + return java.util.Collections.emptyList(); + } + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(OrgDepartmentDO::getDeleteEnum, "false"); + if (orgId != null) { + wrapper.eq(OrgDepartmentDO::getOrgId, orgId); + } + wrapper.in(OrgDepartmentDO::getDeptName, deptNames); + return orgDepartmentMapper.selectList(wrapper).stream() + .map(this::toEntity) + .collect(Collectors.toList()); + } + private LambdaQueryWrapper buildQueryWrapper(OrgDepartmentQuery query) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(OrgDepartmentDO::getDeleteEnum, "false"); diff --git a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgPersonnelGatewayImpl.java b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgPersonnelGatewayImpl.java index 25ee078..49c940d 100644 --- a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgPersonnelGatewayImpl.java +++ b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgPersonnelGatewayImpl.java @@ -18,6 +18,8 @@ import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.annotation.Resource; +import java.util.Collection; +import java.util.Collections; import java.util.List; /** @@ -188,5 +190,19 @@ public class OrgPersonnelGatewayImpl implements OrgPersonnelGateway { return orgPersonnelDoConvertor.converDosToEes(orgPersonnelMapper.selectList(wrapper)); } + @Override + public List listByOrgIdAndAccounts(Long orgId, Collection accounts) { + if (accounts == null || accounts.isEmpty()) { + return Collections.emptyList(); + } + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(OrgPersonnelDO::getDeleteEnum, "false"); + if (orgId != null) { + wrapper.eq(OrgPersonnelDO::getOrgId, orgId); + } + wrapper.in(OrgPersonnelDO::getAccount, accounts); + return orgPersonnelDoConvertor.converDosToEes(orgPersonnelMapper.selectList(wrapper)); + } + } diff --git a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgPositionGatewayImpl.java b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgPositionGatewayImpl.java index d12a570..dd5ea1d 100644 --- a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgPositionGatewayImpl.java +++ b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/gatewayimpl/OrgPositionGatewayImpl.java @@ -15,6 +15,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import javax.annotation.Resource; +import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -99,6 +100,27 @@ public class OrgPositionGatewayImpl implements OrgPositionGateway { return PageResult.of(entities, result.getTotal(), result.getCurrent(), result.getSize()); } + @Override + public List listByOrgIdAndDeptIdsAndNames(Long orgId, Collection deptIds, Collection positionNames) { + if ((deptIds == null || deptIds.isEmpty()) && (positionNames == null || positionNames.isEmpty())) { + return java.util.Collections.emptyList(); + } + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(OrgPositionDO::getDeleteEnum, "false"); + if (orgId != null) { + wrapper.eq(OrgPositionDO::getOrgId, orgId); + } + if (deptIds != null && !deptIds.isEmpty()) { + wrapper.in(OrgPositionDO::getDeptId, deptIds); + } + if (positionNames != null && !positionNames.isEmpty()) { + wrapper.in(OrgPositionDO::getPositionName, positionNames); + } + return orgPositionMapper.selectList(wrapper).stream() + .map(this::toEntity) + .collect(Collectors.toList()); + } + private OrgPositionDO toDO(OrgPositionEntity entity) { OrgPositionDO dataObject = new OrgPositionDO(); dataObject.setOrgId(orgContextResolver.resolveOrgId(entity.getOrgId())); diff --git a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/persistence/queryservice/impl/BasicDisciplineMajorQueryServiceImpl.java b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/persistence/queryservice/impl/BasicDisciplineMajorQueryServiceImpl.java index 1f07290..2ec0d8d 100644 --- a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/persistence/queryservice/impl/BasicDisciplineMajorQueryServiceImpl.java +++ b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/persistence/queryservice/impl/BasicDisciplineMajorQueryServiceImpl.java @@ -34,7 +34,8 @@ public class BasicDisciplineMajorQueryServiceImpl implements BasicDisciplineMajo @Override public PageResponse listBasicDisciplineMajorPage(BasicDisciplineMajorPageQry basicDisciplineMajorPageQry) { - IPage basicDisciplineMajorDoPage = basicDisciplineMajorRepository.listBasicDisciplineMajorPage(PageHelper.queryToPage(basicDisciplineMajorPageQry), basicDisciplineMajorPageQry); + IPage basicDisciplineMajorDoPage = basicDisciplineMajorRepository.listBasicDisciplineMajorPage( + PageHelper.queryToPage(basicDisciplineMajorPageQry), basicDisciplineMajorPageQry); List basicDisciplineMajorCoS = basicDisciplineMajorDoConvertor.converDosToCos(basicDisciplineMajorDoPage.getRecords()); return PageHelper.pageToResponse(basicDisciplineMajorDoPage, basicDisciplineMajorCoS); } diff --git a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/persistence/repository/impl/BasicDisciplineMajorRepositoryImpl.java b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/persistence/repository/impl/BasicDisciplineMajorRepositoryImpl.java index 876e968..d5e1151 100644 --- a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/persistence/repository/impl/BasicDisciplineMajorRepositoryImpl.java +++ b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/persistence/repository/impl/BasicDisciplineMajorRepositoryImpl.java @@ -1,12 +1,13 @@ package org.qinan.safetyeval.infrastructure.persistence.repository.impl; import cn.hutool.core.util.ObjectUtil; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.jjb.saas.framework.enums.enums.BooleanEnum; import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl; import lombok.AllArgsConstructor; import org.qinan.safetyeval.client.major.request.BasicDisciplineMajorPageQry; +import org.qinan.safetyeval.domain.constant.BooleanQAEnum; import org.qinan.safetyeval.infrastructure.persistence.domainobject.BasicDisciplineMajorDO; import org.qinan.safetyeval.infrastructure.persistence.mapper.BasicDisciplineMajorMapper; import org.qinan.safetyeval.infrastructure.persistence.repository.BasicDisciplineMajorRepository; @@ -33,24 +34,22 @@ public class BasicDisciplineMajorRepositoryImpl extends BaseRepositoryImpl listBasicDisciplineMajorPage(IPage iPage, BasicDisciplineMajorPageQry basicDisciplineMajorPageQry) { - QueryWrapper basicDisciplineMajorDoQueryWrapper = new QueryWrapper<>(); - if (ObjectUtil.isNotEmpty(basicDisciplineMajorPageQry.getIndustryCode())) { - basicDisciplineMajorDoQueryWrapper.eq("industry_code", basicDisciplineMajorPageQry.getIndustryCode()); - } - if (ObjectUtil.isNotEmpty(basicDisciplineMajorPageQry.getProfessionalCapabilityCode())) { - basicDisciplineMajorDoQueryWrapper.eq("professional_capability_code", basicDisciplineMajorPageQry.getProfessionalCapabilityCode()); - } - if (ObjectUtil.isNotEmpty(basicDisciplineMajorPageQry.getProfessionalCode())) { - basicDisciplineMajorDoQueryWrapper.eq("professional_code", basicDisciplineMajorPageQry.getProfessionalCode()); - } - if (ObjectUtil.isNotEmpty(basicDisciplineMajorPageQry.getProfessionalName())) { - basicDisciplineMajorDoQueryWrapper.like("professional_name", basicDisciplineMajorPageQry.getProfessionalName()); - } - if (ObjectUtil.isNotEmpty(basicDisciplineMajorPageQry.getEnv())) { - basicDisciplineMajorDoQueryWrapper.eq("env", basicDisciplineMajorPageQry.getEnv()); - } - basicDisciplineMajorDoQueryWrapper.eq("delete_enum", BooleanEnum.FALSE.getValue()); - return basicDisciplineMajorMapper.selectPage(iPage, basicDisciplineMajorDoQueryWrapper); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.select(BasicDisciplineMajorDO::getId, + BasicDisciplineMajorDO::getIndustryCode, + BasicDisciplineMajorDO::getProfessionalCapabilityCode, + BasicDisciplineMajorDO::getProfessionalCode, + BasicDisciplineMajorDO::getProfessionalName) + .like(ObjectUtil.isNotEmpty(basicDisciplineMajorPageQry.getIndustryCode()), + BasicDisciplineMajorDO::getIndustryCode, basicDisciplineMajorPageQry.getIndustryCode()) + .like(ObjectUtil.isNotEmpty(basicDisciplineMajorPageQry.getProfessionalCapabilityCode()), + BasicDisciplineMajorDO::getProfessionalCapabilityCode, basicDisciplineMajorPageQry.getProfessionalCapabilityCode()) + .eq(ObjectUtil.isNotEmpty(basicDisciplineMajorPageQry.getProfessionalCode()), + BasicDisciplineMajorDO::getProfessionalCode, basicDisciplineMajorPageQry.getProfessionalCode()) + .like(ObjectUtil.isNotEmpty(basicDisciplineMajorPageQry.getProfessionalName()), + BasicDisciplineMajorDO::getProfessionalName, basicDisciplineMajorPageQry.getProfessionalName()) + .eq(BasicDisciplineMajorDO::getDeleteEnum, BooleanQAEnum.FALSE.getValue()); + return basicDisciplineMajorMapper.selectPage(iPage, queryWrapper); } @Override