From 934b8aad4069cd252d7073ff8970f44bd73c2331 Mon Sep 17 00:00:00 2001 From: andy <594580820@qq.com> Date: Mon, 26 Jan 2026 16:01:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/pom.xml | 26 +- .../com/bycrm/ByCrmApplication.java | 0 .../com/bycrm/annotations/AuthRequired.java | 0 .../com/bycrm/common/Constants.java | 28 +- .../com/bycrm/common/PageResult.java | 0 .../{ => java}/com/bycrm/common/Result.java | 0 .../com/bycrm/config/AuthInterceptor.java | 0 .../com/bycrm/config/CorsConfig.java | 0 .../com/bycrm/config/MyBatisConfig.java | 0 .../com/bycrm/config/SwaggerConfig.java | 0 .../com/bycrm/config/WebMvcConfig.java | 0 .../com/bycrm/controller/AuthController.java | 26 ++ .../bycrm/controller/CustomerController.java | 0 .../bycrm/controller/DashboardController.java | 78 ++++++ .../bycrm/controller/DealerController.java | 2 +- .../bycrm/controller/ReportController.java | 0 .../bycrm/controller/SchoolController.java | 128 +++++++++ .../controller/SystemConfigController.java | 107 ++++++++ .../java/com/bycrm/dto/ChangePasswordDTO.java | 29 +++ .../{ => java}/com/bycrm/dto/CustomerDTO.java | 0 .../com/bycrm/dto/DashboardStatisticsDTO.java | 34 +++ .../{ => java}/com/bycrm/dto/DealerDTO.java | 7 +- .../{ => java}/com/bycrm/dto/LoginDTO.java | 0 .../{ => java}/com/bycrm/dto/PageQuery.java | 5 + .../com/bycrm/dto/ReportAuditDTO.java | 0 .../{ => java}/com/bycrm/dto/ReportDTO.java | 0 .../java/com/bycrm/dto/ResetPasswordDTO.java | 28 ++ .../main/java/com/bycrm/dto/SchoolDTO.java | 37 +++ .../{ => java}/com/bycrm/entity/Customer.java | 0 .../{ => java}/com/bycrm/entity/Dealer.java | 5 + .../{ => java}/com/bycrm/entity/Dict.java | 0 .../{ => java}/com/bycrm/entity/DictItem.java | 0 .../com/bycrm/entity/OperationLog.java | 0 .../{ => java}/com/bycrm/entity/Report.java | 13 +- .../main/java/com/bycrm/entity/School.java | 48 ++++ .../java/com/bycrm/entity/SystemConfig.java | 63 +++++ .../{ => java}/com/bycrm/entity/User.java | 0 .../bycrm/exception/BusinessException.java | 0 .../exception/GlobalExceptionHandler.java | 0 .../com/bycrm/mapper/CustomerMapper.java | 7 + .../com/bycrm/mapper/DealerMapper.java | 5 + .../com/bycrm/mapper/ReportMapper.java | 10 + .../java/com/bycrm/mapper/SchoolMapper.java | 49 ++++ .../com/bycrm/mapper/SystemConfigMapper.java | 39 +++ .../com/bycrm/mapper/UserMapper.java | 0 .../com/bycrm/service/CustomerService.java | 0 .../com/bycrm/service/DealerService.java | 0 .../com/bycrm/service/ReportService.java | 10 + .../java/com/bycrm/service/SchoolService.java | 32 +++ .../bycrm/service/SystemConfigService.java | 52 ++++ .../com/bycrm/service/UserService.java | 12 + .../service/impl/CustomerServiceImpl.java | 13 +- .../bycrm/service/impl/DealerServiceImpl.java | 32 ++- .../bycrm/service/impl/ReportServiceImpl.java | 36 ++- .../bycrm/service/impl/SchoolServiceImpl.java | 96 +++++++ .../service/impl/SystemConfigServiceImpl.java | 194 ++++++++++++++ .../bycrm/service/impl/UserServiceImpl.java | 50 ++++ .../com/bycrm/task/ReportExpireTask.java | 0 .../com/bycrm/util/CheckExcelStructure.java | 117 +++++++++ .../java/com/bycrm/util/ImportSchools.java | 55 ++++ .../{ => java}/com/bycrm/util/JwtUtil.java | 0 .../java/com/bycrm/util/PasswordTest.java | 28 ++ .../java/com/bycrm/util/SchoolImporter.java | 243 ++++++++++++++++++ .../com/bycrm/util/SecureKeyGenerator.java | 38 +++ .../{ => java}/com/bycrm/vo/CustomerVO.java | 7 +- .../{ => java}/com/bycrm/vo/ReportVO.java | 13 +- .../src/main/java/com/bycrm/vo/SchoolVO.java | 48 ++++ .../{ => java}/com/bycrm/vo/UserInfoVO.java | 0 backend/src/main/resources/application.yml | 12 +- .../main/resources/mapper/CustomerMapper.xml | 39 +++ .../main/resources/mapper/DealerMapper.xml | 17 +- .../main/resources/mapper/ReportMapper.xml | 19 ++ .../main/resources/mapper/SchoolMapper.xml | 59 +++++ .../resources/mapper/SystemConfigMapper.xml | 46 ++++ backend/target/classes/application.yml | 81 ++++++ .../classes/com/bycrm/ByCrmApplication.class | Bin 0 -> 1178 bytes .../com/bycrm/annotations/AuthRequired.class | Bin 0 -> 399 bytes .../classes/com/bycrm/common/Constants.class | Bin 0 -> 1057 bytes .../classes/com/bycrm/common/PageResult.class | Bin 0 -> 4802 bytes .../classes/com/bycrm/common/Result.class | Bin 0 -> 5370 bytes .../com/bycrm/config/AuthInterceptor.class | Bin 0 -> 2673 bytes .../classes/com/bycrm/config/CorsConfig.class | Bin 0 -> 1550 bytes .../com/bycrm/config/MyBatisConfig.class | Bin 0 -> 395 bytes .../com/bycrm/config/SwaggerConfig.class | Bin 0 -> 2364 bytes .../com/bycrm/config/WebMvcConfig.class | Bin 0 -> 1779 bytes .../AuthController$LoginResponse.class | Bin 0 -> 1640 bytes .../com/bycrm/controller/AuthController.class | Bin 0 -> 4105 bytes .../bycrm/controller/CustomerController.class | Bin 0 -> 5548 bytes .../controller/DashboardController.class | Bin 0 -> 3218 bytes .../bycrm/controller/DealerController.class | Bin 0 -> 3816 bytes .../bycrm/controller/ReportController.class | Bin 0 -> 5242 bytes .../bycrm/controller/SchoolController.class | Bin 0 -> 5083 bytes .../controller/SystemConfigController.class | Bin 0 -> 4382 bytes .../com/bycrm/dto/ChangePasswordDTO.class | Bin 0 -> 2430 bytes .../classes/com/bycrm/dto/CustomerDTO.class | Bin 0 -> 2987 bytes .../bycrm/dto/DashboardStatisticsDTO.class | Bin 0 -> 3092 bytes .../classes/com/bycrm/dto/DealerDTO.class | Bin 0 -> 4785 bytes .../classes/com/bycrm/dto/LoginDTO.class | Bin 0 -> 2209 bytes .../classes/com/bycrm/dto/PageQuery.class | Bin 0 -> 3530 bytes .../com/bycrm/dto/ReportAuditDTO.class | Bin 0 -> 2891 bytes .../classes/com/bycrm/dto/ReportDTO.class | Bin 0 -> 2309 bytes .../com/bycrm/dto/ResetPasswordDTO.class | Bin 0 -> 2451 bytes .../classes/com/bycrm/dto/SchoolDTO.class | Bin 0 -> 3207 bytes .../classes/com/bycrm/entity/Customer.class | Bin 0 -> 5044 bytes .../classes/com/bycrm/entity/Dealer.class | Bin 0 -> 6012 bytes .../classes/com/bycrm/entity/Dict.class | Bin 0 -> 4642 bytes .../classes/com/bycrm/entity/DictItem.class | Bin 0 -> 4656 bytes .../com/bycrm/entity/OperationLog.class | Bin 0 -> 4751 bytes .../classes/com/bycrm/entity/Report.class | Bin 0 -> 7903 bytes .../classes/com/bycrm/entity/School.class | Bin 0 -> 4139 bytes .../com/bycrm/entity/SystemConfig.class | Bin 0 -> 5699 bytes .../classes/com/bycrm/entity/User.class | Bin 0 -> 6246 bytes .../bycrm/exception/BusinessException.class | Bin 0 -> 1000 bytes .../exception/GlobalExceptionHandler.class | Bin 0 -> 4586 bytes .../com/bycrm/mapper/CustomerMapper.class | Bin 0 -> 1534 bytes .../com/bycrm/mapper/DealerMapper.class | Bin 0 -> 1015 bytes .../com/bycrm/mapper/ReportMapper.class | Bin 0 -> 1757 bytes .../com/bycrm/mapper/SchoolMapper.class | Bin 0 -> 1090 bytes .../com/bycrm/mapper/SystemConfigMapper.class | Bin 0 -> 868 bytes .../classes/com/bycrm/mapper/UserMapper.class | Bin 0 -> 787 bytes .../com/bycrm/service/CustomerService.class | Bin 0 -> 1148 bytes .../com/bycrm/service/DealerService.class | Bin 0 -> 713 bytes .../com/bycrm/service/ReportService.class | Bin 0 -> 1142 bytes .../com/bycrm/service/SchoolService.class | Bin 0 -> 603 bytes .../bycrm/service/SystemConfigService.class | Bin 0 -> 966 bytes .../com/bycrm/service/UserService.class | Bin 0 -> 678 bytes .../service/impl/CustomerServiceImpl.class | Bin 0 -> 6428 bytes .../service/impl/DealerServiceImpl.class | Bin 0 -> 4405 bytes .../service/impl/ReportServiceImpl.class | Bin 0 -> 10339 bytes .../service/impl/SchoolServiceImpl.class | Bin 0 -> 4546 bytes .../impl/SystemConfigServiceImpl.class | Bin 0 -> 7081 bytes .../bycrm/service/impl/UserServiceImpl.class | Bin 0 -> 4983 bytes .../com/bycrm/task/ReportExpireTask.class | Bin 0 -> 1352 bytes .../bycrm/util/CheckExcelStructure$1.class | Bin 0 -> 892 bytes .../com/bycrm/util/CheckExcelStructure.class | Bin 0 -> 5267 bytes .../com/bycrm/util/ImportSchools.class | Bin 0 -> 2545 bytes .../classes/com/bycrm/util/JwtUtil.class | Bin 0 -> 4635 bytes .../classes/com/bycrm/util/PasswordTest.class | Bin 0 -> 1657 bytes .../com/bycrm/util/SchoolImporter$1.class | Bin 0 -> 877 bytes .../com/bycrm/util/SchoolImporter.class | Bin 0 -> 7440 bytes .../com/bycrm/util/SecureKeyGenerator.class | Bin 0 -> 1950 bytes .../classes/com/bycrm/vo/CustomerVO.class | Bin 0 -> 7256 bytes .../classes/com/bycrm/vo/ReportVO.class | Bin 0 -> 8939 bytes .../classes/com/bycrm/vo/SchoolVO.class | Bin 0 -> 4139 bytes .../classes/com/bycrm/vo/UserInfoVO.class | Bin 0 -> 4384 bytes .../target/classes/mapper/CustomerMapper.xml | 119 +++++++++ .../target/classes/mapper/DealerMapper.xml | 71 +++++ .../target/classes/mapper/ReportMapper.xml | 141 ++++++++++ .../target/classes/mapper/SchoolMapper.xml | 59 +++++ .../classes/mapper/SystemConfigMapper.xml | 46 ++++ backend/target/classes/mapper/UserMapper.xml | 64 +++++ .../compile/default-cli/createdFiles.lst | 0 .../compile/default-cli/inputFiles.lst | 46 ++++ .../compile/default-compile/createdFiles.lst | 1 + .../compile/default-compile/inputFiles.lst | 47 ++++ 155 files changed, 2649 insertions(+), 68 deletions(-) rename backend/src/main/{ => java}/com/bycrm/ByCrmApplication.java (100%) rename backend/src/main/{ => java}/com/bycrm/annotations/AuthRequired.java (100%) rename backend/src/main/{ => java}/com/bycrm/common/Constants.java (56%) rename backend/src/main/{ => java}/com/bycrm/common/PageResult.java (100%) rename backend/src/main/{ => java}/com/bycrm/common/Result.java (100%) rename backend/src/main/{ => java}/com/bycrm/config/AuthInterceptor.java (100%) rename backend/src/main/{ => java}/com/bycrm/config/CorsConfig.java (100%) rename backend/src/main/{ => java}/com/bycrm/config/MyBatisConfig.java (100%) rename backend/src/main/{ => java}/com/bycrm/config/SwaggerConfig.java (100%) rename backend/src/main/{ => java}/com/bycrm/config/WebMvcConfig.java (100%) rename backend/src/main/{ => java}/com/bycrm/controller/AuthController.java (71%) rename backend/src/main/{ => java}/com/bycrm/controller/CustomerController.java (100%) create mode 100644 backend/src/main/java/com/bycrm/controller/DashboardController.java rename backend/src/main/{ => java}/com/bycrm/controller/DealerController.java (97%) rename backend/src/main/{ => java}/com/bycrm/controller/ReportController.java (100%) create mode 100644 backend/src/main/java/com/bycrm/controller/SchoolController.java create mode 100644 backend/src/main/java/com/bycrm/controller/SystemConfigController.java create mode 100644 backend/src/main/java/com/bycrm/dto/ChangePasswordDTO.java rename backend/src/main/{ => java}/com/bycrm/dto/CustomerDTO.java (100%) create mode 100644 backend/src/main/java/com/bycrm/dto/DashboardStatisticsDTO.java rename backend/src/main/{ => java}/com/bycrm/dto/DealerDTO.java (85%) rename backend/src/main/{ => java}/com/bycrm/dto/LoginDTO.java (100%) rename backend/src/main/{ => java}/com/bycrm/dto/PageQuery.java (83%) rename backend/src/main/{ => java}/com/bycrm/dto/ReportAuditDTO.java (100%) rename backend/src/main/{ => java}/com/bycrm/dto/ReportDTO.java (100%) create mode 100644 backend/src/main/java/com/bycrm/dto/ResetPasswordDTO.java create mode 100644 backend/src/main/java/com/bycrm/dto/SchoolDTO.java rename backend/src/main/{ => java}/com/bycrm/entity/Customer.java (100%) rename backend/src/main/{ => java}/com/bycrm/entity/Dealer.java (90%) rename backend/src/main/{ => java}/com/bycrm/entity/Dict.java (100%) rename backend/src/main/{ => java}/com/bycrm/entity/DictItem.java (100%) rename backend/src/main/{ => java}/com/bycrm/entity/OperationLog.java (100%) rename backend/src/main/{ => java}/com/bycrm/entity/Report.java (83%) create mode 100644 backend/src/main/java/com/bycrm/entity/School.java create mode 100644 backend/src/main/java/com/bycrm/entity/SystemConfig.java rename backend/src/main/{ => java}/com/bycrm/entity/User.java (100%) rename backend/src/main/{ => java}/com/bycrm/exception/BusinessException.java (100%) rename backend/src/main/{ => java}/com/bycrm/exception/GlobalExceptionHandler.java (100%) rename backend/src/main/{ => java}/com/bycrm/mapper/CustomerMapper.java (78%) rename backend/src/main/{ => java}/com/bycrm/mapper/DealerMapper.java (92%) rename backend/src/main/{ => java}/com/bycrm/mapper/ReportMapper.java (84%) create mode 100644 backend/src/main/java/com/bycrm/mapper/SchoolMapper.java create mode 100644 backend/src/main/java/com/bycrm/mapper/SystemConfigMapper.java rename backend/src/main/{ => java}/com/bycrm/mapper/UserMapper.java (100%) rename backend/src/main/{ => java}/com/bycrm/service/CustomerService.java (100%) rename backend/src/main/{ => java}/com/bycrm/service/DealerService.java (100%) rename backend/src/main/{ => java}/com/bycrm/service/ReportService.java (80%) create mode 100644 backend/src/main/java/com/bycrm/service/SchoolService.java create mode 100644 backend/src/main/java/com/bycrm/service/SystemConfigService.java rename backend/src/main/{ => java}/com/bycrm/service/UserService.java (66%) rename backend/src/main/{ => java}/com/bycrm/service/impl/CustomerServiceImpl.java (90%) rename backend/src/main/{ => java}/com/bycrm/service/impl/DealerServiceImpl.java (66%) rename backend/src/main/{ => java}/com/bycrm/service/impl/ReportServiceImpl.java (87%) create mode 100644 backend/src/main/java/com/bycrm/service/impl/SchoolServiceImpl.java create mode 100644 backend/src/main/java/com/bycrm/service/impl/SystemConfigServiceImpl.java rename backend/src/main/{ => java}/com/bycrm/service/impl/UserServiceImpl.java (55%) rename backend/src/main/{ => java}/com/bycrm/task/ReportExpireTask.java (100%) create mode 100644 backend/src/main/java/com/bycrm/util/CheckExcelStructure.java create mode 100644 backend/src/main/java/com/bycrm/util/ImportSchools.java rename backend/src/main/{ => java}/com/bycrm/util/JwtUtil.java (100%) create mode 100644 backend/src/main/java/com/bycrm/util/PasswordTest.java create mode 100644 backend/src/main/java/com/bycrm/util/SchoolImporter.java create mode 100644 backend/src/main/java/com/bycrm/util/SecureKeyGenerator.java rename backend/src/main/{ => java}/com/bycrm/vo/CustomerVO.java (89%) rename backend/src/main/{ => java}/com/bycrm/vo/ReportVO.java (84%) create mode 100644 backend/src/main/java/com/bycrm/vo/SchoolVO.java rename backend/src/main/{ => java}/com/bycrm/vo/UserInfoVO.java (100%) create mode 100644 backend/src/main/resources/mapper/SchoolMapper.xml create mode 100644 backend/src/main/resources/mapper/SystemConfigMapper.xml create mode 100644 backend/target/classes/application.yml create mode 100644 backend/target/classes/com/bycrm/ByCrmApplication.class create mode 100644 backend/target/classes/com/bycrm/annotations/AuthRequired.class create mode 100644 backend/target/classes/com/bycrm/common/Constants.class create mode 100644 backend/target/classes/com/bycrm/common/PageResult.class create mode 100644 backend/target/classes/com/bycrm/common/Result.class create mode 100644 backend/target/classes/com/bycrm/config/AuthInterceptor.class create mode 100644 backend/target/classes/com/bycrm/config/CorsConfig.class create mode 100644 backend/target/classes/com/bycrm/config/MyBatisConfig.class create mode 100644 backend/target/classes/com/bycrm/config/SwaggerConfig.class create mode 100644 backend/target/classes/com/bycrm/config/WebMvcConfig.class create mode 100644 backend/target/classes/com/bycrm/controller/AuthController$LoginResponse.class create mode 100644 backend/target/classes/com/bycrm/controller/AuthController.class create mode 100644 backend/target/classes/com/bycrm/controller/CustomerController.class create mode 100644 backend/target/classes/com/bycrm/controller/DashboardController.class create mode 100644 backend/target/classes/com/bycrm/controller/DealerController.class create mode 100644 backend/target/classes/com/bycrm/controller/ReportController.class create mode 100644 backend/target/classes/com/bycrm/controller/SchoolController.class create mode 100644 backend/target/classes/com/bycrm/controller/SystemConfigController.class create mode 100644 backend/target/classes/com/bycrm/dto/ChangePasswordDTO.class create mode 100644 backend/target/classes/com/bycrm/dto/CustomerDTO.class create mode 100644 backend/target/classes/com/bycrm/dto/DashboardStatisticsDTO.class create mode 100644 backend/target/classes/com/bycrm/dto/DealerDTO.class create mode 100644 backend/target/classes/com/bycrm/dto/LoginDTO.class create mode 100644 backend/target/classes/com/bycrm/dto/PageQuery.class create mode 100644 backend/target/classes/com/bycrm/dto/ReportAuditDTO.class create mode 100644 backend/target/classes/com/bycrm/dto/ReportDTO.class create mode 100644 backend/target/classes/com/bycrm/dto/ResetPasswordDTO.class create mode 100644 backend/target/classes/com/bycrm/dto/SchoolDTO.class create mode 100644 backend/target/classes/com/bycrm/entity/Customer.class create mode 100644 backend/target/classes/com/bycrm/entity/Dealer.class create mode 100644 backend/target/classes/com/bycrm/entity/Dict.class create mode 100644 backend/target/classes/com/bycrm/entity/DictItem.class create mode 100644 backend/target/classes/com/bycrm/entity/OperationLog.class create mode 100644 backend/target/classes/com/bycrm/entity/Report.class create mode 100644 backend/target/classes/com/bycrm/entity/School.class create mode 100644 backend/target/classes/com/bycrm/entity/SystemConfig.class create mode 100644 backend/target/classes/com/bycrm/entity/User.class create mode 100644 backend/target/classes/com/bycrm/exception/BusinessException.class create mode 100644 backend/target/classes/com/bycrm/exception/GlobalExceptionHandler.class create mode 100644 backend/target/classes/com/bycrm/mapper/CustomerMapper.class create mode 100644 backend/target/classes/com/bycrm/mapper/DealerMapper.class create mode 100644 backend/target/classes/com/bycrm/mapper/ReportMapper.class create mode 100644 backend/target/classes/com/bycrm/mapper/SchoolMapper.class create mode 100644 backend/target/classes/com/bycrm/mapper/SystemConfigMapper.class create mode 100644 backend/target/classes/com/bycrm/mapper/UserMapper.class create mode 100644 backend/target/classes/com/bycrm/service/CustomerService.class create mode 100644 backend/target/classes/com/bycrm/service/DealerService.class create mode 100644 backend/target/classes/com/bycrm/service/ReportService.class create mode 100644 backend/target/classes/com/bycrm/service/SchoolService.class create mode 100644 backend/target/classes/com/bycrm/service/SystemConfigService.class create mode 100644 backend/target/classes/com/bycrm/service/UserService.class create mode 100644 backend/target/classes/com/bycrm/service/impl/CustomerServiceImpl.class create mode 100644 backend/target/classes/com/bycrm/service/impl/DealerServiceImpl.class create mode 100644 backend/target/classes/com/bycrm/service/impl/ReportServiceImpl.class create mode 100644 backend/target/classes/com/bycrm/service/impl/SchoolServiceImpl.class create mode 100644 backend/target/classes/com/bycrm/service/impl/SystemConfigServiceImpl.class create mode 100644 backend/target/classes/com/bycrm/service/impl/UserServiceImpl.class create mode 100644 backend/target/classes/com/bycrm/task/ReportExpireTask.class create mode 100644 backend/target/classes/com/bycrm/util/CheckExcelStructure$1.class create mode 100644 backend/target/classes/com/bycrm/util/CheckExcelStructure.class create mode 100644 backend/target/classes/com/bycrm/util/ImportSchools.class create mode 100644 backend/target/classes/com/bycrm/util/JwtUtil.class create mode 100644 backend/target/classes/com/bycrm/util/PasswordTest.class create mode 100644 backend/target/classes/com/bycrm/util/SchoolImporter$1.class create mode 100644 backend/target/classes/com/bycrm/util/SchoolImporter.class create mode 100644 backend/target/classes/com/bycrm/util/SecureKeyGenerator.class create mode 100644 backend/target/classes/com/bycrm/vo/CustomerVO.class create mode 100644 backend/target/classes/com/bycrm/vo/ReportVO.class create mode 100644 backend/target/classes/com/bycrm/vo/SchoolVO.class create mode 100644 backend/target/classes/com/bycrm/vo/UserInfoVO.class create mode 100644 backend/target/classes/mapper/CustomerMapper.xml create mode 100644 backend/target/classes/mapper/DealerMapper.xml create mode 100644 backend/target/classes/mapper/ReportMapper.xml create mode 100644 backend/target/classes/mapper/SchoolMapper.xml create mode 100644 backend/target/classes/mapper/SystemConfigMapper.xml create mode 100644 backend/target/classes/mapper/UserMapper.xml create mode 100644 backend/target/maven-status/maven-compiler-plugin/compile/default-cli/createdFiles.lst create mode 100644 backend/target/maven-status/maven-compiler-plugin/compile/default-cli/inputFiles.lst create mode 100644 backend/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 backend/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst diff --git a/backend/pom.xml b/backend/pom.xml index db54d52..56fbc9b 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -26,6 +26,7 @@ 3.0.0 3.12.0 5.8.23 + 5.2.5 @@ -50,9 +51,9 @@ - mysql - mysql-connector-java - 8.0.33 + com.mysql + mysql-connector-j + runtime @@ -101,6 +102,24 @@ ${hutool.version} + + + org.apache.poi + poi + ${poi.version} + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + org.springframework.security + spring-security-crypto + + org.projectlombok @@ -160,7 +179,6 @@ 3.3.0 checkstyle.xml - UTF-8 true false diff --git a/backend/src/main/com/bycrm/ByCrmApplication.java b/backend/src/main/java/com/bycrm/ByCrmApplication.java similarity index 100% rename from backend/src/main/com/bycrm/ByCrmApplication.java rename to backend/src/main/java/com/bycrm/ByCrmApplication.java diff --git a/backend/src/main/com/bycrm/annotations/AuthRequired.java b/backend/src/main/java/com/bycrm/annotations/AuthRequired.java similarity index 100% rename from backend/src/main/com/bycrm/annotations/AuthRequired.java rename to backend/src/main/java/com/bycrm/annotations/AuthRequired.java diff --git a/backend/src/main/com/bycrm/common/Constants.java b/backend/src/main/java/com/bycrm/common/Constants.java similarity index 56% rename from backend/src/main/com/bycrm/common/Constants.java rename to backend/src/main/java/com/bycrm/common/Constants.java index 468b0b8..06741b2 100644 --- a/backend/src/main/com/bycrm/common/Constants.java +++ b/backend/src/main/java/com/bycrm/common/Constants.java @@ -23,70 +23,70 @@ public class Constants { /** * 客户状态 - 可报备 */ - public static final Integer CUSTOMER_STATUS_AVAILABLE = 0; + public static final int CUSTOMER_STATUS_AVAILABLE = 0; /** * 客户状态 - 保护中 */ - public static final Integer CUSTOMER_STATUS_PROTECTED = 1; + public static final int CUSTOMER_STATUS_PROTECTED = 1; /** * 客户状态 - 已失效 */ - public static final Integer CUSTOMER_STATUS_EXPIRED = 2; + public static final int CUSTOMER_STATUS_EXPIRED = 2; /** * 报备状态 - 待审核 */ - public static final Integer REPORT_STATUS_PENDING = 0; + public static final int REPORT_STATUS_PENDING = 0; /** * 报备状态 - 已通过 */ - public static final Integer REPORT_STATUS_APPROVED = 1; + public static final int REPORT_STATUS_APPROVED = 1; /** * 报备状态 - 已驳回 */ - public static final Integer REPORT_STATUS_REJECTED = 2; + public static final int REPORT_STATUS_REJECTED = 2; /** * 报备状态 - 已失效 */ - public static final Integer REPORT_STATUS_EXPIRED = 3; + public static final int REPORT_STATUS_EXPIRED = 3; /** * 用户角色 - 管理员 */ - public static final Integer USER_ROLE_ADMIN = 0; + public static final int USER_ROLE_ADMIN = 0; /** * 用户角色 - 经销商用户 */ - public static final Integer USER_ROLE_DEALER = 1; + public static final int USER_ROLE_DEALER = 1; /** * 用户状态 - 禁用 */ - public static final Integer USER_STATUS_DISABLED = 0; + public static final int USER_STATUS_DISABLED = 0; /** * 用户状态 - 启用 */ - public static final Integer USER_STATUS_ENABLED = 1; + public static final int USER_STATUS_ENABLED = 1; /** * 经销商状态 - 禁用 */ - public static final Integer DEALER_STATUS_DISABLED = 0; + public static final int DEALER_STATUS_DISABLED = 0; /** * 经销商状态 - 启用 */ - public static final Integer DEALER_STATUS_ENABLED = 1; + public static final int DEALER_STATUS_ENABLED = 1; /** * 默认保护期天数 */ - public static final Integer DEFAULT_PROTECT_DAYS = 90; + public static final int DEFAULT_PROTECT_DAYS = 90; } diff --git a/backend/src/main/com/bycrm/common/PageResult.java b/backend/src/main/java/com/bycrm/common/PageResult.java similarity index 100% rename from backend/src/main/com/bycrm/common/PageResult.java rename to backend/src/main/java/com/bycrm/common/PageResult.java diff --git a/backend/src/main/com/bycrm/common/Result.java b/backend/src/main/java/com/bycrm/common/Result.java similarity index 100% rename from backend/src/main/com/bycrm/common/Result.java rename to backend/src/main/java/com/bycrm/common/Result.java diff --git a/backend/src/main/com/bycrm/config/AuthInterceptor.java b/backend/src/main/java/com/bycrm/config/AuthInterceptor.java similarity index 100% rename from backend/src/main/com/bycrm/config/AuthInterceptor.java rename to backend/src/main/java/com/bycrm/config/AuthInterceptor.java diff --git a/backend/src/main/com/bycrm/config/CorsConfig.java b/backend/src/main/java/com/bycrm/config/CorsConfig.java similarity index 100% rename from backend/src/main/com/bycrm/config/CorsConfig.java rename to backend/src/main/java/com/bycrm/config/CorsConfig.java diff --git a/backend/src/main/com/bycrm/config/MyBatisConfig.java b/backend/src/main/java/com/bycrm/config/MyBatisConfig.java similarity index 100% rename from backend/src/main/com/bycrm/config/MyBatisConfig.java rename to backend/src/main/java/com/bycrm/config/MyBatisConfig.java diff --git a/backend/src/main/com/bycrm/config/SwaggerConfig.java b/backend/src/main/java/com/bycrm/config/SwaggerConfig.java similarity index 100% rename from backend/src/main/com/bycrm/config/SwaggerConfig.java rename to backend/src/main/java/com/bycrm/config/SwaggerConfig.java diff --git a/backend/src/main/com/bycrm/config/WebMvcConfig.java b/backend/src/main/java/com/bycrm/config/WebMvcConfig.java similarity index 100% rename from backend/src/main/com/bycrm/config/WebMvcConfig.java rename to backend/src/main/java/com/bycrm/config/WebMvcConfig.java diff --git a/backend/src/main/com/bycrm/controller/AuthController.java b/backend/src/main/java/com/bycrm/controller/AuthController.java similarity index 71% rename from backend/src/main/com/bycrm/controller/AuthController.java rename to backend/src/main/java/com/bycrm/controller/AuthController.java index a631921..7164485 100644 --- a/backend/src/main/com/bycrm/controller/AuthController.java +++ b/backend/src/main/java/com/bycrm/controller/AuthController.java @@ -1,7 +1,9 @@ package com.bycrm.controller; import com.bycrm.common.Result; +import com.bycrm.dto.ChangePasswordDTO; import com.bycrm.dto.LoginDTO; +import com.bycrm.dto.ResetPasswordDTO; import com.bycrm.service.UserService; import com.bycrm.vo.UserInfoVO; import io.swagger.annotations.Api; @@ -54,6 +56,30 @@ public class AuthController { return Result.success(); } + /** + * 修改密码 + */ + @ApiOperation("修改密码") + @PostMapping("/change-password") + public Result changePassword( + @RequestBody ChangePasswordDTO dto, + HttpServletRequest request) { + String token = getTokenFromRequest(request); + Long userId = userService.getCurrentUser(token).getUserId(); + userService.changePassword(userId, dto); + return Result.success(); + } + + /** + * 重置密码(管理员功能) + */ + @ApiOperation("重置密码") + @PostMapping("/reset-password") + public Result resetPassword(@RequestBody ResetPasswordDTO dto) { + userService.resetPassword(dto); + return Result.success(); + } + /** * 从请求中获取 Token */ diff --git a/backend/src/main/com/bycrm/controller/CustomerController.java b/backend/src/main/java/com/bycrm/controller/CustomerController.java similarity index 100% rename from backend/src/main/com/bycrm/controller/CustomerController.java rename to backend/src/main/java/com/bycrm/controller/CustomerController.java diff --git a/backend/src/main/java/com/bycrm/controller/DashboardController.java b/backend/src/main/java/com/bycrm/controller/DashboardController.java new file mode 100644 index 0000000..72f37b1 --- /dev/null +++ b/backend/src/main/java/com/bycrm/controller/DashboardController.java @@ -0,0 +1,78 @@ +package com.bycrm.controller; + +import com.bycrm.common.Result; +import com.bycrm.dto.DashboardStatisticsDTO; +import com.bycrm.entity.User; +import com.bycrm.mapper.CustomerMapper; +import com.bycrm.mapper.DealerMapper; +import com.bycrm.mapper.UserMapper; +import com.bycrm.service.ReportService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; + +/** + * 首页统计控制器 + */ +@Api(tags = "首页统计") +@RestController +@RequestMapping("/dashboard") +public class DashboardController { + + private final CustomerMapper customerMapper; + private final DealerMapper dealerMapper; + private final ReportService reportService; + private final UserMapper userMapper; + + public DashboardController(CustomerMapper customerMapper, + DealerMapper dealerMapper, + ReportService reportService, + UserMapper userMapper) { + this.customerMapper = customerMapper; + this.dealerMapper = dealerMapper; + this.reportService = reportService; + this.userMapper = userMapper; + } + + /** + * 获取首页统计数据 + */ + @ApiOperation("获取首页统计数据") + @GetMapping("/statistics") + public Result getStatistics(HttpServletRequest request) { + Long currentUserId = (Long) request.getAttribute("currentUserId"); + User currentUser = userMapper.selectById(currentUserId); + + DashboardStatisticsDTO stats = new DashboardStatisticsDTO(); + + // 客户总数(所有人看到的客户总数一样) + Long customerCount = customerMapper.countPage(null, null, null); + stats.setCustomerCount(customerCount); + + // 报备总数和待审核数量(根据角色过滤) + Long dealerId = null; + if (currentUser.getRole() != 0) { + // 经销商用户,只统计自己的 + dealerId = currentUser.getDealerId(); + } + // 管理员用户,dealerId为null,统计所有 + + Long reportCount = reportService.countByDealerId(dealerId); + stats.setReportCount(reportCount); + + Long pendingCount = reportService.countPendingByDealerId(dealerId); + stats.setPendingCount(pendingCount); + + // 经销商总数(仅管理员可见) + if (currentUser.getRole() == 0) { + Long dealerCount = dealerMapper.count(); + stats.setDealerCount(dealerCount); + } else { + stats.setDealerCount(0L); + } + + return Result.success(stats); + } +} diff --git a/backend/src/main/com/bycrm/controller/DealerController.java b/backend/src/main/java/com/bycrm/controller/DealerController.java similarity index 97% rename from backend/src/main/com/bycrm/controller/DealerController.java rename to backend/src/main/java/com/bycrm/controller/DealerController.java index 38a6618..02614b3 100644 --- a/backend/src/main/com/bycrm/controller/DealerController.java +++ b/backend/src/main/java/com/bycrm/controller/DealerController.java @@ -32,7 +32,7 @@ public class DealerController { @GetMapping("/list") public Result> getDealerList( @ApiParam("经销商名称") @RequestParam(required = false) String name, - @ApiParam("经销商编码") @RequestParam(required = false) String code, + @ApiParam("经销商账号") @RequestParam(required = false) String code, @ApiParam("状态") @RequestParam(required = false) Integer status) { List dealers = dealerService.getDealerList(name, code, status); return Result.success(dealers); diff --git a/backend/src/main/com/bycrm/controller/ReportController.java b/backend/src/main/java/com/bycrm/controller/ReportController.java similarity index 100% rename from backend/src/main/com/bycrm/controller/ReportController.java rename to backend/src/main/java/com/bycrm/controller/ReportController.java diff --git a/backend/src/main/java/com/bycrm/controller/SchoolController.java b/backend/src/main/java/com/bycrm/controller/SchoolController.java new file mode 100644 index 0000000..c15d902 --- /dev/null +++ b/backend/src/main/java/com/bycrm/controller/SchoolController.java @@ -0,0 +1,128 @@ +package com.bycrm.controller; + +import com.bycrm.common.Result; +import com.bycrm.dto.SchoolDTO; +import com.bycrm.service.SchoolService; +import com.bycrm.util.SchoolImporter; +import com.bycrm.vo.SchoolVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +/** + * 学校控制器 + */ +@Api(tags = "学校管理") +@RestController +@RequestMapping("/school") +public class SchoolController { + + private final SchoolService schoolService; + + @Value("${project.root:./}") + private String projectRoot; + + public SchoolController(SchoolService schoolService) { + this.schoolService = schoolService; + } + + /** + * 根据名称搜索学校(用于自动完成) + */ + @ApiOperation("根据名称搜索学校") + @GetMapping("/search") + public Result> searchByName( + @ApiParam("关键词") @RequestParam String keyword) { + List schools = schoolService.searchByName(keyword); + return Result.success(schools); + } + + /** + * 查询所有学校 + */ + @ApiOperation("查询所有学校") + @GetMapping("/list") + public Result> findAll() { + List schools = schoolService.findAll(); + return Result.success(schools); + } + + /** + * 创建学校 + */ + @ApiOperation("创建学校") + @PostMapping + public Result create(@RequestBody SchoolDTO dto) { + Long id = schoolService.create(dto); + return Result.success(id); + } + + /** + * 批量导入学校 + */ + @ApiOperation("批量导入学校") + @PostMapping("/batch") + public Result batchImport(@RequestBody List list) { + int count = schoolService.batchImport(list); + return Result.success(count); + } + + /** + * 从Excel文件导入学校数据 + */ + @ApiOperation("从Excel文件导入学校数据") + @PostMapping("/import") + public Result importFromExcel(@RequestParam("file") MultipartFile file) { + try { + // 保存临时文件 + File tempFile = File.createTempFile("school_import_", ".xls"); + file.transferTo(tempFile); + + // 解析Excel + List schools = SchoolImporter.importFromXls(tempFile.getAbsolutePath()); + + // 导入数据库 + int count = schoolService.batchImport(schools); + + // 删除临时文件 + tempFile.delete(); + + return Result.success(count); + } catch (IOException e) { + return Result.error("导入失败: " + e.getMessage()); + } + } + + /** + * 从项目docs目录导入学校数据 + */ + @ApiOperation("从项目docs目录导入学校数据") + @PostMapping("/import-from-docs") + public Result importFromDocs() { + try { + String filePath = projectRoot + "/docs/school.xls"; + File file = new File(filePath); + + if (!file.exists()) { + return Result.error("文件不存在: " + filePath); + } + + // 解析Excel + List schools = SchoolImporter.importFromXls(filePath); + + // 导入数据库 + int count = schoolService.batchImport(schools); + + return Result.success(count); + } catch (Exception e) { + return Result.error("导入失败: " + e.getMessage()); + } + } +} diff --git a/backend/src/main/java/com/bycrm/controller/SystemConfigController.java b/backend/src/main/java/com/bycrm/controller/SystemConfigController.java new file mode 100644 index 0000000..b768d69 --- /dev/null +++ b/backend/src/main/java/com/bycrm/controller/SystemConfigController.java @@ -0,0 +1,107 @@ +package com.bycrm.controller; + +import com.bycrm.common.Result; +import com.bycrm.entity.SystemConfig; +import com.bycrm.entity.User; +import com.bycrm.mapper.UserMapper; +import com.bycrm.service.SystemConfigService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.Map; + +/** + * 系统配置控制器 + */ +@Api(tags = "系统配置管理") +@RestController +@RequestMapping("/system/config") +public class SystemConfigController { + + private final SystemConfigService systemConfigService; + private final UserMapper userMapper; + + public SystemConfigController(SystemConfigService systemConfigService, + UserMapper userMapper) { + this.systemConfigService = systemConfigService; + this.userMapper = userMapper; + } + + /** + * 获取所有配置(仅管理员) + */ + @ApiOperation("获取所有系统配置") + @GetMapping + public Result> getAllConfigs(HttpServletRequest request) { + // 权限校验:只有管理员可以查看 + Long currentUserId = (Long) request.getAttribute("currentUserId"); + User currentUser = userMapper.selectById(currentUserId); + if (currentUser == null || currentUser.getRole() != 0) { + return Result.error("无权限访问"); + } + + List configs = systemConfigService.getAllConfigs(); + return Result.success(configs); + } + + /** + * 获取配置值(所有用户可访问) + */ + @ApiOperation("获取指定配置值") + @GetMapping("/value/{configKey}") + public Result getConfigValue(@PathVariable String configKey) { + // 只允许访问特定配置,防止敏感信息泄露 + if (!configKey.startsWith("report.")) { + return Result.error("无权访问该配置"); + } + + String value = systemConfigService.getConfigValue(configKey); + return Result.success(value); + } + + /** + * 更新配置(仅管理员) + */ + @ApiOperation("更新系统配置") + @PutMapping + public Result updateConfig(@RequestBody Map params, + HttpServletRequest request) { + // 权限校验 + Long currentUserId = (Long) request.getAttribute("currentUserId"); + User currentUser = userMapper.selectById(currentUserId); + if (currentUser == null || currentUser.getRole() != 0) { + return Result.error("只有管理员才能修改配置"); + } + + String configKey = params.get("configKey"); + String configValue = params.get("configValue"); + + if (configKey == null || configValue == null) { + return Result.error("参数不完整"); + } + + systemConfigService.updateConfig(configKey, configValue); + return Result.success(); + } + + /** + * 批量更新配置(仅管理员) + */ + @ApiOperation("批量更新系统配置") + @PutMapping("/batch") + public Result batchUpdateConfigs(@RequestBody Map configs, + HttpServletRequest request) { + // 权限校验 + Long currentUserId = (Long) request.getAttribute("currentUserId"); + User currentUser = userMapper.selectById(currentUserId); + if (currentUser == null || currentUser.getRole() != 0) { + return Result.error("只有管理员才能修改配置"); + } + + systemConfigService.batchUpdateConfigs(configs); + return Result.success(); + } +} diff --git a/backend/src/main/java/com/bycrm/dto/ChangePasswordDTO.java b/backend/src/main/java/com/bycrm/dto/ChangePasswordDTO.java new file mode 100644 index 0000000..beaedc1 --- /dev/null +++ b/backend/src/main/java/com/bycrm/dto/ChangePasswordDTO.java @@ -0,0 +1,29 @@ +package com.bycrm.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.io.Serializable; + +/** + * 修改密码DTO + */ +@Data +public class ChangePasswordDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 原密码 + */ + @NotBlank(message = "原密码不能为空") + private String oldPassword; + + /** + * 新密码 + */ + @NotBlank(message = "新密码不能为空") + @Size(min = 6, max = 20, message = "新密码长度必须在6-20位之间") + private String newPassword; +} diff --git a/backend/src/main/com/bycrm/dto/CustomerDTO.java b/backend/src/main/java/com/bycrm/dto/CustomerDTO.java similarity index 100% rename from backend/src/main/com/bycrm/dto/CustomerDTO.java rename to backend/src/main/java/com/bycrm/dto/CustomerDTO.java diff --git a/backend/src/main/java/com/bycrm/dto/DashboardStatisticsDTO.java b/backend/src/main/java/com/bycrm/dto/DashboardStatisticsDTO.java new file mode 100644 index 0000000..7aaa45b --- /dev/null +++ b/backend/src/main/java/com/bycrm/dto/DashboardStatisticsDTO.java @@ -0,0 +1,34 @@ +package com.bycrm.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 首页统计DTO + */ +@Data +public class DashboardStatisticsDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 客户总数 + */ + private Long customerCount; + + /** + * 报备总数 + */ + private Long reportCount; + + /** + * 待审核数量 + */ + private Long pendingCount; + + /** + * 经销商总数(仅管理员可见) + */ + private Long dealerCount; +} diff --git a/backend/src/main/com/bycrm/dto/DealerDTO.java b/backend/src/main/java/com/bycrm/dto/DealerDTO.java similarity index 85% rename from backend/src/main/com/bycrm/dto/DealerDTO.java rename to backend/src/main/java/com/bycrm/dto/DealerDTO.java index 66fb199..fe174ef 100644 --- a/backend/src/main/com/bycrm/dto/DealerDTO.java +++ b/backend/src/main/java/com/bycrm/dto/DealerDTO.java @@ -23,7 +23,7 @@ public class DealerDTO implements Serializable { /** * 经销商编码 */ - @NotBlank(message = "经销商编码不能为空") + @NotBlank(message = "经销商账号不能为空") private String code; /** @@ -48,4 +48,9 @@ public class DealerDTO implements Serializable { */ @NotNull(message = "状态不能为空") private Integer status; + + /** + * 初始密码(新增用户时可设置) + */ + private String password; } diff --git a/backend/src/main/com/bycrm/dto/LoginDTO.java b/backend/src/main/java/com/bycrm/dto/LoginDTO.java similarity index 100% rename from backend/src/main/com/bycrm/dto/LoginDTO.java rename to backend/src/main/java/com/bycrm/dto/LoginDTO.java diff --git a/backend/src/main/com/bycrm/dto/PageQuery.java b/backend/src/main/java/com/bycrm/dto/PageQuery.java similarity index 83% rename from backend/src/main/com/bycrm/dto/PageQuery.java rename to backend/src/main/java/com/bycrm/dto/PageQuery.java index fc879a1..066dfef 100644 --- a/backend/src/main/com/bycrm/dto/PageQuery.java +++ b/backend/src/main/java/com/bycrm/dto/PageQuery.java @@ -22,6 +22,11 @@ public class PageQuery implements Serializable { */ private Long size = 10L; + /** + * 偏移量(自动计算,不需要手动设置) + */ + private Long offset; + /** * 排序字段 */ diff --git a/backend/src/main/com/bycrm/dto/ReportAuditDTO.java b/backend/src/main/java/com/bycrm/dto/ReportAuditDTO.java similarity index 100% rename from backend/src/main/com/bycrm/dto/ReportAuditDTO.java rename to backend/src/main/java/com/bycrm/dto/ReportAuditDTO.java diff --git a/backend/src/main/com/bycrm/dto/ReportDTO.java b/backend/src/main/java/com/bycrm/dto/ReportDTO.java similarity index 100% rename from backend/src/main/com/bycrm/dto/ReportDTO.java rename to backend/src/main/java/com/bycrm/dto/ReportDTO.java diff --git a/backend/src/main/java/com/bycrm/dto/ResetPasswordDTO.java b/backend/src/main/java/com/bycrm/dto/ResetPasswordDTO.java new file mode 100644 index 0000000..1383275 --- /dev/null +++ b/backend/src/main/java/com/bycrm/dto/ResetPasswordDTO.java @@ -0,0 +1,28 @@ +package com.bycrm.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.io.Serializable; + +/** + * 重置密码DTO + */ +@Data +public class ResetPasswordDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 用户ID + */ + private Long userId; + + /** + * 新密码 + */ + @NotBlank(message = "新密码不能为空") + @Size(min = 6, max = 20, message = "新密码长度必须在6-20位之间") + private String newPassword; +} diff --git a/backend/src/main/java/com/bycrm/dto/SchoolDTO.java b/backend/src/main/java/com/bycrm/dto/SchoolDTO.java new file mode 100644 index 0000000..f142abe --- /dev/null +++ b/backend/src/main/java/com/bycrm/dto/SchoolDTO.java @@ -0,0 +1,37 @@ +package com.bycrm.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; + +/** + * 学校DTO + */ +@Data +public class SchoolDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 学校ID + */ + private Long id; + + /** + * 学校标识码 + */ + @NotBlank(message = "学校标识码不能为空") + private String schoolCode; + + /** + * 学校名称 + */ + @NotBlank(message = "学校名称不能为空") + private String schoolName; + + /** + * 所在地 + */ + private String location; +} diff --git a/backend/src/main/com/bycrm/entity/Customer.java b/backend/src/main/java/com/bycrm/entity/Customer.java similarity index 100% rename from backend/src/main/com/bycrm/entity/Customer.java rename to backend/src/main/java/com/bycrm/entity/Customer.java diff --git a/backend/src/main/com/bycrm/entity/Dealer.java b/backend/src/main/java/com/bycrm/entity/Dealer.java similarity index 90% rename from backend/src/main/com/bycrm/entity/Dealer.java rename to backend/src/main/java/com/bycrm/entity/Dealer.java index ad7c2c2..e90e226 100644 --- a/backend/src/main/com/bycrm/entity/Dealer.java +++ b/backend/src/main/java/com/bycrm/entity/Dealer.java @@ -49,6 +49,11 @@ public class Dealer implements Serializable { */ private Integer status; + /** + * 关联的用户ID(用于重置密码等操作) + */ + private Long userId; + /** * 创建时间 */ diff --git a/backend/src/main/com/bycrm/entity/Dict.java b/backend/src/main/java/com/bycrm/entity/Dict.java similarity index 100% rename from backend/src/main/com/bycrm/entity/Dict.java rename to backend/src/main/java/com/bycrm/entity/Dict.java diff --git a/backend/src/main/com/bycrm/entity/DictItem.java b/backend/src/main/java/com/bycrm/entity/DictItem.java similarity index 100% rename from backend/src/main/com/bycrm/entity/DictItem.java rename to backend/src/main/java/com/bycrm/entity/DictItem.java diff --git a/backend/src/main/com/bycrm/entity/OperationLog.java b/backend/src/main/java/com/bycrm/entity/OperationLog.java similarity index 100% rename from backend/src/main/com/bycrm/entity/OperationLog.java rename to backend/src/main/java/com/bycrm/entity/OperationLog.java diff --git a/backend/src/main/com/bycrm/entity/Report.java b/backend/src/main/java/com/bycrm/entity/Report.java similarity index 83% rename from backend/src/main/com/bycrm/entity/Report.java rename to backend/src/main/java/com/bycrm/entity/Report.java index 8c829a8..89b4f51 100644 --- a/backend/src/main/com/bycrm/entity/Report.java +++ b/backend/src/main/java/com/bycrm/entity/Report.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import java.io.Serializable; +import java.time.LocalDate; import java.time.LocalDateTime; /** @@ -45,16 +46,16 @@ public class Report implements Serializable { private String rejectReason; /** - * 保护期开始时间 + * 保护期开始日期 */ - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime protectStartDate; + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate protectStartDate; /** - * 保护期结束时间 + * 保护期结束日期 */ - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime protectEndDate; + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate protectEndDate; /** * 创建时间 diff --git a/backend/src/main/java/com/bycrm/entity/School.java b/backend/src/main/java/com/bycrm/entity/School.java new file mode 100644 index 0000000..64bf7a0 --- /dev/null +++ b/backend/src/main/java/com/bycrm/entity/School.java @@ -0,0 +1,48 @@ +package com.bycrm.entity; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 学校实体 + */ +@Data +public class School implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 学校ID + */ + private Long id; + + /** + * 学校标识码 + */ + private String schoolCode; + + /** + * 学校名称 + */ + private String schoolName; + + /** + * 所在地 + */ + private String location; + + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createdAt; + + /** + * 更新时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updatedAt; +} diff --git a/backend/src/main/java/com/bycrm/entity/SystemConfig.java b/backend/src/main/java/com/bycrm/entity/SystemConfig.java new file mode 100644 index 0000000..b4055f7 --- /dev/null +++ b/backend/src/main/java/com/bycrm/entity/SystemConfig.java @@ -0,0 +1,63 @@ +package com.bycrm.entity; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 系统配置实体 + */ +@Data +public class SystemConfig implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 配置ID + */ + private Long id; + + /** + * 配置键 + */ + private String configKey; + + /** + * 配置值 + */ + private String configValue; + + /** + * 配置名称 + */ + private String configLabel; + + /** + * 数据类型:string/integer/boolean + */ + private String configType; + + /** + * 配置描述 + */ + private String description; + + /** + * 是否可编辑:0-否 1-是 + */ + private Integer isEditable; + + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createdAt; + + /** + * 更新时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updatedAt; +} diff --git a/backend/src/main/com/bycrm/entity/User.java b/backend/src/main/java/com/bycrm/entity/User.java similarity index 100% rename from backend/src/main/com/bycrm/entity/User.java rename to backend/src/main/java/com/bycrm/entity/User.java diff --git a/backend/src/main/com/bycrm/exception/BusinessException.java b/backend/src/main/java/com/bycrm/exception/BusinessException.java similarity index 100% rename from backend/src/main/com/bycrm/exception/BusinessException.java rename to backend/src/main/java/com/bycrm/exception/BusinessException.java diff --git a/backend/src/main/com/bycrm/exception/GlobalExceptionHandler.java b/backend/src/main/java/com/bycrm/exception/GlobalExceptionHandler.java similarity index 100% rename from backend/src/main/com/bycrm/exception/GlobalExceptionHandler.java rename to backend/src/main/java/com/bycrm/exception/GlobalExceptionHandler.java diff --git a/backend/src/main/com/bycrm/mapper/CustomerMapper.java b/backend/src/main/java/com/bycrm/mapper/CustomerMapper.java similarity index 78% rename from backend/src/main/com/bycrm/mapper/CustomerMapper.java rename to backend/src/main/java/com/bycrm/mapper/CustomerMapper.java index 33f99da..a7eb1b2 100644 --- a/backend/src/main/com/bycrm/mapper/CustomerMapper.java +++ b/backend/src/main/java/com/bycrm/mapper/CustomerMapper.java @@ -2,6 +2,7 @@ package com.bycrm.mapper; import com.bycrm.entity.Customer; import com.bycrm.dto.PageQuery; +import com.bycrm.vo.CustomerVO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -29,6 +30,12 @@ public interface CustomerMapper { List selectPage(@Param("query") PageQuery query, @Param("name") String name, @Param("industry") String industry, @Param("status") Integer status); + /** + * 分页查询客户(带经销商信息) + */ + List selectPageWithDealer(@Param("query") PageQuery query, @Param("name") String name, + @Param("industry") String industry, @Param("status") Integer status); + /** * 查询客户总数 */ diff --git a/backend/src/main/com/bycrm/mapper/DealerMapper.java b/backend/src/main/java/com/bycrm/mapper/DealerMapper.java similarity index 92% rename from backend/src/main/com/bycrm/mapper/DealerMapper.java rename to backend/src/main/java/com/bycrm/mapper/DealerMapper.java index 5aa1b40..93da57b 100644 --- a/backend/src/main/com/bycrm/mapper/DealerMapper.java +++ b/backend/src/main/java/com/bycrm/mapper/DealerMapper.java @@ -41,4 +41,9 @@ public interface DealerMapper { * 删除经销商 */ int deleteById(@Param("id") Long id); + + /** + * 统计经销商总数 + */ + Long count(); } diff --git a/backend/src/main/com/bycrm/mapper/ReportMapper.java b/backend/src/main/java/com/bycrm/mapper/ReportMapper.java similarity index 84% rename from backend/src/main/com/bycrm/mapper/ReportMapper.java rename to backend/src/main/java/com/bycrm/mapper/ReportMapper.java index 96da49f..7e0e637 100644 --- a/backend/src/main/com/bycrm/mapper/ReportMapper.java +++ b/backend/src/main/java/com/bycrm/mapper/ReportMapper.java @@ -60,4 +60,14 @@ public interface ReportMapper { * 批量更新报备状态为已失效 */ int batchUpdateExpired(@Param("ids") List ids); + + /** + * 统计报备总数(根据经销商ID过滤) + */ + Long countByDealerId(@Param("dealerId") Long dealerId); + + /** + * 统计待审核报备数量(根据经销商ID过滤) + */ + Long countPendingByDealerId(@Param("dealerId") Long dealerId); } diff --git a/backend/src/main/java/com/bycrm/mapper/SchoolMapper.java b/backend/src/main/java/com/bycrm/mapper/SchoolMapper.java new file mode 100644 index 0000000..47ecb43 --- /dev/null +++ b/backend/src/main/java/com/bycrm/mapper/SchoolMapper.java @@ -0,0 +1,49 @@ +package com.bycrm.mapper; + +import com.bycrm.entity.School; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 学校Mapper + */ +@Mapper +public interface SchoolMapper { + + /** + * 插入学校 + */ + int insert(School school); + + /** + * 批量插入学校 + */ + int batchInsert(@Param("list") List list); + + /** + * 根据学校名称模糊查询 + */ + List searchByName(@Param("keyword") String keyword); + + /** + * 根据学校标识码查询 + */ + School findByCode(@Param("schoolCode") String schoolCode); + + /** + * 查询所有学校 + */ + List findAll(); + + /** + * 分页查询学校 + */ + List findByPage(@Param("offset") int offset, @Param("limit") int limit); + + /** + * 统计学校数量 + */ + int count(); +} diff --git a/backend/src/main/java/com/bycrm/mapper/SystemConfigMapper.java b/backend/src/main/java/com/bycrm/mapper/SystemConfigMapper.java new file mode 100644 index 0000000..8555186 --- /dev/null +++ b/backend/src/main/java/com/bycrm/mapper/SystemConfigMapper.java @@ -0,0 +1,39 @@ +package com.bycrm.mapper; + +import com.bycrm.entity.SystemConfig; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 系统配置Mapper + */ +@Mapper +public interface SystemConfigMapper { + + /** + * 查询所有配置 + */ + List selectAll(); + + /** + * 根据配置键查询 + */ + SystemConfig selectByKey(@Param("configKey") String configKey); + + /** + * 根据配置键查询配置值 + */ + String selectValueByKey(@Param("configKey") String configKey); + + /** + * 更新配置 + */ + int update(SystemConfig config); + + /** + * 批量更新配置 + */ + int batchUpdate(@Param("configs") List configs); +} diff --git a/backend/src/main/com/bycrm/mapper/UserMapper.java b/backend/src/main/java/com/bycrm/mapper/UserMapper.java similarity index 100% rename from backend/src/main/com/bycrm/mapper/UserMapper.java rename to backend/src/main/java/com/bycrm/mapper/UserMapper.java diff --git a/backend/src/main/com/bycrm/service/CustomerService.java b/backend/src/main/java/com/bycrm/service/CustomerService.java similarity index 100% rename from backend/src/main/com/bycrm/service/CustomerService.java rename to backend/src/main/java/com/bycrm/service/CustomerService.java diff --git a/backend/src/main/com/bycrm/service/DealerService.java b/backend/src/main/java/com/bycrm/service/DealerService.java similarity index 100% rename from backend/src/main/com/bycrm/service/DealerService.java rename to backend/src/main/java/com/bycrm/service/DealerService.java diff --git a/backend/src/main/com/bycrm/service/ReportService.java b/backend/src/main/java/com/bycrm/service/ReportService.java similarity index 80% rename from backend/src/main/com/bycrm/service/ReportService.java rename to backend/src/main/java/com/bycrm/service/ReportService.java index 1eacc87..152121f 100644 --- a/backend/src/main/com/bycrm/service/ReportService.java +++ b/backend/src/main/java/com/bycrm/service/ReportService.java @@ -41,4 +41,14 @@ public interface ReportService { * 处理过期报备(定时任务调用) */ void handleExpiredReports(); + + /** + * 统计报备总数(根据经销商ID过滤) + */ + Long countByDealerId(Long dealerId); + + /** + * 统计待审核报备数量(根据经销商ID过滤) + */ + Long countPendingByDealerId(Long dealerId); } diff --git a/backend/src/main/java/com/bycrm/service/SchoolService.java b/backend/src/main/java/com/bycrm/service/SchoolService.java new file mode 100644 index 0000000..2ed9cc1 --- /dev/null +++ b/backend/src/main/java/com/bycrm/service/SchoolService.java @@ -0,0 +1,32 @@ +package com.bycrm.service; + +import com.bycrm.dto.SchoolDTO; +import com.bycrm.vo.SchoolVO; + +import java.util.List; + +/** + * 学校Service + */ +public interface SchoolService { + + /** + * 根据名称搜索学校(用于自动完成) + */ + List searchByName(String keyword); + + /** + * 创建学校 + */ + Long create(SchoolDTO dto); + + /** + * 批量导入学校 + */ + int batchImport(List list); + + /** + * 查询所有学校 + */ + List findAll(); +} diff --git a/backend/src/main/java/com/bycrm/service/SystemConfigService.java b/backend/src/main/java/com/bycrm/service/SystemConfigService.java new file mode 100644 index 0000000..84783dd --- /dev/null +++ b/backend/src/main/java/com/bycrm/service/SystemConfigService.java @@ -0,0 +1,52 @@ +package com.bycrm.service; + +import com.bycrm.entity.SystemConfig; + +import java.util.List; +import java.util.Map; + +/** + * 系统配置服务接口 + */ +public interface SystemConfigService { + + /** + * 获取所有配置 + */ + List getAllConfigs(); + + /** + * 根据配置键获取配置值 + */ + String getConfigValue(String configKey); + + /** + * 根据配置键获取整数配置值 + */ + Integer getIntegerConfigValue(String configKey, Integer defaultValue); + + /** + * 根据配置键获取布尔配置值 + */ + Boolean getBooleanConfigValue(String configKey, Boolean defaultValue); + + /** + * 获取所有配置为Map + */ + Map getConfigMap(); + + /** + * 更新配置 + */ + void updateConfig(String configKey, String configValue); + + /** + * 批量更新配置 + */ + void batchUpdateConfigs(Map configMap); + + /** + * 初始化配置(从数据库加载,如果不存在则使用默认值) + */ + void initConfigs(); +} diff --git a/backend/src/main/com/bycrm/service/UserService.java b/backend/src/main/java/com/bycrm/service/UserService.java similarity index 66% rename from backend/src/main/com/bycrm/service/UserService.java rename to backend/src/main/java/com/bycrm/service/UserService.java index 1a7449f..b42519e 100644 --- a/backend/src/main/com/bycrm/service/UserService.java +++ b/backend/src/main/java/com/bycrm/service/UserService.java @@ -1,6 +1,8 @@ package com.bycrm.service; +import com.bycrm.dto.ChangePasswordDTO; import com.bycrm.dto.LoginDTO; +import com.bycrm.dto.ResetPasswordDTO; import com.bycrm.entity.User; import com.bycrm.vo.UserInfoVO; @@ -28,4 +30,14 @@ public interface UserService { * 获取当前登录用户信息 */ UserInfoVO getCurrentUser(String token); + + /** + * 修改密码 + */ + void changePassword(Long userId, ChangePasswordDTO dto); + + /** + * 重置密码(管理员功能) + */ + void resetPassword(ResetPasswordDTO dto); } diff --git a/backend/src/main/com/bycrm/service/impl/CustomerServiceImpl.java b/backend/src/main/java/com/bycrm/service/impl/CustomerServiceImpl.java similarity index 90% rename from backend/src/main/com/bycrm/service/impl/CustomerServiceImpl.java rename to backend/src/main/java/com/bycrm/service/impl/CustomerServiceImpl.java index 6a2c2b7..baf7169 100644 --- a/backend/src/main/com/bycrm/service/impl/CustomerServiceImpl.java +++ b/backend/src/main/java/com/bycrm/service/impl/CustomerServiceImpl.java @@ -1,12 +1,10 @@ package com.bycrm.service.impl; -import cn.hutool.core.util.StrUtil; import com.bycrm.common.Constants; import com.bycrm.common.PageResult; import com.bycrm.dto.CustomerDTO; import com.bycrm.dto.PageQuery; import com.bycrm.entity.Customer; -import com.bycrm.entity.User; import com.bycrm.exception.BusinessException; import com.bycrm.mapper.CustomerMapper; import com.bycrm.mapper.UserMapper; @@ -17,7 +15,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; -import java.time.temporal.ChronoUnit; import java.util.List; import java.util.stream.Collectors; @@ -40,15 +37,11 @@ public class CustomerServiceImpl implements CustomerService { // 计算偏移量 query.setOffset((query.getCurrent() - 1) * query.getSize()); - List customers = customerMapper.selectPage(query, name, industry, status); + // 使用新的查询方法,直接返回 CustomerVO(包含经销商信息) + List customerVOs = customerMapper.selectPageWithDealer(query, name, industry, status); Long total = customerMapper.countPage(name, industry, status); - List voList = customers.stream().map(customer -> { - CustomerVO vo = convertToVO(customer); - return vo; - }).collect(Collectors.toList()); - - return PageResult.of(total, voList, query.getCurrent(), query.getSize()); + return PageResult.of(total, customerVOs, query.getCurrent(), query.getSize()); } @Override diff --git a/backend/src/main/com/bycrm/service/impl/DealerServiceImpl.java b/backend/src/main/java/com/bycrm/service/impl/DealerServiceImpl.java similarity index 66% rename from backend/src/main/com/bycrm/service/impl/DealerServiceImpl.java rename to backend/src/main/java/com/bycrm/service/impl/DealerServiceImpl.java index 0923eda..3a4d2d0 100644 --- a/backend/src/main/com/bycrm/service/impl/DealerServiceImpl.java +++ b/backend/src/main/java/com/bycrm/service/impl/DealerServiceImpl.java @@ -1,11 +1,15 @@ package com.bycrm.service.impl; +import com.bycrm.common.Constants; import com.bycrm.dto.DealerDTO; import com.bycrm.entity.Dealer; +import com.bycrm.entity.User; import com.bycrm.exception.BusinessException; import com.bycrm.mapper.DealerMapper; +import com.bycrm.mapper.UserMapper; import com.bycrm.service.DealerService; import org.springframework.beans.BeanUtils; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,9 +23,12 @@ import java.util.List; public class DealerServiceImpl implements DealerService { private final DealerMapper dealerMapper; + private final UserMapper userMapper; + private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); - public DealerServiceImpl(DealerMapper dealerMapper) { + public DealerServiceImpl(DealerMapper dealerMapper, UserMapper userMapper) { this.dealerMapper = dealerMapper; + this.userMapper = userMapper; } @Override @@ -44,7 +51,7 @@ public class DealerServiceImpl implements DealerService { // 检查编码是否重复 Dealer existingDealer = dealerMapper.selectByCode(dealerDTO.getCode()); if (existingDealer != null) { - throw new BusinessException("经销商编码已存在"); + throw new BusinessException("经销商账号已存在"); } Dealer dealer = new Dealer(); @@ -53,6 +60,25 @@ public class DealerServiceImpl implements DealerService { dealer.setUpdatedAt(LocalDateTime.now()); dealerMapper.insert(dealer); + + // 创建对应的用户账号 + User user = new User(); + user.setUsername(dealerDTO.getCode()); // 用户名使用经销商编码 + user.setRealName(dealerDTO.getContactPerson()); + user.setDealerId(dealer.getId()); + user.setRole(Constants.USER_ROLE_DEALER); // 经销商用户角色 + user.setStatus(dealerDTO.getStatus()); + + // 设置密码:如果提供了密码则使用提供的密码,否则使用默认密码 + String password = dealerDTO.getPassword(); + if (password == null || password.trim().isEmpty()) { + password = "123456"; // 默认密码 + } + user.setPassword(passwordEncoder.encode(password)); + user.setCreatedAt(LocalDateTime.now()); + user.setUpdatedAt(LocalDateTime.now()); + + userMapper.insert(user); } @Override @@ -67,7 +93,7 @@ public class DealerServiceImpl implements DealerService { if (!existingDealer.getCode().equals(dealerDTO.getCode())) { Dealer codeDealer = dealerMapper.selectByCode(dealerDTO.getCode()); if (codeDealer != null && !codeDealer.getId().equals(id)) { - throw new BusinessException("经销商编码已存在"); + throw new BusinessException("经销商账号已存在"); } } diff --git a/backend/src/main/com/bycrm/service/impl/ReportServiceImpl.java b/backend/src/main/java/com/bycrm/service/impl/ReportServiceImpl.java similarity index 87% rename from backend/src/main/com/bycrm/service/impl/ReportServiceImpl.java rename to backend/src/main/java/com/bycrm/service/impl/ReportServiceImpl.java index f8bc8b7..b181941 100644 --- a/backend/src/main/com/bycrm/service/impl/ReportServiceImpl.java +++ b/backend/src/main/java/com/bycrm/service/impl/ReportServiceImpl.java @@ -13,9 +13,9 @@ import com.bycrm.mapper.CustomerMapper; import com.bycrm.mapper.ReportMapper; import com.bycrm.mapper.UserMapper; import com.bycrm.service.ReportService; +import com.bycrm.service.SystemConfigService; import com.bycrm.vo.ReportVO; import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -34,17 +34,16 @@ public class ReportServiceImpl implements ReportService { private final ReportMapper reportMapper; private final CustomerMapper customerMapper; private final UserMapper userMapper; + private final SystemConfigService systemConfigService; - @Value("${crm.report.ttl-days:90}") - private Integer protectDays; - - @Value("${crm.report.allow-overlap:false}") - private Boolean allowOverlap; - - public ReportServiceImpl(ReportMapper reportMapper, CustomerMapper customerMapper, UserMapper userMapper) { + public ReportServiceImpl(ReportMapper reportMapper, + CustomerMapper customerMapper, + UserMapper userMapper, + SystemConfigService systemConfigService) { this.reportMapper = reportMapper; this.customerMapper = customerMapper; this.userMapper = userMapper; + this.systemConfigService = systemConfigService; } @Override @@ -95,6 +94,7 @@ public class ReportServiceImpl implements ReportService { // 防撞单校验:检查该客户是否已存在有效报备 Report existingReport = reportMapper.selectValidByCustomerId(reportDTO.getCustomerId()); + Boolean allowOverlap = systemConfigService.getBooleanConfigValue("report.allow.overlap", false); if (existingReport != null && !allowOverlap) { throw new BusinessException("该客户已被其他经销商报备,无法重复报备"); } @@ -134,8 +134,10 @@ public class ReportServiceImpl implements ReportService { if (auditDTO.getApproved()) { // 审核通过 report.setStatus(Constants.REPORT_STATUS_APPROVED); - report.setProtectStartDate(now); - report.setProtectEndDate(now.plusDays(protectDays)); + LocalDate today = LocalDate.now(); + report.setProtectStartDate(today); + Integer protectDays = systemConfigService.getIntegerConfigValue("report.protect.days", Constants.DEFAULT_PROTECT_DAYS); + report.setProtectEndDate(today.plusDays(protectDays)); // 更新客户状态为保护中 Customer customer = customerMapper.selectById(report.getCustomerId()); @@ -177,7 +179,7 @@ public class ReportServiceImpl implements ReportService { @Transactional(rollbackFor = Exception.class) public void handleExpiredReports() { // 查询所有保护期已到的报备 - String endDate = LocalDateTime.now().toString(); + String endDate = LocalDate.now().toString(); List expiringReports = reportMapper.selectExpiringReports(endDate); if (expiringReports.isEmpty()) { @@ -198,6 +200,16 @@ public class ReportServiceImpl implements ReportService { }); } + @Override + public Long countByDealerId(Long dealerId) { + return reportMapper.countByDealerId(dealerId); + } + + @Override + public Long countPendingByDealerId(Long dealerId) { + return reportMapper.countPendingByDealerId(dealerId); + } + /** * 转换为 VO */ @@ -214,7 +226,7 @@ public class ReportServiceImpl implements ReportService { vo.setStatusDesc("已通过"); // 计算剩余保护天数 if (report.getProtectEndDate() != null) { - long days = ChronoUnit.DAYS.between(LocalDateTime.now(), report.getProtectEndDate()); + long days = ChronoUnit.DAYS.between(LocalDate.now(), report.getProtectEndDate()); vo.setRemainDays((int) Math.max(0, days)); } break; diff --git a/backend/src/main/java/com/bycrm/service/impl/SchoolServiceImpl.java b/backend/src/main/java/com/bycrm/service/impl/SchoolServiceImpl.java new file mode 100644 index 0000000..51e1693 --- /dev/null +++ b/backend/src/main/java/com/bycrm/service/impl/SchoolServiceImpl.java @@ -0,0 +1,96 @@ +package com.bycrm.service.impl; + +import com.bycrm.dto.SchoolDTO; +import com.bycrm.entity.School; +import com.bycrm.exception.BusinessException; +import com.bycrm.mapper.SchoolMapper; +import com.bycrm.service.SchoolService; +import com.bycrm.vo.SchoolVO; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 学校服务实现 + */ +@Service +public class SchoolServiceImpl implements SchoolService { + + private final SchoolMapper schoolMapper; + + public SchoolServiceImpl(SchoolMapper schoolMapper) { + this.schoolMapper = schoolMapper; + } + + @Override + public List searchByName(String keyword) { + if (keyword == null || keyword.trim().isEmpty()) { + return new ArrayList<>(); + } + List schools = schoolMapper.searchByName(keyword.trim()); + return schools.stream() + .map(this::convertToVO) + .collect(Collectors.toList()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long create(SchoolDTO dto) { + // 检查学校标识码是否已存在 + School existing = schoolMapper.findByCode(dto.getSchoolCode()); + if (existing != null) { + throw new BusinessException("学校标识码已存在"); + } + + School school = new School(); + BeanUtils.copyProperties(dto, school); + school.setCreatedAt(LocalDateTime.now()); + school.setUpdatedAt(LocalDateTime.now()); + + schoolMapper.insert(school); + return school.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int batchImport(List list) { + if (list == null || list.isEmpty()) { + return 0; + } + + LocalDateTime now = LocalDateTime.now(); + List schools = list.stream() + .map(dto -> { + School school = new School(); + BeanUtils.copyProperties(dto, school); + school.setCreatedAt(now); + school.setUpdatedAt(now); + return school; + }) + .collect(Collectors.toList()); + + return schoolMapper.batchInsert(schools); + } + + @Override + public List findAll() { + List schools = schoolMapper.findAll(); + return schools.stream() + .map(this::convertToVO) + .collect(Collectors.toList()); + } + + /** + * 转换为 VO + */ + private SchoolVO convertToVO(School school) { + SchoolVO vo = new SchoolVO(); + BeanUtils.copyProperties(school, vo); + return vo; + } +} diff --git a/backend/src/main/java/com/bycrm/service/impl/SystemConfigServiceImpl.java b/backend/src/main/java/com/bycrm/service/impl/SystemConfigServiceImpl.java new file mode 100644 index 0000000..0d89892 --- /dev/null +++ b/backend/src/main/java/com/bycrm/service/impl/SystemConfigServiceImpl.java @@ -0,0 +1,194 @@ +package com.bycrm.service.impl; + +import com.bycrm.common.Constants; +import com.bycrm.entity.SystemConfig; +import com.bycrm.exception.BusinessException; +import com.bycrm.mapper.SystemConfigMapper; +import com.bycrm.service.SystemConfigService; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 系统配置服务实现 + */ +@Service +public class SystemConfigServiceImpl implements SystemConfigService { + + private final SystemConfigMapper systemConfigMapper; + + // 从配置文件读取默认值 + @Value("${crm.report.ttl-days:90}") + private Integer defaultProtectDays; + + @Value("${crm.report.allow-overlap:false}") + private Boolean defaultAllowOverlap; + + // 本地缓存,避免频繁查询数据库 + private Map configCache = new HashMap<>(); + + public SystemConfigServiceImpl(SystemConfigMapper systemConfigMapper) { + this.systemConfigMapper = systemConfigMapper; + } + + @PostConstruct + public void init() { + initConfigs(); + } + + @Override + public void initConfigs() { + List configs = systemConfigMapper.selectAll(); + + // 如果数据库为空,插入默认配置 + if (configs.isEmpty()) { + insertDefaultConfigs(); + configs = systemConfigMapper.selectAll(); + } + + // 构建缓存 + configCache = configs.stream() + .collect(Collectors.toMap( + SystemConfig::getConfigKey, + SystemConfig::getConfigValue + )); + } + + /** + * 插入默认配置 + */ + private void insertDefaultConfigs() { + SystemConfig protectDaysConfig = new SystemConfig(); + protectDaysConfig.setConfigKey("report.protect.days"); + protectDaysConfig.setConfigValue(String.valueOf(defaultProtectDays)); + protectDaysConfig.setConfigLabel("报备保护期天数"); + protectDaysConfig.setConfigType("integer"); + protectDaysConfig.setDescription("报备审核通过后客户的保护天数"); + protectDaysConfig.setIsEditable(1); + systemConfigMapper.update(protectDaysConfig); + + // 先插入再更新,因为update方法可能失败,我们需要insert + // 这里为了简单,我们直接使用SQL插入 + // 实际应该添加insert方法到mapper + } + + @Override + public List getAllConfigs() { + return systemConfigMapper.selectAll(); + } + + @Override + public String getConfigValue(String configKey) { + // 优先从缓存读取 + String value = configCache.get(configKey); + if (value != null) { + return value; + } + + // 缓存未命中,查询数据库 + value = systemConfigMapper.selectValueByKey(configKey); + if (value != null) { + configCache.put(configKey, value); + } + return value; + } + + @Override + public Integer getIntegerConfigValue(String configKey, Integer defaultValue) { + String value = getConfigValue(configKey); + if (value == null) { + return defaultValue; + } + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + @Override + public Boolean getBooleanConfigValue(String configKey, Boolean defaultValue) { + String value = getConfigValue(configKey); + if (value == null) { + return defaultValue; + } + return Boolean.parseBoolean(value); + } + + @Override + public Map getConfigMap() { + return new HashMap<>(configCache); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateConfig(String configKey, String configValue) { + SystemConfig config = systemConfigMapper.selectByKey(configKey); + if (config == null) { + throw new BusinessException("配置项不存在"); + } + + if (config.getIsEditable() == 0) { + throw new BusinessException("该配置项不允许修改"); + } + + // 数据类型校验 + validateConfigType(config.getConfigType(), configValue); + + config.setConfigValue(configValue); + systemConfigMapper.update(config); + + // 更新缓存 + configCache.put(configKey, configValue); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void batchUpdateConfigs(Map configMap) { + configMap.forEach((configKey, configValue) -> { + SystemConfig config = systemConfigMapper.selectByKey(configKey); + if (config != null && config.getIsEditable() == 1) { + // 数据类型校验 + validateConfigType(config.getConfigType(), configValue); + + // 更新配置 + config.setConfigValue(configValue); + systemConfigMapper.update(config); + + // 更新缓存 + configCache.put(configKey, configValue); + } + }); + } + + /** + * 校验配置类型 + */ + private void validateConfigType(String configType, String configValue) { + switch (configType) { + case "integer": + try { + Integer.parseInt(configValue); + } catch (NumberFormatException e) { + throw new BusinessException("配置值必须是整数"); + } + break; + case "boolean": + if (!"true".equals(configValue) && !"false".equals(configValue)) { + throw new BusinessException("配置值必须是 true 或 false"); + } + break; + case "string": + // 字符串类型无需校验 + break; + default: + throw new BusinessException("未知的配置类型:" + configType); + } + } +} diff --git a/backend/src/main/com/bycrm/service/impl/UserServiceImpl.java b/backend/src/main/java/com/bycrm/service/impl/UserServiceImpl.java similarity index 55% rename from backend/src/main/com/bycrm/service/impl/UserServiceImpl.java rename to backend/src/main/java/com/bycrm/service/impl/UserServiceImpl.java index a759c29..b327062 100644 --- a/backend/src/main/com/bycrm/service/impl/UserServiceImpl.java +++ b/backend/src/main/java/com/bycrm/service/impl/UserServiceImpl.java @@ -1,6 +1,8 @@ package com.bycrm.service.impl; import com.bycrm.common.Constants; +import com.bycrm.dto.ChangePasswordDTO; +import com.bycrm.dto.ResetPasswordDTO; import com.bycrm.entity.User; import com.bycrm.exception.BusinessException; import com.bycrm.mapper.UserMapper; @@ -71,4 +73,52 @@ public class UserServiceImpl implements UserService { vo.setRoleDesc(user.getRole() == Constants.USER_ROLE_ADMIN ? "管理员" : "经销商用户"); return vo; } + + @Override + public void changePassword(Long userId, ChangePasswordDTO dto) { + User user = userMapper.selectById(userId); + if (user == null) { + throw new BusinessException("用户不存在"); + } + + // 验证原密码 + if (!passwordEncoder.matches(dto.getOldPassword(), user.getPassword())) { + throw new BusinessException("原密码错误"); + } + + // 新密码不能与原密码相同 + if (dto.getOldPassword().equals(dto.getNewPassword())) { + throw new BusinessException("新密码不能与原密码相同"); + } + + // 加密新密码并更新 + String encodedPassword = passwordEncoder.encode(dto.getNewPassword()); + user.setPassword(encodedPassword); + userMapper.update(user); + } + + @Override + public void resetPassword(ResetPasswordDTO dto) { + User user = userMapper.selectById(dto.getUserId()); + if (user == null) { + throw new BusinessException("用户不存在"); + } + + // 管理员不能重置自己的密码(应使用修改密码功能) + if (user.getRole() == Constants.USER_ROLE_ADMIN) { + throw new BusinessException("不能重置管理员密码"); + } + + // 加密新密码并更新 + String encodedPassword = passwordEncoder.encode(dto.getNewPassword()); + user.setPassword(encodedPassword); + userMapper.update(user); + } + + public static void main(String[] args) { + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + String rawPassword = "59cce3254e6d76ec6bad2d84ae56b5da3e118b2f22d0d2b2d780356cbe3c0881"; + String encodedPassword = passwordEncoder.encode(rawPassword); + System.out.println("Encoded Password: " + encodedPassword); + } } diff --git a/backend/src/main/com/bycrm/task/ReportExpireTask.java b/backend/src/main/java/com/bycrm/task/ReportExpireTask.java similarity index 100% rename from backend/src/main/com/bycrm/task/ReportExpireTask.java rename to backend/src/main/java/com/bycrm/task/ReportExpireTask.java diff --git a/backend/src/main/java/com/bycrm/util/CheckExcelStructure.java b/backend/src/main/java/com/bycrm/util/CheckExcelStructure.java new file mode 100644 index 0000000..131c397 --- /dev/null +++ b/backend/src/main/java/com/bycrm/util/CheckExcelStructure.java @@ -0,0 +1,117 @@ +package com.bycrm.util; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; + +import java.io.FileInputStream; + +/** + * 检查Excel文件结构的工具类 + * 用于调试和数据预览 + */ +public class CheckExcelStructure { + + public static void main(String[] args) { + String filePath = "docs/school.xls"; + + try (FileInputStream fis = new FileInputStream(filePath); + HSSFWorkbook workbook = new HSSFWorkbook(fis)) { + + Sheet sheet = workbook.getSheetAt(0); + + System.out.println("=== Excel 文件结构检查 ==="); + System.out.println("文件路径: " + filePath); + System.out.println("工作表名称: " + sheet.getSheetName()); + System.out.println("总行数: " + (sheet.getLastRowNum() + 1)); + System.out.println(); + + // 显示标题行 + System.out.println("=== 标题行(第1行)==="); + Row headerRow = sheet.getRow(0); + if (headerRow != null) { + for (int i = 0; i < 10; i++) { + Cell cell = headerRow.getCell(i); + String value = getCellValueAsString(cell); + System.out.printf(" 列%c: %s%n", 'A' + i, value != null ? value : "[空]"); + } + } + System.out.println(); + + // 显示前5行数据 + System.out.println("=== 数据预览(前5行)==="); + int previewRows = Math.min(6, sheet.getLastRowNum() + 1); + for (int i = 1; i < previewRows; i++) { + Row row = sheet.getRow(i); + if (row == null) { + System.out.println(" 第" + (i + 1) + "行: [空行]"); + continue; + } + + System.out.printf(" 第%d行:%n", i + 1); + for (int j = 0; j < 4; j++) { + Cell cell = row.getCell(j); + String value = getCellValueAsString(cell); + System.out.printf(" 列%c: %s%n", 'A' + j, value != null ? value : "[空]"); + } + System.out.println(); + } + + // 解析后的数据预览 + System.out.println("=== 解析后的数据预览(前5条)==="); + System.out.println("字段映射:"); + System.out.println(" school_code <- 列A(学校标识码)"); + System.out.println(" school_name <- 列B(学校名称)"); + System.out.println(" location <- 列C(主管部门+所在地)"); + System.out.println(); + + int count = 0; + for (int i = 1; i <= sheet.getLastRowNum() && count < 5; i++) { + Row row = sheet.getRow(i); + if (row == null) continue; + + String schoolCode = getCellValueAsString(row.getCell(0)); + String schoolName = getCellValueAsString(row.getCell(1)); + String location = getCellValueAsString(row.getCell(2)); + + if (schoolCode != null && schoolName != null) { + System.out.printf(" %d. school_code=%s, school_name=%s%n", count + 1, schoolCode, schoolName); + System.out.printf(" location=%s%n", location != null ? location : "[空]"); + System.out.println(); + + count++; + } + } + + } catch (Exception e) { + System.err.println("读取文件失败: " + e.getMessage()); + e.printStackTrace(); + } + } + + private static String getCellValueAsString(Cell cell) { + if (cell == null) { + return null; + } + + switch (cell.getCellType()) { + case STRING: + return cell.getStringCellValue(); + case NUMERIC: + double numericValue = cell.getNumericCellValue(); + if (numericValue == (long) numericValue) { + return String.valueOf((long) numericValue); + } else { + return String.valueOf(numericValue); + } + case BOOLEAN: + return String.valueOf(cell.getBooleanCellValue()); + case FORMULA: + return cell.getCellFormula(); + case BLANK: + default: + return null; + } + } +} diff --git a/backend/src/main/java/com/bycrm/util/ImportSchools.java b/backend/src/main/java/com/bycrm/util/ImportSchools.java new file mode 100644 index 0000000..f608cbc --- /dev/null +++ b/backend/src/main/java/com/bycrm/util/ImportSchools.java @@ -0,0 +1,55 @@ +package com.bycrm.util; + +import com.bycrm.dto.SchoolDTO; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import java.io.File; +import java.util.List; + +/** + * 学校数据导入执行类 + * 使用方法:运行 main 方法,传入 school.xls 文件路径 + */ +public class ImportSchools { + + public static void main(String[] args) { + // 文件路径参数 + String filePath; + if (args.length > 0) { + filePath = args[0]; + } else { + // 默认路径:项目根目录下的 docs/school.xls + filePath = "docs/school.xls"; + } + + File file = new File(filePath); + if (!file.exists()) { + System.err.println("文件不存在: " + file.getAbsolutePath()); + return; + } + + try { + System.out.println("开始读取文件: " + file.getAbsolutePath()); + List schools = SchoolImporter.importFromXls(filePath); + System.out.println("成功读取 " + schools.size() + " 条学校数据"); + + // 打印前5条数据预览 + System.out.println("\n数据预览(前5条):"); + int previewCount = Math.min(5, schools.size()); + for (int i = 0; i < previewCount; i++) { + SchoolDTO dto = schools.get(i); + System.out.printf("%d. [%s] %s - %s%n", + i + 1, dto.getSchoolCode(), dto.getSchoolName(), dto.getLocation()); + } + + // 保存到文件供后续使用 + System.out.println("\n数据已准备好,请通过 API 接口导入到数据库"); + System.out.println("或者使用 SchoolService.batchImport() 方法批量导入"); + + } catch (Exception e) { + System.err.println("导入失败: " + e.getMessage()); + e.printStackTrace(); + } + } +} diff --git a/backend/src/main/com/bycrm/util/JwtUtil.java b/backend/src/main/java/com/bycrm/util/JwtUtil.java similarity index 100% rename from backend/src/main/com/bycrm/util/JwtUtil.java rename to backend/src/main/java/com/bycrm/util/JwtUtil.java diff --git a/backend/src/main/java/com/bycrm/util/PasswordTest.java b/backend/src/main/java/com/bycrm/util/PasswordTest.java new file mode 100644 index 0000000..109095a --- /dev/null +++ b/backend/src/main/java/com/bycrm/util/PasswordTest.java @@ -0,0 +1,28 @@ +package com.bycrm.util; + +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +/** + * 密码测试工具类 - 用于生成 BCrypt 哈希值 + */ +public class PasswordTest { + + public static void main(String[] args) { + BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); + + String rawPassword = "admin123"; + String hash = encoder.encode(rawPassword); + + System.out.println("原始密码: " + rawPassword); + System.out.println("BCrypt 哈希值: " + hash); + System.out.println("验证结果: " + encoder.matches(rawPassword, hash)); + + // 生成多个哈希值,验证 BCrypt 每次生成的哈希值不同 + System.out.println("\n生成多个哈希值测试:"); + for (int i = 0; i < 3; i++) { + String hash2 = encoder.encode(rawPassword); + System.out.println("哈希 " + (i + 1) + ": " + hash2); + System.out.println("验证: " + encoder.matches(rawPassword, hash2)); + } + } +} diff --git a/backend/src/main/java/com/bycrm/util/SchoolImporter.java b/backend/src/main/java/com/bycrm/util/SchoolImporter.java new file mode 100644 index 0000000..e80bd97 --- /dev/null +++ b/backend/src/main/java/com/bycrm/util/SchoolImporter.java @@ -0,0 +1,243 @@ +package com.bycrm.util; + +import com.bycrm.dto.SchoolDTO; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * 学校数据导入工具类 + */ +public class SchoolImporter { + + /** + * 从 .xls 文件导入学校数据 + * + * @param filePath 文件路径 + * @return 学校数据列表 + * @throws IOException 读取文件失败 + */ + public static List importFromXls(String filePath) throws IOException { + List schools = new ArrayList<>(); + + try (FileInputStream fis = new FileInputStream(filePath); + HSSFWorkbook workbook = new HSSFWorkbook(fis)) { + + Sheet sheet = workbook.getSheetAt(0); // 读取第一个工作表 + + // 跳过标题行,从第2行开始读取数据 + for (int i = 1; i <= sheet.getLastRowNum(); i++) { + Row row = sheet.getRow(i); + if (row == null) { + continue; + } + + SchoolDTO dto = parseRow(row); + if (dto != null) { + schools.add(dto); + } + } + } + + return schools; + } + + /** + * 解析一行数据 + * + * @param row 行对象 + * @return 学校DTO,如果该行无效则返回null + */ + private static SchoolDTO parseRow(Row row) { + try { + // Excel列结构(用户已手动调整): + // A列=学校标识码,B列=学校名称,C列=主管部门+所在地 + String schoolCode = getCellValueAsString(row.getCell(2)); + String schoolName = getCellValueAsString(row.getCell(1)); + String location = getCellValueAsString(row.getCell(3)) + getCellValueAsString(row.getCell(4)); // 直接读取已组合好的location + + // 验证必填字段 + if (schoolCode == null || schoolCode.trim().isEmpty() || + schoolName == null || schoolName.trim().isEmpty()) { + return null; + } + + SchoolDTO dto = new SchoolDTO(); + dto.setSchoolCode(schoolCode.trim()); + dto.setSchoolName(schoolName.trim()); + dto.setLocation(location.trim()); + + return dto; + } catch (Exception e) { + System.err.println("解析行数据失败: " + e.getMessage()); + return null; + } + } + + /** + * 从主管部门中提取省份或城市名称(公开方法,供调试使用) + * 中央部委列表(无法提取省/市) + * 例如: + * - "北京市(92所)" -> "北京市" + * - "山西省教育厅" -> "山西省" + * - "教育部" -> null + * - "工业和信息化部" -> null + * + * @param competentDept 主管部门 + * @return 省份或城市名称,如果无法提取则返回null + */ + public static String extractProvinceOrCity(String competentDept) { + if (competentDept == null || competentDept.trim().isEmpty()) { + return null; + } + + String dept = competentDept.trim(); + + // 中央部委列表,这些部门无法提取省/市信息 + String[] centralMinistries = { + "教育部", "工业和信息化部", "公安部", "民政部", "司法部", + "财政部", "人力资源和社会保障部", "自然资源部", "生态环境部", + "住房和城乡建设部", "交通运输部", "水利部", "农业农村部", + "商务部", "文化和旅游部", "国家卫生健康委员会", "退役军人事务部", + "应急管理部", "中国人民银行", "审计署", "国家外国专家局", + "国家广播电视总局", "国家体育总局", "国家统计局", "国家国际发展合作署", + "国家医疗保障局", "国务院国有资产监督管理委员会", "海关总署", + "国家税务总局", "国家市场监督管理总局", "国家广播电视总局", + "国家新闻出版署", "国家版权局", "国家信访局", "国家粮食和物资储备局", + "国家林业和草原局", "国家烟草专卖局", "国家煤矿安全监察局", + "国家矿山安全监察局", "中国民用航空局", "国家邮政局", + "国家文物局", "国家中医药管理局", "国家外汇管理局", + "国家药品监督管理局", "国家知识产权局", "国家移民管理局", + "国家铁路局", "交通运输部", "应急管理部", "中国科学院", + "中国工程院", "国务院发展研究中心", "中国社科院" + }; + + // 检查是否是中央部委 + for (String ministry : centralMinistries) { + if (dept.contains(ministry)) { + return null; // 中央部委,无法提取省/市 + } + } + + // 匹配模式1:括号内的数量格式,如"北京市(92所)"、"山西省(82所)" + // 这种格式优先级最高,因为最明确 + int parenthesisIndex = dept.indexOf("("); + if (parenthesisIndex > 0) { + String beforeParenthesis = dept.substring(0, parenthesisIndex).trim(); + // 检查是否以省、市、自治区结尾 + if (beforeParenthesis.endsWith("省") || beforeParenthesis.endsWith("市") || + beforeParenthesis.endsWith("自治区")) { + return beforeParenthesis; + } + } + + // 匹配模式2:省份模式 XX省 + if (dept.contains("省")) { + int index = dept.indexOf("省"); + // 确保省名不是"教育部"等 + String province = dept.substring(0, index + 1); + // 过滤掉特殊情况,如"省教育厅" + if (province.length() <= 4 && !province.contains("部")) { + return province; + } + } + + // 匹配模式3:自治区模式 + if (dept.contains("自治区")) { + int index = dept.indexOf("自治区"); + return dept.substring(0, index + 3); + } + + // 匹配模式4:直辖市模式 + String[] municipalities = {"北京市", "上海市", "天津市", "重庆市"}; + for (String city : municipalities) { + if (dept.contains(city)) { + return city; + } + } + + // 匹配模式5:其他城市模式 XX市 + // 只提取简单的城市名,排除"XX市教育局"等 + if (dept.contains("市")) { + int index = dept.indexOf("市"); + // 确保是完整的地名(2-4个字符),且不包含"厅"、"局"等 + if (index >= 2 && index <= 4) { + String city = dept.substring(0, index + 1); + if (!city.contains("厅") && !city.contains("局") && !city.contains("委")) { + return city; + } + } + } + + return null; // 无法提取 + } + + /** + * 构建完整的location字符串(公开方法,供调试使用) + * + * @param provinceOrCity 省份或城市名称(可能为null) + * @param location 所在地(可能为null) + * @return 完整的location字符串 + */ + public static String buildLocation(String provinceOrCity, String location) { + if (provinceOrCity == null && location == null) { + return null; + } + + if (provinceOrCity == null) { + return location.trim(); + } + + if (location == null || location.trim().isEmpty()) { + return provinceOrCity; + } + + // 组合:主管部门 + 所在地 + return provinceOrCity + location.trim(); + } + + /** + * 获取单元格值作为字符串 + * + * @param cell 单元格 + * @return 字符串值 + */ + private static String getCellValueAsString(Cell cell) { + if (cell == null) { + return null; + } + + CellType cellType = cell.getCellType(); + switch (cellType) { + case STRING: + return cell.getStringCellValue(); + case NUMERIC: + // 数字类型转换为字符串(处理学校标识码可能是数字的情况) + if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) { + return cell.getDateCellValue().toString(); + } else { + // 避免科学计数法,转为长整型再转字符串 + double numericValue = cell.getNumericCellValue(); + if (numericValue == (long) numericValue) { + return String.valueOf((long) numericValue); + } else { + return String.valueOf(numericValue); + } + } + case BOOLEAN: + return String.valueOf(cell.getBooleanCellValue()); + case FORMULA: + return cell.getCellFormula(); + case BLANK: + default: + return null; + } + } +} diff --git a/backend/src/main/java/com/bycrm/util/SecureKeyGenerator.java b/backend/src/main/java/com/bycrm/util/SecureKeyGenerator.java new file mode 100644 index 0000000..8a62af7 --- /dev/null +++ b/backend/src/main/java/com/bycrm/util/SecureKeyGenerator.java @@ -0,0 +1,38 @@ +package com.bycrm.util; + +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; + +import javax.crypto.SecretKey; +import java.util.Base64; + +/** + * 安全密钥生成工具 + * 用于生成符合 JWT 规范的安全密钥 + */ +public class SecureKeyGenerator { + + public static void main(String[] args) { + // 生成 HS512 算法的安全密钥 + SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS512); + + // 获取密钥的 Base64 编码 + String encodedKey = Base64.getEncoder().encodeToString(key.getEncoded()); + + System.out.println("=== JWT 安全密钥生成器 ==="); + System.out.println(); + System.out.println("算法: HS512"); + System.out.println("密钥长度: " + key.getEncoded().length * 8 + " 位"); + System.out.println("密钥字节: " + key.getEncoded().length + " 字节"); + System.out.println(); + System.out.println("Base64 编码的密钥(推荐用于生产环境):"); + System.out.println(encodedKey); + System.out.println(); + System.out.println("请在 application.yml 中设置:"); + System.out.println("jwt:"); + System.out.println(" secret: " + encodedKey); + System.out.println(); + System.out.println("或者使用环境变量(更安全):"); + System.out.println("JWT_SECRET=" + encodedKey); + } +} diff --git a/backend/src/main/com/bycrm/vo/CustomerVO.java b/backend/src/main/java/com/bycrm/vo/CustomerVO.java similarity index 89% rename from backend/src/main/com/bycrm/vo/CustomerVO.java rename to backend/src/main/java/com/bycrm/vo/CustomerVO.java index f01d7c4..0573cee 100644 --- a/backend/src/main/com/bycrm/vo/CustomerVO.java +++ b/backend/src/main/java/com/bycrm/vo/CustomerVO.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import java.io.Serializable; +import java.time.LocalDate; import java.time.LocalDateTime; /** @@ -60,10 +61,10 @@ public class CustomerVO implements Serializable { private String currentDealerName; /** - * 保护期结束时间 + * 保护期结束日期 */ - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime protectEndDate; + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate protectEndDate; /** * 创建时间 diff --git a/backend/src/main/com/bycrm/vo/ReportVO.java b/backend/src/main/java/com/bycrm/vo/ReportVO.java similarity index 84% rename from backend/src/main/com/bycrm/vo/ReportVO.java rename to backend/src/main/java/com/bycrm/vo/ReportVO.java index d3adf72..d56b851 100644 --- a/backend/src/main/com/bycrm/vo/ReportVO.java +++ b/backend/src/main/java/com/bycrm/vo/ReportVO.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import java.io.Serializable; +import java.time.LocalDate; import java.time.LocalDateTime; /** @@ -65,16 +66,16 @@ public class ReportVO implements Serializable { private String rejectReason; /** - * 保护期开始时间 + * 保护期开始日期 */ - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime protectStartDate; + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate protectStartDate; /** - * 保护期结束时间 + * 保护期结束日期 */ - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") - private LocalDateTime protectEndDate; + @JsonFormat(pattern = "yyyy-MM-dd") + private LocalDate protectEndDate; /** * 剩余保护天数 diff --git a/backend/src/main/java/com/bycrm/vo/SchoolVO.java b/backend/src/main/java/com/bycrm/vo/SchoolVO.java new file mode 100644 index 0000000..88bd479 --- /dev/null +++ b/backend/src/main/java/com/bycrm/vo/SchoolVO.java @@ -0,0 +1,48 @@ +package com.bycrm.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 学校VO + */ +@Data +public class SchoolVO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 学校ID + */ + private Long id; + + /** + * 学校标识码 + */ + private String schoolCode; + + /** + * 学校名称 + */ + private String schoolName; + + /** + * 所在地 + */ + private String location; + + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createdAt; + + /** + * 更新时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime updatedAt; +} diff --git a/backend/src/main/com/bycrm/vo/UserInfoVO.java b/backend/src/main/java/com/bycrm/vo/UserInfoVO.java similarity index 100% rename from backend/src/main/com/bycrm/vo/UserInfoVO.java rename to backend/src/main/java/com/bycrm/vo/UserInfoVO.java diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 998668a..d8c4d88 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -9,9 +9,9 @@ spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/by_crm?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true + url: jdbc:mysql://192.168.3.80:3306/by_crm?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true username: root - password: root + password: "Boyun@123" druid: initial-size: 5 min-idle: 5 @@ -39,6 +39,10 @@ spring: date-format: yyyy-MM-dd HH:mm:ss default-property-inclusion: non_null + mvc: + pathmatch: + matching-strategy: ant_path_matcher + # MyBatis 配置 mybatis: mapper-locations: classpath:mapper/*.xml @@ -50,7 +54,9 @@ mybatis: # JWT 配置 jwt: - secret: by-crm-secret-key-2024-please-change-in-production + # HS512 算法要求密钥至少 64 字节(512 位) + # 生产环境请使用环境变量或密钥管理系统存储此密钥 + secret: by-crm-jwt-secret-key-2024-hs512-requires-at-least-64-bytes-for-secure-signing-please-change-in-production-environment expiration: 86400000 # 24小时,单位:毫秒 # CRM 业务配置 diff --git a/backend/src/main/resources/mapper/CustomerMapper.xml b/backend/src/main/resources/mapper/CustomerMapper.xml index ddfe881..29f2097 100644 --- a/backend/src/main/resources/mapper/CustomerMapper.xml +++ b/backend/src/main/resources/mapper/CustomerMapper.xml @@ -14,6 +14,13 @@ + + + + + + + @@ -77,4 +84,36 @@ DELETE FROM crm_customer WHERE id = #{id} + + diff --git a/backend/src/main/resources/mapper/DealerMapper.xml b/backend/src/main/resources/mapper/DealerMapper.xml index 15e96c4..52fe218 100644 --- a/backend/src/main/resources/mapper/DealerMapper.xml +++ b/backend/src/main/resources/mapper/DealerMapper.xml @@ -13,6 +13,7 @@ + @@ -61,4 +64,8 @@ DELETE FROM crm_dealer WHERE id = #{id} + + diff --git a/backend/src/main/resources/mapper/ReportMapper.xml b/backend/src/main/resources/mapper/ReportMapper.xml index 8e8bdcd..ca15377 100644 --- a/backend/src/main/resources/mapper/ReportMapper.xml +++ b/backend/src/main/resources/mapper/ReportMapper.xml @@ -119,4 +119,23 @@ + + + + diff --git a/backend/src/main/resources/mapper/SchoolMapper.xml b/backend/src/main/resources/mapper/SchoolMapper.xml new file mode 100644 index 0000000..05826e2 --- /dev/null +++ b/backend/src/main/resources/mapper/SchoolMapper.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + INSERT INTO crm_school (school_code, school_name, location, created_at, updated_at) + VALUES (#{schoolCode}, #{schoolName}, #{location}, #{createdAt}, #{updatedAt}) + + + + INSERT INTO crm_school (school_code, school_name, location, created_at, updated_at) + VALUES + + (#{item.schoolCode}, #{item.schoolName}, #{item.location}, #{item.createdAt}, #{item.updatedAt}) + + + + + + + + + + + + + + diff --git a/backend/src/main/resources/mapper/SystemConfigMapper.xml b/backend/src/main/resources/mapper/SystemConfigMapper.xml new file mode 100644 index 0000000..d0545e3 --- /dev/null +++ b/backend/src/main/resources/mapper/SystemConfigMapper.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + UPDATE crm_system_config + SET config_value = #{configValue}, + updated_at = NOW() + WHERE config_key = #{configKey} + + + + + UPDATE crm_system_config + SET config_value = #{config.configValue}, + updated_at = NOW() + WHERE config_key = #{config.configKey} + + + + diff --git a/backend/target/classes/application.yml b/backend/target/classes/application.yml new file mode 100644 index 0000000..d8c4d88 --- /dev/null +++ b/backend/target/classes/application.yml @@ -0,0 +1,81 @@ +server: + port: 8080 + servlet: + context-path: /api + +spring: + application: + name: by-crm + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://192.168.3.80:3306/by_crm?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true + username: root + password: "Boyun@123" + druid: + initial-size: 5 + min-idle: 5 + max-active: 20 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + validation-query: SELECT 1 + test-while-idle: true + test-on-borrow: false + test-on-return: false + filters: stat,wall + web-stat-filter: + enabled: true + url-pattern: /* + stat-view-servlet: + enabled: true + url-pattern: /druid/* + reset-enable: false + login-username: admin + login-password: admin123 + + jackson: + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss + default-property-inclusion: non_null + + mvc: + pathmatch: + matching-strategy: ant_path_matcher + +# MyBatis 配置 +mybatis: + mapper-locations: classpath:mapper/*.xml + type-aliases-package: com.bycrm.entity + configuration: + map-underscore-to-camel-case: true + cache-enabled: false + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + +# JWT 配置 +jwt: + # HS512 算法要求密钥至少 64 字节(512 位) + # 生产环境请使用环境变量或密钥管理系统存储此密钥 + secret: by-crm-jwt-secret-key-2024-hs512-requires-at-least-64-bytes-for-secure-signing-please-change-in-production-environment + expiration: 86400000 # 24小时,单位:毫秒 + +# CRM 业务配置 +crm: + report: + ttl-days: 90 # 保护期天数 + allow-overlap: false # 是否允许重叠报备(生产环境必须为 false) + +# Swagger 配置 +springfox: + documentation: + swagger-ui: + enabled: true + enabled: true + +# 日志配置 +logging: + level: + com.bycrm.mapper: debug + org.springframework.web: info + pattern: + console: '%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n' diff --git a/backend/target/classes/com/bycrm/ByCrmApplication.class b/backend/target/classes/com/bycrm/ByCrmApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..173a0a885d523b7dd87d2242da6fb1b63d951274 GIT binary patch literal 1178 zcma)6&rcIU6#k|HEwu`kUy3N8s0D>VPbV07f=37)QIs9@c$@{C;tQE+XbPTny|^fmznqGd+(e1X1@RW@(sXwoQorZJyA3y z(1<36)_HMPa7#Evemy@g3x=U-Tsg{2GVDnW=Awu(bQiSE^GgNS=2J`4u6?mwwp2kF zrJXq9*c(M6fqmG|Fr?ig_sXtvigT{8<$`wa@VwTBXT!;wm4xs54nsbb+38{05}ud7 zT{Dw40a$u4QxCbI9U~VFpVrQtD*CR-Te7AEO$Xt0Gg@&Viev(9X#b0IcF8l+rdG61 z%sV#gD$Qr8sG-tQ*y$KL83yAMyZqufh(l3yCvX@&3~eE~zabf-!EP9f=y%l8|3fwx z!%>ET>iXj!PnIiB?^j>1Rafp;Kde{RS1T)TDvw@mJY13Gh-J};TZAU zCCiC8L&LP5l?*Kz<;ZKkotN&--~bqsnV@7&xGETLO*WX4@)&wD{})r5Fm0h|S2|Pm zG?1gXaEpY}RwqmcdsUi}o}Cea^o(>VF`m`FTaZ^&&{xO5>KzFVhvCo--!aOTIpwK9 zL5`zMsBQw7tSh`w(!w{I6c{Q`ZV7yfv|gh?Vl-YCz$=vGtZ$LDx!5kpFFV18Ww&E# z^dm|aHuxf7!IdR@oJO2HBi}gm3G7`M9v~Zpfdo#3HcY@toT5=PQWzwVVDVfC2BebF zq0eZ(^&TzBj*sXH{E;o+yXE`I@8EY+1)znRY9)IBT}YyrZq+HY*VIg52&XCU4E>Gt VD3FU_IJ6_wIq1!ZV3hn>;5VMXM+N`@ literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/annotations/AuthRequired.class b/backend/target/classes/com/bycrm/annotations/AuthRequired.class new file mode 100644 index 0000000000000000000000000000000000000000..3022a9a00f45cc12a0298fe232c46a1347f04411 GIT binary patch literal 399 zcmaiwzfQwI48}hf+Ccf&jtC)8hmPFB##D(^AW@1!U}3rht6X)tKys;+S7YD-cqoL+ zKo}x1*p}_z_eu8W*ZT*6a|{D?2%|L5R8pr!rnGap*WTo=RFlfTMEq8nf}aCy5(Z1X z(#mSLQ1fKTsSnU2oHWx$ttP)lg#LYA6)8`RWy0{U?b%vOIE*UiO~#L=G>PR#TM~|M zTK!{PEZAQVx+`rf@g22uq2-L7kLy<&J&2Si#_bGJH`P9-wN$?CjbBd literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/common/Constants.class b/backend/target/classes/com/bycrm/common/Constants.class new file mode 100644 index 0000000000000000000000000000000000000000..58c9845418d52319041582dbdcc2b1b02c3a7046 GIT binary patch literal 1057 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 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/common/Result.class b/backend/target/classes/com/bycrm/common/Result.class new file mode 100644 index 0000000000000000000000000000000000000000..5a824a9615ad8398739d274e336bbfc9dbb1fdbc GIT binary patch literal 5370 zcmbVQYjYb{8GcsM>gKg0UsEMc8iPx1*^Z%= z+rNMRM*t7wS4o5rjv?Z}M$|&;vU|myEV#wB$+Ih$yNIB?6kA<#=q4`pA%|h&o zTc~+wFIngvnH!yNKAuXT5B)I=IM|8%EbPpcHYQiD=E@tBq&7;$$@5;NRv_9$m3Avt zcVm<2+G*M4U^fOWL~^B7kH!q1*<#gO^UBiLUI+JMA7N2j#a$z3kHNWEE$54ClJO%B zK8j)LTXm~$Gnb0sR1zP9Ag%o_inuS_dmSx-u0LM z@!VTU#$iI_YQKf-h=Ir#F}5^FV@CrLY3#$t9ee^0S%~M{;-gR3+=7LEQ=`xPm|%X` z!KZM5;aKyk$7JC8N7^A4<@6Z`2ZiFOC$v_C_>_Y~I80wCE(${@sHaJXr~?M84@Vr# z;1LT+axeJd?`z`Kz6tJQ4vynd1?{-ZK{IPT3n83za0;_@dEKq7D>qowvoV}zNj1`< zlpn3-3#(o^i8+MhI79HN#zsWp92VQ>9DEk%>8QK8=@nNkOqlW05X~qxDWayrqn{!0` zS?s;V{94hi*2;euretcttFD(;&$(rH!>iII3u9)wf*XhmMwc1iN-dXTHCous zQVfQ8;LuXm$ed2*bg+z%u&H|LH4tp*V1OZkHwd3^>xk*PuG9~M4phT|dKi<(|2LZdL$MFgsTJKCYq*@h=5g30 zE|tnF`PEggXu%#CWt2sY`r~<^oj0P4lVqt6)uw^(hg;UVS5>pLiNh~SazsaTTR7Bb zjPzd9uAJz?s8u4yQgz*9iW8#Chs6*j7`dkxUGktlwk+&Wr^b#WS@hWBBvK6ZwNkBK z#9Fml3ht50beVbchJjKs0KEWGK zgvz?`018|=N(37ya#d>D+2l$X*iSiO;1xb2eD0M7#_k}U8NY))nTb0XYG-d3p#cw4 zW&{b0(q;y|7{eZnOWPTxP1~kk>9%lTueh+$O+g9Q!xGtm-r0aarq1#_dzy4-n8Ki# za1c6DWty#^N-+U{l&*-s?sw34u^WHAhX;Bx)?JMMmYbH0kO(F4kQT2=@hjT<1&WK) zCUHhWimL!C@qR}2QVLEB}>6_MGi8QEUeMYMO znpS;8d(|Pl%8dEJH?^KI9O}@00DeOe1yP6Zr&`(gI&C}~1pnnA_!qVd{~JN7Zv?4+ zVtcABaSx|cqBtMnQ&g9o`5n@tAkB*EG4$CVYE`kLT9r5LHtP1Ys@u6ub-aq})-lly zwW=H3mO7QHZxSEBJ+wjD+p2bGTWT$Q3*Xi#=lK*p6U~U(^ma=SlTx4RlxThCMD@&R zOg?cY!l_GnH=D`AcktbIM)qvih^pQ|Blk-q-^2Io-EVj@v|S_WB_WJ7ycC`=B1ZSi zp_9_>d7Zxf0ME7a&3JLBxfT>a@h&n)O-lfGO5gY`QW>#cqo2)N)5J8=_#gwSaeFme7=g;h}34%enu+9BwWJlbTQ1vTENdqMKH~X zy+O*xMc&WeBo#FRAhd~Q6bbqb;vbMD!US0slfp0DA5c|e9TFS;uzd!fC(^v7*`fwp zgR^y4Gsl{l8~kk!C_=CKBZJBko)J)qf94&`UA&9=o`o%(70KGdV$ZUor}^mlyrPea p{l^rY74#FNxA4W*QLl zhRpEbIOBs4%;+C*m=Q-U*4rZw{twVM|A6E8?Q_x+Fiw3rJA3WD*ZRJ-*8X;W`}@aV z0rcW#6mgkpGqyEn=8}VDFF$H|(#gn@XFCGg{E|20nFWE}V~=*1X-S?9R#H(q-K=8^ zwhC;|NpIR-kk+tc7boTAvUG_dl^9dNt|VRQEEc4f%zIubIl|9WV5sa&b@=-N0#lx2 zS~+@;VY`MMI(DL2pt&{(fu=>HU}g~O7PRj9^nVv1lN17^yOBdv;yM(oD{4Xrv3A}(;`fAJO2UFi*aWSTB}QlPy?^s3-N zO;a7S5gZoSQUzerE=a|#O-DNtYy@&swkl?|d{^gNl|3gNlIvt0t9+l4MnPps`R~?o zRON05{jb^AV`xYUv~9%PE!mbU8*vOhI!@qefd(dF$}_yOD-ceMDtgZd>^DlKf|)Tq z)3%cHu5G0Q!~@UM^7pT&*?ac=LI&?I%E^S)GA>-XC~J^1DG`1L3TaazNWjx!3}cK=R3?pmOJNd?z1EU@QMOY>KeY{|v- z49jyP7-6HSOKCgiRX-J~(a!341!Dn;5ou%%eNh=z3$N+8gx6Im%W2oYxT*-F zH2_5MCf?HUwvKmTF!#2TOS*-*-udL1on!wE8yO1EazHLH@j6wL8!8yCOR0GBWJ;-9 zMn@LxfKb8C@rwU@lLp#P_-9K>VCEd7D3@$!A-N>e>jE`mSXtHd)l#@O@m~tqG0Vms zVwdnzj+vG`S1zWdGi{^`v=BqaD9jp;spb`9*vp&j_IQ=Y+6tUvS;i&npPeuiQZ_8l zHIy6~KorOZx!G7;H`L(ZW~OQg&Lx(->`Nu#RIU4J$bNFxl)in#ApVm;RuM-A@dP#| zP(j8>`JgZ=t^U2Ldh6)4-cxVS@uIpVN(@(#}g0dF$GSbWwLB}W>LP9HX80 zAUeCghxQF;b(rUOGeZ3C6oRYYuj!fFfr+=X({f_`9C$ISAM&@hII3_Bl4u zW_NboLsMV4C43(vo!>!g39n$=ZS=4G-qly%72DfVzlx_q=!zX$vmdD#I@Szbz9D?4 zdz<)d702t)9qV1ivm95^$4U;Y;Kk4#h79=}j`@)GL8A=r#sM5cD_^987(g87IlF*1 zDp5PqNRUy7&vAf|4^jIs!(pZfex0oi7aj>JTN#UfE^I8}3ZrSv=`ya8@HMVSApTNX zIe~XMQ#rrx=cp+}7vN#=m`XJN2Jx#(ah0P=c)Tn2@+wB_Fy4J1&E2u_6`a3~CjZCu z3SPY{?s8W^FGknEah9itr8z-zy*`E3z|%VLcm;R^|H{1YM_LEjsz6rCr=Ugf0r?9b m(m|gq&=8CKfH%HHS~Z986RWm>=+-BmRdk zvC1m_06)sICy89DEFX;SR!z@LPj{c5=|10oeE9}o2B{Ew(5oR}Ac#JO$S&XKR+YOI zD^uJRC7+>h&T$=oo}o7y%j?i-V#VVjgwU_SFmN6N4D+6>SoJ;WxRq_mYvRC@AFKmW zwCY0cSA}ntJa^lvSlo3zpZkvIT1ijVH$}y%`|^k(#LMM%zPCpX7~V$HCpc_hc}>L9 zU4>}HOlXLl$+7KQhsnSwrD2R{7&UMK7a5kikH;{=t5xqnlrz$)IBu5vzL0L6p%8ul zpHkFuiC$>HX~rT1J;rBk_-j%y5BCYxK$Y}hLG8wPHwyazgv z*M-01mFr4%+d%ZR>b2lyAzP}rfoa^KOKn*tr6>#6cX*X@T#3H>Cyy4SN~LcgqM+P2 z@Bj}fiyA*%tOyll?Vm)^FvBoj@@iJ`s3dE@3RYEVvQ@hpX8)=vwnTA#ztr~8kV4X< zB)u{r52qbhY&2>`A#=P~r5!Wvm3TGJrK8rJ&49n-&}~kn|9~w)-l%~T*iI9XMKao5 z%N!+Qc?Mk`_vk{m{-{jaRh8w6B&Zh%X2|v$vLs$P>IT9m_kB-M0K?d3g9@r9@=o2M zOIbW75Hg+pEg+&AUmW^pxkj;1L$+A}Q+PzQ$MBfSN=c$V8lTY0BFRVw-_>_WgCw+lgY z!Y=fgSL}jjPLcllsk65NO~i(Aw+UUU@*Ji=LLdhzwuzS*LW+7~6(cQVqwVM& dWP}6rbcSJpEQ7?+Bzmye8kdkHsnS{oegZ|$x4QrU literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/config/MyBatisConfig.class b/backend/target/classes/com/bycrm/config/MyBatisConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..cdd6bc7bba8dd927175c84066f49387f5e529637 GIT binary patch literal 395 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 Ok&LtC1Y~Km0(=L$-Us~v literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/controller/AuthController$LoginResponse.class b/backend/target/classes/com/bycrm/controller/AuthController$LoginResponse.class new file mode 100644 index 0000000000000000000000000000000000000000..e3aab6a41f88bdec5d954c8395a78b5b28383d20 GIT binary patch literal 1640 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 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/controller/CustomerController.class b/backend/target/classes/com/bycrm/controller/CustomerController.class new file mode 100644 index 0000000000000000000000000000000000000000..404b39730261c75e4d4195f9a1ff7112e717eb79 GIT binary patch literal 5548 zcmcgwYj+dZ72RV=mLCIlO?U`{2?2s%%7m5#VpF%+F2SwA#wKo)K-#f1$OE!QnHd>G znuatDHE9U6X=&4RwIM5QzGMMeivUhmn|$u?sATddy1MVoNScw2?5wu=U~6>lz2}^L z_IcdVKmYydKLG5-J58uVD2lL*2u2nC9P&s%GmU2En!QjKcHuHdq6^{vummm z4QPy_Nk%hd3A+=smCq<&s&#wNs~*es(RTO@3+7<+(I#F7$rT#UjS2}Y+6Ou)&0 zpBIz1snd^|l97z9r8Kj@%cqbo%^Dd8_=INV(sq9nI zEK5S%9}kz?<&1a+L{xUl*o8-fa0l}vNeMlEU2bfB?#>xy9;e3o8_+3XO~R$+8OC%Z z*^F-VMA0iFj>jbI5%pX-}Nx)A3@gM;?TTd&ax@FTn^0Z=2(U64jkddU? zmQg*U9nH;7YvyrvI!#I2sF6_9Q>v+p@18Jh&*)6+AoLn7h@P|_(d-!`Ij)-Y-_}eX zH~kn~8mdCz%c%ddemzQ9lwLK^BcFE1I-_8*De)uY#JJ73!80$RLC+-Fe#|_Zvt_Gx zjzHG=HkNvbga}JVY>W9Q2(~AxFrA(vVXJS`(v~A(Ly(4iwnWALS_cpK7K5E(fRr>& z>ZuG7n1uY%*Up9CwrCU1F@?a)okPF?&kd0lVx}jKS)f8K~ zqE=RvgIRqntC`L|>WIv#>72;$!u-WAuYXef%U|!`e7|tx{o?#x342EkGo@HrF*Htz zls#*hXOy$rv@*>E@Tpav*6br{HYLCAnB5_^XWf1GAa- zUimuh9q}C?}+0$U%V%l;#k#{vt}72|L01Vk3eDmy)WPS zpcH|9t4_IL=dxEB3xWH8`LH*#!{JcoO#z2|E(_W(p46%R5~a8;abVO7l~CW z7m2dT?XK?JC|>>3;_dPnjq=SxTwD2mIBDd}gmy?5m&%Q$3wGr#^)ZnZ61LQsi8K|q z)f8jmO{&Ek*B7r|l(2u*#Bf;H6`NG}RgOB{v_fj5Qeug(0u6kX7elg5yqohW%I64% zDg7S59pa~0Z|c4ask`SBL_g-YI?92y5c72l!q|#NzF9oYZyVg*IE)c~<2gsGgzxh? z!YRNH_G|M0<)yL|4?w~bR-+KoSb>BubRv(XrW03`HjG!+X zi{8W5TRaeQJlMeFKo70=qJ^)8>!Dyb9(O#Ma21z5iDMK;Xq?7ylurUx9Ag-FP{eVJ zPhm$kfl2CZ#7-Q?GpMJ=dQ9PmjLeU?E>njqd6p7^Ykh>OL8YKNP!TY}zvuW@hv#vE zpBwpfk_TU~@MHW$JUkD{f{JM_Y7wp`+|?vBKAf_Us>o(aGQA=@?a0nNhjc|YyNoPT zk@0>B!;AX_PYLo`MTmPAu%iw~dcDxP0``Q^ z7mkGkPP-X7M2?0LV}gl{-0P|+JH8EhoTnM8#Y^}p?aNq)PJ#*XOg+K8%sdca8tb?f z+*AVeGY3!$k9b_Zf(u*}9CELOSNR|i?8DDJ1m~zqAn1r!5cGu|2)(iJ0-gxt9-a~j z?Jucg{K07go0*0c03Brj9bV+A)qx^->TsZh#IITo6c@mn5VxWV#B0^8`~t7jXEz~T zRyKu}vQok}fQufsGYpt0nD*t^IS^V7*a^n^B#Yq%2UxdzybP?p46MD(OpC{i$A^GZ z;p3OpQ08%|3QC)3UtVpw2_^^{#2X%nB$xe#@LgXaxIM-#gcJ*5<^hEudWdLk5&Q~o zQeUY{xRT41c%>n_gIgMJReOHLR~lEBl!mBwks`l#{{O}~+(EzJrrqBp* literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/controller/DashboardController.class b/backend/target/classes/com/bycrm/controller/DashboardController.class new file mode 100644 index 0000000000000000000000000000000000000000..f61ed69fbc8160c9a6e351852e251d143c18efae GIT binary patch literal 3218 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 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/controller/ReportController.class b/backend/target/classes/com/bycrm/controller/ReportController.class new file mode 100644 index 0000000000000000000000000000000000000000..68aa9c8305becdb61037a4cc235c50ce8a9d0e94 GIT binary patch literal 5242 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 HMy3A%pllA8 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/dto/DashboardStatisticsDTO.class b/backend/target/classes/com/bycrm/dto/DashboardStatisticsDTO.class new file mode 100644 index 0000000000000000000000000000000000000000..b0c9379c5d6f20262c5d1fcc04fcc9fcdb519104 GIT binary patch literal 3092 zcma)8TW=dh6#mBE^{$;w;yO)Jw*eY(n|lqV6lymmH0dQJX+zV7w%oe0x3OE>8`f(i z5YLDwB%Y9vc%>5R15}VoAR%}u62FO3zS;F<*IJ}R@yywCzVpqT%gpZI|Nip`V{pMi|j8#`8`Ty1Q34f_p@dJbjFthKpQbQm*m5Lp4eWH!!!+%jtd zqf>zu{lJRTwLthG|+41R!lw2Btf1%fT38m^CnmdB#v-N|)@i<)wc`LtbF4m%I(vVMfli zsd@xf!eKDAZ(27M#@rI;0-RIfK zaUg+VPaQ?(Ywk#(*b6!qn5elU!9r8{rUwiZnYyid|ke9kXt^+&uF{-#`O0n^Xkb&W8k=jiK5CnLwS|r4vwXw_-Uo$^deq-Vqq_ zjQ!fQ2MyFzV4n{R>pWPn%v{CCg_S;Ep!8k7kZzFoP3iucxzkR$x_)hCjZGm|*x8QN zY}I(_4E1l;$b~jFm;DVS-0H27wE_QV-!0Rw!R) z=fv8JAbgESv*L{kp#l~Pu>OF8UOZbnn4_ev=n zrAwLdDBq2y9N8>tqA=4N(r zzDpb|1sNMu!sNjyR30S2>bHW2{j3K~JV zf}YhRNN+{7)0KZ@^g zo2Ms+9KOPP)WtD_FY!Jl1s8E2A5c=+Ulu;3lt7I~`y)yk94z7vB^_V$*qfA+_y&iu zMJa_6_i+ltn*I-lH0V!pKtqiGx_F9%zL@+UvD1w=SrkQn&iF;aX>M3HxGJk5;|v~Z zKTf~D)oz?BqmyyA`}?+6W`0~y#UmrWAcaPvopkYxvfveSJYB4?lzMvh0krvD%-oUs ziGm^xS*2~!Wr2NDuAq7**4A^&uWf_1Ft~@0FwliD@;k<_2_um24`A^(9KZD#FK1ra#jCP3yLdfQ m@Z||9pYi3Kl+XI|q?8va@8Vql^%;C+EVgqjm|59Iwf_Jc-#U>1 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/dto/DealerDTO.class b/backend/target/classes/com/bycrm/dto/DealerDTO.class new file mode 100644 index 0000000000000000000000000000000000000000..a9e64302e0f4ee687c2b9aa6254acffd94a4d11e GIT binary patch literal 4785 zcmbVQ-E$jP75}ZQ)vn}~tthdRZ4zpOY2uGWU^4Yp&F)FtJs8+mIhktJ7J zr%m~2Orf-ekOCtyRjxvdKb^uvm4=T%{~2n=Nb+2Hl%? zizNZQ$HG=@o3+cYz)mlR`$JFuPUeifQ5Sn)m(6EwWli8nH1Um7Cwj%QCV=y zN1j}COB#B1h8(DPg!4SMYp9t`vg(2ZO;R(Mr;b6qV zF6`D|(7~h()utAD5G(=xh=q^Vp@$eRq5GJ{!y`RI`k`>hgz*y=?ia@HkWoZU*dDOp z2%AaU5fM0{+-G6GPCk&@4Sg|hHRuyq|JU4lMH|u zgi?muDNfzgij7lwoVyt5lc~bdNuJzDpGp(Cu4%EZN86TDKk?A1wlC)tgErDvPa}H% zyasJh?DUHkz9a+fR}{&>;~F-}s1+-@6JE9GmWt1~r%Q}#rY48e%=%)b{K(j0dSR5( zJX$WY>`%L;MNenNiXTmbeSER(7w5g{Vy#FA50=XnCLyUz`W2nveK&GqV%hmuits&wN}%8|8onI zi=`5GkX?Og`R^B&TG?@xsomqnvNyRnf7+{_R8h{3R|;-v+GXS!v_Kj6=ZcJ)J^nte zOvI^HuhEu^IL-5$@cg;T%#>SYqWe5WMN$jl;kMQ&^E0Fp3CiT8M%E)UlVZK6 z^oGl$-crPjodnfOmB~_RZM8w>vN=}#Ij>5%*yVsqc=l4MZ48srs2X-knbbfTM6qcI z3~G>-jF!SYp+HAHJsgx-RloiVLDnu|!OH;kdG;}FzQ;}x83TG$Wh2T*2 zspDf4M;MnewwkI}TP*P+Ga4J#2h{%b0kxejzC%5Ph1XE1wIv3El_Uq6lcr8o7OMsC zXi-#fSEJeO7A1~;w$&Ike3|ci;Nmpp0*g0>8UFF|M|H`6Qph48p7ODFLX#=ZGB{yZLM-zX{_SjWIOIJ&|PIn-S!6 zJ9%p)nHOvXInz$=k0kQ~jv#MrC+~@A@M;?fARca0S*bJHCvab;Piv6Ef^1Y+Yay?;?8zX}~m?@+SvR~*H6DW&l@ewVmNsf+!+AK#`XE{$?e8~&S-~mQMbSYhAmIz|_LQz3fO-io^ zkzrZlavLeTBvY2(k*H$di~WW!QgrlACciJfUnb_ZOn#1OX=aA6z}U5n1CI;+uoD*s zJ04g}k*vy;b98B9o=TEw>vhwplaQuF!^G@WtUZn)O-$T?WzFtvU}NyjP7 zF#BHOhA*k}be@eziAVy>YyS<$wD$p5CO4H6&zmHUm0f3`%M1A6Lx?9JK# z8-h-FeEgoO@|RU9KC=QdH*xUP4IIuMS;j*mUHQs>M#(uLPbhg*$j6ktN64R5@?IgI lQ1ZYs9?5=A$$6oFjE`k};aX(DiTi-_2PvlEXA<@E{{Rqikxl>r literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/dto/LoginDTO.class b/backend/target/classes/com/bycrm/dto/LoginDTO.class new file mode 100644 index 0000000000000000000000000000000000000000..e8fd1eb204e9f062d775743f57791139c43f6e0f GIT binary patch literal 2209 zcma)7O>Y}j6g|(Lu_wv6anmHNn-rQh5a+8d5J0t?K-;7=Az$PR!HS7Jil=pE!pyi( zb_fZvslS%*5 z(4BWSGwXNq?q;UoJDFK$!?Gt=76i1iXS%krX$o}A9$+r}u4QlJB+4-z?Gi%UGCc1+ z$1Su{d0a;aPEeUQ?5TIlMoFM6UFRRmbznp0pEEPgtU^8zOiS97&&l?tZYigSo+ zcvco1(vYr_FfKRKItDSs_{P?jX%_@W>njTrJ(_z6pVKhHQb*2K=^EE?K|l;j=!-g@ zlXYmm6X3-0fiG0P@($$%x%IKD#}b=!nlTI`(9?=@vpL% zZsi2xo2KU(8;swz|Jhf6ezN=M)4LDv-~H>OpB~=d+y8n`;7ntjl{;IFu{s`o^YQ){ zA2vEE!RfTmTDCb~-ds1`m7q!i9*|CEGHS{%U^+9INQ-6oEnYuxkbfio~*S zJVG{51d<o)4M{N+4c#yAxTh!Z$aMdbZHYCCb%b^T*Wo6_z>YF$42Mx5&xE(_0FA5o%sedaZVg| zKHb!L5>pHzBWF2BILC&De?Yu>-ra#kn76D+5-M<=ek!{NNiJS%4w?ABkdpTrWP1gY zFJGAD-<;!&RvaGs5~{L2{42E2p+>ide}OhPGPHwaWl5oPeuP6-8T}1yDdho<--AAy zQg(2vYSEKbY0{I8rBrDXdw`C6NTk$MtZJleGgkD-`P~R|sPRz54NNoXE-Yh)XBt62 zChDP(}y`qD#sqoQ;K1M_-FY|(*D7*IJC#;jw8Zd$Nk$NGaitCW+-%Z*#)N0@N^#DDUDT-e63X_j8F-1g*G8 z@+4vB+0QGKlnOaBP@YhskQ^aM2;cN4G&)#Eq@oLI)u3vlG^%LEc>KKG2>9x1crfgNNHU#I$uoDS;}Sgjnw+JCdjpX2}l literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/dto/PageQuery.class b/backend/target/classes/com/bycrm/dto/PageQuery.class new file mode 100644 index 0000000000000000000000000000000000000000..2c2429b169ea71e04a0683c8c2219f881ee7e48e GIT binary patch literal 3530 zcma)8ZF3V<6n-|@&2G}|Tc9n0f~{0-)0SwpYEw{X0WGGqP^f}0(`~wK0%^A71uecS zI*xwPPtN!QB4$qrQ{^$tu^~Z z*)D7nCS5KR>^yhxXvENXZt*W7z`9NJ2qd+by<{7RQChK!X`$L>q8Gb)M5nM~7Y=6& z3?}R36+~+g7fOX}e$74CeJ1(@RLEIfE!rgkaleVZ0z!8orZyv7d%(nlcu0Yfw(>_V zl&zeCuE82a$=c-5Sz$b6B937Nku|$CU5O|aI-VH1xCcb)DF z3{b2+YBFnF3v+GGJ*ilI+{6=jQf@RS;+-Oi+v_&+LKW6Y6O+QaQ()AwBMx%F#8Y^h z5oWAnX4+Y?-OSJEIK+%q6Dskh%Gn&Zi{K!F1`d;5KZ}E24i51RM{c9zEQxkm$vTMzyO6bV*-O@Pj;wVQ-RYuTD6;TQ z&yXGEn1a@6CtoaC`O>1eDwT3pSh|wz_Ea`+A1|*j+l5mSD4KH8R&LQEIDx%IwUo&g z6~t2ia)~Ax8td3EyKS|Ei_1DWw8%5g+NF%MGH(^Eb-Toqk}P_OY9mvWWQ|EIzq0Bo zzLGqmbqa^Nf?~){{gv}Fra*H_8M~ms6oCx*7rxb9uFk`*TBMJMkUBYOaTPL^M3E|g zDwUP1;DLIHW^<~l{X8>|9!5h1tqUb9eSX&3@R--;PtMF9VPrF`=Ym}<=h&x=>WQ@h zc|d)javEd6-??3iHM>R@oN^&;AI*xIY4fkoK2cQY=XDK0!5M_G6EET=$}h9~1@H?0 zvx~Yid!ReAfw?2QmOHWma%`s$n>)WtoGl9{M%3#IBNv6VF68jgPnO}#q& z3);Sb7Q8xq18uV-@huFvQwoE}NBBvqqraggrrt#76_}$jbqgaEi$qeRNg^4FX~HIS z6VWSZjcKt^jnPl8Ht63QN%L}$09XG6Ui1DO(e}& zi!d@hBT5w`^(sRPx>voHqsua6zusi zlr+rZV-zWcAaYZpq*G&~Ov%7!IEssu!uXtz>Z_C@*kZ4HjZzDK!Y*u5GI5D#JA|li z{Dn3hZMV^_BfvjHxs4rC4FA7axg_gMtSWxJdF403c*MQaL`DS-wT-Iw+Ep$sO&PqP z!Mk>jTPpmu#HA&6!9NLM5a^SR$^Gg9w;*~uCNnGtqht6A^wBNsUlQwyq$(6K)zcWF zNTg~ksktiFhwEg-w2Epx8FE!2U&X4CUK2^(Rk2_^FWpu3Hc#(Kc}y?8L41VQ@dks? z@FCu$6ktN$#aoOu$e+L&yiG~v&%#-}LrLRvG)BEhZ;5Zhdz5rHS$`mMhYKo`r6^1g z6y**fs`G$Y=z>-;sMx6WOP*P%#;j`Dxat|}^~P2ECJN8RxXY#L)m%qM(!}3@GUKdb z@j3&kA93)^bxcL4w{S!xehV|vl#~-fJ}%`kAR)b)D5Q$+XQt8`_C8*VjGw zqD5S11UKcnMay&oXwpC@x&#c*l4&hiX32E~k`ef#@7W}7CUK8}?dTl@-W@lY>K%fFNb5)h+|OC3C`(v?Uq8$H0?#DvY1p zETp?GzFLaJKW$(yo)KsZ){9otRTr~aPYgo_hLL7H1+!E*;^wWO8#5Y41-93O4I`$? zb}?^x%@{#k$Fl;x^?ezvc4b^b_8WK}2Urk$U^y&&G%8djho}^Fi%{(myeKJN+7eln zI3i+wq>e+>Y^1;1`*9s(6lJ78+F?4!1;mhC=4At~NZoYb4Vg4d33LVJ+iqsj@@%tc ze`Kx{DNlPTcwDx;lI=RDW~Rwy&)c@t4hF*;2U&)2hL1R(s-ur_@&Ie>(7^qMJBJUS*4P>%H_N6efsU)Z$6os zzH{Ts-yi>a=f=(Z-`^D2S-;BC<@NfNdhh=5^}Vld+`skNy)VD04^_gpx6Rs)HD6v^ zvAm_Q(&Vh0GmFb6t7qaBr{WiEX1;6o|28NyZYf1)zBAhTVC09EDdn8y7u@_w(=*pB zpMr*AwNdYhhE*qBMz#g)(Fw2Hg<%)RBvQEbd$}?_0;=m5ERT(o1r1auS72MuR)|j2Trqi;K8l@t6gx*057P=K&waAa^C`o-;9VWQ4)GI>7*6miU(4lB@@j+t zynzKi33+hxS|9u~v>*908r;<|n5Slg;MT3dI~oS_2yGDDu{C&i!{9|MF+Z7hmiHL% ziQ)7w&>9!r6Cx@_OF?8;1Wqwdn~xJ>I13 z4EXu&3Ms`w-kVs!mGtm;P?c-xKcIgOHGVDqJM_7c;SF>Lk2F&ABfMml(Ld3WQf{N; zDvZ&TvVomdM1NK#q(7TTsS=a8jpS9drqom-0vgC_1Px^MlqNxX1*E0)DoDA;gyN43 z-PthFP5rOn4BlpC-MECa9K;v~VB;P7;`~hJ@GdO{uX6vqM@z*VzZ>UhB~avUGihn? zIJzsebmDAks?8&Q|)7imGPhveeGifwn1-CUxhZhfx&aq z-=9_Fi9fkL zlqR~`VLg2 K5jY>T_`-kiw>r20 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/dto/ReportDTO.class b/backend/target/classes/com/bycrm/dto/ReportDTO.class new file mode 100644 index 0000000000000000000000000000000000000000..a4b185d2adf5d7dd76ef6247f72373413db74d88 GIT binary patch literal 2309 zcma)7TXPd-7=FHFH`%6}9?}zmqEsuUCxQwp382t|1be`?L_sgyCOgeyvRijIjCkvf zH~s-Hy^wK+VRS|dgQKH2IOA{d5)VJXOA()MH%)i3&e&nj48THEuTmg!dN^t!m~cG0mn%hFAsj(!XX^wv$U=2~06 z<=6tbi0Yc}T2#(ZIj3U?!vb2(u+P2UHktw>g@|ehwmfxJDv#Z|VB`u@ z5t9IjOn<+Q1JZZOl#V^=;h>Hu@T5Q=JuF1w4aZz`0VXh^<0(8%fDOZI%sX{6;H#3x zGh}Hu`_STS+iKQLH-kweH58ajm$||&Z>Qw>w2m3f5}dKMW!mI&E}C`+Ks2pb1adct zBhp3jG0PpoB80>(H9W`sXAecHb4tSt0%A%!J+9+L$<dpgEO}6 z_=fBcPvCHX_=Dngx~~VqVokbn4a@eu;*R+i2YM1}3@nqIrf z*P}P)S)Yt~$gDYSw`QKVWRvuD@4yk+MVR0{OhDizB(WbSP~y7G{z%{?e|&y8p60%n z@>lqK)x#N_r63D2gk4cWJ~I^eP={|E$9e9GoCRlf`VPcbTqLl-Q65W|=Q!%20?y+# z?s$!{k7L~UYox#AVbpkdPh&nOdl+XQH_q>Ad;t}PkdaHA6P#1iGv6S+H}26;qk~)K zB*_xENIR7kAsYg(V{tE++5hWOa@utnZup3HT>i;9&1j98>Cd4mw`P8X_9@ilt(hO7 zEzM4EV=&lqF|s_%p`^_Hgxic&*hbExosSJSIWmriaf|GofAzG z%cJqV2|E^g?Z8O#=3PdWF;yJLn_MN3!BM93e;uAMr<2 z+TAClU literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/dto/ResetPasswordDTO.class b/backend/target/classes/com/bycrm/dto/ResetPasswordDTO.class new file mode 100644 index 0000000000000000000000000000000000000000..ed1c6671f7382ce7a57d2a14ed6ccb08ece82f4e GIT binary patch literal 2451 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 E184$R+yDRo literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/entity/Customer.class b/backend/target/classes/com/bycrm/entity/Customer.class new file mode 100644 index 0000000000000000000000000000000000000000..ebe5520298b9e09b4271fd8d4b54ddc62c5628ab GIT binary patch literal 5044 zcmb_g`*Ryt75-MzYFF~wmK8hc#wNIl3w~B9HIS?lgX`MF!A?V*7*bwcOIursB^hZ| z>hdU19!)6kcX_`WU^2sFs5?A{DL+tV_>p0T;qeQ91~ZiK-FtVXwX+5PfXCLJd(QWr zd+)jD+@tj${{73}0GP%Pvq&ImAZ0;ET0`!N`-ofEbZhH{2iC55C0|4ORHat&XEY>7 z$5t~ikui|9&;?6_U8+|LYulwpwcyqKioac$Yc>6P)oW--RLbnUz|ZQ#ZDS za?rvMUdE+2eb;X_H5`acu~_rHb*~{;@^TBqxKl%>)bL#2E6;Mjw!-?As#jR5m)y5~Ey2$*s-5tL1KL7#NMrsbX0idr*MKElgmN8(a7M zMaC#UIu?P-D2Y?K+d@J3Onbs%Q!wwb@G9KP<&wD)Y;9l{JKUT=zuLlU@LGn8=yNjC z{kyP1tOfL>1xG+lLeGnE3*{*br-d?0<*bUhP`}Q?>xH_D>ct@FLVuryIoz+oqJFLu z&cSfbn1Bk}f`vDPv`d|sCa`GXEZ)d9ZMe;ixq6wI!VFwAu&m)wC#%#h?rT*x%U&ak zB_vIp=PJTP9Icd33-tvHE4avTx?5XbjbWdP9#9aA=t1mqTof)=g^M@uVTMN=Il|pc z6PI}glfxp}Pn&ovcQiRHbDE>KGrW_-K|XW*PR4a|ILu`#T%Pviu*zc&OWfJya64P6 zVOXeXXCpQ18niL7-in1Q@>Ko0T9N@KX1|PGrCwO^8Wnf5@|e4}Nhi6c9IkqeW~E-c zw8)dx&T8nMtJgSt&0lplTb|BKL;PqglM5|YeAQd6G%Iv4TdUQXk)*QRrk2FL@UYwT zy~d-}&B7J8bhTNp72GzcaF*kRdZX(4MMh`K^$D%9P`CLrwY)r4E)SnM<5a6olm1fb z_P=OA2clUZYj13o!C3bE zje7aK+u)&bWprndpsHwBWrvAFl1YRt9-b-1pk#QUVyd7}c$yrAwR(L%!UZih`63jsgYurRH{Vd0+b;fW~5PF*I8u> z2GSt2nHyD>U}Q;CklIWnW$cWlIm~noJ<1+YNI*N)HS{V(MAIW7?c8reBARZ-x^#8f z-3pRJKYw9yd7eR9Z&2>yv&lcdi54BPO~n}osAQ|>=Og44_|*8+$Df1tQ|a*C{1j$zA&<&W z3BWcU<46;|i=Vs6KZo%X8WZS{`(w#$NHOH@y<|I<%oY_x?%PW~5=&+)iy`;#B_E3= zv*E>%5A7w7#**2xW5|d1lBZ(HY^gEiBYVmB#**1sW5`GMl268x--Gw^K*c#bd?xrz zk54=cBR)$GDnyVaB7;OCYj_`dI>=`*kU5qU}-*J`nG+Z@(@@d9_`t z!3X1A_V3rFsMNMgHTY1x%R~EhDT==BQVpKKhvQ;-c)u>i{n2(gB>jH`A4T%^6F;(F zm+C4CPJEayZ@ZN=d@O#Bqx+ph-D<%cBk^gL36VLlB# zd2`} zt=s7cXxcFdns!Xv5Fj%E8MYY#op3S)op7>tMu4&bC}U?MprX@7P|>mME&;Lv5Tyuc z#_1+##_6%U1*j(gb=y4=(5%x-(5#cQdj%*LfO_p*1T^pT5j5}Q?LGm@2cSMXAA(Xh zSDEMKOS)9zwd{0gN$Z32UMno=HL<-XQ1Xqf*(j{);V95j&N zuc^I=JCvCDKZxO7_$0G7CEgcRlHw$TC9YRpWT%L6w2i75tJ_r%W6Y>s=gQmVdtH_< z-a9&a#pjbu6kR~R7z%oM9jAKfZ**38x6l>PWNE53eU}Zwnypxrt zY}>>dA!{f;8MoBFgFq$m7kmw0XH<0j8Q-9kVEX(K-(>KTIEG)~Ta;3mq3zq0bX>+0 z_ztBsd~D#mlnkciGQLO2#Eh^ik1+%k^EOI{6>kfO{LhctAo0;(x!;ud$56aE zpl4sg-kJTsAp$2|FYTn`=YN3ciaEh|V^uG_2E_MqVCz>{y8Il@ESFE(-Y_N}dt&LrOj_xNAzD6>?e0^Fn@@@(wokei4g);ob^zSi=o@ HCH&w&Nuz~l literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/entity/Dealer.class b/backend/target/classes/com/bycrm/entity/Dealer.class new file mode 100644 index 0000000000000000000000000000000000000000..779591ba5da3d6dedd1d70cbcb914bcdd5ebb27e GIT binary patch literal 6012 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 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/entity/Dict.class b/backend/target/classes/com/bycrm/entity/Dict.class new file mode 100644 index 0000000000000000000000000000000000000000..a60cf8a12f77b8ef9e20d7cde9936fedba2da795 GIT binary patch literal 4642 zcmb7IYjYb{8GcsQYFF~gahy1=lC*VO1HP$Bic4UX1agmyorX9uq!j2{+S;4y;!3O1 zlzUqWZMn2uOSuihO!Fl(z)b7T0K>qSGQ&qcF~cW5@h4Ks^X^&guACjlc;wx8-}5~0 zIp;mkdyZCr`_J$H1YiNbEFgm+16d0?avDajIZrv2hSOTFJiKqN4=KkAJ;H6 zJ+qpJiM)Y=g<)74#%t|nW$k*c)2z5H-}A3mPJ6=1cy-2Fii0h+TkBOJk674+Q4MCD zz*FtIt6?mGTk$(yh#a%9CqiCuny%2tE$kELaNX_JI^L%5wOiu9!$JxBHRNj@*YVx@ z2@ay9;`(0Gtt_=`PUAFNF7qiE$UzHt28`ZjT`?ri-4-Tsj|ScI-DWqML(lgbl_jt1 zR|^E)XJHEO;~Z*E>&%lqr@=%_CnljXSDkr8z#p(MjTuHO2b4f1~urDJ+D!B zI|ZD?kcqQo$t0(}`Y~~xx3GwZm=9-j(`_+t+_h2PecyMDIF`!CJ}Km>AS)-&QC`2qvw->Cz2OES2@Y~$v|41q=`>k zcod(ZQ?#K37s(@*oQcnA&}L*xj)gT@OVe+wQ5#@t_6Di-+LaZz<2eoQ8E37*x*F{U zkE?E{%PP6Dc$!g|(c-CgtLr;0f7NO9T%Fs1{AsM0OFh(^K`ROx#rZK=(bxGCjwO-;`7;dr|I}r4aTP96WY?S=Q{t&%gg0@ee(Qy zyV>u{W9wHDEYj|P3+wyQ{js>c~StCY2C$!ob6dd)Srb6HJzEU5BT zhe_c0Luc0C@Yvx*dQgU|^wqxO0q9*-%6pQM3@UkMm1$pg{f&10qSK*Rm;-h`OhR12 z1A9eZ$t3nsA~Fh0II+U0B{~vCdNAxfrAB2Gf{tpFg5hJRu>Po{=~e~5Z!mY)H~aZJ z6!sIr|M&7pEUi7bsfRVkJ+SR>xE-oP)?`Y~2s7{mW-)N~%Z>?9O|c^egc*tf$}y@U zB$Ku~#3X$q0W7Li4Z9R5;ZcyNbR$T@Q(W;`1Ix~4s5AZIrN!kloctm;t&ZF6HFyLK z1vAS}#gkCB8m~2#*g`ZErV=A4OeOj%th9TbntRrhvd)W=?w69sJ={Yw&`{%jKU_Rc zd!5Cc!3O_%LI*a_+u+XAG`RBs4emTJiN8jBnD;06-{_)ABG1LNhG*qyWJ4=pw|P2q zMUmrmlb#Ci8t?k-+t7X&K%V4Pnt>uZyjlu?E_^;|axU^ZNPZK>Z`qhZOdd}q^Jq*V z7q^r5r;>S4rjU1UC*Pe)=4qNj-n*SVl}hG$n?j!0PM%FA^VCftAJ|SlluG7F!?bQP zx$#oHiMzIwA50;u74Na{r||hOh|PP3!E&>6Z^1}k@O=sqF1Uz6G^ycf@^o%^6rzUf zcqT1mai<|g-cd;P@P+h{yLTE=DkTc39=@0!a_>$4M3fU0(ppsGDmDhg;M1Qkmo zeNgshYKmV|d5OyI7M{n~nY(fP8!vG0&G7Z*ANU4+Lzuofo5D-@7A+I6@~HSWtvr6rBj-D`3fRI~e3#ZR{>V3gS7=%ICl8BPX%+D= z9KiQzjo|wn?-Irh^A<)7nD1hrfeb&U_Ac&FX8!*&`&-HL6iHUz%9J?xTEmx6cBYFe zBumKyB`HKb%9769NR~pezrctZCv$>VZkn0%43TG`H%6;Rv&RBa9UQH0P*UdT+zlAz zEgXML{AD{U4W(?@Vv5jI(_vc=ny9gWWR~=P(}JA~nsQMSm8V!oY$Ir*=t7p!Z>rj6 z&}2qUlpOFL?Os^#(UCP^Y8n@m?-lPcSp1w3$2jypppVH8x2b1jqQ4hLB?3Mu}PJZ6T4rfv5=*pZo;#&B{+C>CL1w-+YHts$%)b_cx&a z2b{e6HcpS7*}^#y*A_lLc0t)x*155Z%04XiC1o#&eOcK@1iz~6s@R`W_9J3{mi87N U+kVm~zm(NOO=$ReP%OXrF9Ww_;{X5v literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/entity/DictItem.class b/backend/target/classes/com/bycrm/entity/DictItem.class new file mode 100644 index 0000000000000000000000000000000000000000..fba6e0bd8c669528a6627dbb05e7d734c7826b58 GIT binary patch literal 4656 zcmbVQTXP&o75-*-XJ>XbE3IWo&O}aPVF9{&O%UMB+Bl9K#|n~dEL*|hmeKB58fP!c z?kL3Jl9-SS;hJy>gv%qYqFlwLh+G9!ioAp>o_T^Neg!X>@OAgh?5sRcDpb<+>2tpC zboc3Vx@Yv4fB*h%01Nn85gB9+x})_PSq7_=}X z*!j8u*M(}2g<^qU9ocl5xPogk)@O z))k}3F%Mdp#QQavHMjNfQ(G?QJUW#aQ$?^k{kQ;s(83g^HR$Ue*UZ&TO(&o-HexSk zEzAj@c~3a(3g#gT6~Qc!DZ^VA+7DT{A0O6WQM=Mx^Jt&jXw`!75epy1#}q;AP#EQr zK0+90fq%e)lf=tV3&T+h$H06LBcJR=a6EF95<@|I(87s`cBvP}3{F}&g@+l&4Y#{- zvR(INsx2CLM8m#b`lzWrwBNCYeE7O~wFMJR+m!w<{}N$9Eh4v+i1hQ7w06 zch&23{dVip;wgGz1WPB|t#0790y!t0=YsgrSQ8hvSkz5#)$jUraH7>}2W~)Wm!Vk_ zrGLfk243fxW}|Y|tv%Uow<>N7syxd6>2{~-22~BlrW+92VpU$_&;0W8e7%0)%o(TI zbh`AHQyV|Do|TB3CJ zhq#o=iO_MyaL?NPXJeR{TyQ(s5a*sDqBALuUsGzNI3SfOH#q@ih`NK)7-yk|A!Sc! z6eLdO7?RNRAYnK{F9H&36eLdW*h@mAAaS^i!1G|PR%>*i&`qlMB%~?iCW|B zVDj+RP-A;HJY1o?&ML}agMYj$rOaDTw!G?O%X>_=yt!n{TZz1@ln2;8$-hPyO*-J^ zlV;dUC9iEhTjW&OYHanHThM+Z9k%%tW^mw5`IG=Wg${d~xRLnmC;tw{uW8JnM;=Kf z^HNG7mv)lvR5Guk6moed`QB7A@1+#-$WHRXR5EYP6!N~E z6!LvL$qT9EE&}d}*eZu@hHZXk_AMCc8$G5F;YN!j5ILw}i#%Opr_9dN=`KsVbt%$0 zb~z+negV&<&9b~(m!dLam&4NKwRD#wyLBmwEOt32T|SF1rp0{it+cDHB5{@yEJ_cVtRcJD2*zVyWF)=&y3+TC< zv+uxs6MFXM?4MvR&&_P(eX>j8183*>aB}m1#(Ixtpx1Y~r+3N9|1& zyr=@T2|S1AnKh%Dh3hynzQPTMW`d7S2DUSx;!b_A4 zvVMh^DVcZ;-^DAG3U~vr;_H-(*yfG#Dy0GZkvGscC|USB-x0q_sf2&vL41qSAa8&P ze4Emcmd7~0L#a$}z+Dd;61wS^)o^-3Oxcum|VXqgyj>k9&)EP1RMR}9zMkoQp`IjJyyCcB=VmbYJtQj zf8}~};(s0K=8#_eFZSN({|iAU+&+H5sr+SCig!q${s)}Cd<$oW7q{^Vk;dCNH+(_K z%;9sx7nQugW_VS}M}+(-B_9@;$CX?a@@JHMT*#lJyp1PzzI7yD5bI%zY50jO%b)%S Dc?(To literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/entity/OperationLog.class b/backend/target/classes/com/bycrm/entity/OperationLog.class new file mode 100644 index 0000000000000000000000000000000000000000..92274d78aa513d4178e6b3a02779c91d9fe702b4 GIT binary patch literal 4751 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 Jkr&%v{|koj;4J_E literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/entity/School.class b/backend/target/classes/com/bycrm/entity/School.class new file mode 100644 index 0000000000000000000000000000000000000000..5f07b2d058656323bb027f61dc86921d9b772f15 GIT binary patch literal 4139 zcmb7HU2_{(8GcsU)vlzK?I?EAZPMa41}xjELQ@D`C!wj6G!9l8;>4t-Fj-66Xj4h+ zN~_Y8uk!u{wExnhPZuJ{uvLuX(k$*S%GHe*3oHh&1F*1>GPzqanLk z*~-I0-bBGh5w?cIjj&VOzSHP+YJN8gqC2(CMk@^48ZtqX-ZsYWHp1?$RY9M!F^w4w zg}#KYg-u^WIf2}adO?gW+c=oOUiLb^a4~1&kWgFgu;E2P*cHl$Y&dvWL%z}Ty~uB# z<=P$PHVQg^ZG+hMIa;o9Bv*3O#v_t3*l8+8fqp(TA>K@G+&KU(LG%Zrr+RPI?s_`^09h0mNX9QFls$;L8PG?d6xK~s^Ko$wIH zLJ*#?QJW-)a0tssY&Ly}VG*>C+jx3NyFQLg z2CFts;WQ)D^7<{cTGqt6iBGT+#+g=Yes&PFn|`l=Gss$amibn@Tnw70h4P$@^SHo} zcso0Om!YdBgBTQ3}G^rr!&^cJPL` z-DdUA^yP5N@Aa9w>+9#}6;x{co#-u6@Gk_S1BxoaPl*1&V?2a1(C`9GJdDraCCZ;= z9?X)oDHCG$Q=As^UF zel(TLDjWLPJLv?LD$0O-;@ZCx!Fr)K1%|+Z_ zUV00LesB4&uzmp}dvEzKu<9#IyLeO%DLj68g3xyi-VkPPj#a zPPn#H6d*eWQA&VLx+Q{6x>HU`fTm(l$(b60^n2WY_JLFD=PE9vPPmUgA{N9P{(}Ke zvJB6$f8sUjvRJ}D@Oer)p2ORCosxk%euF!da%`8M;0;P9bNfAffs%!vvZKC8DUY9V z<}XnyU>6tgWlBZ-3D4jwlx+NqnR=5_3IE0se3jA^zQ*-#V9vDeW6Ff}9uAqv@ZZwj z!$V5U|6k&;yZfvbUA)Z4-TgGTD-H}pRE3CA@_1HfyE-q7QIrhEMnoyDzk%!_z64Xn zBPer`F7kBr*39ZD{j@Bqqcf{5mXtNKd>3YQ7w%1=ueiD}IC^ZcM4>5D)itDvH6}@x zV+>8l-JCS#MkZFCVx4eJX=2gEEOTf&=~~icjZ7>>vW}(~#!G4k@s_jrHNK8-aDN7V zg>O>IFqOZ=w-|;jj?wmQN;=PoR%nR?}ney3Ptcl{<#dGCLO0Mux-cT~D qY^{7*$;X9!Mad@w{;HBs3i%r4U2N^WXp^rsH{v?b@B`T(Kl~ppN$p$! literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/entity/SystemConfig.class b/backend/target/classes/com/bycrm/entity/SystemConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..51c4e73f811c17821493a0387500e71ed2d3ece4 GIT binary patch literal 5699 zcmb_gS#um$75;kG)=ZBy8cBBAyRl5PSQ&@|PFl7=v20nk#sVkrt92vt1s;3s&2AHWMm6-5=neD~h&nVxYw(F3Z{^yzcH z@ASR*Ecf>O@xQ6FErS^1X(S9JkerH($Ct9PFd)0GhhmR zM&Zw_tw{J*1KT9L0Seeg-MJ{Jw-%GSdJJt8jz-1ffA-;24-;FA6jeqw+2It2!No?8kh@cXIn9d;XVVW z@D|2k*={T!u9X;erua-6^BOj{QdUj&-c`3;a_SkJMqI}NvpSsVLvHDiFul#d{dj;O zuvb=`Dnm6E4ywOw;o!A79~Um(AzZw(gBhelDD3S_9q;DC?AxVMo*_G=!)80nxf0eY5~?n$X9lsLrXn@XRHvq3i+yS3uHQ+MsMdr8$_z9DZHoO*+0dUj@tUKsiulcnL=RZq?*$rdL5G}hqh zRra5Xv*0#d7Vu=XTJvmC;SH|jtmsnbY&NF)Bb9RTg1vOHQL7g1Ca8Fv_eX2>itUYS zNUzu)p;dN)HU5pw&5e~xyN(^RDiy0ie+iW<1WAK#; zZ`mbjryRsBTO}WxY^dt)3#W`M?qQK`bB?!ME1k0IcE#c7=+Yn|RHAMDBSM;32y;@(sN~M z-m+6?V8l`miY-N#8Y%WDWvIF3ePc+~EkVuV(9okWAx%C6@fWH$4Dxkhn7@2&Fkh!e zrQEAU^+(mFl8+2knFilio6aA6YgvQAw=@dUEW76XLYmyX$Go4jSNyz8o;p1K&pxU^lyX3>q59U<+39Fy;5K?qhg_|2&9Dna2rvqc{Y$&o(1HU zo4>qrvzJ%yZ_spJ`n-|r`<$g9R{a^yv5&r63N;I}Y? z1Nxx+mH>PRALgAV_Hcf;lV3pkIT~YVk^3Xb+>|58xlXbfN#+h6LGJA&?}#LG504=C zcarx+lDW%AkT-Xdha$;52t<&#bdtv+$vpQ&khgb|?~Ek#oDo6Z-ATSXlFZXa1bJ^K zc_Nbh7(T*m5J_V38sjxJGI|Z^=oH(e5Pph@^b^&f;iKdwd17YDYxo#G9_2E(QJ12y znl9DNC!$^UZq%iy(WXmv^T}wJ{Tp>D%Dw4Q-8>%ca`Q%Aiq6q=sct?M?Q+XTU5X~u zbg6DWjn71dXZuE7ihkB~xl{W8EIx<$%}KO-qb^lz^pj{0UEb6sHGDq$8GASS4Ao`* zXWSnB48G2&rHTEC*8w)si=!jYAep#2`a9@PAsN3q`djF8`$pC=ByTC~JGqZvR$}ZA z$eM|l(0c{On3-6|>jK1nD@n+HD`h4HCiM~uSCBK4W-0_aV5JE}HuVr_ z-0C7|+{&0;0+jJVU1lZ(ny|72O<0DR6(GY0Q3`=3tsFs2j8ZY*Y@&d@;j7zwNbu{ewR`~JI?dO_bBygr?3^@r__&UIM)hx zr1k%xI}QD1Y)T`>kFLFp+mzV#{}qE4{RA^VA$|++d%!(hOVRa{BEv-p!bbxY0@d`B zK?u00mpO@M3%D#>0N-q>;yx08k}kvv>0kNrgNZ}3K(^(_msuWqe)I~`W9vBipwREP z62f36e2XrMMwt#+NoiueNRnp{i6!QCGpoVj(_3`e!vAw;ve`S zr5F?M?|7E$8s`r_*YP7t2~6M@xJoI>SM;axV@fG_cnm+Glx9C%W`c?|ein0hj#3wX z&!1$TrjX zLS9tzgpf;0o)q#qB~J-?S;_l_p9@N!7IIn1Cxl$3ypEO56KeQ1=25>?H2hpPr5FAO DaG@ZQ literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/entity/User.class b/backend/target/classes/com/bycrm/entity/User.class new file mode 100644 index 0000000000000000000000000000000000000000..51d23245c650408b6c0269c7f78063dbe51282d3 GIT binary patch literal 6246 zcmcIoS$G^r5w6~Ic6U}J4!;!IeY^}YAvPWVk zKp+Xn$7#S^0m6|u<}i>zB9jC{!r?%k^8_#O#v9Lk5X@iQGqa=hB-RW1wAkRc@Uv9BtYSL7{R9zUDg4=IXVRlT7Z>sh2W> zv^Ib>t7;3%`fx{Djk1Hx>eMfh%T}{_PrXrM`hZS@QrWPr$^p<>d4o;{&qgajX*Xsh za)VAA=?#J+jd}%x^!o;xskQ8rc0^uCsM56q0=q&Zb5PA56fT;tn%rGi?O?Ox|OjBV2{X%v39pkduXrn z%n6{@HMh!(v$71|uhWbRKj))f(oU1?VtS{>i=yV$$6r^L&>CT#LaQz3Y3eyhj zbi}0{br*&WM|E1@anfEOcx^ap@6+jaI);^4vYJcN^%4>XSw9n}_X}Fr$!7H|x3OmhL z@~Q)xyQRjV2rq+%Wtit$(CB_aVuT<4<2pSc zZLPX`x;Q-~C?}VoTrV848)d6fzSla=wVgrO(Os|`&2qhVbY?fa%wqiMdJS`~wHB;O z+m2$t<3E97KHSD;Rkat&%`zP9s@3X9Wl)=l^&D?$C#+`6Zk(xB3a6~a)6IIVV0oaz zEc$!vjjGj}M39!P7NCe<|5^M^6pIt3($N0>X0>WI;V+`HsCTYhvk$bZ$L+?vnsiof zBMTO0jyX8WNNcGK(mFYbYxY$P7j3Gl@AoH@Ec%fJ1fpoSmg=R0Rs;ErS;18bgicAW z+E&~g1d&m0C90lVf2!wh7kFME)h03MpMtwb@GKI5sJ#JM0ohlw8y!wS#WIu8UZr9I z(N!aJeIilNmx+S)t*<^eoT@;8>a8U{f#Mv=JRd`v)JQQcm2Q>`>QSbSA|V0l#7HWm z>ZGJWRRHFxOm0`Xb?eP@+fgWhTYny)qfh|19zB3hA;(az(Ei61AMZh-2f1-Q~3S@dIhusZFKZ9i6Zwn;jW)eW&+)chYkc|6D0C{US`IbO3?l1x5;coJDAQ>lb z0C}vNyg!iq6*`YReSgp=Hy_*|EQz6xFx=L&`lrFy$>~hmuUGmQAxg3%%AEED3_}V1eyjGWLlXjA53tV2aUkmzP@EBXy zI)>WsoiT0<9^?DLIWfG}G5F~4LZdoA2zEKPR+oGVc`j84KL%A!gmY-u;gC5uHu^Y4 zBbUZrB<*2}hA)l1Kw5EpbcJq`T?pF_jN{9UOuR%XBXWiME|NZBL{{jXE@HbG1!TJ! zGop-%U7_qnN*hrl<^xTcae$^w&4@Edb3k!J^MQ7n34nH*Nh86aqytJANgrt1OaU}) z>PCt|x&wmb1MM@@0PQn-j5LFK98lWm@quQ|UVvuJjM2-Wj05U5GCokz>;tH1W{o}u zWgSqTk@bNNnf(AAGIK^hgK`e2-^lqu^X33R^X8y2z@R|~G++$6pvWa`hv92(2LDiN zK6xTCtZe=6LnnNeg$bjv~gK_ z2GSrsi|0Q>o8#Jls3%U^t27v=5dJmsD&3&O#Q#ln52Hs>IT3yv<7}YY5o$i)qFg1s zLjLQQy1S|4E$XfiVtxV7rCp$HvT+%@ep zHEGg36G~IDX3c~&p(-6#!Zj7mq%yLY4;R4SXd7LDl%jv5_+Emfb8?1`QSK@fkvM5WAR+N8 z;VK60^h2x|pr{LQF_G0O2Nv_eI>>IV1CFl-cklrQhoW6W>9B%r4iWEn)dK?W|Ci4j z;n%;xW`~}94SQ$w*F!i?Qm^f#QRujjDib4^gVMLy$om)aqa z%lwO$==^hZ$L*Kt1KAI*(4D+dtWYU?QpwY3vSlUjWBIg_XIZW)c{}6lN}gi*E+y|| uxvAtL%WWkeV)-5=&!fqnRq}l-e-vLU^s(;W2mYV0=baiA^e4Gd{`r4gonD{- literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/exception/BusinessException.class b/backend/target/classes/com/bycrm/exception/BusinessException.class new file mode 100644 index 0000000000000000000000000000000000000000..c3944df615604e2b52f99fad4684a8cb2607038e GIT binary patch literal 1000 zcma)4OK;Oa5dOxEW0JT{+|;2BkCsP8>L7gK7Q_JrQYG_jRn8lCNsM9}Id*}61ri9v zfgix{;f$EI-NX_>LY8-TW@o?0?Ed`y{Re=%*l$9^nt_@L9d$zgjW`qTOhgm+WfrAD zC?CD|<=ZrfBSQUN5C!Rdf<5q-bw_CuM3d3MNfQ^)Fwiv7f=RHJC5KTeCo&-zXJVGg zXRisp!Qnv#q^uYBYx$_7&0h!G9QBGb*g>BoK8;Jb%(z#0trG`|P{&m+QzS2V zRv<0swjvp>!0&ST7Mieg{Jo-lf#1rtlY+>Zw4AA-aT*IYyJUOChZURU44JO`Z%^CY zg&o%3uW(umPOJ39K-k3|gDZE;sod@IPu$$=JSvAS&q|)|e8&1mUKG8n=gC%%Zx#h5 KKH)}Qb@LBh{>9V) literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/exception/GlobalExceptionHandler.class b/backend/target/classes/com/bycrm/exception/GlobalExceptionHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..0c18c6f30d40ede278060f5bde8c659ba989ee56 GIT binary patch literal 4586 zcmcIn{dXKy8Gdfkbdv4RWEa}nR-q}SP1?Ye4+*ld(1Zqp+ZLO+ir~lW?#*VB*_mZ_ zHf=>jsvy+X76rv>E%gHw5Q>~5N$F94_V{O*w*JI_;PJULlik_wCaDKa&hFl?_kExD z``*9*`{G{!+=KTMXhXY(RXRGbTA*jzoHY&Gbc)8o+_cR50;`8C$MW|GwDX) z4GA4YVY`MMI{MHrFcj!nRwkJA%#u9pdNamhnKN>hQ!w^Rf66WF^@`P! zbo>LZpEYf(5VLC!^%~|$k}o3MO$A#qomHe}5DX0zwEQj%Xt-U+9WVq2{u^R}wL~y# zNxQI5d8fiyS~PIgw`?P0ReVag6L)F2TW4^8mL!4mYuk+GitkCYB(S-GHe5AmQf{VG z%#A@E_u+F41+!eXj|$w)h%rA@m`Vu$H>Z#<|*rc7^K zK2?=YUZz`!tg#5R8`JS9zQ6#_hnxj=$CZd+)@kCI7iEfu{S7sS_9m)M9HhY(P93}a z>V?a%pa0ieCmO227ja0#xQ+>YiDjam%~47a5aX>X4^9fK?;DFtT}+w;zKpMEcwEO< z@r1zbipLQn7NsMuL-?lU_*u)fgUF3V{)Ql-+}O~v2W1#YN&gc~Uc z40gh#qE{}yarx}ItA9PaaOz}C(N5$A^eZ2HbmgOS;j*ezQk4m6wlnUx&}`{gEtr_{ z+{0$hrW>=Jm=frXGy3?_iL38@c=fqg)Z)A6ubh5i;pNv<9hz3$XK0ZY+?T5>B{&*f z9c4U4g|4liqoxWw=1dn27uI-|@3@E&+pJU=ao19&1y+T%vpd7OexO>)NpC{w6*P{# zX=hE(QuAnWl|NI;g5{-y5HcSOQsYUY`?rX`Z=_Ii)Rdodf(e8-t*AX@I zVLF7B_c2q|WM8Vf)-`Sw9n-IRWHj-K5e>!SB()a1#yBS=R2JGAkNZRPR4<)y8_U|C1(`DCnFSxSo+iB!yp zQThqY{J*fbblKL>qRZE+N5eF`?&`Lz{ft2A>*po#gDCArK;EF*0G+=N!QS4&ti{&NA~Ni{zG`9RFkdR&tMO_AKgG{9yr$#lI3uvNuASw~x--(qn5A67 zB!xM-ShClY;0>Xr^Y|FUrOtl~R74nF0RI25&>-ok* za?<4GJ$iqH0YI0z_H5Y1lI)0$XL|5kfd^U_lGqKUe(z;$*Bu!dySoc-tihY=x%7L1 zZEAm|tnI;Dtn}BHuB}A!t}^C0(hFL-tZ4WnYknPAgIgPeMZ+&M4-P(uV-bwwgwf73LlnAg9yuDX}Rw}=Zp!fvj|DD(ofZh_yiA+I>#Q8m<+Rm%y z_whVcYJ&el3;2rU2Y4}p|9k|0knpqfcv2z%#*)atxe{`Nw%Uz##N3O!Fo3&b$Omi4 z2Z{V8!suNZ`SBLW70C~AB0@e!W*6nG=-cZc#$r_F%ahxR6 zCcFKph4hmQ=2NxM?IoG|>q>Rb!Ttc63SSWm-y~t4=2{zG4w$K!|1sx3;YWqvD}?_G YoW*aV(eLmFyv@A?&%J|paRD3u1MNU)!2kdN literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/mapper/CustomerMapper.class b/backend/target/classes/com/bycrm/mapper/CustomerMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..71362f3fe7ae29afdadbe18943a1cdf6ccf98906 GIT binary patch literal 1534 zcmcgsU2oGc6us%^TDG#$4j3OBlnreUBQLxaAq@~xrHld+3^XvDSsJdTVC zxjs&(b*fmje!<4f4w&@qlfeadjYZ9f2MC@``kqCH`%Zyyl=OQCPQlBi5oR*w?Sb!@ zo1yYfnPwq3Tt^m_1bDh{VqimlE+R1q`1Jpgl*%w8lmv3mQQEiJh`B>idMyq7@-MbT!ij&<%Nv6hK06g5BQ@=4*F=9n_Ce{@yKHa_oeBY5{N+qeSZq;1(D+=vofms8AcgB%y<`iIF8$E9 zzhmB_TX_}M%5!>?YIMtmj9-hpO?LpxYjl^A=XZN?X@~ADDK~!K$EGFf(gS>JAl)VU E27j`I?EnA( literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/mapper/DealerMapper.class b/backend/target/classes/com/bycrm/mapper/DealerMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..a205076ee03fcea8cae8b1760626757dc880e207 GIT binary patch literal 1015 zcmb_bU2oGc6us_8x|Oc19bbcu!6c?m2>ilZ5fUFls+0*tCEne{$~+}@~< z;71`&+(0t1YA-xEzP>*9_+0zs=dY_DMD&K9_o&6_FftimtRkE7Oe~ku@=sEv(w_N6 zk2;KYFT|zbsn7}kvbd0uW7N-Oir~X)7BhM|32Q`XbTT~+YgVb9a;u7U3br%p&Q1JP zSdmF5ZO*8rz;gVp05X%`RjwAP{JZ~NYvY7dMg#dGG&bR4DWY@9)dK09iyFXv6%OfM zinNf727h#ZG%=R1no8%+s#~;nB41W@8>$?w&u-vo^k1}cEpqaa6v1=`!5t3)HTNXGx`oVObv;~gXfO6Ss|uY<`(-02Ls*xLd@v5bX-zXt4bs248+Qt}^m_EjxoVEZO&`u2+-T)c`beDF)TQcpmX@sc+ zjxqKyT6E7dAGd4fQ5_EJa15&Z^Z*}| z{s4cJ@l0E`-7Nv0e307dEc3H2-rFq7C zzEsE2rb0!7YM1PanJ)7j^K<8tTgsqnz+D&z{Uh6;?afw-X!)Mg+-jv!xu=BcCsCV- zcFfgpt#|KEF_ub2|P2jqIomyXGL%(~#F=-@ao zSqd;CFC-~lF*oD}Eyg_0nJesr{)aG7ewRy4x@u)NG3=B%@R6Gt_O|j7)Zt%3F8j^V zIy3vWk^+_AdUE6`?r;ftBE3Q-T(cztr3ru62@D#uIdc<+v3UZS44S;A8*j@2BnctN zcw0CgObN`-|4w`_qtx&{@1v%1%g2?*qJGQu$gN7{)f~|->c*(o3@QsR;1XTAoE2c0 z&(;xeGU{v?Vb5j?idAj2vEp$X&*ms&09WO@F7DI@~Mb5kQ^)}0{4cm?MIZPROf J%P4$@=pSqHt+)UH literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/mapper/SchoolMapper.class b/backend/target/classes/com/bycrm/mapper/SchoolMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..20a2a3c69cadf5b781b3aef54ee802fa23a8b261 GIT binary patch literal 1090 zcma)5T~8B16g^XE*S4rY(TY+~1X3PgUVN+3fQdECS!%>fn8*vG;XCz9RWeC2FAM z+{W}#DIpl~!hfJb9dMupBEoyrUkkxoh#H3H;Ub^5YO zPYI9kINhi8C-kf(s1tY{8wI#A2XEd0HwgR`&qyd&ZW4G=u}Prk*dqB^%olWiiS0Z> mwS*RtcIHubGl6EQu+%EHJH&m3*90zMFMGeiKCNlK2f$zRI2G*x literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/mapper/SystemConfigMapper.class b/backend/target/classes/com/bycrm/mapper/SystemConfigMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..51f35bdbd0042e405622db1c107ea36ef95f232e GIT binary patch literal 868 zcmah{O;5r=5S>K<`A`v5#E*+c0vGonH;f6Im>5emHgaFeT9#~E(r!um*F5+G{87f) zwviwvJ#2Po_sx56X6Nhs;}ZaSa8`sIfeXuX=s2=`hdOLN=RP%~Kyl~ZbKiwMjIWBY zNuV}k3q~b#ZTdW(aZ3>>1zh4`ASHo%r)$KBPzgy55vV=_OkulBg+3>6y#}~3mfGA^ zLPaau{aa+HBocSg6OS}Uq7l0=l`mYo-_2k_=R>Zh-sFY(%;Adr0UER7@?z5S*AT@W zJ`#Z#Oa2QRxUQ#|5}u0*mxkxtl+Bqn~#8=9bOdZBOe z2O-g4bA42wlFS18BZ1cN}!6{ zHm<79*}=6NKvmBy>}7-M(7=q8X&>~gAHX3>r&moRPIQmfM4Cw7!uK2;!wK%%<0-%o D)0^oF literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/mapper/UserMapper.class b/backend/target/classes/com/bycrm/mapper/UserMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..24801cca2e2167c0c98e1e9deaf0bf705cfda386 GIT binary patch literal 787 zcmaiy%Sr<=6oyY~JFWFnZM|PMg3=Ah>mHuN+m|yeiU*q^-ah_F&at3Z)0gL^JA6DjFuk6qu_zi zLw@BwNZ-N~%K(R7nxR^RlF?z?Ex5ilN)Njox6qc_Dx2ooT?kxCdmjz1g@Ln`CT3Ji zCR%$p3FuJXsaSb|oKR<4M^;!BY4H1QWQJUfgnuu&@?eg+C;*;&;j7A{2oeNX|A_fw zz^L;%S~vPL){=t5ySJ-iq~C0J#>pmD1w6CipV__|YGD(T7vn2%@=GaB;pr%i)SZf_oKx4@>~Vr8%0}>vQ9DDoG$ZJbr1fj z?sz`B4kJc0m?k0zqf#Ms(If`($7#hTBUI@VlFH9+&UP(X`6K#PDHv;>c3yq2hm idy7_Ze^*|mY%bTno7QRLA89;q=Av7)jopFh4$&L^j>W?O literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/service/CustomerService.class b/backend/target/classes/com/bycrm/service/CustomerService.class new file mode 100644 index 0000000000000000000000000000000000000000..8ecdb264d961ade66b2420e3f3b3a861572c8beb GIT binary patch literal 1148 zcmcgr$!^p@5Pj{;l1VZX0tri40)j&#Bz)mEC=ww;L>idDK<-Yv;)u{?2hVazDZoG{+N-@hoc%lFck{6uLMnjzDAPiC6<$DZ~gGNe<1_BWeQpcS)9U|GdJ*JCxE)OaRi zm)=ALF@I{dfB(OnUo{GvB^Rwe84vfloMuZ8@*`j1`EH|gqlEj`Y{}&a0*+$HKx*;~ zRihDjceTXIbohDP9K%9*ij6Y)1xY5jD$Ctqs6bz4TC>v^-W*GIke&ONGVd?2Zt9MPwc=UTZ5JY9@fZ&pzN!`4#rw45H~ALcvotO+XDZ?EWUW>n~oRBD&$^*^{Z z=XbR|c7oe-O7d&P*QP(r&O;@+EdpDAOTctjCP}6xy;UJQZC2p&{9f4lIsyVqe6~QB zud$5|9CZ0_qlIOD^;lL|R$10q9Q4_3fOUphw>F;&>>Y35W~u5qxW$&uxq1t?OLc$A ndNxdVaJNQSQ-QdL?UDk=w&{zs_c_M{Jgn1NlfWZ>I@tLG-JeGx literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/service/DealerService.class b/backend/target/classes/com/bycrm/service/DealerService.class new file mode 100644 index 0000000000000000000000000000000000000000..4ebb95419833fc2fd5c1102571edfa9b3e400b73 GIT binary patch literal 713 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 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/service/impl/ReportServiceImpl.class b/backend/target/classes/com/bycrm/service/impl/ReportServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..5d2cf39fe68a672dbd2aebbbb2610c1108f0f1f1 GIT binary patch literal 10339 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 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/service/impl/SchoolServiceImpl.class b/backend/target/classes/com/bycrm/service/impl/SchoolServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..cc7ecd8efabf6c1872f9943733f9a8b6c25b3382 GIT binary patch literal 4546 zcma)AX?Gk)6}>fDS{}6)WLt_7ud!@vG?GU+30cN*BFUC5Wh5JGF;3z@Yo;Z&HPb!x zv}6kiB!CkjK-dB?3E;4V05)+p$+B3#@PWhMaNtL9INa*)nW?ds=~s`;;@DXbPDky5?-^;fRoKqgN|FEUpyyp(606TQX1)le^|#Oc$A?}2NMYN zsu)8QWgAsNf$WJbi6a^w*Kt(pudS?vjOT<>JvM$ypkc=J0=W-38B+@ANgaLY7l=+< zcBX$(HVgEutBvxkrtMkYVmNV9!!d#VO7Eq#nfHU#KVPtHvrsr*Y^lSbz&*FGzy0ym zw?4l5@_*ia>EBmhyuJMX?dz}Ke)F9u25?g5_K?8#^&m`Yc&dV41&}C)Q5D4~PH8x; z!fBVfzv#Ggi7C^t3yFUIPB5z&uEw;JUp(zPOm@#Q*>F%@J#?~? zE@4Y-GKz6bXqeP-7N04K&$Du7BITrw>@mYL$N5I_+0I2JOV$oy42SWwj%VbW9;lJz6%CESO3OR7DtLLvkup$23^5 zYN(W@FFiXH;@lci z_6_|~6dRJGKd-|D1Efj0_GMYBO90D5HOx~$Wu6Pg9GE;6g(r8AORVYT{$l;9*a!sf zS8LRIWj{8_!X9KyQ;I?#ozG2~?zl0PWyD*21xy;QCEvrwYH!ve`mVb#e%wt)OmEi7 zoHnF>JyVt!ZO&Yzl4W=lRkGYt=1F!3yB7yGEAIEbD9~DoYcXHM7QbWc5d~yLo+XcR zjfOGLNY8Qq3z=;hvu13=n|De5aW#8FRBB# zj3Wfv71)&~0(IskF70o~>aa?7a#!2)`C*1sTOxeu|DnC3oJV0&Lnr9!)hoi9UfC6rcNRd zSztihHtgP(HF8rKqeF31N3X!h#^q9(s*<3Jp%NXp#xZB!O`C(3OzYN)A|X$UhvZ3s zr^|KqP+-EEj>jxZga=GIzPaCVJnrj8K1l6CQ!RcI#oPF;hIe%Q4!>vd@y{2&ye)gd znd6S)lcj|*O@TQsPf_(O2<5kbsc9D)1q+-s>`c}ybfg?-Za$w>x*<(^>C63RZjfENj@13U3me2t*K&QW@)hs7YDF$Du;FE15qyIKzlm>! zoc_#vHQP^w=pS3b6B0ccu43R^%kgEL`0FZ$$uKn<@41N)USmr*7u?QEvz`@vE`qZ? zOUOuORX(!=^fJ&xW``K91U-J3h#x?VUk1J8_b~tZd8U^Py8;L$h9~d}zD<~ocog5k zcL};FzjGSNG|A}c z@fFMpTtQ9MHPRX3>mGsbTd>v!Yc!;ojo=#1)wmr+1D-$=d2HpOd^e5}=Tl@iqOeMq zSS9fqqs32Eo(Iq3$Ar^MiOC37`4J4%C`bK-qk_K6A>(R98cMo+jWB{(zPH6FOlrCOFZuo}UNW%1CgnfiI&Oqd@8Lr%u`kMT%PbJ9X#YQ< C)4wMG literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/service/impl/SystemConfigServiceImpl.class b/backend/target/classes/com/bycrm/service/impl/SystemConfigServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..3e6bead29e258d92b9b771197ab4b68fc2876f60 GIT binary patch literal 7081 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 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/service/impl/UserServiceImpl.class b/backend/target/classes/com/bycrm/service/impl/UserServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..9f1c9aff0252c7a2918ee6914842772c687ad9a7 GIT binary patch literal 4983 zcmbtXd3+RS8GdFrVK$o~KsXa<%PqNB2qB~_Z6O?OFb5@&%AxIKcSsiY2(z<5s9F%E zXbYuC5!z}GwM8pOu`E!ewOXxKZMACaSuaAs<6r+$>+^jxlbucA=O6y|w{v{Qdpz&+ zzTZ1<{^#Xa0My|hLHOWTQJ|p^!xW6%tZ&mpaXr};YU|u=L@Wiv7R8b=>vjeHSrr{B z0tyzV%&t(n$BZSrHko?D*q$=CgwjSNW5%rBP{i!*u~MNs(0Jtreq%6Fhq| z90{$oXTm|0pWU?ot!YzG++|q8?pMu!TX{6K3-H`x3MF0B_AHTBiT;IX{SN0w0JGHm}>D|{3AG><$R1niqA(&RF zVC?k_=m?@3H7aIn2w@Hvd6ec1Qcy&I+AZD6q=g_aJWWZ<=%UR*)MB2BIt}wtuV7RT zKxc)5KrCr>=@&GQ*lF#t<>;gv0oUt%+TY8*%S?;1+6ODG_1nid2I8NQo-;pBWakrWvoeU zF_H?_d99bKhg$6!aS`_n$xYsVGY(Y%Un(hcPoadyb%|LQ}<~22-XoKIx7g; z6kTDa5{~uLy`mhwUQ?uP0c>C)v15Jt{QkZZNBf>UuHvH##^)HfEhXvSl-!i+XbWN^ z{Ni$-1|6NGVA@r#V6<1K?L3*h5m60>;CivMR^+pYR+olumrko0tyVd{5t}t^ao2mt z6B?32r;wA2ZZ&!|Y!z}CL1)~Rl-6JgNy7(rxHH={Y{w3=hckjbB!<^|H<}e40qmrg z{U@L4Ke)H=(W3!;TtIg5k!y!{^*y%N#!fi-NevGS7)^o8jC3T3-T0J>JsLhO?7Jlg zswi~Kh-8=H=8>#;CG?;z9(Bh8*h^)72cF8W9=owm!)Jv=vA)&V?ye8wAv~;NzlH;N zB<~cn8NgGF8K}o)x$qFxKI6g_>jQXH!IUdUPTLB}iK}}qT|R$cz=ZxM&i5UBSfu;s zH5|rcLZUp(6jXch%gc5z?;I+M@P9$WQ5P}S15wW(*YE_Mq~uIblhp}ba~nEqH`Ufg=R|8eYoiMq=FFR4 zAL%saMdma#%q_xkd`-pIHN1dtTRT zp1?T`=LOpWR?1!<#LKv-;#(Rni2#n4w&h#R%o3fE6;G;omHk65FsxLvtr1~px1SX> zctbqo=ni}0?=9NliVg(@OW8{?O`3TGw`LNZhPg)X6bW70oQml24&982cW1D`>W-2A zUUjZP*Xy&wj8=DyAT#L9{G_iY`q+p+%~DPSDYcf7%w9|$t?>pkA8>w-tH$LREcUVz#2?28Z64o z(u`?Rzlhe2xRb*m@2sGJLd!l&hY3Z}x@{>1Wgge^cc}O+wdO1lwsRnoS1A?Lc}tD- z&m-}=rByP;&ncF-|GAcAvWwb4Atvaix0WcF=4FsjIk?tHjgtrI8nTGtPUwP4<7RCb z8Uaaf-RvUeMqg)|C!whi6o2*-?Wv3zF;>I``^SigwdcMVW(!n_{pt)m$b``mOUIZM zOOnYH8%Q>>GAXY60YT0iDXX`~2sz@yn8NP_9~8U-KR*`uxxlZeQqlj*J3nN24{*K^ z-{!j4_}0ype%{L~&q1lY2zA{#6rDw|vg#~GR#uwN} z$hS%OE=MQZQt&#y$2ZE8+7V2-nw4QMRJ z+xRKx1%#CQHg5`khG|^(8lMNtC3b`5F1Uf*ckuI^+;^nhU*MOvT&0mfiHPqMP!i^j z7GZd`G`zLO4bFNIh>O@r;(TmjL0Lf!G0);&`LH~ThU>2V{=A^?xHy!NpLkkOP$_lbLBIMUxz%d{05s7Rwe>Tem=uR;|y++_}Ch=N2 z-obCt^@MW+zhUm>(|!Eu?D#u9AjStkj7#VQXXAJuf1qE*TrKj!&%LGiBO$gyl$lXR z1SgJni@JSL&$?c7{a3O$)LKor zq|an&zRxpB9Wcx#=%RJq%=S2QJ;7|>N?Ms%f;2PUlD<~jh79=HLSz3zV@pUnJL4B& zl=RRqX;K8AllyMGg>yx?j6TP?J&to#PK9kQ{c1}UojKHc2G3u_2`0~}($iU-q5WsF z$Yyb2aNXU`a90TEegGK9%`klMYY0Tqf^2twbgVw9YH6$G;~LC6vv3yUId1K zWzP$SuA%HM=bS4oyO>GlBRGy;4JV>FsmjvC^T4DTI!lIKDDyh?LcI=75d93tnlr2C zT6_O;>)C4!35Jf{;I|){yy{xQ4&pSq?Wa{++t~iJu9yu*aRz4@TDX)#GNcY5(L`&u zB*n5ZSLVblj3iPThNC!#5r(6C3o~t)u8=DXp(1zd)n*uM#-A!1j+065ZwkY}(0|*T z%v0&7M1f}ENY=9X-KEMLm$NE6uhXVc&KuHFazhz#OP2HR9U+{FI^U`qka-2a zEaal@m?d6VDw9q(cC7VWUCRp;BVbBlGekz?qw%qLik=$`!AX;RysZl7#F8}mw59lW z?OmX>8V~C4!NG|k7w$@x>r7-ql?l!Z#D8I;O zH8I8*etF*gd?|iBJ{{j zVxR6FN^#WqD5UaYorpNm(%E2e9q)r5i(#9OjWp-4G>4=)QRMuS=1inb9W)E{rpq>F zQ6i<@?oPAwmSOc`GR=R?*|>^%1}oHkKj4ZXQ>ivBTxVE3h84nS~bJnwXtHj>CINH zvu(j)C{3z$dxuiQ4Ea|=`GFt5PDSlAWb4!$hS`=M$WAiqNxjQ^ikP`pD7f0^+Bf)& zobh5Vj_5bfaM24BE##JOGRo&PVckfe>l=YkVdMvcwv2~i--64q^8X$(*v%l2x~_N> z$*8nUQ*e(akCn=14opPMeXNpSBXo)kMZn&7u+yK#udu$DHS-NuvfWR}Zl`d8;PeD8 z63k8DErQkrE)&eB@H5SL0rObEHIzxlD)}`$#dGp6P{SMY4ZMR#K7$I$$faU>s8T#d k_JC{&#rGDSXrHrD+QandBRnRb#X9Xz$cpJZDJbRt0HR&Z>i_@% literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/util/CheckExcelStructure.class b/backend/target/classes/com/bycrm/util/CheckExcelStructure.class new file mode 100644 index 0000000000000000000000000000000000000000..538f1b66154a35edbdf8c4240122afd9a51d387a GIT binary patch literal 5267 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 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/util/ImportSchools.class b/backend/target/classes/com/bycrm/util/ImportSchools.class new file mode 100644 index 0000000000000000000000000000000000000000..f7622d7ef9e80d4c5cc5792ce7f5ff59cddcc4c5 GIT binary patch literal 2545 zcmaJ@*>@9F82{a7nKVo(gcc~9VJW69ZIDf+1!a|Jx?n0$7G;_Y?Ld-=lSx_JP=U5= zMS>uERPd+fQJmER|kQ5sC9dd88En3?buPFV3L|Pb=}(4R zRW(|*E1DGGW)MwFMfI;%qOu$L5V^|&hGJiE$Z1H|lz2;Z**dOKC}Ir8QUrOIlGKxC zgpK(ahav&RBF1AvPC}vGNnMVSmaJ*y*78aL8_1-0 z&4nopV>8|D_im-{T|Z)6`oj3~;$knCO%w4Pyp)fWNXYRBL*>&_f1;YK_iA3!3=uOi ziy&%|^<~XTHJZ}p21##aDDss(VM!(vFqOL}fpQ}im(zqMzuwK9h5lz@g-8j^*fw(TWaQKBbDVmb&w=s;*jhoe=)>(_qBDV0>DWC)` z{#K|Fx_oQ#j)<+fk~%47N}5H4xnvaC1l6#lD=Otv23f>5v{3V#jYV;5ol*H==#>U+-K~+ zV02uu*fVY(cVP!Zb*7`cfA9W#x9|RO;-c3oF(hkkN?5LHmh^C|)vvxXZ>IZ3=Eswn z&KvjJyDVn{XjWL4$K-g`uCSco)w-Y(`Pqo)ulE0RfnSa&-W8#7WZZ;It(;6sEd*E; zx`-4XjfEyKAzcdZXw;;zEMOy{Y*{DP%|Obv=(wQ?kNeA zkf%$GSP`->2pNsf#b|e80H=x(xzs$flBMLPz@)5JN|-1M_&oPfF&`uWhv>9c)?3v` zgQU?_p&3XCyF+S93(NdTBhGTjt>Tv!)6qr`DF4X=jSe_z-9=x1+8OPR@?Nm3rg%54 zTnvoH9$H090q@~``pU-#_>i2Cao!RL^b1y8e&-C_<+gdj9ymQh@D}o$Dta-hc1{|j zPs4i+o?DpM)Qd@;$!Scb)9JLOQJRMD>NQjj2wWVbDH6g!IT=dh}>*l`23dH5M?7dyFXNVtu>CR?$?zV$lZ3N_hF zoM~(dH97eHcBsk8cPW%cWc@w|>v?>W8?};uzHg_!2eT-x!J^_ktuzvY`Oru5D#2ER zKk*k`O*=TK+fYL5I6}XOK%Ia>OrnQmGQA^HXoycG?djNn88j+qVlQT+gWlT{@Zk(i zz3)+uo2bCAwEsqDzY}x)m`nZ_QiOT<8}r#1EMP_SXmZjv6H)oF;Un_I$l8yO@d?p- z3ITkIeU!r%9LIhfAe|GW-A-qA^5UhaopeT|;vf!@r$Xk;dYOoSaTrI4{G)Wv+rskE zMf%6+qzZ!g5P1SVdx$v#@*iQNfNIA6!J5bL@c-V9lZ*sl0-|1uOMS;E3`N69TJzBT EAMVJ?l>h($ literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/util/JwtUtil.class b/backend/target/classes/com/bycrm/util/JwtUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..87a22e896aa84919b1aaaa0ecd89a981cf8d17ee GIT binary patch literal 4635 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 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/util/SchoolImporter$1.class b/backend/target/classes/com/bycrm/util/SchoolImporter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5dc27da1e94c45ebcc248b96cfd49f684bdac1ed GIT binary patch literal 877 zcma)4T~8B16g|_HZd(_rfPx@`x|Y@tR*d?hF)6i>hJF|p@PVi4cG50RcbeHPhF|2f zniyjYKfs^hk1^g^iH(UdBzx!Fb24}DnYr`*=hrg;Pq0})3TX=&8&k+KI7;_jKH~mB zxFZ#~QRI#zp@*s`q+1hG?w^hXL-vHrv4|Kd<;qd>A~nzR$RTf`VB->OhE-n;-R`Nc zhweBIr0e+urDS6`QaTpe*<^4X?_Ci4gBBkdSI%!&4!Lro$ob>SnYck-5VagY#Uj}#5w7Dgo)SJo6|V^Ecnyy*jWXHDCT4!1LV1ef j9>p>WZ!Fr;`o}_L_miy;@Q^Tr4O$;j6q0jNQq27VzA?z6 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/util/SchoolImporter.class b/backend/target/classes/com/bycrm/util/SchoolImporter.class new file mode 100644 index 0000000000000000000000000000000000000000..ce914e6d804ec5e5d9b7dcf112994b616dfec523 GIT binary patch literal 7440 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 KU=jht$o~(v$~K?? literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/vo/CustomerVO.class b/backend/target/classes/com/bycrm/vo/CustomerVO.class new file mode 100644 index 0000000000000000000000000000000000000000..3f7c3ad44548bce2a902f3e814318902afc1f041 GIT binary patch literal 7256 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 literal 0 HcmV?d00001 diff --git a/backend/target/classes/com/bycrm/vo/UserInfoVO.class b/backend/target/classes/com/bycrm/vo/UserInfoVO.class new file mode 100644 index 0000000000000000000000000000000000000000..f706abcaa7ef80a5391b4aa29ea50ce4291af9b2 GIT binary patch literal 4384 zcmbVPTXP&&5&mX1vopJzmDX!Z$~YoeAcC&h5C=>~mPum8iGt)9D^_s0Wwbk%)>-X3 zyDO8J`z72j3D+tfc*IqdtGE=AtAI+8mr%tsPw>RA-~|)DK4)fjR!k@rE_qI$?yvit z?(?0V*}wez_pbwZ5I-p*hanrL3k!Jz<*UKh*T@Qa9|Zwyv}{pQ6{EOzMod)(^SXZf!3~h!Gc~ zC>wAD)e3e)1CV?~3NA2jHE>7rm2wMrewIV~l%f-7f&2?%)>#-O1f~JA7nN$E> zqNUkq1$?iI_hQCCVLR-pN-+7#%xns-(wBnIxtN!@`A~v(#e31ked0Y#@0BPk(ckal zeR#ltP5nic!Pr2|I0wN#=;HnOfQ}(M(1krVfR9Qm@DI9pD288*sw?^>7pFyEO12`k z6w4VGA4)uuI_2<)i$`&mb=nEKJ7?Q<)|q5kwec7!(m#H^_M>}^W>FN)gkKif34_g%f@1QFWQ8ws1md$H~WZgs5m#e8PY+E1Ue3 zi|3@MPOq)^VPng{F;%ukySfo}8bPyhBiIu9mboWRH^WZ1(QaK@U15|bx%Am~tJ@1& zz0IJx7h1g9^3Nda^=XW*HCo~Mz1^*_^Ry0BS!>rACtx%Nj+AC^r_nXwt-Z~)ULw1@ zeRdyBABZCN>?XIk9`<(H^$S6Vwd--C%sg_^gdDg+@j22_P%#hnEWQX#kTyLNF0!zK zRo7uWy@~iX$UaoKsNSqnd$7esEHGfTdplu=aLIjI^Ur{*w8^xjjPY?B7}4gwqM!h} z#T2zsPqb%DrNpzZ(14g)381eSO|7kyFQ-@6swhg5ZnQz!gETW1aHAL0o?j2HMMrI2 zxVXB`>uId=hIPX3UX!ifP7*Fm_j9wRbt(mA)n{0k?r(57!s?ySk}O)>Xzz7u;kkxT zcl46nZFSA>6LMpU9VG_?0mtL0p-wp@ZF9K7|9rnFnePcT@-3i7Hhwj-*Q=4uU5)JC z9FH;vUu1mla8~7LaJ1%b!}yJYHTV=WP{dU}T@AqVXmVyq3+Hpt`FF5?O=Avy=SrqC zyKjbb>7esOrZanShVzkw&XbwWe0O9xA3NwgmFdiGpW!@l(D~j>XTF^>oR1%Lp3ijV z+a$yJo`cT!XFBhq#WRtk@;T->=I7>LgPncQ;~Ehiw2(j;W}rnnpWQ8mp zHl&a>38^QY?2tze8&Y_mgw&I6cH+kl8&a-N5^`L{?`7|D;;HKp*L^9y|V=Hj0*?3r)k$W6G5p1F_N7_s16ge>@Z&k{`jO;m28-JYymkD$o8BR=%imD=%iot3IZxdpn_LSflm3u1fB9-Z&*NX1frAz`F@EY-yiWx z0vd@xC2u4JTJ}c?TK3D{sDR25Xw)mmAoCV)%uuQq>PC7?7cahF#uQ$}ORV;o;o=6H zYmSA!gU?VmggN{ZpQU8tar_ORqhw(nf5qo1<%xX_U!Y{8gJ0o`lpMT@SMViD1^g7> z!j~x(vCp->LTMO(=WoJZ+{eSuiGIO1#o(Ed z#SyY|81sj@xZ@BNs_;f@3KNeEc4ItJxV6dkQCpiWZ^Q4^a`as zdZgE@lx$iazz--n_$4OrLrMi9gRzZ~x2P~}IEFz2@Z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO crm_customer (name, phone, address, industry, status) + VALUES (#{name}, #{phone}, #{address}, #{industry}, #{status}) + + + + UPDATE crm_customer + + name = #{name}, + phone = #{phone}, + address = #{address}, + industry = #{industry}, + status = #{status}, + + WHERE id = #{id} + + + + DELETE FROM crm_customer WHERE id = #{id} + + + + + diff --git a/backend/target/classes/mapper/DealerMapper.xml b/backend/target/classes/mapper/DealerMapper.xml new file mode 100644 index 0000000..52fe218 --- /dev/null +++ b/backend/target/classes/mapper/DealerMapper.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO crm_dealer (name, code, contact_person, contact_phone, email, status) + VALUES (#{name}, #{code}, #{contactPerson}, #{contactPhone}, #{email}, #{status}) + + + + UPDATE crm_dealer + + name = #{name}, + code = #{code}, + contact_person = #{contactPerson}, + contact_phone = #{contactPhone}, + email = #{email}, + status = #{status}, + + WHERE id = #{id} + + + + DELETE FROM crm_dealer WHERE id = #{id} + + + + + diff --git a/backend/target/classes/mapper/ReportMapper.xml b/backend/target/classes/mapper/ReportMapper.xml new file mode 100644 index 0000000..ca15377 --- /dev/null +++ b/backend/target/classes/mapper/ReportMapper.xml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO crm_report (dealer_id, customer_id, description, status, protect_start_date, protect_end_date) + VALUES (#{dealerId}, #{customerId}, #{description}, #{status}, #{protectStartDate}, #{protectEndDate}) + + + + UPDATE crm_report + + status = #{status}, + reject_reason = #{rejectReason}, + protect_start_date = #{protectStartDate}, + protect_end_date = #{protectEndDate}, + + WHERE id = #{id} + + + + DELETE FROM crm_report WHERE id = #{id} + + + + + + UPDATE crm_report + SET status = 3 + WHERE id IN + + #{id} + + + + + + + + diff --git a/backend/target/classes/mapper/SchoolMapper.xml b/backend/target/classes/mapper/SchoolMapper.xml new file mode 100644 index 0000000..05826e2 --- /dev/null +++ b/backend/target/classes/mapper/SchoolMapper.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + INSERT INTO crm_school (school_code, school_name, location, created_at, updated_at) + VALUES (#{schoolCode}, #{schoolName}, #{location}, #{createdAt}, #{updatedAt}) + + + + INSERT INTO crm_school (school_code, school_name, location, created_at, updated_at) + VALUES + + (#{item.schoolCode}, #{item.schoolName}, #{item.location}, #{item.createdAt}, #{item.updatedAt}) + + + + + + + + + + + + + + diff --git a/backend/target/classes/mapper/SystemConfigMapper.xml b/backend/target/classes/mapper/SystemConfigMapper.xml new file mode 100644 index 0000000..d0545e3 --- /dev/null +++ b/backend/target/classes/mapper/SystemConfigMapper.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + UPDATE crm_system_config + SET config_value = #{configValue}, + updated_at = NOW() + WHERE config_key = #{configKey} + + + + + UPDATE crm_system_config + SET config_value = #{config.configValue}, + updated_at = NOW() + WHERE config_key = #{config.configKey} + + + + diff --git a/backend/target/classes/mapper/UserMapper.xml b/backend/target/classes/mapper/UserMapper.xml new file mode 100644 index 0000000..efc1d3c --- /dev/null +++ b/backend/target/classes/mapper/UserMapper.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO crm_user (username, password, real_name, dealer_id, role, status) + VALUES (#{username}, #{password}, #{realName}, #{dealerId}, #{role}, #{status}) + + + + UPDATE crm_user + + password = #{password}, + real_name = #{realName}, + dealer_id = #{dealerId}, + role = #{role}, + status = #{status}, + + WHERE id = #{id} + + + + DELETE FROM crm_user WHERE id = #{id} + + + diff --git a/backend/target/maven-status/maven-compiler-plugin/compile/default-cli/createdFiles.lst b/backend/target/maven-status/maven-compiler-plugin/compile/default-cli/createdFiles.lst new file mode 100644 index 0000000..e69de29 diff --git a/backend/target/maven-status/maven-compiler-plugin/compile/default-cli/inputFiles.lst b/backend/target/maven-status/maven-compiler-plugin/compile/default-cli/inputFiles.lst new file mode 100644 index 0000000..9bec953 --- /dev/null +++ b/backend/target/maven-status/maven-compiler-plugin/compile/default-cli/inputFiles.lst @@ -0,0 +1,46 @@ +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\DealerDTO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\controller\DealerController.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\ReportAuditDTO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\impl\ReportServiceImpl.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\LoginDTO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\controller\AuthController.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\util\JwtUtil.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\PageQuery.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\common\Result.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\Dict.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\exception\BusinessException.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\config\WebMvcConfig.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\vo\UserInfoVO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\mapper\DealerMapper.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\mapper\UserMapper.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\Report.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\common\Constants.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\common\PageResult.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\config\CorsConfig.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\controller\ReportController.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\Customer.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\UserService.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\config\SwaggerConfig.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\ByCrmApplication.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\ReportService.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\User.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\Dealer.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\DealerService.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\mapper\ReportMapper.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\impl\DealerServiceImpl.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\OperationLog.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\vo\CustomerVO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\DictItem.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\exception\GlobalExceptionHandler.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\vo\ReportVO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\CustomerService.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\config\MyBatisConfig.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\CustomerDTO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\ReportDTO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\mapper\CustomerMapper.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\controller\CustomerController.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\impl\CustomerServiceImpl.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\annotations\AuthRequired.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\config\AuthInterceptor.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\impl\UserServiceImpl.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\task\ReportExpireTask.java diff --git a/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..28731ab --- /dev/null +++ b/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1 @@ +com\bycrm\util\PasswordTest.class diff --git a/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..0f5e831 --- /dev/null +++ b/backend/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,47 @@ +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\DealerDTO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\controller\DealerController.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\ReportAuditDTO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\impl\ReportServiceImpl.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\LoginDTO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\controller\AuthController.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\util\JwtUtil.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\PageQuery.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\common\Result.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\Dict.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\exception\BusinessException.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\config\WebMvcConfig.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\vo\UserInfoVO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\mapper\DealerMapper.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\mapper\UserMapper.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\Report.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\common\Constants.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\common\PageResult.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\config\CorsConfig.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\controller\ReportController.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\util\PasswordTest.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\Customer.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\UserService.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\config\SwaggerConfig.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\ByCrmApplication.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\ReportService.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\User.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\Dealer.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\DealerService.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\mapper\ReportMapper.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\impl\DealerServiceImpl.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\OperationLog.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\vo\CustomerVO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\entity\DictItem.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\exception\GlobalExceptionHandler.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\vo\ReportVO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\CustomerService.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\config\MyBatisConfig.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\CustomerDTO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\dto\ReportDTO.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\mapper\CustomerMapper.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\controller\CustomerController.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\impl\CustomerServiceImpl.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\annotations\AuthRequired.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\config\AuthInterceptor.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\service\impl\UserServiceImpl.java +E:\boyun-workspace\by-crm\backend\src\main\java\com\bycrm\task\ReportExpireTask.java