From 4f3d1693b40f00c9836cb672155951af42934a92 Mon Sep 17 00:00:00 2001 From: wucongxing8150 <815046773@qq.com> Date: Sat, 21 Jun 2025 11:06:35 +0800 Subject: [PATCH] first commit --- .gitignore | 57 ++ Dockerfile | 41 ++ pom.xml | 390 ++++++++++ sa-admin/pom.xml | 57 ++ .../sa/admin/SmartAdminApplication.java | 33 + .../sa/admin/common/AdminBaseController.java | 13 + .../sa/admin/config/JweAspectConfig.java | 38 + .../admin/config/OperateLogAspectConfig.java | 34 + .../sa/admin/config/SecurityConfig.java | 40 ++ .../sa/admin/config/SecurityMethodConfig.java | 50 ++ .../sa/admin/constant/AdminCacheConst.java | 57 ++ .../sa/admin/constant/AdminRedisKeyConst.java | 17 + .../admin/constant/AdminSwaggerTagConst.java | 66 ++ .../sa/admin/listener/AdminStartupRunner.java | 40 ++ .../app/expert/admin/ExpertBankVerify.java | 23 + .../module/app/expert/admin/ExpertEntity.java | 101 +++ .../app/expert/admin/ExpertLoginVO.java | 25 + .../app/expert/admin/ExpertModifyForm.java | 56 ++ .../app/expert/admin/ExpertModifyVO.java | 48 ++ .../app/expert/admin/ExpertRegisterForm.java | 68 ++ .../app/expert/admin/ExpertSignAddForm.java | 15 + .../module/app/expert/admin/ExpertSignVO.java | 39 + .../module/app/expert/admin/ExpertVO.java | 32 + .../app/expert/admin/ExpertWhiteEntity.java | 68 ++ .../module/app/expert/admin/LoginForm.java | 42 ++ .../module/app/expert/admin/PWDLoginForm.java | 41 ++ .../module/app/expert/admin/SmsLoginForm.java | 36 + .../module/app/expert/constan/ImageType.java | 18 + .../app/expert/constan/SmsTypeEnum.java | 34 + .../expert/controller/ExpertController.java | 588 +++++++++++++++ .../controller/ExpertSignController.java | 59 ++ .../module/app/expert/dao/ExpertDao.java | 18 + .../module/app/expert/dao/ExpertSignDao.java | 31 + .../app/expert/dao/ExpertWhiteEntityDao.java | 19 + .../app/expert/service/ExpertService.java | 82 +++ .../app/expert/service/ExpertSignService.java | 40 ++ .../service/ExpertWhiteEntityService.java | 37 + .../app/file/constant/OSSFileTypeEnum.java | 26 + .../file/controller/OSSFileController.java | 73 ++ .../module/app/file/domain/OSSPolicyVO.java | 28 + .../controller/MedicalRecordController.java | 59 ++ .../dao/MedicalRecorAbstracDao.java | 16 + .../dao/MedicalRecorCheckDataDao.java | 15 + .../medicalrecord/dao/MedicalRecorDao.java | 42 ++ .../dao/MedicalRecorDpmasDao.java | 24 + .../dao/MedicalRecorUserDao.java | 19 + .../app/medicalrecord/domain/DpmsAddForm.java | 21 + .../domain/MedicalRecordAbstracEntity.java | 58 ++ .../domain/MedicalRecordAddForm.java | 226 ++++++ .../domain/MedicalRecordCheckdataEntity.java | 155 ++++ .../domain/MedicalRecordDTO.java | 16 + .../domain/MedicalRecordDetailVO.java | 211 ++++++ .../domain/MedicalRecordDpmsEntity.java | 42 ++ .../domain/MedicalRecordEntity.java | 103 +++ .../domain/MedicalRecordListVO.java | 45 ++ .../domain/MedicalRecordQueryForm.java | 30 + .../domain/MedicalRecordUpdateForm.java | 24 + .../domain/MedicalRecordUserEntity.java | 72 ++ .../service/MedicalRecordService.java | 680 ++++++++++++++++++ .../area/controller/AreaController.java | 54 ++ .../module/business/area/dao/AreaDao.java | 51 ++ .../area/domain/entity/AreaEntity.java | 62 ++ .../area/domain/form/AreaQueryForm.java | 17 + .../business/area/domain/vo/AreaVO.java | 42 ++ .../business/area/domain/vo/ProvVO.java | 14 + .../business/area/manager/AreaManager.java | 20 + .../business/area/service/AreaService.java | 57 ++ .../CaseplatformBankController.java | 44 ++ .../bankcard/dao/CaseplatformBankDao.java | 44 ++ .../domain/entity/CaseplatformBankEntity.java | 67 ++ .../domain/form/CaseplatformBankAddForm.java | 48 ++ .../form/CaseplatformBankQueryForm.java | 21 + .../domain/vo/CaseplatformBankVO.java | 45 ++ .../manager/CaseplatformBankManager.java | 20 + .../service/CaseplatformBankService.java | 80 +++ .../captcha/controller/CaptchaController.java | 21 + .../business/captcha/dao/CaptchaDao.java | 16 + .../captcha/domain/entity/CaptchaEntity.java | 19 + .../captcha/domain/from/CaptchaAddForm.java | 13 + .../captcha/service/CaptchaService.java | 140 ++++ .../constant/CaseSettlementEnum.java | 34 + .../constant/CaseStatusEnum.java | 36 + .../constant/CasetypeEnum.java | 34 + .../CaseplatformCaseController.java | 110 +++ .../CaseplatformCaseExcelController.java | 78 ++ .../converter/CaseCaseSettlConverter.java | 43 ++ .../converter/CaseStatusConverter.java | 43 ++ .../converter/CasetypeConverter.java | 43 ++ .../dao/CaseplatformCaseDao.java | 73 ++ .../domain/entity/CaseplatformCaseEntity.java | 67 ++ .../domain/form/CancelExamineForm.java | 18 + .../domain/form/CaseplatformCaseAddForm.java | 44 ++ .../form/CaseplatformCaseQueryForm.java | 46 ++ .../form/CaseplatformCaseUpdateForm.java | 29 + .../domain/vo/CaseplatformCaseDetailVO.java | 96 +++ .../domain/vo/CaseplatformCaseVO.java | 67 ++ .../domain/vo/EasyExcelCaseDetailVO.java | 78 ++ .../manager/CaseplatformCaseManager.java | 20 + .../service/CaseplatformCaseService.java | 169 +++++ .../CaseplatformCaseAbstracController.java | 40 ++ .../dao/CaseplatformCaseAbstracDao.java | 35 + .../entity/CaseplatformCaseAbstracEntity.java | 52 ++ .../CaseplatformCaseAbstracQueryForm.java | 17 + .../domain/vo/CaseplatformCaseAbstracVO.java | 40 ++ .../CaseplatformCaseAbstracManager.java | 20 + .../CaseplatformCaseAbstracService.java | 45 ++ .../CaseplatformCaseCheckdataController.java | 41 ++ .../dao/CaseplatformCaseCheckdataDao.java | 36 + .../CaseplatformCaseCheckdataEntity.java | 152 ++++ .../CaseplatformCaseCheckdataQueryForm.java | 17 + .../vo/CaseplatformCaseCheckdataVO.java | 100 +++ .../CaseplatformCaseCheckdataManager.java | 20 + .../CaseplatformCaseCheckdataService.java | 45 ++ .../CaseplatformCaseDpmsController.java | 41 ++ .../dao/CaseplatformCaseDpmsDao.java | 36 + .../entity/CaseplatformCaseDpmsEntity.java | 42 ++ .../form/CaseplatformCaseDpmsQueryForm.java | 17 + .../domain/vo/CaseplatformCaseDpmsVO.java | 33 + .../manager/CaseplatformCaseDpmsManager.java | 19 + .../service/CaseplatformCaseDpmsService.java | 45 ++ .../caseplatformuser/constant/SexEnum.java | 24 + .../CaseplatformUserController.java | 41 ++ .../dao/CaseplatformUserDao.java | 35 + .../domain/entity/CaseplatformUserEntity.java | 87 +++ .../form/CaseplatformUserQueryForm.java | 21 + .../domain/vo/CaseplatformUserVO.java | 41 ++ .../manager/CaseplatformUserManager.java | 20 + .../service/CaseplatformUserService.java | 42 ++ .../category/constant/CategoryTypeEnum.java | 36 + .../controller/CategoryController.java | 67 ++ .../business/category/dao/CategoryDao.java | 72 ++ .../category/domain/dto/CategoryBaseDTO.java | 44 ++ .../domain/dto/CategorySimpleDTO.java | 26 + .../domain/entity/CategoryEntity.java | 67 ++ .../category/domain/form/CategoryAddForm.java | 49 ++ .../domain/form/CategoryTreeQueryForm.java | 25 + .../domain/form/CategoryUpdateForm.java | 24 + .../category/domain/vo/CategoryTreeVO.java | 40 ++ .../category/domain/vo/CategoryVO.java | 51 ++ .../manager/CategoryCacheManager.java | 120 ++++ .../service/CategoryQueryService.java | 214 ++++++ .../category/service/CategoryService.java | 220 ++++++ .../goods/constant/GoodsStatusEnum.java | 42 ++ .../goods/controller/GoodsController.java | 75 ++ .../module/business/goods/dao/GoodsDao.java | 43 ++ .../goods/domain/entity/GoodsEntity.java | 75 ++ .../goods/domain/form/GoodsAddForm.java | 57 ++ .../goods/domain/form/GoodsQueryForm.java | 46 ++ .../goods/domain/form/GoodsUpdateForm.java | 23 + .../business/goods/domain/vo/GoodsVO.java | 56 ++ .../business/goods/manager/GoodsManager.java | 20 + .../business/goods/service/GoodsService.java | 168 +++++ .../business/oa/bank/BankController.java | 74 ++ .../module/business/oa/bank/BankDao.java | 61 ++ .../module/business/oa/bank/BankService.java | 162 +++++ .../oa/bank/domain/BankCreateForm.java | 58 ++ .../business/oa/bank/domain/BankEntity.java | 95 +++ .../oa/bank/domain/BankQueryForm.java | 40 ++ .../oa/bank/domain/BankUpdateForm.java | 23 + .../business/oa/bank/domain/BankVO.java | 58 ++ .../oa/enterprise/EnterpriseController.java | 115 +++ .../enterprise/EnterpriseEmployeeManager.java | 19 + .../oa/enterprise/EnterpriseService.java | 252 +++++++ .../constant/EnterpriseTypeEnum.java | 40 ++ .../oa/enterprise/dao/EnterpriseDao.java | 72 ++ .../enterprise/dao/EnterpriseEmployeeDao.java | 88 +++ .../entity/EnterpriseEmployeeEntity.java | 51 ++ .../domain/entity/EnterpriseEntity.java | 153 ++++ .../domain/form/EnterpriseCreateForm.java | 98 +++ .../domain/form/EnterpriseEmployeeForm.java | 29 + .../form/EnterpriseEmployeeQueryForm.java | 35 + .../domain/form/EnterpriseQueryForm.java | 38 + .../domain/form/EnterpriseUpdateForm.java | 23 + .../domain/vo/EnterpriseEmployeeVO.java | 47 ++ .../domain/vo/EnterpriseListVO.java | 20 + .../oa/enterprise/domain/vo/EnterpriseVO.java | 86 +++ .../oa/invoice/InvoiceController.java | 80 +++ .../business/oa/invoice/InvoiceDao.java | 61 ++ .../business/oa/invoice/InvoiceService.java | 158 ++++ .../oa/invoice/domain/InvoiceAddForm.java | 59 ++ .../oa/invoice/domain/InvoiceEntity.java | 98 +++ .../oa/invoice/domain/InvoiceQueryForm.java | 40 ++ .../oa/invoice/domain/InvoiceUpdateForm.java | 23 + .../business/oa/invoice/domain/InvoiceVO.java | 58 ++ .../NoticeVisibleRangeDataTypeEnum.java | 30 + .../notice/controller/NoticeController.java | 135 ++++ .../business/oa/notice/dao/NoticeDao.java | 144 ++++ .../business/oa/notice/dao/NoticeTypeDao.java | 21 + .../oa/notice/domain/entity/NoticeEntity.java | 99 +++ .../domain/entity/NoticeTypeEntity.java | 41 ++ .../oa/notice/domain/form/NoticeAddForm.java | 78 ++ .../domain/form/NoticeEmployeeQueryForm.java | 35 + .../notice/domain/form/NoticeQueryForm.java | 48 ++ .../notice/domain/form/NoticeUpdateForm.java | 24 + .../form/NoticeViewRecordQueryForm.java | 32 + .../domain/form/NoticeVisibleRangeForm.java | 34 + .../oa/notice/domain/vo/NoticeDetailVO.java | 82 +++ .../oa/notice/domain/vo/NoticeEmployeeVO.java | 26 + .../oa/notice/domain/vo/NoticeTypeVO.java | 24 + .../notice/domain/vo/NoticeUpdateFormVO.java | 33 + .../oa/notice/domain/vo/NoticeVO.java | 75 ++ .../notice/domain/vo/NoticeViewRecordVO.java | 49 ++ .../domain/vo/NoticeVisibleRangeVO.java | 29 + .../oa/notice/manager/NoticeManager.java | 67 ++ .../notice/service/NoticeEmployeeService.java | 159 ++++ .../oa/notice/service/NoticeService.java | 250 +++++++ .../oa/notice/service/NoticeTypeService.java | 87 +++ .../controller/StatisticsController.java | 65 ++ .../statistics/dao/StatisticsDao.java | 50 ++ .../statistics/domain/HospitalQureyForm.java | 14 + .../statistics/domain/HospitalVO.java | 15 + .../domain/StatisticsExpertQueryForm.java | 25 + .../statistics/domain/StatisticsExpertVO.java | 41 ++ .../domain/SystemActualEcharsData.java | 14 + .../domain/SystemActualNumQueryForm.java | 24 + .../statistics/domain/SystemActualNumVO.java | 23 + .../statistics/service/StatisticsService.java | 117 +++ .../module/business/token/dao/TokenDao.java | 15 + .../token/domain/entity/TokenEntity.java | 19 + .../business/token/service/TokenService.java | 276 +++++++ .../module/system/datascope/DataScope.java | 54 ++ .../system/datascope/DataScopeController.java | 41 ++ .../system/datascope/MyBatisPlugin.java | 186 +++++ .../datascope/constant/DataScopeTypeEnum.java | 56 ++ .../constant/DataScopeViewTypeEnum.java | 53 ++ .../constant/DataScopeWhereInTypeEnum.java | 42 ++ .../domain/DataScopeAndViewTypeVO.java | 35 + .../system/datascope/domain/DataScopeDTO.java | 32 + .../datascope/domain/DataScopeSqlConfig.java | 41 ++ .../datascope/domain/DataScopeViewTypeVO.java | 28 + .../datascope/service/DataScopeService.java | 75 ++ .../service/DataScopeSqlConfigService.java | 149 ++++ .../service/DataScopeViewService.java | 162 +++++ .../strategy/DataScopePowerStrategy.java | 27 + .../controller/DepartmentController.java | 71 ++ .../system/department/dao/DepartmentDao.java | 40 ++ .../domain/entity/DepartmentEntity.java | 62 ++ .../domain/form/DepartmentAddForm.java | 36 + .../domain/form/DepartmentUpdateForm.java | 24 + .../domain/vo/DepartmentEmployeeTreeVO.java | 27 + .../domain/vo/DepartmentTreeVO.java | 32 + .../department/domain/vo/DepartmentVO.java | 36 + .../manager/DepartmentCacheManager.java | 249 +++++++ .../department/manager/DepartmentManager.java | 21 + .../department/service/DepartmentService.java | 210 ++++++ .../controller/EmployeeController.java | 118 +++ .../system/employee/dao/EmployeeDao.java | 171 +++++ .../domain/entity/EmployeeEntity.java | 81 +++ .../employee/domain/form/EmployeeAddForm.java | 56 ++ .../EmployeeBatchUpdateDepartmentForm.java | 31 + .../domain/form/EmployeeQueryForm.java | 40 ++ .../domain/form/EmployeeUpdateForm.java | 23 + .../form/EmployeeUpdatePasswordForm.java | 33 + .../domain/form/EmployeeUpdateRoleForm.java | 30 + .../system/employee/domain/vo/EmployeeVO.java | 58 ++ .../employee/manager/EmployeeManager.java | 91 +++ .../service/EmployeePermissionService.java | 104 +++ .../employee/service/EmployeeService.java | 399 ++++++++++ .../login/controller/LoginController.java | 90 +++ .../login/domain/LoginEmployeeDetail.java | 169 +++++ .../module/system/login/domain/LoginForm.java | 41 ++ .../system/login/service/LoginService.java | 338 +++++++++ .../menu/constant/MenuPermsTypeEnum.java | 46 ++ .../system/menu/constant/MenuTypeEnum.java | 48 ++ .../menu/controller/MenuController.java | 86 +++ .../admin/module/system/menu/dao/MenuDao.java | 105 +++ .../system/menu/domain/entity/MenuEntity.java | 139 ++++ .../system/menu/domain/form/MenuAddForm.java | 20 + .../system/menu/domain/form/MenuBaseForm.java | 86 +++ .../domain/form/MenuPointsOperateForm.java | 43 ++ .../menu/domain/form/MenuUpdateForm.java | 26 + .../menu/domain/vo/MenuSimpleTreeVO.java | 37 + .../system/menu/domain/vo/MenuTreeVO.java | 22 + .../module/system/menu/domain/vo/MenuVO.java | 35 + .../system/menu/manager/MenuManager.java | 70 ++ .../system/menu/service/MenuService.java | 290 ++++++++ .../role/controller/RoleController.java | 70 ++ .../controller/RoleDataScopeController.java | 50 ++ .../controller/RoleEmployeeController.java | 77 ++ .../role/controller/RoleMenuController.java | 47 ++ .../role/controller/RoleProvCntroller.java | 55 ++ .../admin/module/system/role/dao/RoleDao.java | 33 + .../system/role/dao/RoleDataScopeDao.java | 46 ++ .../system/role/dao/RoleEmployeeDao.java | 95 +++ .../module/system/role/dao/RoleMenuDao.java | 54 ++ .../module/system/role/dao/RoleProvDao.java | 35 + .../domain/entity/RoleDataScopeEntity.java | 53 ++ .../domain/entity/RoleEmployeeEntity.java | 41 ++ .../system/role/domain/entity/RoleEntity.java | 41 ++ .../role/domain/entity/RoleMenuEntity.java | 49 ++ .../system/role/domain/form/RoleAddForm.java | 36 + .../domain/form/RoleDataScopeUpdateForm.java | 43 ++ .../domain/form/RoleEmployeeQueryForm.java | 24 + .../domain/form/RoleEmployeeUpdateForm.java | 30 + .../role/domain/form/RoleMenuUpdateForm.java | 35 + .../role/domain/form/RoleProvUpdateForm.java | 28 + .../role/domain/form/RoleQueryForm.java | 24 + .../role/domain/form/RoleUpdateForm.java | 27 + .../role/domain/vo/RoleDataScopeVO.java | 23 + .../system/role/domain/vo/RoleEmployeeVO.java | 22 + .../system/role/domain/vo/RoleMenuTreeVO.java | 29 + .../system/role/domain/vo/RoleSelectedVO.java | 20 + .../module/system/role/domain/vo/RoleVO.java | 26 + .../role/manager/RoleDataScopeManager.java | 20 + .../role/manager/RoleEmployeeManager.java | 37 + .../system/role/manager/RoleMenuManager.java | 40 ++ .../role/service/RoleDataScopeService.java | 67 ++ .../role/service/RoleEmployeeService.java | 153 ++++ .../system/role/service/RoleMenuService.java | 139 ++++ .../system/role/service/RoleProvService.java | 49 ++ .../system/role/service/RoleService.java | 119 +++ .../system/support/AdminCacheController.java | 56 ++ .../support/AdminChangeLogController.java | 59 ++ .../system/support/AdminConfigController.java | 59 ++ .../system/support/AdminDictController.java | 79 ++ .../system/support/AdminFileController.java | 43 ++ .../support/AdminHeartBeatController.java | 41 ++ .../support/AdminHelpDocController.java | 108 +++ .../support/AdminLoginLogController.java | 42 ++ .../support/AdminOperateLogController.java | 46 ++ .../system/support/AdminReloadController.java | 54 ++ .../support/AdminSerialNumberController.java | 74 ++ .../wx/miniapp/config/WxMaConfiguration.java | 131 ++++ .../wx/miniapp/config/WxMaProperties.java | 46 ++ .../controller/WxMaMediaController.java | 88 +++ .../controller/WxMaUserController.java | 190 +++++ .../controller/WxPortalController.java | 109 +++ .../wx/miniapp/error/ErrorController.java | 29 + .../miniapp/error/ErrorPageConfiguration.java | 27 + .../module/wx/miniapp/utils/JsonUtils.java | 28 + .../src/main/resources/dev/application.yaml | 43 ++ sa-admin/src/main/resources/dev/log4j2.xml | 99 +++ .../src/main/resources/dev/spy.properties | 18 + .../mapper/app/expert/ExpertMapper.xml | 7 + .../MedicalRecordDpmasMapper.xml | 7 + .../app/medicalrecord/MedicalRecordMapper.xml | 44 ++ .../mapper/business/area/AreaMapper.xml | 13 + .../bankcard/CaseplatformBankMapper.xml | 21 + .../mapper/business/captcha/CaptchaMapper.xml | 13 + .../CaseplatformCaseMapper.xml | 123 ++++ .../CaseplatformCaseAbstracMapper.xml | 18 + .../CaseplatformCaseCheckdataMapper.xml | 18 + .../CaseplatformCaseDpmsMapper.xml | 18 + .../CaseplatformUserMapper.xml | 21 + .../business/category/CategoryMapper.xml | 61 ++ .../mapper/business/goods/GoodsMapper.xml | 41 ++ .../mapper/business/notice/NoticeMapper.xml | 69 ++ .../mapper/business/oa/bank/BankMapper.xml | 58 ++ .../enterprise/EnterpriseEmployeeMapper.xml | 94 +++ .../oa/enterprise/EnterpriseMapper.xml | 59 ++ .../business/oa/invoice/InvoiceMapper.xml | 56 ++ .../mapper/business/oa/notice/NoticeDao.xml | 246 +++++++ .../business/statistics/StatisticMapper.xml | 222 ++++++ .../mapper/business/token/TokenMapper.xml | 13 + .../system/department/DepartmentMapper.xml | 23 + .../mapper/system/employee/EmployeeMapper.xml | 200 ++++++ .../mapper/system/menu/MenuMapper.xml | 78 ++ .../system/role/RoleDataScopeMapper.xml | 24 + .../mapper/system/role/RoleEmployeeMapper.xml | 134 ++++ .../mapper/system/role/RoleMapper.xml | 35 + .../mapper/system/role/RoleMenuMapper.xml | 42 ++ .../mapper/system/role/RoleProvMapper.xml | 36 + .../src/main/resources/pre/application.yaml | 41 ++ sa-admin/src/main/resources/pre/log4j2.xml | 99 +++ .../src/main/resources/prod/application.yaml | 35 + sa-admin/src/main/resources/prod/log4j2.xml | 99 +++ .../src/main/resources/test/application.yaml | 41 ++ sa-admin/src/main/resources/test/log4j2.xml | 99 +++ .../src/main/resources/test/spy.properties | 18 + .../sa/admin/SmartAdminApplicationTest.java | 77 ++ sa-common/pom.xml | 267 +++++++ .../common/common/annoation/NoNeedLogin.java | 20 + .../sa/common/common/annoation/SaAuth.java | 22 + .../sa/common/common/code/AppErrorCode.java | 39 + .../sa/common/common/code/ErrorCode.java | 52 ++ .../common/code/ErrorCodeRangeContainer.java | 119 +++ .../common/common/code/ErrorCodeRegister.java | 44 ++ .../common/common/code/SystemErrorCode.java | 36 + .../common/code/UnexpectedErrorCode.java | 36 + .../sa/common/common/code/UserErrorCode.java | 53 ++ .../common/constant/RequestHeaderConst.java | 18 + .../common/common/constant/StringConst.java | 44 ++ .../controller/SupportBaseController.java | 16 + .../common/common/domain/DataScopePlugin.java | 15 + .../sa/common/common/domain/PageParam.java | 58 ++ .../sa/common/common/domain/PageResult.java | 53 ++ .../sa/common/common/domain/RequestUrlVO.java | 26 + .../sa/common/common/domain/RequestUser.java | 49 ++ .../sa/common/common/domain/ResponseDTO.java | 114 +++ .../common/domain/SystemEnvironment.java | 35 + .../sa/common/common/domain/ValidateData.java | 21 + .../sa/common/common/domain/ValidateList.java | 153 ++++ .../common/common/enumeration/BaseEnum.java | 99 +++ .../common/common/enumeration/GenderEnum.java | 37 + .../enumeration/SystemEnvironmentEnum.java | 50 ++ .../common/enumeration/UserTypeEnum.java | 38 + .../sa/common/common/excel/ExcelStyle.java | 185 +++++ .../common/exception/BusinessException.java | 38 + .../interceptor/AbstractInterceptor.java | 148 ++++ .../deserializer/DictValueVoDeserializer.java | 52 ++ .../deserializer/FileKeyVoDeserializer.java | 53 ++ .../deserializer/LongJsonDeserializer.java | 30 + .../BigDecimalNullZeroSerializer.java | 29 + .../serializer/DictValueVoSerializer.java | 52 ++ .../json/serializer/FileKeySerializer.java | 45 ++ .../json/serializer/FileKeyVoSerializer.java | 46 ++ .../json/serializer/LongJsonSerializer.java | 28 + .../security/AbstractSecurityConfig.java | 95 +++ .../SecurityAuthenticationFailHandler.java | 43 ++ .../common/security/SecurityMethodSource.java | 66 ++ .../SecurityPermissionCheckService.java | 74 ++ .../common/security/SecurityTokenFilter.java | 64 ++ .../common/swagger/ApiModelPropertyEnum.java | 40 ++ .../swagger/Swagger2MapperImplExtension.java | 91 +++ .../SwaggerApiModelPropertyEnumPlugin.java | 77 ++ .../sa/common/common/util/EncryptionKit.java | 79 ++ .../sa/common/common/util/HttpUtil.java | 542 ++++++++++++++ .../sa/common/common/util/Sha256Util.java | 47 ++ .../sa/common/common/util/SmartBeanUtil.java | 94 +++ .../common/util/SmartBigDecimalUtil.java | 247 +++++++ .../common/util/SmartEasyExcelUtil.java | 41 ++ .../common/util/SmartEasyPoiExcelUtil.java | 114 +++ .../sa/common/common/util/SmartEnumUtil.java | 165 +++++ .../sa/common/common/util/SmartPageUtil.java | 122 ++++ .../common/common/util/SmartRequestUtil.java | 38 + .../common/common/util/SmartStringUtil.java | 334 +++++++++ .../common/util/SmartVerificationUtil.java | 98 +++ .../validator/enumeration/CheckEnum.java | 52 ++ .../validator/enumeration/EnumValidator.java | 75 ++ .../common/wangyi/yidun/enums/PicType.java | 38 + .../yidun/enums/SignatureMethodEnum.java | 29 + .../common/wangyi/yidun/resp/APIResponse.java | 48 ++ .../common/wangyi/yidun/resp/APIResult.java | 50 ++ .../wangyi/yidun/sdk/BankCardCheckAPI.java | 97 +++ .../wangyi/yidun/sdk/IdCardCheckAPI.java | 88 +++ .../wangyi/yidun/utils/ConstantUtil.java | 20 + .../wangyi/yidun/utils/SignatureUtils.java | 71 ++ .../lab1024/sa/common/config/AsyncConfig.java | 71 ++ .../sa/common/config/CorsFilterConfig.java | 45 ++ .../sa/common/config/DataSourceConfig.java | 197 +++++ .../lab1024/sa/common/config/DateConfig.java | 88 +++ .../sa/common/config/FileCloudConfig.java | 85 +++ .../sa/common/config/HeartBeatConfig.java | 37 + .../lab1024/sa/common/config/MvcConfig.java | 50 ++ .../sa/common/config/MybatisPlusConfig.java | 33 + .../sa/common/config/PostProcessorConfig.java | 56 ++ .../lab1024/sa/common/config/RedisConfig.java | 72 ++ .../sa/common/config/ReloadConfig.java | 38 + .../sa/common/config/RepeatSubmitConfig.java | 40 ++ .../sa/common/config/RestTemplateConfig.java | 130 ++++ .../sa/common/config/ScheduleConfig.java | 47 ++ .../sa/common/config/SwaggerConfig.java | 206 ++++++ .../config/SystemEnvironmentConfig.java | 49 ++ .../lab1024/sa/common/config/UrlConfig.java | 150 ++++ .../sa/common/constant/CacheKeyConst.java | 14 + .../sa/common/constant/RedisKeyConst.java | 31 + .../sa/common/constant/ReloadConst.java | 18 + .../sa/common/constant/SwaggerTagConst.java | 49 ++ .../sa/common/constant/UrlPrefixConst.java | 18 + .../handler/GlobalExceptionHandler.java | 126 ++++ .../listener/SmartApplicationListener.java | 54 ++ .../module/support/cache/CacheService.java | 78 ++ .../support/captcha/CaptchaController.java | 36 + .../support/captcha/CaptchaService.java | 114 +++ .../support/captcha/config/CaptchaColor.java | 38 + .../support/captcha/config/CaptchaConfig.java | 46 ++ .../support/captcha/config/CaptchaNoise.java | 44 ++ .../captcha/config/CaptchaWordRenderer.java | 74 ++ .../support/captcha/domain/CaptchaForm.java | 28 + .../support/captcha/domain/CaptchaVO.java | 29 + .../changelog/constant/ChangeLogTypeEnum.java | 28 + .../controller/ChangeLogController.java | 38 + .../support/changelog/dao/ChangeLogDao.java | 44 ++ .../domain/entity/ChangeLogEntity.java | 68 ++ .../domain/form/ChangeLogAddForm.java | 46 ++ .../domain/form/ChangeLogQueryForm.java | 42 ++ .../domain/form/ChangeLogUpdateForm.java | 50 ++ .../changelog/domain/vo/ChangeLogVO.java | 49 ++ .../changelog/manager/ChangeLogManager.java | 20 + .../changelog/service/ChangeLogService.java | 103 +++ .../constant/CodeDeleteEnum.java | 38 + .../constant/CodeFrontComponentEnum.java | 52 ++ .../constant/CodeGeneratorConstant.java | 30 + .../constant/CodeGeneratorPageTypeEnum.java | 38 + .../constant/CodeQueryFieldQueryTypeEnum.java | 43 ++ .../controller/CodeGeneratorController.java | 106 +++ .../dao/CodeGeneratorConfigDao.java | 20 + .../codegenerator/dao/CodeGeneratorDao.java | 45 ++ .../entity/CodeGeneratorConfigEntity.java | 74 ++ .../domain/form/CodeGeneratorConfigForm.java | 64 ++ .../domain/form/CodeGeneratorPreviewForm.java | 28 + .../domain/form/TableQueryForm.java | 23 + .../codegenerator/domain/model/CodeBasic.java | 55 ++ .../domain/model/CodeDelete.java | 40 ++ .../codegenerator/domain/model/CodeField.java | 59 ++ .../domain/model/CodeInsertAndUpdate.java | 42 ++ .../model/CodeInsertAndUpdateField.java | 46 ++ .../domain/model/CodeQueryField.java | 47 ++ .../domain/model/CodeTableField.java | 46 ++ .../domain/vo/TableColumnVO.java | 44 ++ .../domain/vo/TableConfigVO.java | 40 ++ .../codegenerator/domain/vo/TableVO.java | 37 + .../service/CodeGeneratorService.java | 228 ++++++ .../service/CodeGeneratorTemplateService.java | 238 ++++++ .../CodeGenerateBaseVariableService.java | 162 +++++ .../backend/ControllerVariableService.java | 78 ++ .../variable/backend/DaoVariableService.java | 59 ++ .../backend/ManagerVariableService.java | 55 ++ .../backend/ServiceVariableService.java | 62 ++ .../domain/AddFormVariableService.java | 131 ++++ .../domain/DeleteFormVariableService.java | 130 ++++ .../backend/domain/EntityVariableService.java | 73 ++ .../backend/domain/MapperVariableService.java | 93 +++ .../domain/QueryFormVariableService.java | 128 ++++ .../domain/UpdateFormVariableService.java | 145 ++++ .../backend/domain/VOVariableService.java | 115 +++ .../variable/front/ApiVariableService.java | 29 + .../variable/front/ConstVariableService.java | 45 ++ .../variable/front/FormVariableService.java | 82 +++ .../variable/front/ListVariableService.java | 57 ++ .../codegenerator/util/CodeGeneratorTool.java | 59 ++ .../support/config/ConfigController.java | 36 + .../module/support/config/ConfigDao.java | 41 ++ .../module/support/config/ConfigKeyEnum.java | 40 ++ .../module/support/config/ConfigService.java | 205 ++++++ .../support/config/domain/ConfigAddForm.java | 39 + .../support/config/domain/ConfigEntity.java | 49 ++ .../config/domain/ConfigQueryForm.java | 23 + .../config/domain/ConfigUpdateForm.java | 23 + .../support/config/domain/ConfigVO.java | 39 + .../annoation/DataTracerFieldBigDecimal.java | 21 + .../annoation/DataTracerFieldDict.java | 22 + .../annoation/DataTracerFieldEnum.java | 25 + .../annoation/DataTracerFieldLabel.java | 26 + .../annoation/DataTracerFieldSql.java | 40 ++ .../datatracer/constant/DataTracerConst.java | 27 + .../constant/DataTracerTypeEnum.java | 32 + .../controller/DataTracerController.java | 40 ++ .../support/datatracer/dao/DataTracerDao.java | 42 ++ .../domain/bo/DataTracerContentBO.java | 39 + .../domain/entity/DataTracerEntity.java | 90 +++ .../domain/form/DataTracerForm.java | 54 ++ .../domain/form/DataTracerQueryForm.java | 32 + .../datatracer/domain/vo/DataTracerVO.java | 62 ++ .../datatracer/manager/DataTracerManger.java | 19 + .../DataTracerChangeContentService.java | 486 +++++++++++++ .../datatracer/service/DataTracerService.java | 224 ++++++ .../dict/controller/DictController.java | 63 ++ .../module/support/dict/dao/DictKeyDao.java | 58 ++ .../module/support/dict/dao/DictValueDao.java | 69 ++ .../dict/domain/entity/DictKeyEntity.java | 54 ++ .../dict/domain/entity/DictValueEntity.java | 58 ++ .../dict/domain/form/DictKeyAddForm.java | 34 + .../dict/domain/form/DictKeyQueryForm.java | 24 + .../dict/domain/form/DictKeyUpdateForm.java | 23 + .../dict/domain/form/DictValueAddForm.java | 44 ++ .../dict/domain/form/DictValueQueryForm.java | 30 + .../dict/domain/form/DictValueUpdateForm.java | 23 + .../support/dict/domain/vo/DictKeyVO.java | 29 + .../support/dict/domain/vo/DictValueVO.java | 35 + .../dict/service/DictCacheService.java | 133 ++++ .../support/dict/service/DictService.java | 196 +++++ .../controller/FeedbackController.java | 53 ++ .../support/feedback/dao/FeedbackDao.java | 31 + .../feedback/domain/FeedbackAddForm.java | 31 + .../feedback/domain/FeedbackEntity.java | 62 ++ .../feedback/domain/FeedbackQueryForm.java | 31 + .../support/feedback/domain/FeedbackVO.java | 49 ++ .../feedback/service/FeedbackService.java | 62 ++ .../file/constant/FileFolderTypeEnum.java | 49 ++ .../file/controller/FileController.java | 72 ++ .../module/support/file/dao/FileDao.java | 44 ++ .../file/domain/entity/FileEntity.java | 73 ++ .../file/domain/form/FileQueryForm.java | 47 ++ .../file/domain/form/FileUrlUploadForm.java | 31 + .../file/domain/vo/FileDownloadVO.java | 28 + .../file/domain/vo/FileMetadataVO.java | 31 + .../support/file/domain/vo/FileUploadVO.java | 35 + .../module/support/file/domain/vo/FileVO.java | 56 ++ .../support/file/service/FileService.java | 207 ++++++ .../service/FileStorageCloudServiceImpl.java | 215 ++++++ .../service/FileStorageLocalServiceImpl.java | 157 ++++ .../file/service/IFileStorageService.java | 209 ++++++ .../support/heartbeat/HeartBeatRecordDao.java | 51 ++ .../heartbeat/HeartBeatRecordHandler.java | 42 ++ .../support/heartbeat/HeartBeatService.java | 38 + .../heartbeat/core/HeartBeatManager.java | 59 ++ .../heartbeat/core/HeartBeatRecord.java | 41 ++ .../heartbeat/core/HeartBeatRunnable.java | 71 ++ .../core/IHeartBeatRecordHandler.java | 20 + .../domain/HeartBeatRecordEntity.java | 53 ++ .../domain/HeartBeatRecordQueryForm.java | 30 + .../heartbeat/domain/HeartBeatRecordVO.java | 38 + .../helpdoc/controller/HelpDocController.java | 77 ++ .../helpdoc/dao/HelpDocCatalogDao.java | 21 + .../support/helpdoc/dao/HelpDocDao.java | 137 ++++ .../domain/entity/HelpDocCatalogEntity.java | 53 ++ .../helpdoc/domain/entity/HelpDocEntity.java | 77 ++ .../helpdoc/domain/form/HelpDocAddForm.java | 57 ++ .../domain/form/HelpDocCatalogAddForm.java | 31 + .../domain/form/HelpDocCatalogUpdateForm.java | 23 + .../helpdoc/domain/form/HelpDocQueryForm.java | 33 + .../domain/form/HelpDocRelationForm.java | 28 + .../domain/form/HelpDocUpdateForm.java | 24 + .../form/HelpDocViewRecordQueryForm.java | 32 + .../helpdoc/domain/vo/HelpDocCatalogVO.java | 30 + .../helpdoc/domain/vo/HelpDocDetailVO.java | 62 ++ .../helpdoc/domain/vo/HelpDocRecordVO.java | 49 ++ .../helpdoc/domain/vo/HelpDocRelationVO.java | 23 + .../support/helpdoc/domain/vo/HelpDocVO.java | 50 ++ .../domain/vo/HelpDocViewRecordVO.java | 46 ++ .../helpdoc/manager/HelpDocManager.java | 60 ++ .../service/HelpDocCatalogService.java | 115 +++ .../helpdoc/service/HelpDocService.java | 117 +++ .../helpdoc/service/HelpDocUserService.java | 85 +++ .../module/support/jwe/DecryptData.java | 18 + .../common/module/support/jwe/JweAspect.java | 128 ++++ .../common/module/support/jwe/JweDecrypt.java | 20 + .../common/module/support/jwe/JweEncrypt.java | 20 + .../common/module/support/jwe/JweUserKey.java | 32 + .../module/support/loginlog/LoginLogDao.java | 46 ++ .../support/loginlog/LoginLogResultEnum.java | 37 + .../support/loginlog/LoginLogService.java | 67 ++ .../loginlog/domain/LoginLogEntity.java | 67 ++ .../loginlog/domain/LoginLogQueryForm.java | 31 + .../support/loginlog/domain/LoginLogVO.java | 48 ++ .../support/operatelog/OperateLogDao.java | 49 ++ .../support/operatelog/OperateLogService.java | 57 ++ .../operatelog/annoation/OperateLog.java | 19 + .../operatelog/core/OperateLogAspect.java | 274 +++++++ .../operatelog/core/OperateLogConfig.java | 38 + .../operatelog/domain/OperateLogEntity.java | 106 +++ .../domain/OperateLogQueryForm.java | 33 + .../operatelog/domain/OperateLogVO.java | 72 ++ .../module/support/redis/RedisService.java | 222 ++++++ .../module/support/reload/ReloadCommand.java | 56 ++ .../module/support/reload/ReloadService.java | 68 ++ .../core/AbstractSmartReloadCommand.java | 96 +++ .../reload/core/SmartReloadManager.java | 97 +++ .../reload/core/annoation/SmartReload.java | 22 + .../reload/core/domain/SmartReloadItem.java | 32 + .../reload/core/domain/SmartReloadObject.java | 32 + .../reload/core/domain/SmartReloadResult.java | 43 ++ .../core/thread/SmartReloadRunnable.java | 120 ++++ .../support/reload/dao/ReloadItemDao.java | 25 + .../support/reload/dao/ReloadResultDao.java | 26 + .../support/reload/domain/ReloadForm.java | 31 + .../reload/domain/ReloadItemEntity.java | 50 ++ .../support/reload/domain/ReloadItemVO.java | 36 + .../reload/domain/ReloadResultEntity.java | 53 ++ .../support/reload/domain/ReloadResultVO.java | 34 + .../repeatsubmit/RepeatSubmitAspect.java | 90 +++ .../repeatsubmit/annoation/RepeatSubmit.java | 33 + .../ticket/AbstractRepeatSubmitTicket.java | 56 ++ .../ticket/RepeatSubmitCaffeineTicket.java | 50 ++ .../ticket/RepeatSubmitRedisTicket.java | 48 ++ .../constant/SerialNumberIdEnum.java | 42 ++ .../constant/SerialNumberRuleTypeEnum.java | 44 ++ .../serialnumber/dao/SerialNumberDao.java | 41 ++ .../dao/SerialNumberRecordDao.java | 55 ++ .../domain/SerialNumberEntity.java | 79 ++ .../domain/SerialNumberGenerateForm.java | 28 + .../domain/SerialNumberGenerateResultBO.java | 52 ++ .../domain/SerialNumberInfoBO.java | 97 +++ .../domain/SerialNumberLastGenerateBO.java | 41 ++ .../domain/SerialNumberRecordEntity.java | 57 ++ .../domain/SerialNumberRecordQueryForm.java | 24 + .../service/SerialNumberBaseService.java | 252 +++++++ .../service/SerialNumberRecordService.java | 39 + .../service/SerialNumberService.java | 36 + .../impl/SerialNumberInternService.java | 78 ++ .../impl/SerialNumberMysqlService.java | 61 ++ .../impl/SerialNumberRedisService.java | 105 +++ .../support/table/TableColumnController.java | 51 ++ .../module/support/table/TableColumnDao.java | 23 + .../support/table/TableColumnService.java | 72 ++ .../table/domain/TableColumnEntity.java | 49 ++ .../table/domain/TableColumnItemForm.java | 37 + .../table/domain/TableColumnUpdateForm.java | 27 + .../common/module/support/token/JwtConst.java | 38 + .../module/support/token/LoginDeviceEnum.java | 43 ++ .../module/support/token/TokenService.java | 220 ++++++ .../main/resources/META-INF/spring.factories | 2 + sa-common/src/main/resources/banner.txt | 7 + .../java/constant/enum.java.vm | 24 + .../java/controller/Controller.java.vm | 68 ++ .../java/dao/Dao.java.vm | 51 ++ .../java/domain/entity/Entity.java.vm | 32 + .../java/domain/form/AddForm.java.vm | 30 + .../java/domain/form/QueryForm.java.vm | 38 + .../java/domain/form/UpdateForm.java.vm | 30 + .../java/domain/vo/VO.java.vm | 32 + .../java/manager/Manager.java.vm | 21 + .../java/mapper/Mapper.xml.vm | 74 ++ .../java/service/Service.java.vm | 108 +++ .../code-generator-template/js/api.js.vm | 78 ++ .../code-generator-template/js/const.js.vm | 23 + .../code-generator-template/js/form.vue.vm | 235 ++++++ .../code-generator-template/js/list.vue.vm | 314 ++++++++ .../code-generator-template/tools.xml | 7 + .../src/main/resources/dev/sa-common.yaml | 127 ++++ .../mapper/support/ChangeLogMapper.xml | 47 ++ .../mapper/support/CodeGeneratorMapper.xml | 36 + .../resources/mapper/support/ConfigMapper.xml | 22 + .../mapper/support/DataTracerMapper.xml | 31 + .../mapper/support/DictKeyMapper.xml | 37 + .../mapper/support/DictValueMapper.xml | 44 ++ .../mapper/support/FeedbackMapper.xml | 26 + .../resources/mapper/support/FileMapper.xml | 49 ++ .../mapper/support/HeartBeatRecordMapper.xml | 37 + .../resources/mapper/support/HelpDocDao.xml | 130 ++++ .../mapper/support/LoginLogMapper.xml | 37 + .../mapper/support/OperateLogMapper.xml | 37 + .../mapper/support/ReloadItemMapper.xml | 10 + .../mapper/support/ReloadResultMapper.xml | 10 + .../mapper/support/SerialNumberMapper.xml | 21 + .../support/SerialNumberRecordMapper.xml | 32 + .../mapper/support/TableColumnMapper.xml | 18 + .../src/main/resources/pre/sa-common.yaml | 127 ++++ .../main/resources/prod----ttt/sa-common.yaml | 127 ++++ .../src/main/resources/test/sa-common.yaml | 128 ++++ 721 files changed, 47462 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 pom.xml create mode 100644 sa-admin/pom.xml create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/SmartAdminApplication.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/common/AdminBaseController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/config/JweAspectConfig.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/config/OperateLogAspectConfig.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityConfig.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityMethodConfig.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminCacheConst.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminRedisKeyConst.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/listener/AdminStartupRunner.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertBankVerify.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertLoginVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertModifyForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertModifyVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertRegisterForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertSignAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertSignVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertWhiteEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/LoginForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/PWDLoginForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/SmsLoginForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/constan/ImageType.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/constan/SmsTypeEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/controller/ExpertController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/controller/ExpertSignController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertSignDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertWhiteEntityDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertSignService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertWhiteEntityService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/constant/OSSFileTypeEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/controller/OSSFileController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/domain/OSSPolicyVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/controller/MedicalRecordController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorAbstracDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorCheckDataDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorDpmasDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorUserDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/DpmsAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordAbstracEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordCheckdataEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDTO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDetailVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDpmsEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordListVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordUserEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/service/MedicalRecordService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/controller/AreaController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/dao/AreaDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/entity/AreaEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/form/AreaQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/vo/AreaVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/vo/ProvVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/manager/AreaManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/service/AreaService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/controller/CaseplatformBankController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/dao/CaseplatformBankDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/entity/CaseplatformBankEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/form/CaseplatformBankAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/form/CaseplatformBankQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/vo/CaseplatformBankVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/manager/CaseplatformBankManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/service/CaseplatformBankService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/controller/CaptchaController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/dao/CaptchaDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/domain/entity/CaptchaEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/domain/from/CaptchaAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/service/CaptchaService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CaseSettlementEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CaseStatusEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CasetypeEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseExcelController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CaseCaseSettlConverter.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CaseStatusConverter.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CasetypeConverter.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/dao/CaseplatformCaseDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/entity/CaseplatformCaseEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CancelExamineForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/CaseplatformCaseDetailVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/CaseplatformCaseVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/EasyExcelCaseDetailVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/manager/CaseplatformCaseManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/service/CaseplatformCaseService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/controller/CaseplatformCaseAbstracController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/dao/CaseplatformCaseAbstracDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/entity/CaseplatformCaseAbstracEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/form/CaseplatformCaseAbstracQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/vo/CaseplatformCaseAbstracVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/manager/CaseplatformCaseAbstracManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/service/CaseplatformCaseAbstracService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/controller/CaseplatformCaseCheckdataController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/dao/CaseplatformCaseCheckdataDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/entity/CaseplatformCaseCheckdataEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/form/CaseplatformCaseCheckdataQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/vo/CaseplatformCaseCheckdataVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/manager/CaseplatformCaseCheckdataManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/service/CaseplatformCaseCheckdataService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/controller/CaseplatformCaseDpmsController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/dao/CaseplatformCaseDpmsDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/entity/CaseplatformCaseDpmsEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/form/CaseplatformCaseDpmsQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/vo/CaseplatformCaseDpmsVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/manager/CaseplatformCaseDpmsManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/service/CaseplatformCaseDpmsService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/constant/SexEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/controller/CaseplatformUserController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/dao/CaseplatformUserDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/entity/CaseplatformUserEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/form/CaseplatformUserQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/vo/CaseplatformUserVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/manager/CaseplatformUserManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/service/CaseplatformUserService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/controller/CategoryController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/manager/GoodsManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/service/GoodsService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseEmployeeManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/controller/StatisticsController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/dao/StatisticsDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/HospitalQureyForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/HospitalVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/StatisticsExpertQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/StatisticsExpertVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualEcharsData.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualNumQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualNumVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/service/StatisticsService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/dao/TokenDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/domain/entity/TokenEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/service/TokenService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/DataScope.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/DataScopeController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeTypeEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeViewTypeEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeWhereInTypeEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeAndViewTypeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeSqlConfig.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeViewService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/strategy/DataScopePowerStrategy.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/dao/DepartmentDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/entity/DepartmentEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentEmployeeTreeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentTreeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/manager/DepartmentCacheManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/manager/DepartmentManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/service/DepartmentService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/dao/EmployeeDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/entity/EmployeeEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeBatchUpdateDepartmentForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdatePasswordForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateRoleForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/vo/EmployeeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/manager/EmployeeManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeePermissionService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/controller/LoginController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginEmployeeDetail.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/service/LoginService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuPermsTypeEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/controller/MenuController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/dao/MenuDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/entity/MenuEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuBaseForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuPointsOperateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuSimpleTreeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuTreeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/manager/MenuManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleProvCntroller.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDataScopeDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleEmployeeDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleMenuDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleProvDao.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleDataScopeEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEmployeeEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleMenuEntity.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleAddForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleMenuUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleProvUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleQueryForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleUpdateForm.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleDataScopeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleEmployeeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleMenuTreeVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleSelectedVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleVO.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleDataScopeManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleEmployeeManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleMenuManager.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleDataScopeService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleProvService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleService.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminCacheController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminConfigController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminDictController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminFileController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHeartBeatController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminReloadController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/config/WxMaConfiguration.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/config/WxMaProperties.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxMaMediaController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxMaUserController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxPortalController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/error/ErrorController.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/error/ErrorPageConfiguration.java create mode 100644 sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/utils/JsonUtils.java create mode 100644 sa-admin/src/main/resources/dev/application.yaml create mode 100644 sa-admin/src/main/resources/dev/log4j2.xml create mode 100644 sa-admin/src/main/resources/dev/spy.properties create mode 100644 sa-admin/src/main/resources/mapper/app/expert/ExpertMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/app/medicalrecord/MedicalRecordDpmasMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/app/medicalrecord/MedicalRecordMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/area/AreaMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/bankcard/CaseplatformBankMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/captcha/CaptchaMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/caseplatformcase/CaseplatformCaseMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/caseplatformcaseabstrac/CaseplatformCaseAbstracMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/caseplatformcasecheckdata/CaseplatformCaseCheckdataMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/caseplatformcasedpms/CaseplatformCaseDpmsMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/caseplatformuser/CaseplatformUserMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/category/CategoryMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/goods/GoodsMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/notice/NoticeMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/oa/bank/BankMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseEmployeeMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/oa/invoice/InvoiceMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/oa/notice/NoticeDao.xml create mode 100644 sa-admin/src/main/resources/mapper/business/statistics/StatisticMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/business/token/TokenMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/system/department/DepartmentMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/system/employee/EmployeeMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/system/menu/MenuMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/system/role/RoleDataScopeMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/system/role/RoleEmployeeMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/system/role/RoleMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/system/role/RoleMenuMapper.xml create mode 100644 sa-admin/src/main/resources/mapper/system/role/RoleProvMapper.xml create mode 100644 sa-admin/src/main/resources/pre/application.yaml create mode 100644 sa-admin/src/main/resources/pre/log4j2.xml create mode 100644 sa-admin/src/main/resources/prod/application.yaml create mode 100644 sa-admin/src/main/resources/prod/log4j2.xml create mode 100644 sa-admin/src/main/resources/test/application.yaml create mode 100644 sa-admin/src/main/resources/test/log4j2.xml create mode 100644 sa-admin/src/main/resources/test/spy.properties create mode 100644 sa-admin/src/test/java/net/lab1024/sa/admin/SmartAdminApplicationTest.java create mode 100644 sa-common/pom.xml create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/annoation/NoNeedLogin.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/annoation/SaAuth.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/code/AppErrorCode.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCode.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCodeRangeContainer.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCodeRegister.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/code/SystemErrorCode.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/code/UnexpectedErrorCode.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/code/UserErrorCode.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/constant/RequestHeaderConst.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/constant/StringConst.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/controller/SupportBaseController.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/domain/DataScopePlugin.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/domain/PageParam.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/domain/PageResult.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUrlVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUser.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/domain/ResponseDTO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/domain/SystemEnvironment.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/domain/ValidateData.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/domain/ValidateList.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/BaseEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/GenderEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/SystemEnvironmentEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/UserTypeEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/excel/ExcelStyle.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/exception/BusinessException.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/interceptor/AbstractInterceptor.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/DictValueVoDeserializer.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/FileKeyVoDeserializer.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/LongJsonDeserializer.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/BigDecimalNullZeroSerializer.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/DictValueVoSerializer.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/FileKeySerializer.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/FileKeyVoSerializer.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/LongJsonSerializer.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/security/AbstractSecurityConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityAuthenticationFailHandler.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityMethodSource.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityPermissionCheckService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityTokenFilter.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/swagger/ApiModelPropertyEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/swagger/Swagger2MapperImplExtension.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/swagger/SwaggerApiModelPropertyEnumPlugin.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/EncryptionKit.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/HttpUtil.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/Sha256Util.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartBeanUtil.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartBigDecimalUtil.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEasyExcelUtil.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEasyPoiExcelUtil.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEnumUtil.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartPageUtil.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartStringUtil.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartVerificationUtil.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/validator/enumeration/CheckEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/validator/enumeration/EnumValidator.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/enums/PicType.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/enums/SignatureMethodEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/resp/APIResponse.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/resp/APIResult.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/sdk/BankCardCheckAPI.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/sdk/IdCardCheckAPI.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/utils/ConstantUtil.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/utils/SignatureUtils.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/AsyncConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/CorsFilterConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/DataSourceConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/DateConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/FileCloudConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/HeartBeatConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/MybatisPlusConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/PostProcessorConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/RedisConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/ReloadConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/RepeatSubmitConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/RestTemplateConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/ScheduleConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/SystemEnvironmentConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/constant/CacheKeyConst.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/constant/RedisKeyConst.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/constant/ReloadConst.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/constant/SwaggerTagConst.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/constant/UrlPrefixConst.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/handler/GlobalExceptionHandler.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/listener/SmartApplicationListener.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/cache/CacheService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaController.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaColor.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaNoise.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaWordRenderer.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/domain/CaptchaForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/domain/CaptchaVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/constant/ChangeLogTypeEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/controller/ChangeLogController.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/dao/ChangeLogDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/entity/ChangeLogEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogAddForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogUpdateForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/vo/ChangeLogVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/manager/ChangeLogManager.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/service/ChangeLogService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeDeleteEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeFrontComponentEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeGeneratorConstant.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeGeneratorPageTypeEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeQueryFieldQueryTypeEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/controller/CodeGeneratorController.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/dao/CodeGeneratorConfigDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/dao/CodeGeneratorDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/entity/CodeGeneratorConfigEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/CodeGeneratorConfigForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/CodeGeneratorPreviewForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/TableQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeBasic.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeDelete.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeField.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeInsertAndUpdate.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeInsertAndUpdateField.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeQueryField.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeTableField.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableColumnVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableConfigVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/CodeGeneratorService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/CodeGeneratorTemplateService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/CodeGenerateBaseVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ControllerVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/DaoVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ManagerVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ServiceVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/AddFormVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/DeleteFormVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/EntityVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/MapperVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/QueryFormVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/UpdateFormVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/VOVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ApiVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ConstVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/FormVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ListVariableService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/util/CodeGeneratorTool.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigController.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigKeyEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigAddForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigUpdateForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldBigDecimal.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldDict.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldLabel.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldSql.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/constant/DataTracerConst.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/constant/DataTracerTypeEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/controller/DataTracerController.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/dao/DataTracerDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/bo/DataTracerContentBO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/entity/DataTracerEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/form/DataTracerForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/form/DataTracerQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/vo/DataTracerVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/manager/DataTracerManger.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerChangeContentService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/controller/DictController.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/dao/DictKeyDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/dao/DictValueDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/entity/DictKeyEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/entity/DictValueEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyAddForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyUpdateForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueAddForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueUpdateForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/vo/DictKeyVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/vo/DictValueVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/service/DictCacheService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/service/DictService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/controller/FeedbackController.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/dao/FeedbackDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackAddForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/service/FeedbackService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/constant/FileFolderTypeEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/controller/FileController.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/dao/FileDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/entity/FileEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/form/FileQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/form/FileUrlUploadForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileDownloadVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileMetadataVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileUploadVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileStorageCloudServiceImpl.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileStorageLocalServiceImpl.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/IFileStorageService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatRecordDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatRecordHandler.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatManager.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatRecord.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatRunnable.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/IHeartBeatRecordHandler.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/controller/HelpDocController.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/dao/HelpDocCatalogDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/dao/HelpDocDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/entity/HelpDocCatalogEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/entity/HelpDocEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocAddForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocCatalogAddForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocCatalogUpdateForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocRelationForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocUpdateForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocViewRecordQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocCatalogVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocDetailVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocRecordVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocRelationVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocViewRecordVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/manager/HelpDocManager.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocCatalogService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocUserService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/DecryptData.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweAspect.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweDecrypt.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweEncrypt.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweUserKey.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogResultEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/OperateLogDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/OperateLogService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/annoation/OperateLog.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogAspect.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogConfig.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/redis/RedisService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/ReloadCommand.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/ReloadService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/AbstractSmartReloadCommand.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/SmartReloadManager.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/annoation/SmartReload.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadItem.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadObject.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadResult.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/thread/SmartReloadRunnable.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/dao/ReloadItemDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/dao/ReloadResultDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadItemEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadItemVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadResultEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadResultVO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/RepeatSubmitAspect.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/annoation/RepeatSubmit.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/AbstractRepeatSubmitTicket.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/RepeatSubmitCaffeineTicket.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/RepeatSubmitRedisTicket.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/constant/SerialNumberIdEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/constant/SerialNumberRuleTypeEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/dao/SerialNumberDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/dao/SerialNumberRecordDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberGenerateForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberGenerateResultBO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberInfoBO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberLastGenerateBO.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberRecordEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberRecordQueryForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberBaseService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberRecordService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberInternService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberMysqlService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberRedisService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnController.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnDao.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnService.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnEntity.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnItemForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnUpdateForm.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/token/JwtConst.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/token/LoginDeviceEnum.java create mode 100644 sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java create mode 100644 sa-common/src/main/resources/META-INF/spring.factories create mode 100644 sa-common/src/main/resources/banner.txt create mode 100644 sa-common/src/main/resources/code-generator-template/java/constant/enum.java.vm create mode 100644 sa-common/src/main/resources/code-generator-template/java/controller/Controller.java.vm create mode 100644 sa-common/src/main/resources/code-generator-template/java/dao/Dao.java.vm create mode 100644 sa-common/src/main/resources/code-generator-template/java/domain/entity/Entity.java.vm create mode 100644 sa-common/src/main/resources/code-generator-template/java/domain/form/AddForm.java.vm create mode 100644 sa-common/src/main/resources/code-generator-template/java/domain/form/QueryForm.java.vm create mode 100644 sa-common/src/main/resources/code-generator-template/java/domain/form/UpdateForm.java.vm create mode 100644 sa-common/src/main/resources/code-generator-template/java/domain/vo/VO.java.vm create mode 100644 sa-common/src/main/resources/code-generator-template/java/manager/Manager.java.vm create mode 100644 sa-common/src/main/resources/code-generator-template/java/mapper/Mapper.xml.vm create mode 100644 sa-common/src/main/resources/code-generator-template/java/service/Service.java.vm create mode 100644 sa-common/src/main/resources/code-generator-template/js/api.js.vm create mode 100644 sa-common/src/main/resources/code-generator-template/js/const.js.vm create mode 100644 sa-common/src/main/resources/code-generator-template/js/form.vue.vm create mode 100644 sa-common/src/main/resources/code-generator-template/js/list.vue.vm create mode 100644 sa-common/src/main/resources/code-generator-template/tools.xml create mode 100644 sa-common/src/main/resources/dev/sa-common.yaml create mode 100644 sa-common/src/main/resources/mapper/support/ChangeLogMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/CodeGeneratorMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/ConfigMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/DataTracerMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/DictKeyMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/DictValueMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/FeedbackMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/FileMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/HeartBeatRecordMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/HelpDocDao.xml create mode 100644 sa-common/src/main/resources/mapper/support/LoginLogMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/OperateLogMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/ReloadItemMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/ReloadResultMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/SerialNumberMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/SerialNumberRecordMapper.xml create mode 100644 sa-common/src/main/resources/mapper/support/TableColumnMapper.xml create mode 100644 sa-common/src/main/resources/pre/sa-common.yaml create mode 100644 sa-common/src/main/resources/prod----ttt/sa-common.yaml create mode 100644 sa-common/src/main/resources/test/sa-common.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..23d109a --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +HELP.md +target/ + +velocity.log + +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +.DS_Store + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + + +### VS Code ### +.vscode/ +/logs +*.log +*.class +*.ctxt +.mtj.tmp/ +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar +hs_err_pid* +replay_pid* +*.vue +*.js +*.ts diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7b9ff1a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,41 @@ +# 第一阶段:使用 Maven + Java8 构建 JAR 包 +FROM maven:3.9.2-eclipse-temurin-8-alpine AS builder + +WORKDIR /app + +# 添加国内 Maven 镜像源 +RUN mkdir -p /root/.m2 && \ + echo ' \ + \ + \ + aliyun \ + * \ + aliyun maven \ + https://maven.aliyun.com/repository/public \ + \ + \ + ' > /root/.m2/settings.xml + +# 复制项目代码 +COPY pom.xml . +COPY src ./src + +# 构建项目 +RUN mvn clean package -DskipTests + +# 第二阶段:使用更小的 Java8 JDK 镜像运行 +FROM eclipse-temurin:8-jdk-alpine + +WORKDIR /app + +# 复制构建产物 +COPY --from=builder /app/target/*.jar app.jar + +# 暴露端口(请替换成你实际应用端口) +EXPOSE 5477 + +# 启动应用 +ENTRYPOINT ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..df86870 --- /dev/null +++ b/pom.xml @@ -0,0 +1,390 @@ + + 4.0.0 + + net.1024lab + sa-parent + 1.0.0 + pom + + sa-parent + SmartAdmin project + + + sa-common + sa-admin + + + + UTF-8 + UTF-8 + 1.8 + 2.7.5 + 2.0.8 + 3.5.2 + 3.8.6 + 2.7.0 + 2.0.16 + 1.2.14 + 1.4.2 + 20.0 + 1.21 + 2.3.2 + 0.9.11 + 2.6 + 3.12.0 + 4.4 + 1.13 + 4.2.0 + 2.12.0 + 4.1.1 + 1.3 + 1.11.842 + 2.17.2 + 5.7.22 + 2.3 + 0.9.1 + 0.9.0 + 3.1 + 3.3.3 + 3.15.1 + 4.6.0 + + + + + + + + org.springframework.boot + spring-boot-dependencies + ${springboot.version} + pom + import + + + + + org.springframework + spring-mock + ${spring-mock.version} + + + commons-logging + commons-logging + + + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + org.springframework.boot + spring-boot-starter-logging + + + + + + p6spy + p6spy + ${p6spy.version} + + + + io.springfox + springfox-swagger2 + ${swagger.version} + + + guava + com.google.guava + + + + + + io.springfox + springfox-swagger-ui + ${swagger.version} + + + + com.alibaba + fastjson + ${fastjson.version} + + + + com.alibaba + druid + ${druid.version} + + + + com.googlecode.concurrentlinkedhashmap + concurrentlinkedhashmap-lru + ${google-linkedhashmap.version} + + + + com.google.guava + guava + ${google-guava.version} + + + + eu.bitwalker + UserAgentUtils + ${user-agent-utils.version} + + + + com.github.penggle + kaptcha + ${kaptcha.version} + + + + org.reflections + reflections + ${reflections.version} + + + guava + com.google.guava + + + + + + commons-io + commons-io + ${commons-io.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + + cn.afterturn + easypoi-spring-boot-starter + ${easypoi.version} + + + + cn.afterturn + easypoi-web + ${easypoi.version} + + + javassist + org.javassist + + + guava + com.google.guava + + + + + + + + + + + + org.apache.poi + poi-scratchpad + ${poi-scratchpad.version} + + + + + org.apache.poi + ooxml-schemas + ${poi-ooxml-schemas.version} + + + + com.amazonaws + aws-java-sdk-s3 + ${aws-java-sdk.version} + + + commons-logging + commons-logging + + + + + + org.apache.logging.log4j + log4j-spring-boot + ${log4j-spring-boot.version} + + + + cn.hutool + hutool-all + ${hutool.version} + + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + + com.auth0 + jwks-rsa + ${jwks-rsa.version} + + + + + org.apache.velocity + velocity-engine-core + ${velocity-engine-core.version} + + + org.apache.velocity.tools + velocity-tools-generic + ${velocity-tools.version} + + + + + com.alibaba + easyexcel + ${easyexcel.version} + + + + com.aliyun.oss + aliyun-sdk-oss + ${aliyun-sdk-oss.version} + + + + com.github.binarywang + weixin-java-miniapp + ${weixin-java-miniapp.version} + + + + + + ${profiles.active}-${project.name} + + + false + src/main/resources + + dev/* + test/* + pre/* + prod/* + + + + + src/main/resources/${profiles.active} + true + + *.yaml + + + + + src/main/resources/${profiles.active} + false + + *.* + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.2 + + 1.8 + 1.8 + UTF-8 + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + true + + + + org.springframework.boot + spring-boot-maven-plugin + ${springboot.version} + + + + + + + + dev + + dev + + + true + + + + + test + + test + + + + + pre + + pre + + + + + prod + + prod + + + + + \ No newline at end of file diff --git a/sa-admin/pom.xml b/sa-admin/pom.xml new file mode 100644 index 0000000..3bc1422 --- /dev/null +++ b/sa-admin/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + + net.1024lab + sa-parent + 1.0.0 + ../pom.xml + + + sa-case-admin + 1.0.0 + jar + + sa-case-admin + sa-case-admin project + + + + + net.1024lab + sa-case-common + ${project.version} + + + + com.aliyun.oss + aliyun-sdk-oss + + + + com.github.binarywang + weixin-java-miniapp + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + net.lab1024.sa.admin.SmartAdminApplication + + + + + repackage + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/SmartAdminApplication.java b/sa-admin/src/main/java/net/lab1024/sa/admin/SmartAdminApplication.java new file mode 100644 index 0000000..8297564 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/SmartAdminApplication.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.admin; + +import org.apache.ibatis.annotations.Mapper; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.scheduling.annotation.EnableScheduling; + +/** + * SmartAdmin 项目启动类 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022-08-29 21:00:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@EnableCaching +@EnableScheduling +@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true) +@ComponentScan(basePackages = {"net.lab1024.sa"}) +@MapperScan(value = "net.lab1024.sa", annotationClass = Mapper.class) +@SpringBootApplication(exclude = {UserDetailsServiceAutoConfiguration.class }) +public class SmartAdminApplication { + + public static void main(String[] args) { + SpringApplication.run(SmartAdminApplication.class, args); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/common/AdminBaseController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/common/AdminBaseController.java new file mode 100644 index 0000000..f54bbd5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/common/AdminBaseController.java @@ -0,0 +1,13 @@ +package net.lab1024.sa.admin.common; + +/** + * admin 相关的父类 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022-06-10 21:00:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +public class AdminBaseController { +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/config/JweAspectConfig.java b/sa-admin/src/main/java/net/lab1024/sa/admin/config/JweAspectConfig.java new file mode 100644 index 0000000..c4e74ff --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/config/JweAspectConfig.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.admin.config; + +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.jwe.JweAspect; +import net.lab1024.sa.common.module.support.jwe.JweUserKey; +import net.lab1024.sa.common.module.support.operatelog.core.OperateLogAspect; +import net.lab1024.sa.common.module.support.operatelog.core.OperateLogConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 操作日志切面 配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class JweAspectConfig { + + /** + * 配置信息 + */ + @Bean + public JweAspect jweConfig() { + return new JweAspect((request -> { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + JweUserKey userKey = new JweUserKey(); + userKey.setUserId(requestUser.getUserId()); + userKey.setUserName(requestUser.getUserName()); + userKey.setExtData(requestUser.getUserType().getValue().toString()); + return userKey; + })); + } +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/config/OperateLogAspectConfig.java b/sa-admin/src/main/java/net/lab1024/sa/admin/config/OperateLogAspectConfig.java new file mode 100644 index 0000000..214502e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/config/OperateLogAspectConfig.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.admin.config; + +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.operatelog.core.OperateLogAspect; +import net.lab1024.sa.common.module.support.operatelog.core.OperateLogConfig; +import org.springframework.context.annotation.Configuration; + +import javax.servlet.http.HttpServletRequest; + +/** + * 操作日志切面 配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class OperateLogAspectConfig extends OperateLogAspect{ + + /** + * 配置信息 + * @return + */ + @Override + public OperateLogConfig getOperateLogConfig() { + OperateLogConfig config = OperateLogConfig.builder().corePoolSize(4).queueCapacity(1000).build(); + return config; + } + + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityConfig.java b/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityConfig.java new file mode 100644 index 0000000..8f12ba2 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityConfig.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.config; + +import net.lab1024.sa.admin.module.system.login.service.LoginService; +import net.lab1024.sa.common.common.security.AbstractSecurityConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.userdetails.UserDetails; + +import javax.servlet.http.HttpServletRequest; +import java.util.function.BiFunction; + +/** + * 权限配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class SecurityConfig extends AbstractSecurityConfig { + /** + * 获取TOKEN 解析类 + */ + @Autowired + private LoginService loginService; + + @Override + protected BiFunction userFunction() { + return (token, request) -> loginService.getLoginUserDetail(token, request); + } + + @Override + protected String[] getAuthenticatedUrlPatterns() { + return new String[]{"/**"}; + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityMethodConfig.java b/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityMethodConfig.java new file mode 100644 index 0000000..772b2d5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityMethodConfig.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.admin.config; + +import net.lab1024.sa.admin.module.system.login.domain.LoginEmployeeDetail; +import net.lab1024.sa.common.common.annoation.SaAuth; +import net.lab1024.sa.common.common.security.SecurityMethodSource; +import net.lab1024.sa.common.common.security.SecurityPermissionCheckService; +import org.springframework.context.annotation.Bean; +import org.springframework.security.access.expression.method.ExpressionBasedAnnotationAttributeFactory; +import org.springframework.security.access.method.MethodSecurityMetadataSource; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; +import org.springframework.security.core.Authentication; + +/** + * 1、以类名加方法名为权限字符串的校验模式
+ * 2、重写MethodSecurityMetadataSource将优化security配置,只需在方法上加上@saAuth注解,方法上就会存在权限(权限字符串为类名加方法名),而无需另外手动设置,减轻后端开发成本
+ * 3、security将不再依据权限字符串进行权限控制,
+ * 4、security将依据对应权限字符串下的接口权限进行控制
+ * 5、采用此配置原@PreAuthorize依然有效
+ * 6、如若无需此配置,需将@EnableGlobalMethodSecurity注解添加至SecurityConfig类上 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-08-31 0:01 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class SecurityMethodConfig extends GlobalMethodSecurityConfiguration { + + @Bean(SaAuth.saAuth) + public SecurityPermissionCheckService securityPermissionCheckService() { + return new SecurityPermissionCheckService() { + @Override + public boolean checkPermission(Authentication authentication, String permission) { + LoginEmployeeDetail loginEmployeeDetail = (LoginEmployeeDetail) authentication.getPrincipal(); + if (loginEmployeeDetail.getAdministratorFlag()) { + return true; + } + return super.permissionJudge(loginEmployeeDetail, permission); + } + }; + } + + @Override + public MethodSecurityMetadataSource customMethodSecurityMetadataSource() { + ExpressionBasedAnnotationAttributeFactory attributeFactory = new ExpressionBasedAnnotationAttributeFactory(this.getExpressionHandler()); + return new SecurityMethodSource(attributeFactory, SaAuth.saAuth); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminCacheConst.java b/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminCacheConst.java new file mode 100644 index 0000000..ebacfdf --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminCacheConst.java @@ -0,0 +1,57 @@ +package net.lab1024.sa.admin.constant; + +import net.lab1024.sa.common.constant.CacheKeyConst; + +/** + * 缓存 key + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022-01-07 18:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +public class AdminCacheConst extends CacheKeyConst { + + public static class Department { + + /** + * 部门列表 + */ + public static final String DEPARTMENT_LIST_CACHE = "department_list_cache"; + + /** + * 部门map + */ + public static final String DEPARTMENT_MAP_CACHE = "department_map_cache"; + + /** + * 部门树 + */ + public static final String DEPARTMENT_TREE_CACHE = "department_tree_cache"; + + /** + * 某个部门以及下级的id列表 + */ + public static final String DEPARTMENT_SELF_CHILDREN_CACHE = "department_self_children_cache"; + + /** + * 部门路径 缓存 + */ + public static final String DEPARTMENT_PATH_CACHE = "department_path_cache"; + + } + + /** + * 分类相关缓存 + */ + public static class CATEGORY { + + public static final String CATEGORY_ENTITY = "category_cache"; + + public static final String CATEGORY_SUB = "category_sub_cache"; + + public static final String CATEGORY_TREE = "category_tree_cache"; + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminRedisKeyConst.java b/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminRedisKeyConst.java new file mode 100644 index 0000000..301c73a --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminRedisKeyConst.java @@ -0,0 +1,17 @@ +package net.lab1024.sa.admin.constant; + +import net.lab1024.sa.common.constant.RedisKeyConst; + +/** + * redis key 常量类 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022-01-07 18:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +public class AdminRedisKeyConst extends RedisKeyConst { + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.java b/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.java new file mode 100644 index 0000000..d9eb902 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.java @@ -0,0 +1,66 @@ +package net.lab1024.sa.admin.constant; + +import net.lab1024.sa.common.constant.SwaggerTagConst; + +/** + * swagger + * + * @Author 1024创新实验室:罗伊 + * @Date 2022-01-07 18:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +public class AdminSwaggerTagConst extends SwaggerTagConst { + + public static class Business { + public static final String MANAGER_CATEGORY = "ERP进销存-分类管理"; + + public static final String MANAGER_GOODS = "ERP进销存-商品管理"; + + public static final String OA_BANK = "OA办公-银行卡信息"; + + public static final String OA_ENTERPRISE = "OA办公-企业"; + + public static final String OA_INVOICE = "OA办公-发票信息"; + + public static final String OA_NOTICE = "OA办公-通知公告"; + } + + + public static class System { + + public static final String SYSTEM_LOGIN = "系统-员工登录"; + + public static final String SYSTEM_EMPLOYEE = "系统-员工管理"; + + public static final String SYSTEM_DEPARTMENT = "系统-部门管理"; + + public static final String SYSTEM_MENU = "系统-菜单"; + + public static final String SYSTEM_DATA_SCOPE = "系统-系统-数据范围"; + + public static final String SYSTEM_ROLE = "系统-角色"; + + public static final String SYSTEM_ROLE_DATA_SCOPE = "系统-角色-数据范围"; + + public static final String SYSTEM_ROLE_EMPLOYEE = "系统-角色-员工"; + + public static final String SYSTEM_ROLE_MENU = "系统-角色-菜单"; + public static final String SYSTEM_ROLE_PROV = "系统-角色-省份"; + + public static final String SYSTEM_DATA_TRACER = "系统-"; + } + + + public static class App { + + public static final String MedicalRecord = "前端-病历"; + + public static final String Expert = "前端-登录、注册、首页"; + public static final String ExpertSign = "前端-医生签名"; + + public static final String OSS = "前端-oss"; + public static final String WX_MINI = "前端-微信小程序"; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/listener/AdminStartupRunner.java b/sa-admin/src/main/java/net/lab1024/sa/admin/listener/AdminStartupRunner.java new file mode 100644 index 0000000..cf8d049 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/listener/AdminStartupRunner.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.listener; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.code.ErrorCodeRegister; +import net.lab1024.sa.common.config.ScheduleConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +/** + * admin 应用启动加载 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2021-08-26 18:46:32 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Slf4j +@Component +public class AdminStartupRunner implements CommandLineRunner { + + @Autowired + private ScheduleConfig scheduleConfig; + + @Override + public void run(String... args) { + + // 初始化状态码 + int codeCount = ErrorCodeRegister.initialize(); + + //TODO <卓大> :根据实际情况来决定是否开启定时任务 + String destroySchedules = "Spring 定时任务 @Schedule 已启动"; +// destroySchedules = scheduleConfig.destroy(); + + log.info("\n ---------------【1024创新实验室 温馨提示:】 ErrorCode 共计完成初始化: {}个!---------------" + + "\n ---------------【1024创新实验室 温馨提示:】 {}---------------\n", codeCount, destroySchedules); + + } +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertBankVerify.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertBankVerify.java new file mode 100644 index 0000000..634901b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertBankVerify.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class ExpertBankVerify { + + @ApiModelProperty("姓名") + @NotBlank(message = "姓名 不能为空") + private String name; + + @ApiModelProperty("身份证") + @NotBlank(message = "身份证 不能为空") + private String idCardNo; + + @ApiModelProperty("银行卡") + @NotBlank(message = "银行卡 不能为空") + private String bankCardNo; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertEntity.java new file mode 100644 index 0000000..91c10e9 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertEntity.java @@ -0,0 +1,101 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import net.lab1024.sa.admin.module.system.login.domain.LoginEmployeeDetail; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.Set; + +@Data +@TableName("t_caseplatform_expert") +public class ExpertEntity implements UserDetails, RequestUser { + + @TableId(type = IdType.AUTO) + private Long id; + private String uuid; + private String mobile; + private String name; + private String photo; + private String hospitalUuid; + private String hospitalName; + private String token; + private String ip; + private Integer provId; + private Integer countyId; + private Integer cityId; + + /** + * security 权限串 + */ + private Set authorities; + + @Override + public Collection getAuthorities() { + return authorities; + } + + @Override + @JsonIgnore + public String getPassword() { + return null; + } + + @Override + public String getUsername() { + return this.getName(); + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + + @Override + public Long getUserId() { + return id; + } + + @Override + public String getUserName() { + return name; + } + + @Override + public UserTypeEnum getUserType() { + return UserTypeEnum.EXPERT; + } + + @Override + public String getIp() { + return this.ip; + } + + @Override + public String getUserAgent() { + return "wx"; + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertLoginVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertLoginVO.java new file mode 100644 index 0000000..6f01966 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertLoginVO.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class ExpertLoginVO { + @ApiModelProperty(value = "专家ID") + private Long id; + + @ApiModelProperty(value = "专家UUID") + private String uuid; + + @ApiModelProperty(value = "专家姓名") + private String name; + + @ApiModelProperty(value = "专家头像") + private String photo; + + @ApiModelProperty(value = "专家医院名称") + private String hospitalName; + + @ApiModelProperty(value = "token") + private String token; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertModifyForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertModifyForm.java new file mode 100644 index 0000000..475520a --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertModifyForm.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +@Data +public class ExpertModifyForm { + + @ApiModelProperty("UUID") + @NotBlank(message = "UUID 不能为空") + private String uuid; + + @ApiModelProperty("姓名") + @NotBlank(message = "姓名 不能为空") + @Length(max = 20, message = "姓名最多20字符") + private String name; + + @ApiModelProperty("医院UUID") + @NotBlank(message = "医院UUID 不能为空") + @Length(max = 32, message = "医院UUID最多32字符") + private String hospital_uuid; + + @ApiModelProperty("医院名称") + @NotBlank(message = "医院名称 不能为空") + @Length(max = 50, message = "医院名称最多50字符") + private String hospital_name; + + @ApiModelProperty("科室UUID") + @NotBlank(message = "科室UUID 不能为空") + @Length(max = 32, message = "科室UUID最多32字符") + private String office_uuid; + + @ApiModelProperty("科室名称") + @NotBlank(message = "科室名称 不能为空") + @Length(max = 20, message = "科室名称最多20字符") + private String office_name; + + @ApiModelProperty("职称UUID") + @NotBlank(message = "职称UUID 不能为空") + @Length(max = 32, message = "职称UUID最多32字符") + private String position_uuid; + + @ApiModelProperty("执业证号") + private String certificate; + + @ApiModelProperty("执业医师资格证或工作胸牌") + @NotBlank(message = "执业医师资格证或工作胸牌 不能为空") + private String certificate_img; + + @ApiModelProperty("地区ID") + @NotBlank(message = "地区ID 不能为空") + private String county_id; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertModifyVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertModifyVO.java new file mode 100644 index 0000000..6eab75b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertModifyVO.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +@Data +public class ExpertModifyVO { + + @ApiModelProperty("UUID") + private String uuid; + + @ApiModelProperty("姓名") + private String name; + + @ApiModelProperty("医院UUID") + private String hospital_uuid; + + @ApiModelProperty("医院名称") + private String hospital_name; + + @ApiModelProperty("科室UUID") + private String office_uuid; + + @ApiModelProperty("科室名称") + private String office_name; + + @ApiModelProperty("职称UUID") + private String position_uuid; + + @ApiModelProperty("执业证号") + private String certificate; + + @ApiModelProperty("执业医师资格证或工作胸牌") + private String certificate_img; + + @ApiModelProperty("地区ID") + private Integer county_id; + + @ApiModelProperty("省份ID") + private Integer prov_id; + + @ApiModelProperty("城市ID") + private Integer city_id; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertRegisterForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertRegisterForm.java new file mode 100644 index 0000000..6adb3f9 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertRegisterForm.java @@ -0,0 +1,68 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +@Data +public class ExpertRegisterForm { + + @ApiModelProperty("手机号") + @NotBlank(message = "手机号 不能为空") + @Length(max = 11, message = "手机号最多11字符") + private String mobile; + + @ApiModelProperty("短信验证码") + @NotBlank(message = "短信验证码 不能为空") + @Length(max = 6, message = "短信验证码最多6字符") + private String sms; + + @ApiModelProperty("密码") + @NotBlank(message = "密码 不能为空") + @Length(max = 32, message = "密码最多32字符") + private String password; + + @ApiModelProperty("姓名") + @NotBlank(message = "姓名 不能为空") + @Length(max = 20, message = "姓名最多20字符") + private String name; + + @ApiModelProperty("医院UUID") + @NotBlank(message = "医院UUID 不能为空") + @Length(max = 32, message = "医院UUID最多32字符") + private String hospital_uuid; + + @ApiModelProperty("医院名称") + @NotBlank(message = "医院名称 不能为空") + @Length(max = 50, message = "医院名称最多50字符") + private String hospital_name; + + @ApiModelProperty("科室UUID") + @NotBlank(message = "科室UUID 不能为空") + @Length(max = 32, message = "科室UUID最多32字符") + private String office_uuid; + + @ApiModelProperty("科室名称") + @NotBlank(message = "科室名称 不能为空") + @Length(max = 20, message = "科室名称最多20字符") + private String office_name; + + @ApiModelProperty("职称UUID") + @NotBlank(message = "职称UUID 不能为空") + @Length(max = 32, message = "职称UUID最多32字符") + private String position_uuid; + + @ApiModelProperty("执业证号") + private String certificate; + + @ApiModelProperty("执业医师资格证或工作胸牌") + @NotBlank(message = "执业医师资格证或工作胸牌 不能为空") + private String certificate_img; + + @ApiModelProperty("地区ID") + @NotBlank(message = "地区ID 不能为空") + private String county_id; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertSignAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertSignAddForm.java new file mode 100644 index 0000000..20d1169 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertSignAddForm.java @@ -0,0 +1,15 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +public class ExpertSignAddForm { + + @ApiModelProperty(value = "签名图片") + @NotNull(message = "签名图片 不能为空") + private String signImg; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertSignVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertSignVO.java new file mode 100644 index 0000000..341ca2f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertSignVO.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.time.LocalDateTime; + +@Data +public class ExpertSignVO { + + @ApiModelProperty(hidden = true) + private Long id; + + @ApiModelProperty(value = "专家ID") + private String expertId; + + @ApiModelProperty(value = "签名图片地址") + private String signImg; + + @ApiModelProperty(value = "专家姓名") + private String name; + + @ApiModelProperty(value = "专家手机") + private String mobile; + + @ApiModelProperty(value = "专家银行卡号") + private String bankCardNo; + + @ApiModelProperty(value = "开户行", required = true) + private String bankName; + + @ApiModelProperty(value = "身份证号", required = true) + private String idCardNo; + + @ApiModelProperty(value = "签名日期") + private LocalDateTime createTime; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertVO.java new file mode 100644 index 0000000..edc10d3 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertVO.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class ExpertVO { + + @ApiModelProperty(value = "专家ID") + private Long id; + + @ApiModelProperty(value = "专家UUID") + private String uuid; + + @ApiModelProperty(value = "专家姓名") + private String name; + + @ApiModelProperty(value = "专家头像") + private String photo; + + @ApiModelProperty(value = "专家医院名称") + private String hospitalName; + + @ApiModelProperty(value = "专家通过数量") + private Integer passNum; + + @ApiModelProperty(value = "专家待审核数量") + private Integer waitNum; + + @ApiModelProperty(value = "专家待修改数量") + private Integer refuseNum; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertWhiteEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertWhiteEntity.java new file mode 100644 index 0000000..c40cfcb --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/ExpertWhiteEntity.java @@ -0,0 +1,68 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 专家表-白名单实体类 + */ +@TableName("`t_caseplatform_expert_white`") // 指定数据库表名 +public class ExpertWhiteEntity { + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + /** + * 手机号 + */ + @TableField("mobile") + private String mobile; + + /** + * 姓名 + */ + @TableField("name") + private String name; + + /** + * 头像 + */ + @TableField("photo") + private String photo; + + /** + * 医院uuid + */ + @TableField("hospital_uuid") + private String hospitalUuid; + + /** + * 医院名称 + */ + @TableField("hospital_name") + private String hospitalName; + + /** + * 省ID + */ + @TableField("prov_id") + private Integer provinceId; + + /** + * 市ID + */ + @TableField("city_id") + private Integer cityId; + + /** + * 区ID + */ + @TableField("county_id") + private Integer countyId; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/LoginForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/LoginForm.java new file mode 100644 index 0000000..0ba8151 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/LoginForm.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.app.expert.constan.SmsTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.util.SmartVerificationUtil; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.captcha.domain.CaptchaForm; +import net.lab1024.sa.common.module.support.token.LoginDeviceEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +/** + * 员工登录 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-19 11:49:45 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class LoginForm extends CaptchaForm { + + @ApiModelProperty("手机号") + @NotBlank(message = "手机号 不能为空") + @Length(max = 11, message = "登录账号最多11字符") + private String mobile; + + @ApiModelProperty(value = "登录终端") + @ApiModelPropertyEnum(LoginDeviceEnum.class) + @CheckEnum(value = LoginDeviceEnum.class, required = true, message = "此终端不允许登录") + private Integer loginDevice; + + @ApiModelProperty(value = "短信类型") + @ApiModelPropertyEnum(SmsTypeEnum.class) + @CheckEnum(value = SmsTypeEnum.class, required = true, message = "短信类型错误") + private Integer smsType; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/PWDLoginForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/PWDLoginForm.java new file mode 100644 index 0000000..3823496 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/PWDLoginForm.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.app.expert.constan.SmsTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.util.SmartVerificationUtil; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.captcha.domain.CaptchaForm; +import net.lab1024.sa.common.module.support.token.LoginDeviceEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +/** + * 手机号 密码登录 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-19 11:49:45 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class PWDLoginForm extends CaptchaForm { + + @ApiModelProperty("手机号") + @NotBlank(message = "手机号 不能为空") + @Length(max = 11, message = "登录账号最多11字符") + private String mobile; + + @ApiModelProperty(value = "登录终端") + @ApiModelPropertyEnum(LoginDeviceEnum.class) + @CheckEnum(value = LoginDeviceEnum.class, required = true, message = "此终端不允许登录") + private Integer loginDevice; + + @ApiModelProperty(value = "密码") + @NotBlank(message = "密码 不能为空") + private String pwd; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/SmsLoginForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/SmsLoginForm.java new file mode 100644 index 0000000..fccfebf --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/admin/SmsLoginForm.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.admin.module.app.expert.admin; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.app.expert.constan.SmsTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.captcha.domain.CaptchaForm; +import net.lab1024.sa.common.module.support.token.LoginDeviceEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +/** + * 短信验证码登录 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-19 11:49:45 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class SmsLoginForm { + + @ApiModelProperty("手机号") + @NotBlank(message = "手机号 不能为空") + @Length(max = 11, message = "登录账号最多11字符") + private String mobile; + + @ApiModelProperty("短信验证码") + @NotBlank(message = "短信验证码 不能为空") + @Length(max = 6, message = "短信验证码最多6字符") + private String sms; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/constan/ImageType.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/constan/ImageType.java new file mode 100644 index 0000000..4847178 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/constan/ImageType.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.admin.module.app.expert.constan; + +public enum ImageType { + JPG("jpg"), + JPEG("jpeg"), + PNG("png"), + GIF("gif"); + + private final String fileExtension; + + ImageType(String fileExtension) { + this.fileExtension = fileExtension; + } + + public String getFileExtension() { + return fileExtension; + } +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/constan/SmsTypeEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/constan/SmsTypeEnum.java new file mode 100644 index 0000000..ba402ed --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/constan/SmsTypeEnum.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.admin.module.app.expert.constan; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 病历类型 + * + * @Author HMM + * @Date 2024-01-11T15:18:32 + * @Copyright gdxz + */ + +@AllArgsConstructor +@Getter +public enum SmsTypeEnum implements BaseEnum { + register(1, "短信注册"), + login(2, "短信登录"), + ; + + private final Integer value; + + private final String desc; + + public static SmsTypeEnum getByVal(int val){ + for (SmsTypeEnum type: SmsTypeEnum.values()){ + if(type.getValue() == val){ + return type; + } + } + return null; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/controller/ExpertController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/controller/ExpertController.java new file mode 100644 index 0000000..4de0a77 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/controller/ExpertController.java @@ -0,0 +1,588 @@ +package net.lab1024.sa.admin.module.app.expert.controller; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.app.expert.admin.*; +import net.lab1024.sa.admin.module.app.expert.service.ExpertService; +import net.lab1024.sa.admin.module.app.expert.service.ExpertWhiteEntityService; +import net.lab1024.sa.admin.module.app.medicalrecord.dao.MedicalRecorDao; +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.admin.module.business.area.service.AreaService; +import net.lab1024.sa.admin.module.business.captcha.service.CaptchaService; +import net.lab1024.sa.admin.module.system.login.service.LoginService; +import net.lab1024.sa.common.common.annoation.NoNeedLogin; +import net.lab1024.sa.common.common.constant.RequestHeaderConst; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.Sha256Util; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.captcha.domain.CaptchaVO; +import net.lab1024.sa.common.module.support.config.ConfigKeyEnum; +import net.lab1024.sa.common.module.support.config.ConfigService; +import net.lab1024.sa.common.module.support.config.domain.ConfigVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import javax.validation.Valid; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static net.lab1024.sa.common.common.code.UserErrorCode.*; + +@Slf4j +@RestController +@Api(tags = {AdminSwaggerTagConst.App.Expert}) +public class ExpertController { + + //发送验证码 + private final String SENDSMS_URL = "hcp/sendSms"; + + //短信登录 + private final String SMSLOGIN_URL = "hcp/smsLogin"; + + //短信注册 + private final String SMSREGISTER_URL = "hcp/smsRegister"; + + private final String UOLOADIMGV2_URL = "hcp/uoloadImgV2"; + + //科室列表 + private final String OFFICELIST_URL = "hcp/officeList"; + + //职称列表 + private final String POSITIONLIST_URL = "hcp/positionList"; + + //医院列表 + private final String HOSPITALLIST_URL = "hcp/hospitalList"; + + //获取HCP详情 + private final String GETINFO_URL = "hcp/getInfo"; + + //修改HCP资料 + private final String MODIFY_URL = "hcp/modify"; + + //账户密码登录 + private final String PWDLOGIN_URL = "hcp/PwdLogin"; + + @Value("${igandan.doc.host}") + private String IGANDAN_DOC_HOST; + + @Value("${igandan.wx.host}") + private String IGANDAN_WX_HOST; + + @Value("${igandan.wx.platform}") + private String IGANDAN_WX_PLATFORM; + + @Value("${igandan.wx.token}") + private String IGANDAN_WX_token; + + @Autowired + private CaptchaService captchaService; + + @Autowired + private ExpertService expertService; + + @Autowired + private ConfigService configService; + + @Autowired + private AreaService areaService; + + @Autowired + private LoginService loginService; + + @Autowired + private MedicalRecorDao medicalRecorDao; + + @Autowired + private ExpertWhiteEntityService expertWhiteEntityService; + + @ApiOperation("获取验证码") + @GetMapping("/user/getCaptcha") + @NoNeedLogin + public ResponseDTO getCaptcha() { + return ResponseDTO.app_ok(captchaService.generateCaptcha()); + } + + /** + * 发送验证码 + * @return + */ + @NoNeedLogin + @ApiOperation(value = "发送验证码", notes = "") + @PostMapping("/user/sendSms") + public ResponseDTO sendSms(@RequestBody @Valid LoginForm loginForm) { + + ResponseDTO checkCaptcha = captchaService.checkCaptcha(loginForm); + if(!checkCaptcha.getOk()){ + return checkCaptcha; + } + + Integer smsType = loginForm.getSmsType(); + String mobile = loginForm.getMobile(); + Map params = new HashMap<>(8); + params.put("type", smsType); + params.put("mobile", mobile); + params.put("platform", IGANDAN_WX_PLATFORM); + params.put("timestamp", System.currentTimeMillis()/1000); + String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + params.put("signature", signature); + + String result = HttpUtil.post(IGANDAN_WX_HOST + SENDSMS_URL, params); + ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + return responseDTO; + } + + /** + * 短信注册 + * @return + */ + @NoNeedLogin + @ApiOperation(value = "短信注册") + @PostMapping("/user/smsRegister") + public ResponseDTO smsRegister(@RequestBody @Valid ExpertRegisterForm form) { + + String mobile = form.getMobile(); + String sms = form.getSms(); + String password = form.getPassword(); + String name = form.getName(); + String hospital_uuid = form.getHospital_uuid(); + String hospital_name = form.getHospital_name(); + String office_uuid = form.getOffice_uuid(); + String office_name = form.getOffice_name(); + String position_uuid = form.getPosition_uuid(); + String certificate = form.getCertificate(); + String certificate_img = form.getCertificate_img(); + String county_id = form.getCounty_id(); + Map params = new HashMap<>(16); + params.put("mobile", mobile); + params.put("sms", sms); + params.put("password", password); + params.put("name", name); + params.put("hospital_uuid", hospital_uuid); + params.put("hospital_name", hospital_name); + params.put("office_uuid", office_uuid); + params.put("office_name", office_name); + params.put("position_uuid", position_uuid); + params.put("certificate", certificate); + params.put("certificate_img", certificate_img); + params.put("county_id", county_id); + + params.put("platform", IGANDAN_WX_PLATFORM); + params.put("timestamp", System.currentTimeMillis()/1000); + String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + params.put("signature", signature); + + String result = HttpUtil.post(IGANDAN_WX_HOST + SMSREGISTER_URL, params); + ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + return responseDTO; + } + + /** + * 短信登录 + * @return + */ + @NoNeedLogin + @ApiOperation(value = "短信登录") + @PostMapping("/user/smsLogin") + public ResponseDTO smsLogin(@RequestBody @Valid SmsLoginForm form) { + Map params = new HashMap<>(8); + String mobile = form.getMobile(); + params.put("mobile", mobile); + params.put("sms", form.getSms()); + params.put("platform", IGANDAN_WX_PLATFORM); + params.put("timestamp", System.currentTimeMillis()/1000); + String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + params.put("signature", signature); + + String result = HttpUtil.post(IGANDAN_WX_HOST + SMSLOGIN_URL, params); + ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + if(responseDTO.getCode() == 200){ + Map data = (Map) responseDTO.getData(); + String uuid = (String) data.get("uuid"); + String name = (String) data.get("name"); + String photo = (String) data.get("photo"); + String hospital_uuid = (String) data.get("hospital_uuid"); + String hospital_name = (String) data.get("hospital_name"); + Integer prov_id = (Integer) data.get("prov_id"); + Integer county_id = (Integer) data.get("county_id"); + Integer city_id = (Integer) data.get("city_id"); + + // 获取白名单用户-姓名、医院名称 + ExpertWhiteEntity expertWhiteEntity = expertWhiteEntityService.getExpertWhiteEntityByNameAndHospitalName(name,hospital_name); + if (expertWhiteEntity == null) { + responseDTO.setMsg("暂无登录权限"); + return responseDTO; + } + + ExpertEntity expert = new ExpertEntity(); + expert.setName(name); + if(StrUtil.isBlank(photo)){ + expert.setPhoto(""); + }else{ + expert.setPhoto(IGANDAN_DOC_HOST+photo); + } + expert.setUuid(uuid); + expert.setHospitalName(hospital_name); + expert.setHospitalUuid(hospital_uuid); + expert.setProvId(prov_id); + expert.setCityId(city_id); + expert.setCountyId(county_id); + expert.setMobile(mobile); + ExpertEntity expertVO = expertService.addExpert(expert); + ExpertLoginVO expertLoginVO = SmartBeanUtil.copy(expertVO, ExpertLoginVO.class); + return ResponseDTO.app_ok(expertLoginVO); + }else{ + responseDTO.setMsg("账号未注册,请您注册后登陆"); + return responseDTO; + } + } + + @NoNeedLogin + @ApiOperation("获取省市区") + @GetMapping("/user/areaList") + public ResponseDTO> areaList(Long parent) { + return ResponseDTO.app_ok(areaService.areaList(parent)); + } + + @ApiOperation(value = "退出登录") + @GetMapping("/user/logOut") + public ResponseDTO logOut(@RequestHeader(value = RequestHeaderConst.TOKEN, required = false) String token) { + return loginService.appLogout(token, SmartRequestUtil.getRequestUser()); + } + + @ApiOperation(value = "个人中心") + @GetMapping("/user/getInfo") + public ResponseDTO getInfo() { + return ResponseDTO.app_ok(expertService.getInfo()); + } + + @NoNeedLogin + @ApiOperation(value = "项目协议") + @GetMapping("/user/getDeal") + public ResponseDTO getDeal() { + ConfigVO config = configService.getConfig(ConfigKeyEnum.DEAL); + return ResponseDTO.app_ok(config.getConfigValue()); + } + + @NoNeedLogin + @ApiOperation(value = "隐私协议") + @GetMapping("/user/getPrivacy") + public ResponseDTO getPrivacy() { + ConfigVO config = configService.getConfig(ConfigKeyEnum.PRIVACY); + return ResponseDTO.app_ok(config.getConfigValue()); + } + + @ApiOperation(value = "项目状态") + @GetMapping("/user/getProjectStatus") + public ResponseDTO getCaseNum() { + ConfigVO CaseSwitch = configService.getConfig(ConfigKeyEnum.CaseSwitch); + if(CaseSwitch.getConfigValue().equals("false")){ + return ResponseDTO.error(PROJECT_CLOSE); + } + + ConfigVO CaseNum = configService.getConfig(ConfigKeyEnum.CaseNum); + int total = medicalRecorDao.getTotal(); + if(Integer.parseInt(CaseNum.getConfigValue()) <= total){ + return ResponseDTO.error(PROJECT_CLOSE); + } + + return ResponseDTO.app_ok(); + } + + @NoNeedLogin + @ApiOperation(value = "操作说明") + @GetMapping("/user/getRubric") + public ResponseDTO getRubric() { + ConfigVO config = configService.getConfig(ConfigKeyEnum.RUBRIC); + return ResponseDTO.app_ok(config.getConfigValue()); + } + + //@NoNeedLogin + //@ApiOperation(value = "上传图片", notes = "仅在上传执业医师资格证使用") + //@PostMapping("/user/uoloadImg") + //public ResponseDTO uoloadImg(@RequestParam("file") MultipartFile file) throws IOException { + // HashMap params = new HashMap<>(); + // //文件上传只需将参数中的键指定(默认file),值设为文件对象即可,对于使用者来说,文件上传与普通表单提交并无区别 + // byte[] fileBytes = file.getBytes(); + // String base64String = Base64.getEncoder().encodeToString(fileBytes); + // + // String originalFilename = file.getOriginalFilename(); + // String fileExtension = FilenameUtils.getExtension(originalFilename); + // ImageType imageType = ImageType.valueOf(fileExtension.toUpperCase()); + // + // long timestamp = System.currentTimeMillis() / 1000; + // params.put("type", imageType.getFileExtension()); + // params.put("base64Img", base64String); + // params.put("platform", IGANDAN_WX_PLATFORM); + // params.put("timestamp", timestamp); + // String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + // params.put("signature", signature); + // + // + // String result = HttpUtil.post(IGANDAN_WX_HOST + UOLOADIMG_URL, params, 60 * 1000); + // ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + // if(responseDTO.getCode() == 200){ + // String data = (String) responseDTO.getData(); + // + // return ResponseDTO.app_ok(IGANDAN_DOC_HOST + data); + // } + // return ResponseDTO.userErrorParam(); + //} + + @NoNeedLogin + @ApiOperation(value = "上传图片", notes = "仅在上传执业医师资格证使用") + @PostMapping("/user/uoloadImg") + public ResponseDTO uoloadImg(@RequestParam("file") MultipartFile file) throws IOException { + HashMap params = new HashMap<>(); + //文件上传只需将参数中的键指定(默认file),值设为文件对象即可,对于使用者来说,文件上传与普通表单提交并无区别 + // 创建一个临时文件 + File tempFile = File.createTempFile("temp", file.getOriginalFilename()); + // 将 MultipartFile 的内容写入到临时文件中 + try (InputStream inputStream = file.getInputStream(); + OutputStream outputStream = new FileOutputStream(tempFile)) { + + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + params.put("platform", IGANDAN_WX_PLATFORM); + params.put("timestamp", System.currentTimeMillis()/1000); + String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + params.put("signature", signature); + params.put("file", tempFile); + String result= HttpUtil.post(IGANDAN_WX_HOST + UOLOADIMGV2_URL, params); + ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + if(responseDTO.getCode() == 200){ + String data = (String) responseDTO.getData(); + return ResponseDTO.app_ok(IGANDAN_DOC_HOST + data); + } + }finally { + tempFile.deleteOnExit(); + } + return ResponseDTO.userErrorParam(); + } + + @NoNeedLogin + @ApiOperation(value = "科室列表") + @GetMapping("/user/officeList") + public ResponseDTO officeList() { + HashMap params = new HashMap<>(); + params.put("platform", IGANDAN_WX_PLATFORM); + params.put("timestamp", System.currentTimeMillis()/1000); + String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + params.put("signature", signature); + String result = HttpUtil.post(IGANDAN_WX_HOST + OFFICELIST_URL, params); + ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + if(responseDTO.getCode() == 200){ + Object data = responseDTO.getData(); + return ResponseDTO.app_ok(data); + } + return ResponseDTO.userErrorParam(); + } + + @NoNeedLogin + @ApiOperation(value = "职称列表") + @GetMapping("/user/positionList") + public ResponseDTO positionList() { + HashMap params = new HashMap<>(); + params.put("platform", IGANDAN_WX_PLATFORM); + params.put("timestamp", System.currentTimeMillis()/1000); + String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + params.put("signature", signature); + String result = HttpUtil.post(IGANDAN_WX_HOST + POSITIONLIST_URL, params); + ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + if(responseDTO.getCode() == 200){ + Object data = responseDTO.getData(); + return ResponseDTO.app_ok(data); + } + return ResponseDTO.userErrorParam(); + } + + @NoNeedLogin + @ApiOperation(value = "医院列表") + @GetMapping("/user/hospitalList/{countyId}") + public ResponseDTO hospitalList(@PathVariable Long countyId) { + HashMap params = new HashMap<>(); + params.put("countyId", countyId); + params.put("platform", IGANDAN_WX_PLATFORM); + params.put("timestamp", System.currentTimeMillis()/1000); + String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + params.put("signature", signature); + String result = HttpUtil.post(IGANDAN_WX_HOST + HOSPITALLIST_URL, params); + ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + if(responseDTO.getCode() == 200){ + Object data = responseDTO.getData(); + return ResponseDTO.app_ok(data); + } + return ResponseDTO.userErrorParam(); + } + + @NoNeedLogin + @ApiOperation(value = "账户密码登录") + @PostMapping("/user/login") + public ResponseDTO login(@RequestBody @Valid PWDLoginForm loginForm) { + + ResponseDTO checkCaptcha = captchaService.checkCaptcha(loginForm); + if(!checkCaptcha.getOk()){ + return checkCaptcha; + } + String pwd = loginForm.getPwd(); + String mobile = loginForm.getMobile(); + Map params = new HashMap<>(8); + params.put("password", pwd); + params.put("mobile", mobile); + params.put("platform", IGANDAN_WX_PLATFORM); + params.put("timestamp", System.currentTimeMillis()/1000); + String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + params.put("signature", signature); + + String result = HttpUtil.post(IGANDAN_WX_HOST + PWDLOGIN_URL, params); + ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + if(responseDTO.getCode() == 200){ + Map data = (Map) responseDTO.getData(); + String uuid = (String) data.get("uuid"); + String name = (String) data.get("name"); + String photo = (String) data.get("photo"); + String hospital_uuid = (String) data.get("hospital_uuid"); + String hospital_name = (String) data.get("hospital_name"); + Integer prov_id = (Integer) data.get("prov_id"); + Integer county_id = (Integer) data.get("county_id"); + Integer city_id = (Integer) data.get("city_id"); + + // 获取白名单用户-姓名、医院名称 + ExpertWhiteEntity expertWhiteEntity = expertWhiteEntityService.getExpertWhiteEntityByNameAndHospitalName(name,hospital_name); + if (expertWhiteEntity == null) { + responseDTO.setMsg("暂无登录权限"); + return responseDTO; + } + + ExpertEntity expert = new ExpertEntity(); + expert.setName(name); + if(StrUtil.isBlank(photo)){ + expert.setPhoto(""); + }else{ + expert.setPhoto(IGANDAN_DOC_HOST+photo); + } + expert.setUuid(uuid); + expert.setHospitalName(hospital_name); + expert.setHospitalUuid(hospital_uuid); + expert.setProvId(prov_id); + expert.setCityId(city_id); + expert.setCountyId(county_id); + expert.setMobile(mobile); + ExpertEntity expertVO = expertService.addExpert(expert); + + ExpertLoginVO expertLoginVO = SmartBeanUtil.copy(expertVO, ExpertLoginVO.class); + return ResponseDTO.app_ok(expertLoginVO); + }else{ + return responseDTO; + } + } + + @NoNeedLogin + @ApiOperation(value = "获取待补充资料时候-HCP详情") + @GetMapping("/user/getDetail/{mobile}") + public ResponseDTO getDetail(@PathVariable String mobile) { + HashMap params = new HashMap<>(); + params.put("mobile", mobile); + params.put("platform", IGANDAN_WX_PLATFORM); + params.put("timestamp", System.currentTimeMillis()/1000); + String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + params.put("signature", signature); + String result = HttpUtil.post(IGANDAN_WX_HOST + GETINFO_URL, params); + ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + if(responseDTO.getCode() == 200){ + Map data = (Map) responseDTO.getData(); + if(data == null){ + return ResponseDTO.error(NO_MODIFY); + } + String uuid = (String) data.get("uuid"); + String name = (String) data.get("realname"); + String office_uuid = (String) data.get("office_uuid"); + String office_name = (String) data.get("office_name"); + String position_uuid = (String) data.get("position_uuid"); + String certificate = (String) data.get("certificate"); + String certificate_img = (String) data.get("certificate_img"); + String hospital_uuid = (String) data.get("hospital_uuid"); + String hospital_name = (String) data.get("hospital_name"); + Integer prov_id = (Integer) data.get("prov_id"); + Integer county_id = (Integer) data.get("county_id"); + Integer city_id = (Integer) data.get("city_id"); + ExpertModifyVO expert = new ExpertModifyVO(); + expert.setName(name); + expert.setUuid(uuid); + expert.setHospital_name(hospital_name); + expert.setHospital_uuid(hospital_uuid); + expert.setProv_id(prov_id); + expert.setCity_id(city_id); + expert.setCounty_id(county_id); + + expert.setOffice_name(office_name); + expert.setOffice_uuid(office_uuid); + expert.setPosition_uuid(position_uuid); + expert.setCertificate(certificate); + expert.setCertificate_img(certificate_img); + if(StrUtil.isBlank(certificate_img)){ + expert.setCertificate_img(""); + }else{ + expert.setCertificate_img(IGANDAN_DOC_HOST+certificate_img); + } + return ResponseDTO.app_ok(expert); + } + return ResponseDTO.userErrorParam(); + } + + @NoNeedLogin + @ApiOperation(value = "修改HCP资料") + @PostMapping("/user/modify") + public ResponseDTO modify(@RequestBody @Valid ExpertModifyForm form) { + String uuid = form.getUuid(); + String name = form.getName(); + String hospital_uuid = form.getHospital_uuid(); + String hospital_name = form.getHospital_name(); + String office_uuid = form.getOffice_uuid(); + String office_name = form.getOffice_name(); + String position_uuid = form.getPosition_uuid(); + String certificate = form.getCertificate(); + String certificate_img = form.getCertificate_img().replaceAll(IGANDAN_DOC_HOST,""); + String county_id = form.getCounty_id(); + Map params = new HashMap<>(16); + params.put("uuid", uuid); + params.put("realname", name); + params.put("hospital_uuid", hospital_uuid); + params.put("hospital_name", hospital_name); + params.put("office_uuid", office_uuid); + params.put("office_name", office_name); + params.put("position_uuid", position_uuid); + params.put("certificate", certificate); + params.put("certificate_img", certificate_img); + params.put("county_id", county_id); + params.put("platform", IGANDAN_WX_PLATFORM); + params.put("timestamp", System.currentTimeMillis()/1000); + String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + params.put("signature", signature); + String result = HttpUtil.post(IGANDAN_WX_HOST + MODIFY_URL, params); + ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + return responseDTO; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/controller/ExpertSignController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/controller/ExpertSignController.java new file mode 100644 index 0000000..74530eb --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/controller/ExpertSignController.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.admin.module.app.expert.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertSignVO; +import net.lab1024.sa.admin.module.app.expert.service.ExpertSignService; +import net.lab1024.sa.admin.module.business.bankcard.domain.form.CaseplatformBankAddForm; +import net.lab1024.sa.admin.module.business.bankcard.service.CaseplatformBankService; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.wangyi.yidun.sdk.BankCardCheckAPI; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +import static net.lab1024.sa.common.common.code.UserErrorCode.ExpertBankVerifyFail; + +@RestController +@Api(tags = {AdminSwaggerTagConst.App.ExpertSign}) +public class ExpertSignController { + + @Autowired + private ExpertSignService expertSignService; + + @Autowired + private CaseplatformBankService caseplatformBankService; + + /** + * 获取专家 签名 + * @return + */ + @ApiOperation(value = "获取专家 签名") + @GetMapping("/user/getSign") + public ResponseDTO getExpertSign() { + ExpertSignVO expertSign = expertSignService.getExpertSign(); + return ResponseDTO.app_ok(expertSign); + } + + /** + * 添加专家 签名 + * 认证银行卡 + * @return + */ + @ApiOperation(value = "添加专家 签名 & 认证银行卡") + @PostMapping("/user/addBank") + public ResponseDTO bankVerify(@RequestBody @Valid CaseplatformBankAddForm addForm) { + boolean check = BankCardCheckAPI.check(addForm.getName(), addForm.getIdCardNo(), addForm.getBankCardNo()); + if(check){ + return caseplatformBankService.add(addForm); + }else { + return ResponseDTO.error(ExpertBankVerifyFail); + } + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertDao.java new file mode 100644 index 0000000..bb0f60c --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertDao.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.admin.module.app.expert.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; +import org.springframework.stereotype.Component; + +@Mapper +@Component +public interface ExpertDao extends BaseMapper { + + @Select("select * from t_caseplatform_expert where id=#{id}") + public ExpertEntity getExpert(Long id); + + @Select("select * from t_caseplatform_expert where uuid=#{uuid}") + public ExpertEntity getExpertByUuid(String uuid); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertSignDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertSignDao.java new file mode 100644 index 0000000..be7f221 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertSignDao.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.admin.module.app.expert.dao; + +import net.lab1024.sa.admin.module.app.expert.admin.ExpertSignAddForm; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertSignVO; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Component; + +@Mapper +@Component +public interface ExpertSignDao { + + @Insert("insert into t_caseplatform_sign(expert_id, sign_img) values(#{expertId}, #{sign_img}) ") + public int addExpertSign(@Param("expertId")Long expertId, @Param("sign_img")String sign_img); + + @Select("select t_caseplatform_sign.id,t_caseplatform_sign.expert_id,t_caseplatform_sign.sign_img,t_caseplatform_sign.create_time," + + "t_caseplatform_bank.id_card_no,t_caseplatform_bank.bank_card_no,t_caseplatform_bank.bank_name," + + "t_caseplatform_expert.mobile,t_caseplatform_expert.name " + + "from t_caseplatform_sign " + + "left join t_caseplatform_bank on t_caseplatform_sign.expert_id = t_caseplatform_bank.expert_id " + + "left join t_caseplatform_expert on t_caseplatform_expert.id = t_caseplatform_sign.expert_id " + + "where t_caseplatform_sign.expert_id=#{expert_id} " + + "order by t_caseplatform_sign.create_time desc limit 1") + public ExpertSignVO getExpertSign(Long expert_id); + + @Update("update t_caseplatform_sign set sign_img=#{sign_img} where id=#{id}") + public int updateById(@Param("id")Long id, @Param("sign_img")String sign_img); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertWhiteEntityDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertWhiteEntityDao.java new file mode 100644 index 0000000..35cc286 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/dao/ExpertWhiteEntityDao.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.app.expert.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertEntity; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertWhiteEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.springframework.stereotype.Component; + +@Mapper +@Component +public interface ExpertWhiteEntityDao extends BaseMapper { + @Select("select * from t_caseplatform_expert_white where id=#{id}") + public ExpertWhiteEntity getExpertWhite(Long id); + + @Select("SELECT * FROM t_caseplatform_expert_white WHERE name = #{name} AND hospital_name = #{hospitalName}") + ExpertWhiteEntity getExpertWhiteByNameAndHospital(@Param("name")String name, @Param("hospitalName")String hospitalName); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertService.java new file mode 100644 index 0000000..2bc34f6 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertService.java @@ -0,0 +1,82 @@ +package net.lab1024.sa.admin.module.app.expert.service; + +import net.lab1024.sa.admin.module.app.expert.admin.ExpertEntity; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertVO; +import net.lab1024.sa.admin.module.app.expert.dao.ExpertDao; +import net.lab1024.sa.admin.module.app.medicalrecord.dao.MedicalRecorDao; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.token.service.TokenService; +import net.lab1024.sa.admin.module.system.login.service.LoginService; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.loginlog.LoginLogService; +import net.lab1024.sa.common.module.support.token.LoginDeviceEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ExpertService { + + @Autowired + private TokenService tokenService; + + @Autowired + private ExpertDao expertDao; + + @Autowired + private MedicalRecorDao medicalRecorDao; + + + + + /** + * 根据id 查询 + * @param userId + * @return + */ + public ExpertEntity getById(Long userId) { + ExpertEntity expert = expertDao.getExpert(userId); + return expert; + } + + public ExpertVO getInfo() { + Long expertId = SmartRequestUtil.getRequestUserId(); + ExpertEntity expert = expertDao.getExpert(expertId); + int waitNum = medicalRecorDao.getNum(expertId, CaseStatusEnum.WAIT.getValue()); + int passNum = medicalRecorDao.getNum(expertId, CaseStatusEnum.PASS.getValue()); + int refuseNum = medicalRecorDao.getNum(expertId, CaseStatusEnum.REFUSE.getValue()); + + ExpertVO data = SmartBeanUtil.copy(expert, ExpertVO.class); + data.setRefuseNum(refuseNum); + data.setPassNum(passNum); + data.setWaitNum(waitNum); + return data; + } + + /** + * 添加 + * @return + */ + public ExpertEntity addExpert(ExpertEntity addForm) { + String uuid = addForm.getUuid(); + ExpertEntity expertByUuid = expertDao.getExpertByUuid(uuid); + Long id = null; + if(expertByUuid == null){ + expertDao.insert(addForm); + id = addForm.getId(); + }else{ + id = expertByUuid.getId(); + addForm.setId(id); + expertDao.updateById(addForm); + } + String name = addForm.getName(); + String token = tokenService.generateToken(id, name, UserTypeEnum.EXPERT, LoginDeviceEnum.WEIXIN_MP, false); + addForm.setToken(token); + return addForm; + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertSignService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertSignService.java new file mode 100644 index 0000000..b5e1488 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertSignService.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.app.expert.service; + +import net.lab1024.sa.admin.module.app.expert.admin.ExpertSignAddForm; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertSignVO; +import net.lab1024.sa.admin.module.app.expert.dao.ExpertSignDao; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.RequestBody; + +import javax.validation.Valid; + +@Service +public class ExpertSignService { + + @Autowired + private ExpertSignDao expertSignDao; + + public ExpertSignVO getExpertSign() { + Long expertId = SmartRequestUtil.getRequestUserId(); + return expertSignDao.getExpertSign(expertId); + } + + /** + * 添加专家 签名 + * @return + */ + public ResponseDTO addExpertSign(ExpertSignAddForm addForm) { + Long expertId = SmartRequestUtil.getRequestUserId(); + String signImg = addForm.getSignImg(); + ExpertSignVO expertSign = expertSignDao.getExpertSign(expertId); + if(expertSign == null){ + expertSignDao.addExpertSign(expertId, signImg); + return ResponseDTO.app_ok(); + } + expertSignDao.updateById(expertSign.getId(), signImg); + return ResponseDTO.app_ok(); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertWhiteEntityService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertWhiteEntityService.java new file mode 100644 index 0000000..01fb564 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/expert/service/ExpertWhiteEntityService.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.admin.module.app.expert.service; + +import net.lab1024.sa.admin.module.app.expert.admin.ExpertEntity; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertVO; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertWhiteEntity; +import net.lab1024.sa.admin.module.app.expert.dao.ExpertDao; +import net.lab1024.sa.admin.module.app.expert.dao.ExpertWhiteEntityDao; +import net.lab1024.sa.admin.module.app.medicalrecord.dao.MedicalRecorDao; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.token.service.TokenService; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.token.LoginDeviceEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ExpertWhiteEntityService { + @Autowired + private ExpertWhiteEntityDao expertWhiteEntityDao; + + /** + * 获取白名单用户-姓名、医院名称 + * @param name 专家姓名 + * @param hospitalName 专家所属医院名称 + * @return 白名单类 + */ + public ExpertWhiteEntity getExpertWhiteEntityByNameAndHospitalName(String name, String hospitalName) { + if (name == null || hospitalName == null) { + return null; + } + + return expertWhiteEntityDao.getExpertWhiteByNameAndHospital(name, hospitalName); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/constant/OSSFileTypeEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/constant/OSSFileTypeEnum.java new file mode 100644 index 0000000..80cc029 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/constant/OSSFileTypeEnum.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.app.file.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +@AllArgsConstructor +@Getter +public enum OSSFileTypeEnum implements BaseEnum { + PUBLIC(1, "public"), + SIGN(2, "sign"), + ; + + public static OSSFileTypeEnum getByVal(int val){ + OSSFileTypeEnum[] values = OSSFileTypeEnum.values(); + for(OSSFileTypeEnum type:values){ + if(val == type.getValue()){ + return type; + } + } + return null; + } + private final Integer value; + + private final String desc; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/controller/OSSFileController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/controller/OSSFileController.java new file mode 100644 index 0000000..dc2e5bb --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/controller/OSSFileController.java @@ -0,0 +1,73 @@ +package net.lab1024.sa.admin.module.app.file.controller; + +import com.aliyun.oss.OSSClient; +import com.aliyun.oss.common.utils.BinaryUtil; +import com.aliyun.oss.model.MatchMode; +import com.aliyun.oss.model.PolicyConditions; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.app.file.constant.OSSFileTypeEnum; +import net.lab1024.sa.admin.module.app.file.domain.OSSPolicyVO; +import net.lab1024.sa.common.common.annoation.NoNeedLogin; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import java.io.File; +import java.util.Date; + +import static net.lab1024.sa.common.common.code.UserErrorCode.LOGIN_STATE_INVALID; + +@RestController +@Api(tags = {AdminSwaggerTagConst.App.OSS}) +public class OSSFileController { + + @Value("${file.storage.cloud.endpoint}") + private String endpoint; + + @Value("${file.storage.cloud.bucket-name}") + private String bucketName; + + @Value("${file.storage.cloud.access-key}") + private String accessKey; + + @Value("${file.storage.cloud.secret-key}") + private String secretKey; + + @Value("${file.storage.cloud.url.public}") + private String host; + + @ApiOperation(value = "获取上传文件 Policy", notes="type==1 普通;type==2 签名图片") + @GetMapping("/file/getOSSPolicy/{type}") + public ResponseDTO getOSSPolicy(@PathVariable int type){ + OSSFileTypeEnum ossFileType = OSSFileTypeEnum.getByVal(type); + Long requestUserId = SmartRequestUtil.getRequestUserId(); + String dir = ossFileType.getDesc() + File.separator + requestUserId + File.separator; + // callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。 + OSSClient client = new OSSClient(endpoint, accessKey, secretKey); + try { + long expireTime = 30; + long expireEndTime = System.currentTimeMillis() + expireTime * 1000; + Date expiration = new Date(expireEndTime); + PolicyConditions policyConds = new PolicyConditions(); + policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 10*1024*1024);// 最大 10 M + policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, ossFileType.getDesc()); + + String postPolicy = client.generatePostPolicy(expiration, policyConds); + byte[] binaryData = postPolicy.getBytes("utf-8"); + String encodedPolicy = BinaryUtil.toBase64String(binaryData); + String postSignature = client.calculatePostSignature(postPolicy); + + + OSSPolicyVO policyVO = new OSSPolicyVO(accessKey, encodedPolicy, postSignature, dir, host, String.valueOf(expireEndTime / 1000)); + return ResponseDTO.app_ok(policyVO); + } catch (Exception e) { + e.printStackTrace(); + return ResponseDTO.userErrorParam(); + } + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/domain/OSSPolicyVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/domain/OSSPolicyVO.java new file mode 100644 index 0000000..06692fc --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/file/domain/OSSPolicyVO.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.admin.module.app.file.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class OSSPolicyVO { + + @ApiModelProperty(value = "OSS accessid") + private String accessid; + + @ApiModelProperty(value = "OSS policy") + private String policy; + + @ApiModelProperty(value = "OSS 签名") + private String signature; + + @ApiModelProperty(value = "OSS 上传路径") + private String dir; + + @ApiModelProperty(value = "OSS host") + private String host; + + @ApiModelProperty(value = "OSS 过期时间") + private String expire; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/controller/MedicalRecordController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/controller/MedicalRecordController.java new file mode 100644 index 0000000..55e6ee5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/controller/MedicalRecordController.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordAddForm; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordDetailVO; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordListVO; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordQueryForm; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordUpdateForm; +import net.lab1024.sa.admin.module.app.medicalrecord.service.MedicalRecordService; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +@RestController +@Api(tags = {AdminSwaggerTagConst.App.MedicalRecord}) +public class MedicalRecordController { + + @Autowired + private MedicalRecordService medicalRecordService; + + /** + * 列表页 + * @param queryForm + * @return + */ + @ApiOperation(value = "获取病历列表") + @PostMapping("/medicalRecord/getList") + public ResponseDTO> getList(@RequestBody @Valid MedicalRecordQueryForm queryForm) { + return ResponseDTO.app_ok(medicalRecordService.getList(queryForm)); + } + + @ApiOperation(value = "获取病历详情") + @GetMapping("/medicalRecord/getDetail/{MedicalRecordId}") + public ResponseDTO getList(@PathVariable Long MedicalRecordId) { + return ResponseDTO.app_ok(medicalRecordService.getDetail(MedicalRecordId)); + } + + @ApiOperation(value = "添加病历") + @PostMapping("/medicalRecord/add") + public ResponseDTO add(@RequestBody @Valid MedicalRecordAddForm addForm) { + return medicalRecordService.add(addForm); + } + + @ApiOperation(value = "修改病历") + @PostMapping("/medicalRecord/update") + public ResponseDTO update(@RequestBody @Valid MedicalRecordUpdateForm updateForm) { + return medicalRecordService.update(updateForm); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorAbstracDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorAbstracDao.java new file mode 100644 index 0000000..c9ffb09 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorAbstracDao.java @@ -0,0 +1,16 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordAbstracEntity; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordUserEntity; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +@Mapper +@Component +public interface MedicalRecorAbstracDao extends BaseMapper { + + @Delete("delete from t_caseplatform_case_abstract where case_id=#{medicalRecordId}") + int deleteByCaseId(Long medicalRecordId); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorCheckDataDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorCheckDataDao.java new file mode 100644 index 0000000..f809701 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorCheckDataDao.java @@ -0,0 +1,15 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordCheckdataEntity; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +@Mapper +@Component +public interface MedicalRecorCheckDataDao extends BaseMapper { + + @Delete("delete from t_caseplatform_case_checkdata where case_id=#{medicalRecordId}") + int deleteByCaseId(Long medicalRecordId); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorDao.java new file mode 100644 index 0000000..90a7729 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorDao.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordAbstracEntity; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordDTO; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordDetailVO; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordEntity; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordListVO; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordQueryForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; + +@Mapper +@Component +public interface MedicalRecorDao extends BaseMapper { + + List getList(Page page, @Param("queryForm") MedicalRecordQueryForm queryForm); + + MedicalRecordDetailVO getDetail(Long MedicalRecordId); + + @Select("select t_caseplatform_case.id, t_caseplatform_case.admission_time from t_caseplatform_case " + + "left join t_caseplatform_user on t_caseplatform_case.user_id = t_caseplatform_user.id " + + "where t_caseplatform_case.expert_id=#{expertId} and t_caseplatform_user.uid=#{uid} order by admission_time desc") + List getAdmissionTimeByUid(@Param("expertId")Long expertId, @Param("uid")String uid); + + @Select("select * from t_caseplatform_case where id=#{MedicalRecordId}") + MedicalRecordListVO getById(Long MedicalRecordId); + + @Select("select count(*) from t_caseplatform_case where expert_id=#{expertId} and status=#{status}") + int getNum(@Param("expertId")Long expertId, @Param("status")int status); + + @Select("select count(*) from t_caseplatform_case") + int getTotal(); + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorDpmasDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorDpmasDao.java new file mode 100644 index 0000000..a424f30 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorDpmasDao.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.DpmsAddForm; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordDpmsEntity; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordUserEntity; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Mapper +@Component +public interface MedicalRecorDpmasDao extends BaseMapper { + + @Select("select * from t_caseplatform_case_dpms where case_id=#{caseId}") + List getByCaseId(Long caseId); + + @Delete("delete from t_caseplatform_case_dpms where case_id=#{medicalRecordId}") + int deleteByCaseId(Long medicalRecordId); + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorUserDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorUserDao.java new file mode 100644 index 0000000..14c1b4e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/dao/MedicalRecorUserDao.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordDetailVO; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordListVO; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordQueryForm; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordUserEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Mapper +@Component +public interface MedicalRecorUserDao extends BaseMapper { + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/DpmsAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/DpmsAddForm.java new file mode 100644 index 0000000..08b9f53 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/DpmsAddForm.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +@Data +public class DpmsAddForm { + + @ApiModelProperty(value = "治疗时间", required = true) + @NotNull(message = "治疗时间 不能为空") + private LocalDateTime treatTime; + + @ApiModelProperty(value = "治疗图片", required = true) + @NotNull(message = "治疗图片 不能为空") + @Length(min = 1, max = 1000, message = "治疗图片 不能为空") + private String dpmasImg; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordAbstracEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordAbstracEntity.java new file mode 100644 index 0000000..6148e98 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordAbstracEntity.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 病历摘要表 实体类 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@TableName("t_caseplatform_case_abstract") +public class MedicalRecordAbstracEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 关联病历表 + */ + private Long caseId; + + /** + * 病历摘要 文字 + */ + private String abstractStr; + + /** + * 病历摘要 图片 + */ + private String abstractImg; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 修改时间 + */ + private LocalDateTime updateTime; + + public MedicalRecordAbstracEntity(Long caseId, String abstractStr, String abstractImg, LocalDateTime createTime) { + this.caseId = caseId; + this.abstractStr = abstractStr; + this.abstractImg = abstractImg; + this.createTime = createTime; + } +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordAddForm.java new file mode 100644 index 0000000..7fd8736 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordAddForm.java @@ -0,0 +1,226 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; +import net.lab1024.sa.common.common.domain.PageParam; +import net.lab1024.sa.common.common.enumeration.GenderEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.Range; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 前端提交病历 from + */ +@Data +public class MedicalRecordAddForm { + + /*************************基本信息***************************/ + @ApiModelProperty(value = "患者姓名", required = true) + @NotNull(message = "患者姓名 不能为空") + @Length(min = 1, max = 20, message = "患者姓名 的长度为在1-20") + private String name; + + @ApiModelProperty(value = "患者id", required = true) + @NotNull(message = "患者id 不能为空") + @Length(min = 1, max = 100, message = "患者id 的长度为在1-100") + private String uid; + + @ApiModelPropertyEnum(GenderEnum.class) + @CheckEnum(value = GenderEnum.class, message = "性别错误") + private Integer sex; + + @ApiModelProperty(value = "年龄", required = true) + @NotNull(message = "年龄 不能为空") + @Range(min = 1, max = 120, message = "年龄输入有误") + private Integer age; + + @ApiModelProperty(value = "入院时间", required = true) + @NotNull(message = "入院时间 不能为空") + private LocalDateTime admissionTime; + + @ApiModelPropertyEnum(value = CasetypeEnum.class, desc = "病历类型") + @CheckEnum(value = CasetypeEnum.class, message = "病历类型 错误", required = true) + private Integer caseType; + + @ApiModelProperty(value = "基本信息图片", required = true) + @NotNull(message = "基本信息图片 不能为空") + @Length(min = 1, max = 1000, message = "基本信息图片 不能为空") + private String baseImg; + + /*************************临床资料 病历摘要***************************/ + @ApiModelProperty(value = "临床资料 病历摘要 文字", required = true) + private String abstractStr; + + @ApiModelProperty(value = "临床资料 病历摘要 图片", required = true) + private String abstractImg; + + + /*************************DPMAS***************************/ + @ApiModelProperty(value = "DPMAS", required = true) + @NotNull(message = "DPMAS 不能为空") + @Valid + private List dpmas; + + + /*************************实验室数据***************************/ + @ApiModelProperty(value = "治疗前 检测时间", required = true) + @NotNull(message = "治疗前 检测时间 不能为空") + private LocalDateTime headTime; + + /** + * 治疗后 检测时间 + */ + @ApiModelProperty(value = "治疗后 检测时间 ", required = true) + @NotNull(message = "治疗后 检测时间 不能为空") + private LocalDateTime afterTime; + + /** + * 治疗前 总胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗前 总胆红素", required = true) + @NotNull(message = "治疗前 总胆红素 不能为空") + @Length(min = 1, max = 10, message = "治疗前 总胆红素 输入不合法") + private String headTb; + + /** + * 治疗后 总胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗后 总胆红素 ", required = true) + @NotNull(message = "治疗后 总胆红素 不能为空") + @Length(min = 1, max = 10, message = "治疗后 总胆红素 输入不合法") + private String afterTb; + + /** + * 治疗前 白蛋白(g/L) + */ + @ApiModelProperty(value = "治疗前 白蛋白", required = true) + private String headAlb; + + /** + * 治疗后 白蛋白(g/L) + */ + @ApiModelProperty(value = "治疗后 白蛋白 ", required = true) + private String afterAlb; + + /** + * 治疗前 直接胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗前 直接胆红素", required = true) + private String headDb; + + /** + * 治疗后 直接胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗后 直接胆红素 ", required = true) + private String afterDb; + + /** + * 治疗前 凝血酶原活动度 (%) + */ + @ApiModelProperty(value = "治疗前 凝血酶原活动度", required = true) + private String headPta; + + /** + * 治疗后 凝血酶原活动度 (%) + */ + @ApiModelProperty(value = "治疗后 凝血酶原活动度 ", required = true) + private String afterPta; + + /** + * 治疗前 间接胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗前 间接胆红素", required = true) + private String headIb; + + /** + * 治疗后 间接胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗后 间接胆红素 ", required = true) + private String afterIb; + + /** + * 治疗前 国际标准化比值 (INR) + */ + @ApiModelProperty(value = "治疗前 国际标准化比值", required = true) + @NotNull(message = "治疗前 国际标准化比值 不能为空") + @Length(min = 1, max = 10, message = "治疗前 国际标准化比值 输入不合法") + private String headInr; + + /** + * 治疗后 国际标准化比值 (INR) + */ + @ApiModelProperty(value = "治疗后 国际标准化比值 ", required = true) + @NotNull(message = "治疗后 国际标准化比值 不能为空") + @Length(min = 1, max = 10, message = "治疗后 国际标准化比值 输入不合法") + private String afterInr; + + /** + * 治疗前 谷丙转氨 (U/L) + */ + @ApiModelProperty(value = "治疗前 谷丙转氨", required = true) + @NotNull(message = "治疗前 谷丙转氨 不能为空") + @Length(min = 1, max = 10, message = "治疗前 谷丙转氨 输入不合法") + private String headAlt; + + /** + * 治疗后 谷丙转氨 (U/L) + */ + @ApiModelProperty(value = "治疗后 谷丙转氨 ", required = true) + @NotNull(message = "治疗后 谷丙转氨 不能为空") + @Length(min = 1, max = 10, message = "治疗后 谷丙转氨 输入不合法") + private String afterAlt; + + /** + * 治疗前 白介素6(ng/L) + */ + @ApiModelProperty(value = "治疗前 白介素6", required = true) + private String headIl6; + + /** + * 治疗后 白介素6(ng/L) + */ + @ApiModelProperty(value = "治疗后 白介素6 ", required = true) + private String afterIl6; + + /** + * 治疗前 谷草转氨酶 (U/L) + */ + @ApiModelProperty(value = "治疗前 谷草转氨酶", required = true) + @NotNull(message = "治疗前 谷草转氨酶 不能为空") + @Length(min = 1, max = 10, message = "治疗前 谷草转氨酶 输入不合法") + private String headAst; + + /** + * 治疗后 谷草转氨酶 (U/L) + */ + @ApiModelProperty(value = "治疗后 谷草转氨酶 ", required = true) + @NotNull(message = "治疗后 谷草转氨酶 不能为空") + @Length(min = 1, max = 10, message = "治疗后 谷草转氨酶 输入不合法") + private String afterAst; + + /** + * 治疗前 肿瘤坏死因子α(μg/L) + */ + @ApiModelProperty(value = "治疗前 肿瘤坏死因子α", required = true) + private String headTnf; + + /** + * 治疗后 肿瘤坏死因子α(μg/L) + */ + @ApiModelProperty(value = "治疗后 肿瘤坏死因子α ", required = true) + private String afterTnf; + + @ApiModelProperty(value = "实验室检测 图片 图片", required = true) + @NotNull(message = "实验室检测 图片 不能为空") + @Length(min = 1, max = 1000, message = "实验室检测 图片 不能为空") + private String checkImg; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordCheckdataEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordCheckdataEntity.java new file mode 100644 index 0000000..8dbdd8f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordCheckdataEntity.java @@ -0,0 +1,155 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; + +import lombok.Builder; +import lombok.Data; + +/** + * 实验室检测 实体类 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@TableName("t_caseplatform_case_checkdata") +@Builder +public class MedicalRecordCheckdataEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 关联病历 + */ + private Long caseId; + + /** + * 治疗前 检测时间 + */ + private LocalDateTime headTime; + + /** + * 治疗后 检测时间 + */ + private LocalDateTime afterTime; + + /** + * 治疗前 总胆红素(umol/L) + */ + private String headTb; + + /** + * 治疗后 总胆红素(umol/L) + */ + private String afterTb; + + /** + * 治疗前 白蛋白(g/L) + */ + private String headAlb; + + /** + * 治疗后 白蛋白(g/L) + */ + private String afterAlb; + + /** + * 治疗前 直接胆红素(umol/L) + */ + private String headDb; + + /** + * 治疗后 直接胆红素(umol/L) + */ + private String afterDb; + + /** + * 治疗前 凝血酶原活动度 (%) + */ + private String headPta; + + /** + * 治疗后 凝血酶原活动度 (%) + */ + private String afterPta; + + /** + * 治疗前 间接胆红素(umol/L) + */ + private String headIb; + + /** + * 治疗后 间接胆红素(umol/L) + */ + private String afterIb; + + /** + * 治疗前 国际标准化比值 (INR) + */ + private String headInr; + + /** + * 治疗后 国际标准化比值 (INR) + */ + private String afterInr; + + /** + * 治疗前 谷丙转氨 (U/L) + */ + private String headAlt; + + /** + * 治疗后 谷丙转氨 (U/L) + */ + private String afterAlt; + + /** + * 治疗前 白介素6(ng/L) + */ + private String headIl6; + + /** + * 治疗后 白介素6(ng/L) + */ + private String afterIl6; + + /** + * 治疗前 谷草转氨酶 (U/L) + */ + private String headAst; + + /** + * 治疗后 谷草转氨酶 (U/L) + */ + private String afterAst; + + /** + * 治疗前 肿瘤坏死因子α(μg/L) + */ + private String headTnf; + + /** + * 治疗后 肿瘤坏死因子α(μg/L) + */ + private String afterTnf; + + /** + * 图片 + */ + private String checkImg; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDTO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDTO.java new file mode 100644 index 0000000..74f633c --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDTO.java @@ -0,0 +1,16 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class MedicalRecordDTO { + + @ApiModelProperty(value = "入院时间", required = true) + private LocalDateTime admissionTime; + + @ApiModelProperty(value = "入院时间", required = true) + private Long id; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDetailVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDetailVO.java new file mode 100644 index 0000000..36ef7b6 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDetailVO.java @@ -0,0 +1,211 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; +import net.lab1024.sa.common.common.enumeration.GenderEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 前端病历 详情 + */ +@Data +public class MedicalRecordDetailVO { + + /*************************基本信息***************************/ + @ApiModelProperty(value = "患者姓名", required = true) + @NotNull(message = "患者姓名 不能为空") + private String name; + + @ApiModelProperty(value = "患者id", required = true) + @NotNull(message = "患者id 不能为空") + private String uid; + + @ApiModelPropertyEnum(GenderEnum.class) + @CheckEnum(value = GenderEnum.class, message = "性别错误") + private Integer sex; + + @ApiModelProperty(value = "年龄", required = true) + @NotNull(message = "年龄 不能为空") + private Integer age; + + @ApiModelProperty(value = "入院时间", required = true) + @NotNull(message = "入院时间 不能为空") + private LocalDateTime admissionTime; + + @ApiModelPropertyEnum(value = CasetypeEnum.class, desc = "病历类型") + @CheckEnum(value = CasetypeEnum.class, message = "病历类型 错误", required = true) + private Integer caseType; + + @ApiModelProperty(value = "基本信息图片", required = true) + @NotNull(message = "基本信息图片 不能为空") + private String baseImg; + + @ApiModelProperty(value = "病例状态", required = true) + private Integer status; + + /*************************临床资料 病历摘要***************************/ + @ApiModelProperty(value = "临床资料 病历摘要 文字", required = true) + @NotNull(message = "临床资料 病历摘要 文字 不能为空") + private String abstractStr; + + @ApiModelProperty(value = "临床资料 病历摘要 图片", required = true) + @NotNull(message = "临床资料 病历摘要 图片 不能为空") + private String abstractImg; + + + /*************************DPMAS***************************/ + @ApiModelProperty(value = "临床资料 病历摘要 图片", required = true) + @NotNull(message = "临床资料 病历摘要 图片 不能为空") + private List dpmas; + + + /*************************实验室数据***************************/ + @ApiModelProperty(value = "治疗前 检测时间", required = true) + @NotNull(message = "治疗前 检测时间 不能为空") + private LocalDateTime headTime; + + /** + * 治疗后 检测时间 + */ + @ApiModelProperty(value = "治疗后 检测时间 ", required = true) + @NotNull(message = "治疗后 检测时间 不能为空") + private LocalDateTime afterTime; + + /** + * 治疗前 总胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗前 总胆红素", required = true) + @NotNull(message = "治疗前 总胆红素 不能为空") + private String headTb; + + /** + * 治疗后 总胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗后 总胆红素 ", required = true) + @NotNull(message = "治疗后 总胆红素 不能为空") + private String afterTb; + + /** + * 治疗前 白蛋白(g/L) + */ + @ApiModelProperty(value = "治疗前 白蛋白", required = true) + private String headAlb; + + /** + * 治疗后 白蛋白(g/L) + */ + @ApiModelProperty(value = "治疗后 白蛋白 ", required = true) + private String afterAlb; + + /** + * 治疗前 直接胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗前 直接胆红素", required = true) + private String headDb; + + /** + * 治疗后 直接胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗后 直接胆红素 ", required = true) + private String afterDb; + + /** + * 治疗前 凝血酶原活动度 (%) + */ + @ApiModelProperty(value = "治疗前 凝血酶原活动度", required = true) + private String headPta; + + /** + * 治疗后 凝血酶原活动度 (%) + */ + @ApiModelProperty(value = "治疗后 凝血酶原活动度 ", required = true) + private String afterPta; + + /** + * 治疗前 间接胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗前 间接胆红素", required = true) + private String headIb; + + /** + * 治疗后 间接胆红素(umol/L) + */ + @ApiModelProperty(value = "治疗后 间接胆红素 ", required = true) + private String afterIb; + + /** + * 治疗前 国际标准化比值 (INR) + */ + @ApiModelProperty(value = "治疗前 国际标准化比值", required = true) + @NotNull(message = "治疗前 国际标准化比值 不能为空") + private String headInr; + + /** + * 治疗后 国际标准化比值 (INR) + */ + @ApiModelProperty(value = "治疗后 国际标准化比值 ", required = true) + @NotNull(message = "治疗后 国际标准化比值 不能为空") + private String afterInr; + + /** + * 治疗前 谷丙转氨 (U/L) + */ + @ApiModelProperty(value = "治疗前 谷丙转氨", required = true) + @NotNull(message = "治疗前 谷丙转氨 不能为空") + private String headAlt; + + /** + * 治疗后 谷丙转氨 (U/L) + */ + @ApiModelProperty(value = "治疗后 谷丙转氨 ", required = true) + @NotNull(message = "治疗后 谷丙转氨 不能为空") + private String afterAlt; + + /** + * 治疗前 白介素6(ng/L) + */ + @ApiModelProperty(value = "治疗前 白介素6", required = true) + private String headIl6; + + /** + * 治疗后 白介素6(ng/L) + */ + @ApiModelProperty(value = "治疗后 白介素6 ", required = true) + private String afterIl6; + + /** + * 治疗前 谷草转氨酶 (U/L) + */ + @ApiModelProperty(value = "治疗前 谷草转氨酶", required = true) + @NotNull(message = "治疗前 谷草转氨酶 不能为空") + private String headAst; + + /** + * 治疗后 谷草转氨酶 (U/L) + */ + @ApiModelProperty(value = "治疗后 谷草转氨酶 ", required = true) + @NotNull(message = "治疗后 谷草转氨酶 不能为空") + private String afterAst; + + /** + * 治疗前 肿瘤坏死因子α(μg/L) + */ + @ApiModelProperty(value = "治疗前 肿瘤坏死因子α", required = true) + private String headTnf; + + /** + * 治疗后 肿瘤坏死因子α(μg/L) + */ + @ApiModelProperty(value = "治疗后 肿瘤坏死因子α ", required = true) + private String afterTnf; + + @ApiModelProperty(value = "实验室检测 病历摘要 图片", required = true) + @NotNull(message = "实验室检测 图片 不能为空") + private String checkImg; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDpmsEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDpmsEntity.java new file mode 100644 index 0000000..d1c1c22 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordDpmsEntity.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 病历摘要表 实体类 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@TableName("t_caseplatform_case_dpms") +public class MedicalRecordDpmsEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 关联病历表 + */ + private Long caseId; + + /** + * 治疗时间 + */ + private LocalDateTime treatTime; + + /** + * 图片 + */ + private String dpmasImg; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordEntity.java new file mode 100644 index 0000000..40bde3f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordEntity.java @@ -0,0 +1,103 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 病历表 实体类 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@TableName("t_caseplatform_case") +public class MedicalRecordEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 关联用户表 + */ + private Long userId; + + /** + * 图片 + */ + private String baseImg; + + /** + * 入院时间 + */ + private LocalDateTime admissionTime; + + /** + * 病历类型 + */ + private Integer caseType; + + /** + * 统计 天 + */ + private Integer statisticsDay; + + /** + * 统计 月 + */ + private Integer statisticsMonth; + + /** + * 统计 季度 + */ + private Integer statisticsQuarter; + + /** + * 统计 年 + */ + private Integer statisticsYear; + + /** + * 专家 id + */ + private Long expertId; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + + private Integer status; + /** + * 修改时间 + */ + private LocalDateTime updateTime; + + public MedicalRecordEntity(Long userId, String baseImg, LocalDateTime admissionTime, Integer caseType, Long expertId, LocalDateTime createTime) { + this.userId = userId; + this.admissionTime = admissionTime; + this.caseType = caseType; + this.baseImg = baseImg; + this.expertId = expertId; + this.createTime = createTime; + } + + public MedicalRecordEntity(Long id, Long userId, String baseImg, LocalDateTime admissionTime, Integer caseType, Long expertId, Integer status, LocalDateTime updateTime) { + this.id = id; + this.userId = userId; + this.admissionTime = admissionTime; + this.caseType = caseType; + this.baseImg = baseImg; + this.expertId = expertId; + this.status = status; + this.updateTime = updateTime; + } +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordListVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordListVO.java new file mode 100644 index 0000000..45226e6 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordListVO.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +import java.time.LocalDateTime; + +/** + * 病历表 列表VO + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class MedicalRecordListVO { + + private Long id; + + @ApiModelProperty(value = "用户关联id") + private Long userId; + + @ApiModelProperty(value = "用户姓名") + private String userName; + + @ApiModelProperty(value = "用户id") + private String uid; + + @ApiModelProperty(value = "不通过原因") + private String reason; + + @ApiModelProperty(value = "用户性别") + private Integer sex; + + @ApiModelPropertyEnum(value = CaseStatusEnum.class, desc = "状态") + private Integer status; + + @ApiModelProperty(value = "创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordQueryForm.java new file mode 100644 index 0000000..f4e6d10 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordQueryForm.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; +import net.lab1024.sa.common.common.domain.PageParam; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; + +/** + * 前端请求列表的 from + */ +@Data +public class MedicalRecordQueryForm extends PageParam { + + @ApiModelProperty(value = "name") + private String name; + + @ApiModelPropertyEnum(value = CasetypeEnum.class, desc = "病历类型") + @CheckEnum(value = CasetypeEnum.class, message = "病历类型 错误") + private Integer caseType; + + @ApiModelPropertyEnum(value = CaseStatusEnum.class, desc = "病例状态(0待审核 1审核通过 2审核不通过)") + @CheckEnum(value = CaseStatusEnum.class, message = "病例状态 错误") + private Integer status; + + @ApiModelProperty(hidden = true) + private Long expertId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordUpdateForm.java new file mode 100644 index 0000000..2be4415 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordUpdateForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; +import net.lab1024.sa.common.common.enumeration.GenderEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 前端提交病历 from + */ +@Data +public class MedicalRecordUpdateForm extends MedicalRecordAddForm{ + + @ApiModelProperty(value = "病例ID", required = true) + @NotNull(message = "病例ID 不能为空") + private Long id; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordUserEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordUserEntity.java new file mode 100644 index 0000000..dc368e8 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/domain/MedicalRecordUserEntity.java @@ -0,0 +1,72 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 用户表 实体类 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@TableName("t_caseplatform_user") +public class MedicalRecordUserEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 关联医生id + */ + private Long expertId; + + /** + * 患者姓名 + */ + private String name; + + /** + * 患者id + */ + private String uid; + + + + /** + * 性别 + */ + private Integer sex; + + /** + * 年龄 + */ + private Integer age; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 修改时间 + */ + private LocalDateTime updateTime; + + public MedicalRecordUserEntity(Long expertId, String name, String uid, Integer sex, Integer age, LocalDateTime createTime) { + this.expertId = expertId; + this.name = name; + this.uid = uid; + this.sex = sex; + this.age = age; + this.createTime = createTime; + } +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/service/MedicalRecordService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/service/MedicalRecordService.java new file mode 100644 index 0000000..e2b16a5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/app/medicalrecord/service/MedicalRecordService.java @@ -0,0 +1,680 @@ +package net.lab1024.sa.admin.module.app.medicalrecord.service; + +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertSignVO; +import net.lab1024.sa.admin.module.app.expert.service.ExpertSignService; +import net.lab1024.sa.admin.module.app.medicalrecord.dao.MedicalRecorAbstracDao; +import net.lab1024.sa.admin.module.app.medicalrecord.dao.MedicalRecorCheckDataDao; +import net.lab1024.sa.admin.module.app.medicalrecord.dao.MedicalRecorDao; +import net.lab1024.sa.admin.module.app.medicalrecord.dao.MedicalRecorDpmasDao; +import net.lab1024.sa.admin.module.app.medicalrecord.dao.MedicalRecorUserDao; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.*; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.config.ConfigKeyEnum; +import net.lab1024.sa.common.module.support.config.ConfigService; +import net.lab1024.sa.common.module.support.config.domain.ConfigVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.List; + +import static net.lab1024.sa.common.common.code.UserErrorCode.NO_PERMISSION_EDIT; +import static net.lab1024.sa.common.common.code.UserErrorCode.PROJECT_CLOSE; + +@Service +public class MedicalRecordService { + + @Autowired + private MedicalRecorDao medicalRecorDao; + + @Autowired + private MedicalRecorUserDao medicalRecorUserDao; + + @Autowired + private MedicalRecorAbstracDao medicalRecorAbstracDao; + + @Autowired + private MedicalRecorDpmasDao medicalRecorDpmasDao; + + @Autowired + private MedicalRecorCheckDataDao medicalRecorCheckDataDao; + + @Autowired + private ConfigService configService; + + @Autowired + private ExpertSignService expertSignService; + + public PageResult getList(MedicalRecordQueryForm queryForm){ + Page page = SmartPageUtil.convert2PageQuery(queryForm); + Long expertId = SmartRequestUtil.getRequestUserId(); + queryForm.setExpertId(expertId); + List list = medicalRecorDao.getList(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return pageResult; + } + + public MedicalRecordDetailVO getDetail(Long MedicalRecordId){ + MedicalRecordDetailVO detail = medicalRecorDao.getDetail(MedicalRecordId); + List dpmas = medicalRecorDpmasDao.getByCaseId(MedicalRecordId); + detail.setDpmas(dpmas); + return detail; + } + + @Transactional + public ResponseDTO add(MedicalRecordAddForm addForm){ + + + ConfigVO caseNum = configService.getConfig(ConfigKeyEnum.CaseNum); + int total = medicalRecorDao.getTotal(); + if(Integer.parseInt(caseNum.getConfigValue()) <= total){ + return ResponseDTO.error(PROJECT_CLOSE); + } + + Long expertId = SmartRequestUtil.getRequestUserId(); + + ExpertSignVO expertSign = expertSignService.getExpertSign(); + if(expertSign == null){ + return ResponseDTO.userErrorParam("请先签署项目协议!"); + } + /*************************前置 检查*****************************/ + + ResponseDTO check = check(SmartBeanUtil.copy(addForm, MedicalRecordUpdateForm.class), expertId); + + if(!check.getOk()){ + return check; + } + + //病历类型 + Integer caseType = addForm.getCaseType(); + List dpmas = addForm.getDpmas(); + //入院时间 + LocalDateTime admissionTime = addForm.getAdmissionTime(); + + //患者id + String uid = addForm.getUid(); + + //临床资料 病历摘要 文字 + String abstractStr = addForm.getAbstractStr(); + + //临床资料 病历摘要 图片 + String abstractImg = addForm.getAbstractImg(); + + + //治疗前 检测时间 + LocalDateTime headTime = addForm.getHeadTime(); + + /** + * 治疗后 检测时间 + */ + LocalDateTime afterTime = addForm.getAfterTime(); + + + + + /*************************基本信息*****************************/ + //姓名 + String name = addForm.getName(); + + //性别 + Integer sex = addForm.getSex(); + + //年龄 + Integer age = addForm.getAge(); + + //基本信息图片 + String baseImg = addForm.getBaseImg(); + + MedicalRecordUserEntity user = new MedicalRecordUserEntity(expertId, name, uid, sex, age, LocalDateTime.now()); + medicalRecorUserDao.insert(user); + Long userId = user.getId(); + /*************************病例主体***************************/ + + MedicalRecordEntity medicalRecord = new MedicalRecordEntity(userId, baseImg, admissionTime, caseType, expertId, LocalDateTime.now()); + + DateTime nowDate = DateUtil.date(); + String statistics_date = DateUtil.format(nowDate, "yyyyMMdd"); + String statistics_month = DateUtil.format(nowDate, "yyyyMM"); + String statistics_year = DateUtil.format(nowDate, "yyyy"); + int quarter = DateUtil.quarter(nowDate); + String statistics_quarter = statistics_year + quarter; + + medicalRecord.setStatisticsDay(Integer.parseInt(statistics_date)); + medicalRecord.setStatisticsMonth(Integer.parseInt(statistics_month)); + medicalRecord.setStatisticsQuarter(Integer.parseInt(statistics_quarter)); + medicalRecord.setStatisticsYear(Integer.parseInt(statistics_year)); + medicalRecorDao.insert(medicalRecord); + Long medicalRecordId = medicalRecord.getId(); + + /*************************临床资料 病历摘要***************************/ + + + + MedicalRecordAbstracEntity abstracEntity = new MedicalRecordAbstracEntity(medicalRecordId, abstractStr, abstractImg, LocalDateTime.now()); + medicalRecorAbstracDao.insert(abstracEntity); + /*************************DPMAS***************************/ + //DPMAS + + for(DpmsAddForm item:dpmas){ + MedicalRecordDpmsEntity dp = new MedicalRecordDpmsEntity(); + dp.setDpmasImg(item.getDpmasImg()); + dp.setCaseId(medicalRecordId); + dp.setTreatTime(item.getTreatTime()); + medicalRecorDpmasDao.insert(dp); + } + /*************************实验室数据***************************/ + + /** + * 治疗前 总胆红素(umol/L) + */ + String headTb = addForm.getHeadTb(); + + /** + * 治疗后 总胆红素(umol/L) + */ + String afterTb = addForm.getAfterTb(); + + /** + * 治疗前 白蛋白(g/L) + */ + String headAlb = addForm.getHeadAlb(); + + /** + * 治疗后 白蛋白(g/L) + */ + String afterAlb = addForm.getAfterAlb(); + + /** + * 治疗前 直接胆红素(umol/L) + */ + String headDb = addForm.getHeadDb(); + + /** + * 治疗后 直接胆红素(umol/L) + */ + String afterDb = addForm.getAfterDb(); + + /** + * 治疗前 凝血酶原活动度 (%) + */ + String headPta = addForm.getHeadPta(); + + /** + * 治疗后 凝血酶原活动度 (%) + */ + String afterPta = addForm.getAfterPta(); + + /** + * 治疗前 间接胆红素(umol/L) + */ + String headIb = addForm.getHeadIb(); + + /** + * 治疗后 间接胆红素(umol/L) + */ + String afterIb = addForm.getAfterIb(); + + /** + * 治疗前 国际标准化比值 (INR) + */ + String headInr = addForm.getHeadInr(); + + /** + * 治疗后 国际标准化比值 (INR) + */ + String afterInr = addForm.getAfterInr(); + + /** + * 治疗前 谷丙转氨 (U/L) + */ + String headAlt = addForm.getHeadAlt(); + + /** + * 治疗后 谷丙转氨 (U/L) + */ + String afterAlt = addForm.getAfterAlt(); + + /** + * 治疗前 白介素6(ng/L) + */ + String headIl6 = addForm.getHeadIl6(); + + /** + * 治疗后 白介素6(ng/L) + */ + String afterIl6 = addForm.getAfterIl6(); + + /** + * 治疗前 谷草转氨酶 (U/L) + */ + String headAst = addForm.getHeadAst(); + + /** + * 治疗后 谷草转氨酶 (U/L) + */ + String afterAst = addForm.getAfterAst(); + + /** + * 治疗前 肿瘤坏死因子α(μg/L) + */ + String headTnf = addForm.getHeadTnf(); + + /** + * 治疗后 肿瘤坏死因子α(μg/L) + */ + String afterTnf = addForm.getAfterTnf(); + + //实验室检测 病历摘要 图片 + String checkImg = addForm.getCheckImg(); + + MedicalRecordCheckdataEntity CheckdataEntity = MedicalRecordCheckdataEntity.builder() + .afterAlb(afterAlb) + .afterAlt(afterAlt) + .afterAst(afterAst) + .afterDb(afterDb) + .afterIb(afterIb) + .afterIl6(afterIl6) + .afterInr(afterInr) + .afterPta(afterPta) + .afterTb(afterTb) + .afterTime(afterTime) + .afterTnf(afterTnf) + .headAst(headAst) + .headDb(headDb) + .headIb(headIb) + .headIl6(headIl6) + .headAlb(headAlb) + .headAlt(headAlt) + .headInr(headInr) + .headPta(headPta) + .headTb(headTb) + .headTime(headTime) + .headTnf(headTnf) + .headAlt(headAlt) + .headAlt(headAlt) + .checkImg(checkImg) + .createTime(LocalDateTime.now()) + .caseId(medicalRecordId) + .build(); + + medicalRecorCheckDataDao.insert(CheckdataEntity); + return ResponseDTO.app_ok(); + } + + @Transactional + public ResponseDTO update(MedicalRecordUpdateForm updateForm){ + Long expertId = SmartRequestUtil.getRequestUserId(); + Long medicalRecordId = updateForm.getId(); + MedicalRecordListVO recorDaoById = medicalRecorDao.getById(medicalRecordId); + if(recorDaoById == null){ + return ResponseDTO.userErrorParam(); + } + /*************************前置 检查*****************************/ + + Integer status = recorDaoById.getStatus(); + + if(!status.equals(CaseStatusEnum.REFUSE.getValue())){ + return ResponseDTO.error(NO_PERMISSION_EDIT); + } + ResponseDTO check = check(updateForm, expertId); + + if(!check.getOk()){ + return check; + } + + //病历类型 + Integer caseType = updateForm.getCaseType(); + List dpmas = updateForm.getDpmas(); + //入院时间 + LocalDateTime admissionTime = updateForm.getAdmissionTime(); + + //临床资料 病历摘要 文字 + String abstractStr = updateForm.getAbstractStr(); + + //临床资料 病历摘要 图片 + String abstractImg = updateForm.getAbstractImg(); + + + //治疗前 检测时间 + LocalDateTime headTime = updateForm.getHeadTime(); + + /** + * 治疗后 检测时间 + */ + LocalDateTime afterTime = updateForm.getAfterTime(); + + /*************************基本信息*****************************/ + //姓名 + String name = updateForm.getName(); + + //性别 + Integer sex = updateForm.getSex(); + + //年龄 + Integer age = updateForm.getAge(); + + //基本信息图片 + String baseImg = updateForm.getBaseImg(); + + //患者id + String uid = updateForm.getUid(); + + Long userId = recorDaoById.getUserId(); + MedicalRecordUserEntity user = new MedicalRecordUserEntity(expertId, name, uid, sex, age, LocalDateTime.now()); + user.setId(userId); + medicalRecorUserDao.updateById(user); + /*************************病例主体***************************/ + + MedicalRecordEntity medicalRecord = new MedicalRecordEntity(medicalRecordId, userId, baseImg, admissionTime, caseType, expertId, CaseStatusEnum.WAIT.getValue(), LocalDateTime.now()); + medicalRecorDao.updateById(medicalRecord); + /*************************临床资料 病历摘要***************************/ + + medicalRecorAbstracDao.deleteByCaseId(medicalRecordId); + MedicalRecordAbstracEntity abstracEntity = new MedicalRecordAbstracEntity(medicalRecordId, abstractStr, abstractImg, LocalDateTime.now()); + medicalRecorAbstracDao.insert(abstracEntity); + /*************************DPMAS***************************/ + //DPMAS + medicalRecorDpmasDao.deleteByCaseId(medicalRecordId); + for(DpmsAddForm item:dpmas){ + MedicalRecordDpmsEntity dp = new MedicalRecordDpmsEntity(); + dp.setDpmasImg(item.getDpmasImg()); + dp.setCaseId(medicalRecordId); + dp.setTreatTime(item.getTreatTime()); + medicalRecorDpmasDao.insert(dp); + } + /*************************实验室数据***************************/ + + /** + * 治疗前 总胆红素(umol/L) + */ + String headTb = updateForm.getHeadTb(); + + /** + * 治疗后 总胆红素(umol/L) + */ + String afterTb = updateForm.getAfterTb(); + + /** + * 治疗前 白蛋白(g/L) + */ + String headAlb = updateForm.getHeadAlb(); + + /** + * 治疗后 白蛋白(g/L) + */ + String afterAlb = updateForm.getAfterAlb(); + + /** + * 治疗前 直接胆红素(umol/L) + */ + String headDb = updateForm.getHeadDb(); + + /** + * 治疗后 直接胆红素(umol/L) + */ + String afterDb = updateForm.getAfterDb(); + + /** + * 治疗前 凝血酶原活动度 (%) + */ + String headPta = updateForm.getHeadPta(); + + /** + * 治疗后 凝血酶原活动度 (%) + */ + String afterPta = updateForm.getAfterPta(); + + /** + * 治疗前 间接胆红素(umol/L) + */ + String headIb = updateForm.getHeadIb(); + + /** + * 治疗后 间接胆红素(umol/L) + */ + String afterIb = updateForm.getAfterIb(); + + /** + * 治疗前 国际标准化比值 (INR) + */ + String headInr = updateForm.getHeadInr(); + + /** + * 治疗后 国际标准化比值 (INR) + */ + String afterInr = updateForm.getAfterInr(); + + /** + * 治疗前 谷丙转氨 (U/L) + */ + String headAlt = updateForm.getHeadAlt(); + + /** + * 治疗后 谷丙转氨 (U/L) + */ + String afterAlt = updateForm.getAfterAlt(); + + /** + * 治疗前 白介素6(ng/L) + */ + String headIl6 = updateForm.getHeadIl6(); + + /** + * 治疗后 白介素6(ng/L) + */ + String afterIl6 = updateForm.getAfterIl6(); + + /** + * 治疗前 谷草转氨酶 (U/L) + */ + String headAst = updateForm.getHeadAst(); + + /** + * 治疗后 谷草转氨酶 (U/L) + */ + String afterAst = updateForm.getAfterAst(); + + /** + * 治疗前 肿瘤坏死因子α(μg/L) + */ + String headTnf = updateForm.getHeadTnf(); + + /** + * 治疗后 肿瘤坏死因子α(μg/L) + */ + String afterTnf = updateForm.getAfterTnf(); + + //实验室检测 病历摘要 图片 + String checkImg = updateForm.getCheckImg(); + + MedicalRecordCheckdataEntity CheckdataEntity = MedicalRecordCheckdataEntity.builder() + .afterAlb(afterAlb) + .afterAlt(afterAlt) + .afterAst(afterAst) + .afterDb(afterDb) + .afterIb(afterIb) + .afterIl6(afterIl6) + .afterInr(afterInr) + .afterPta(afterPta) + .afterTb(afterTb) + .afterTime(afterTime) + .afterTnf(afterTnf) + .headAst(headAst) + .headDb(headDb) + .headIb(headIb) + .headIl6(headIl6) + .headAlb(headAlb) + .headAlt(headAlt) + .headInr(headInr) + .headPta(headPta) + .headTb(headTb) + .headTime(headTime) + .headTnf(headTnf) + .headAlt(headAlt) + .headAlt(headAlt) + .checkImg(checkImg) + .createTime(LocalDateTime.now()) + .caseId(medicalRecordId) + .build(); + + medicalRecorCheckDataDao.deleteByCaseId(medicalRecordId); + + medicalRecorCheckDataDao.insert(CheckdataEntity); + return ResponseDTO.app_ok(); + } + + public ResponseDTO check(MedicalRecordUpdateForm form, Long expertId){ + + ConfigVO caseSwitch = configService.getConfig(ConfigKeyEnum.CaseSwitch); + if(caseSwitch.getConfigValue().equals("false")){ + return ResponseDTO.error(PROJECT_CLOSE); + } + /*************************前置 检查*****************************/ + + //入院时间 + LocalDateTime admissionTime = form.getAdmissionTime(); + //患者id + String uid = form.getUid(); + //获取全部病例 + List admissionTimeByUid = medicalRecorDao.getAdmissionTimeByUid(expertId, uid); + for(MedicalRecordDTO dto:admissionTimeByUid){ + if(dto.getId().equals(form.getId())){ + continue; + } + long daysDiff = Duration.between(dto.getAdmissionTime(), admissionTime).toDays(); + if(Math.abs(daysDiff) < 30){ + return ResponseDTO.userErrorParam("同一患者记录入院时间必须间隔30天以上!"); + } + } + + String baseImg = form.getBaseImg(); + String[] baseImgNum = baseImg.split(","); + if(baseImgNum.length > 6){ + return ResponseDTO.userErrorParam("病案照片应为(1-6张)!"); + } + + //临床资料 病历摘要 文字 + String abstractStr = form.getAbstractStr(); + + //临床资料 病历摘要 图片 + String abstractImg = form.getAbstractImg(); + + if(StrUtil.isBlank(abstractStr+abstractImg)){ + return ResponseDTO.userErrorParam("临床资料 病历摘要或者病历图片至少上传一项"); + } + + String[] abstractImgNum = abstractImg.split(","); + if(abstractImgNum.length > 6){ + return ResponseDTO.userErrorParam("病历摘要图片照片应为(1-6张)!"); + } + //病历类型 + Integer caseType = form.getCaseType(); + List dpmas = form.getDpmas(); + + int size = dpmas.size(); + + if(caseType == CasetypeEnum.BEFORE.getValue()){ + if(size == 0){ + return ResponseDTO.userErrorParam("至少上传1次DPMAS数据!"); + } + } + if(caseType == CasetypeEnum.DEFAULT.getValue()){ + if(size < 4){ + return ResponseDTO.userErrorParam("至少上传4次DPMAS数据!"); + } + } + LocalDateTime firstTreatTime = dpmas.get(0).getTreatTime();//第一次治疗时间 + + //治疗时间 2024 + + int headYear = firstTreatTime.getYear(); + + if(headYear != 2024){ + return ResponseDTO.userErrorParam("治疗时间:限制在2024年1月1日-2024年12月31日!"); + } + + LocalDateTime lastTreatTime = dpmas.get(size-1).getTreatTime();//最后一次治疗时间 + + if(firstTreatTime.toLocalDate().compareTo(admissionTime.toLocalDate()) < 0){ + return ResponseDTO.userErrorParam("第1次治疗时间比患者基本信息入院时间后!"); + } + LocalDateTime temp = firstTreatTime; + for(int i=0;i 0){ + if(!treatTime.isAfter(temp)){ + return ResponseDTO.userErrorParam("第"+(i+1)+"次治疗时间必须在第"+i+"次治疗时间后!"); + } + } + + String dpmasImg = dpmas.get(i).getDpmasImg(); + String[] dpmasImgNum = dpmasImg.split(","); + if(dpmasImgNum.length > 3){ + return ResponseDTO.userErrorParam("第"+(i+1)+"次治疗照片应为(1-3张)!"); + } + temp = treatTime; + } + + int lastYear = lastTreatTime.getYear(); + if(lastYear != 2024){ + return ResponseDTO.userErrorParam("治疗时间:限制在2024年1月1日-2024年12月31日!"); + } + + //治疗前 检测时间 + LocalDateTime headTime = form.getHeadTime(); + + /** + * 治疗后 检测时间 + */ + LocalDateTime afterTime = form.getAfterTime(); + + if(!afterTime.isAfter(headTime)){ + return ResponseDTO.userErrorParam("治疗前检测时间:应该小于治疗后检测时间!"); + } + + if(caseType == CasetypeEnum.BEFORE.getValue()){ + if((headTime.toLocalDate().compareTo(admissionTime.toLocalDate())) < 0 || (headTime.toLocalDate().compareTo(firstTreatTime.toLocalDate())) > 0){ + return ResponseDTO.userErrorParam("治疗前检测时间:应该在入院时间与第1次治疗时间之间!"); + } + if(size == 1){ + if(afterTime.toLocalDate().compareTo(firstTreatTime.toLocalDate()) < 0){ + return ResponseDTO.userErrorParam("治疗后检测时间:应该在第1次治疗时间之后"); + } + } + //治疗后检测时间:应该在第一次治疗时间之后,如果有第二次治疗时间,在应该在第一次与第二次治疗时间之间 + if(size >= 2){ + LocalDateTime secondTreatTime = dpmas.get(1).getTreatTime();//第2次治疗时间 + if((afterTime.toLocalDate().compareTo(firstTreatTime.toLocalDate())) < 0 || (afterTime.compareTo(secondTreatTime)) > 0){ + return ResponseDTO.userErrorParam("治疗后检测时间:应该在第1次与第2次治疗时间之间"); + } + } + } + if(caseType == CasetypeEnum.DEFAULT.getValue()){ + if((headTime.toLocalDate().compareTo(admissionTime.toLocalDate())) < 0 || (headTime.toLocalDate().compareTo(firstTreatTime.toLocalDate())) > 0){ + return ResponseDTO.userErrorParam("治疗前检测时间:应该在入院时间与第1次治疗时间之间!"); + } + if(afterTime.toLocalDate().compareTo(lastTreatTime.toLocalDate()) < 0){ + return ResponseDTO.userErrorParam("治疗后检测时间:应该在最后1次治疗时间之后"); + } + } + + String checkImg = form.getCheckImg(); + String[] checkImgNum = checkImg.split(","); + if(checkImgNum.length > 6){ + return ResponseDTO.userErrorParam("实验室检测照片应为(1-6张)!"); + } + return ResponseDTO.app_ok(); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/controller/AreaController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/controller/AreaController.java new file mode 100644 index 0000000..5a578fa --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/controller/AreaController.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.admin.module.business.area.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.module.business.area.domain.form.AreaQueryForm; +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.admin.module.business.area.service.AreaService; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import java.util.List; + +/** + * 省市区 Controller + * + * @Author HMM + * @Date 2024-01-12 16:03:16 + * @Copyright gdxz + */ + +@RestController +@Api(tags = "") +public class AreaController { + + @Autowired + private AreaService areaService; + + @ApiOperation("分页查询 @author HMM") + @PostMapping("/area/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid AreaQueryForm queryForm) { + return ResponseDTO.ok(areaService.queryPage(queryForm)); + } + + @ApiOperation("获取省份 @author HMM") + @GetMapping("/area/provList") + public ResponseDTO> provList() { + return ResponseDTO.ok(areaService.provList()); + } + + @ApiOperation("获取市区 @author HMM") + @GetMapping("/area/cityList/{parent}") + public ResponseDTO> cityList(@PathVariable Long parent) { + return ResponseDTO.ok(areaService.cityList(parent)); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/dao/AreaDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/dao/AreaDao.java new file mode 100644 index 0000000..a9bfbf1 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/dao/AreaDao.java @@ -0,0 +1,51 @@ +package net.lab1024.sa.admin.module.business.area.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.area.domain.entity.AreaEntity; +import net.lab1024.sa.admin.module.business.area.domain.form.AreaQueryForm; +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 省市区 Dao + * + * @Author HMM + * @Date 2024-01-12 16:03:16 + * @Copyright gdxz + */ + +@Mapper +@Component +public interface AreaDao extends BaseMapper { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") AreaQueryForm queryForm); + + /** + * 获取省份列表 + * @return + */ + @Select("select * from t_area where parent is null") + List provList(); + + /** + * 获取城市列表 + * @return + */ + @Select("select * from t_area where parent = #{parent}") + List cityList(long parent); + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/entity/AreaEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/entity/AreaEntity.java new file mode 100644 index 0000000..0a18e77 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/entity/AreaEntity.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.admin.module.business.area.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 省市区 实体类 + * + * @Author HMM + * @Date 2024-01-12 16:03:16 + * @Copyright gdxz + */ + +@Data +@TableName("t_area") +public class AreaEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 创建时间 + */ + private LocalDateTime createDate; + + /** + * 更新时间 + */ + private LocalDateTime modifyDate; + + /** + * 排序 + */ + private Integer orders; + + /** + * 全名 + */ + private String fullName; + + /** + * 名称 + */ + private String name; + + /** + * 树路径 + */ + private String treePath; + + /** + * 父节点 + */ + private Long parent; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/form/AreaQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/form/AreaQueryForm.java new file mode 100644 index 0000000..f96ba96 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/form/AreaQueryForm.java @@ -0,0 +1,17 @@ +package net.lab1024.sa.admin.module.business.area.domain.form; + +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +/** + * 省市区 分页查询表单 + * + * @Author HMM + * @Date 2024-01-12 16:03:16 + * @Copyright gdxz + */ + +@Data +public class AreaQueryForm extends PageParam{ + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/vo/AreaVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/vo/AreaVO.java new file mode 100644 index 0000000..065c7be --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/vo/AreaVO.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.admin.module.business.area.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 省市区 列表VO + * + * @Author HMM + * @Date 2024-01-12 16:03:16 + * @Copyright gdxz + */ + +@Data +public class AreaVO { + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "创建时间") + private LocalDateTime createDate; + + @ApiModelProperty(value = "更新时间") + private LocalDateTime modifyDate; + + @ApiModelProperty(value = "排序") + private Integer orders; + + @ApiModelProperty(value = "全名") + private String fullName; + + @ApiModelProperty(value = "名称") + private String name; + + @ApiModelProperty(value = "树路径") + private String treePath; + + @ApiModelProperty(value = "父节点") + private Long parent; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/vo/ProvVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/vo/ProvVO.java new file mode 100644 index 0000000..0a4044c --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/domain/vo/ProvVO.java @@ -0,0 +1,14 @@ +package net.lab1024.sa.admin.module.business.area.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class ProvVO { + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "名称") + private String name; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/manager/AreaManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/manager/AreaManager.java new file mode 100644 index 0000000..73b7d99 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/manager/AreaManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.business.area.manager; + +import net.lab1024.sa.admin.module.business.area.domain.entity.AreaEntity; +import net.lab1024.sa.admin.module.business.area.dao.AreaDao; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * 省市区 Manager + * + * @Author HMM + * @Date 2024-01-12 16:03:16 + * @Copyright gdxz + */ +@Service +public class AreaManager extends ServiceImpl { + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/service/AreaService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/service/AreaService.java new file mode 100644 index 0000000..c8e8258 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/area/service/AreaService.java @@ -0,0 +1,57 @@ +package net.lab1024.sa.admin.module.business.area.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.area.dao.AreaDao; +import net.lab1024.sa.admin.module.business.area.domain.form.AreaQueryForm; +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 省市区 Service + * + * @Author HMM + * @Date 2024-01-12 16:03:16 + * @Copyright gdxz + */ + +@Service +public class AreaService { + + @Autowired + private AreaDao areaDao; + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public PageResult queryPage(AreaQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = areaDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return pageResult; + } + + public List provList() { + return areaDao.provList(); + } + + public List cityList(Long parent) { + return areaDao.cityList(parent); + } + + public List areaList(Long parent) { + if(parent == null){ + return areaDao.provList(); + } + return areaDao.cityList(parent); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/controller/CaseplatformBankController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/controller/CaseplatformBankController.java new file mode 100644 index 0000000..8d3dac3 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/controller/CaseplatformBankController.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.admin.module.business.bankcard.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.module.business.bankcard.domain.form.CaseplatformBankAddForm; +import net.lab1024.sa.admin.module.business.bankcard.domain.form.CaseplatformBankQueryForm; +import net.lab1024.sa.admin.module.business.bankcard.domain.vo.CaseplatformBankVO; +import net.lab1024.sa.admin.module.business.bankcard.service.CaseplatformBankService; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * 银行卡 Controller + * + * @Author HMM + * @Date 2024-02-27 13:20:37 + * @Copyright gdxz + */ + +@RestController +public class CaseplatformBankController { + + @Autowired + private CaseplatformBankService caseplatformBankService; + + @ApiOperation("分页查询 @author HMM") + @PostMapping("/caseplatformBank/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid CaseplatformBankQueryForm queryForm) { + return ResponseDTO.ok(caseplatformBankService.queryPage(queryForm)); + } + + @ApiOperation("添加 @author HMM") + @PostMapping("/caseplatformBank/add") + public ResponseDTO add(@RequestBody @Valid CaseplatformBankAddForm addForm) { + return caseplatformBankService.add(addForm); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/dao/CaseplatformBankDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/dao/CaseplatformBankDao.java new file mode 100644 index 0000000..9c0bdeb --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/dao/CaseplatformBankDao.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.admin.module.business.bankcard.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.bankcard.domain.entity.CaseplatformBankEntity; +import net.lab1024.sa.admin.module.business.bankcard.domain.form.CaseplatformBankQueryForm; +import net.lab1024.sa.admin.module.business.bankcard.domain.vo.CaseplatformBankVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 银行卡 Dao + * + * @Author HMM + * @Date 2024-02-27 13:20:37 + * @Copyright gdxz + */ + +@Mapper +@Component +public interface CaseplatformBankDao extends BaseMapper { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") CaseplatformBankQueryForm queryForm); + + /** + * 获取医生的银行卡信息 + * @param expertId + * @return + */ + @Select("select * from t_caseplatform_bank where expert_id=#{expertId} order by create_time desc limit 1") + CaseplatformBankVO getExpertBank(Long expertId); + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/entity/CaseplatformBankEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/entity/CaseplatformBankEntity.java new file mode 100644 index 0000000..ad3598d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/entity/CaseplatformBankEntity.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.admin.module.business.bankcard.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 银行卡 实体类 + * + * @Author HMM + * @Date 2024-02-27 13:20:37 + * @Copyright gdxz + */ + +@Data +@TableName("t_caseplatform_bank") +public class CaseplatformBankEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 专家id + */ + private Long expertId; + + /** + * 身份证 + */ + private String idCardNo; + + /** + * 银行卡 + */ + private String bankCardNo; + + /** + * 开户行 + */ + private String bankName; + + /** + * 省 + */ + private Integer provId; + + /** + * 市 + */ + private Integer cityId; + + /** + * 区 + */ + private Integer countyId; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/form/CaseplatformBankAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/form/CaseplatformBankAddForm.java new file mode 100644 index 0000000..0dadf4c --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/form/CaseplatformBankAddForm.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.admin.module.business.bankcard.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Data; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertSignAddForm; + +/** + * 银行卡 新建表单 + * + * @Author HMM + * @Date 2024-02-27 13:20:37 + * @Copyright gdxz + */ + +@Data +public class CaseplatformBankAddForm extends ExpertSignAddForm { + + @ApiModelProperty(value = "身份证", required = true) + @NotBlank(message = "身份证 不能为空") + private String idCardNo; + + @ApiModelProperty(value = "姓名", required = true) + @NotBlank(message = "姓名 不能为空") + private String name; + + @ApiModelProperty(value = "开户行", required = true) + @NotBlank(message = "开户行 不能为空") + private String bankName; + + @ApiModelProperty(value = "银行卡", required = true) + @NotBlank(message = "银行卡 不能为空") + private String bankCardNo; + + @ApiModelProperty(value = "省", required = true) + @NotNull(message = "省 不能为空") + private Integer provId; + + @ApiModelProperty(value = "市", required = true) + @NotNull(message = "市 不能为空") + private Integer cityId; + + @ApiModelProperty(value = "区", required = true) + @NotNull(message = "区 不能为空") + private Integer countyId; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/form/CaseplatformBankQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/form/CaseplatformBankQueryForm.java new file mode 100644 index 0000000..76a02de --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/form/CaseplatformBankQueryForm.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.admin.module.business.bankcard.domain.form; + +import net.lab1024.sa.common.common.domain.PageParam; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 银行卡 分页查询表单 + * + * @Author HMM + * @Date 2024-02-27 13:20:37 + * @Copyright gdxz + */ + +@Data +public class CaseplatformBankQueryForm extends PageParam{ + + @ApiModelProperty(value = "keywords") + private String keywords; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/vo/CaseplatformBankVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/vo/CaseplatformBankVO.java new file mode 100644 index 0000000..f565282 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/domain/vo/CaseplatformBankVO.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.admin.module.business.bankcard.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 银行卡 列表VO + * + * @Author HMM + * @Date 2024-02-27 13:20:37 + * @Copyright gdxz + */ + +@Data +public class CaseplatformBankVO { + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "专家id") + private Long expertId; + + @ApiModelProperty(value = "身份证") + private String idCardNo; + + @ApiModelProperty(value = "银行卡") + private String bankCardNo; + + @ApiModelProperty(value = "开户行") + private String bankName; + + @ApiModelProperty(value = "省") + private Integer provId; + + @ApiModelProperty(value = "市") + private Integer cityId; + + @ApiModelProperty(value = "区") + private Integer countyId; + + @ApiModelProperty(value = "创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/manager/CaseplatformBankManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/manager/CaseplatformBankManager.java new file mode 100644 index 0000000..ed17eb5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/manager/CaseplatformBankManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.business.bankcard.manager; + +import net.lab1024.sa.admin.module.business.bankcard.domain.entity.CaseplatformBankEntity; +import net.lab1024.sa.admin.module.business.bankcard.dao.CaseplatformBankDao; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * 银行卡 Manager + * + * @Author HMM + * @Date 2024-02-27 13:20:37 + * @Copyright gdxz + */ +@Service +public class CaseplatformBankManager extends ServiceImpl { + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/service/CaseplatformBankService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/service/CaseplatformBankService.java new file mode 100644 index 0000000..6c49328 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/bankcard/service/CaseplatformBankService.java @@ -0,0 +1,80 @@ +package net.lab1024.sa.admin.module.business.bankcard.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertSignVO; +import net.lab1024.sa.admin.module.app.expert.dao.ExpertSignDao; +import net.lab1024.sa.admin.module.business.bankcard.dao.CaseplatformBankDao; +import net.lab1024.sa.admin.module.business.bankcard.domain.entity.CaseplatformBankEntity; +import net.lab1024.sa.admin.module.business.bankcard.domain.form.CaseplatformBankAddForm; +import net.lab1024.sa.admin.module.business.bankcard.domain.form.CaseplatformBankQueryForm; +import net.lab1024.sa.admin.module.business.bankcard.domain.vo.CaseplatformBankVO; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 银行卡 Service + * + * @Author HMM + * @Date 2024-02-27 13:20:37 + * @Copyright gdxz + */ + +@Service +public class CaseplatformBankService { + + @Autowired + private CaseplatformBankDao caseplatformBankDao; + + @Autowired + private ExpertSignDao expertSignDao; + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public PageResult queryPage(CaseplatformBankQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = caseplatformBankDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return pageResult; + } + + /** + * 添加 + */ + @Transactional + public synchronized ResponseDTO add(CaseplatformBankAddForm addForm) { + CaseplatformBankEntity caseplatformBankEntity = SmartBeanUtil.copy(addForm, CaseplatformBankEntity.class); + Long expertId = SmartRequestUtil.getRequestUserId(); + caseplatformBankEntity.setExpertId(expertId); + + CaseplatformBankVO expertBank = caseplatformBankDao.getExpertBank(expertId); + if(expertBank == null){ + caseplatformBankDao.insert(caseplatformBankEntity); + }else{ + caseplatformBankEntity.setId(expertBank.getId()); + caseplatformBankDao.updateById(caseplatformBankEntity); + } + + + String signImg = addForm.getSignImg(); + ExpertSignVO expertSign = expertSignDao.getExpertSign(expertId); + if(expertSign == null){ + expertSignDao.addExpertSign(expertId, signImg); + return ResponseDTO.app_ok(); + }else{ + expertSignDao.updateById(expertSign.getId(), signImg); + } + return ResponseDTO.app_ok(); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/controller/CaptchaController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/controller/CaptchaController.java new file mode 100644 index 0000000..65c6daa --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/controller/CaptchaController.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.admin.module.business.captcha.controller; + +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.module.business.captcha.service.CaptchaService; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.captcha.domain.CaptchaVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; + +public class CaptchaController extends SupportBaseController { + + @Autowired + private CaptchaService captchaService; + + @ApiOperation("获取图形验证码 @author 胡克") + @GetMapping("/captcha") + public ResponseDTO generateCaptcha() { + return ResponseDTO.ok(captchaService.generateCaptcha()); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/dao/CaptchaDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/dao/CaptchaDao.java new file mode 100644 index 0000000..095aa39 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/dao/CaptchaDao.java @@ -0,0 +1,16 @@ +package net.lab1024.sa.admin.module.business.captcha.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.business.captcha.domain.entity.CaptchaEntity; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +@Component +@Mapper +public interface CaptchaDao extends BaseMapper { + + CaptchaEntity getByCaptchaKey(String captchaKey); + + int delByCaptchaKey(String captchaKey); + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/domain/entity/CaptchaEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/domain/entity/CaptchaEntity.java new file mode 100644 index 0000000..31ca903 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/domain/entity/CaptchaEntity.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.business.captcha.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; + +import java.time.LocalDateTime; + +@Data +@TableName("t_captcha") +public class CaptchaEntity { + @TableId(type = IdType.ASSIGN_UUID) + private String captchaUuid; + private String captchaKey; + private String captchaText; + private LocalDateTime exprireDate; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/domain/from/CaptchaAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/domain/from/CaptchaAddForm.java new file mode 100644 index 0000000..14037b4 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/domain/from/CaptchaAddForm.java @@ -0,0 +1,13 @@ +package net.lab1024.sa.admin.module.business.captcha.domain.from; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class CaptchaAddForm { + private String captchaUuid; + private String captchaKey; + private String captchaText; + private LocalDateTime exprireDate; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/service/CaptchaService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/service/CaptchaService.java new file mode 100644 index 0000000..7be986f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/captcha/service/CaptchaService.java @@ -0,0 +1,140 @@ +package net.lab1024.sa.admin.module.business.captcha.service; + +import cn.hutool.core.date.LocalDateTimeUtil; +import com.google.code.kaptcha.impl.DefaultKaptcha; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.captcha.dao.CaptchaDao; +import net.lab1024.sa.admin.module.business.captcha.domain.entity.CaptchaEntity; +import net.lab1024.sa.admin.module.business.captcha.domain.from.CaptchaAddForm; +import net.lab1024.sa.common.common.constant.StringConst; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.domain.SystemEnvironment; +import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum; +import net.lab1024.sa.common.common.exception.BusinessException; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.constant.RedisKeyConst; +import net.lab1024.sa.common.module.support.captcha.domain.CaptchaForm; +import net.lab1024.sa.common.module.support.captcha.domain.CaptchaVO; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.Base64Utils; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Objects; +import java.util.UUID; + +@Service +@Slf4j +public class CaptchaService { + + @Autowired + private CaptchaDao captchaDao; + + /** + * 过期时间:65秒 + */ + private static final long EXPIRE_SECOND = 65L; + + @Autowired + private DefaultKaptcha defaultKaptcha; + + @Autowired + private SystemEnvironment systemEnvironment; + + public ResponseDTO add(CaptchaAddForm addForm) { + CaptchaEntity captchaEntity = SmartBeanUtil.copy(addForm, CaptchaEntity.class); + captchaDao.insert(captchaEntity); + return ResponseDTO.ok(); + } + + /** + * 生成图形验证码 + * 默认 1 分钟有效期 + * + * @return + */ + public CaptchaVO generateCaptcha() { + String captchaText = defaultKaptcha.createText(); + BufferedImage image = defaultKaptcha.createImage(captchaText); + + String base64Code; + try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { + ImageIO.write(image, "jpg", os); + base64Code = Base64Utils.encodeToString(os.toByteArray()); + } catch (Exception e) { + log.error("generateCaptcha error:", e); + throw new BusinessException("生成验证码错误"); + } + + /** + * 返回验证码对象 + * 图片 base64格式 + */ + // uuid 唯一标识 + String uuid = UUID.randomUUID().toString().replace("-", StringConst.EMPTY); + + CaptchaVO captchaVO = new CaptchaVO(); + captchaVO.setCaptchaUuid(uuid); + captchaVO.setCaptchaBase64Image("data:image/png;base64," + base64Code); + captchaVO.setExpireSeconds(EXPIRE_SECOND); + //if (!systemEnvironment.isProd()) { + // captchaVO.setCaptchaText(captchaText); + //} + String redisCaptchaKey = generateRedisKey(RedisKeyConst.Support.CAPTCHA, uuid); + CaptchaEntity captchaEntity = new CaptchaEntity(); + captchaEntity.setCaptchaKey(redisCaptchaKey); + captchaEntity.setCaptchaText(captchaText); + captchaEntity.setExprireDate(LocalDateTimeUtil.offset(LocalDateTime.now(), EXPIRE_SECOND, ChronoUnit.SECONDS)); + captchaDao.insert(captchaEntity); + return captchaVO; + } + + /** + * 校验图形验证码 + * + * @param captchaForm + * @return + */ + public ResponseDTO checkCaptcha(CaptchaForm captchaForm) { + + if (systemEnvironment.getCurrentEnvironment().equals(SystemEnvironmentEnum.TEST)) { + return ResponseDTO.ok(); + } + + if (StringUtils.isBlank(captchaForm.getCaptchaUuid()) || StringUtils.isBlank(captchaForm.getCaptchaCode())) { + return ResponseDTO.userErrorParam("请输入正确验证码"); + } + /** + * 1、校验redis里的验证码 + * 2、校验成功后,删除redis + */ + String redisCaptchaKey = generateRedisKey(RedisKeyConst.Support.CAPTCHA, captchaForm.getCaptchaUuid()); + try { + CaptchaEntity byCaptchaKey = captchaDao.getByCaptchaKey(redisCaptchaKey); + if(byCaptchaKey == null){ + return ResponseDTO.userErrorParam("验证码错误,请输入正确的验证码"); + } + String redisCaptchaCode = byCaptchaKey.getCaptchaText(); + if (StringUtils.isBlank(redisCaptchaCode)) { + return ResponseDTO.userErrorParam("验证码已过期,请刷新重试"); + } + if (!Objects.equals(redisCaptchaCode, captchaForm.getCaptchaCode())) { + return ResponseDTO.userErrorParam("验证码错误,请输入正确的验证码"); + } + }finally { + // 删除已使用的验证码 + captchaDao.delByCaptchaKey(redisCaptchaKey); + } + return ResponseDTO.ok(); + } + + public String generateRedisKey(String prefix, String key) { + SystemEnvironmentEnum currentEnvironment = systemEnvironment.getCurrentEnvironment(); + return systemEnvironment.getProjectName() + RedisKeyConst.SEPARATOR + currentEnvironment.getValue() + RedisKeyConst.SEPARATOR + prefix + key; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CaseSettlementEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CaseSettlementEnum.java new file mode 100644 index 0000000..6510eb5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CaseSettlementEnum.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 病历结算状态 + * + * @Author HMM + * @Date 2024-01-11T15:18:32 + * @Copyright gdxz + */ + +@AllArgsConstructor +@Getter +public enum CaseSettlementEnum implements BaseEnum { + No(0, "未结算"), + Yes(1, "已结算"), + ; + + private final Integer value; + + private final String desc; + + public static CaseSettlementEnum getByVal(int val){ + for (CaseSettlementEnum type: CaseSettlementEnum.values()){ + if(type.getValue() == val){ + return type; + } + } + return null; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CaseStatusEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CaseStatusEnum.java new file mode 100644 index 0000000..6262e27 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CaseStatusEnum.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 0待审核 1审核通过 2审核不通过 + * + * @Author HMM + * @Date 2024-01-11T15:18:32 + * @Copyright gdxz + */ + +@AllArgsConstructor +@Getter +public enum CaseStatusEnum implements BaseEnum { + WAIT(0, "待审核"), + PASS(1, "审核通过"), + REFUSE(2, "审核拒绝"), + ; + + private final Integer value; + + private final String desc; + + public static CaseStatusEnum getByVal(int val){ + for (CaseStatusEnum type:CaseStatusEnum.values()){ + if(type.getValue() == val){ + return type; + } + } + return null; + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CasetypeEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CasetypeEnum.java new file mode 100644 index 0000000..2bdc990 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/constant/CasetypeEnum.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 病历类型 + * + * @Author HMM + * @Date 2024-01-11T15:18:32 + * @Copyright gdxz + */ + +@AllArgsConstructor +@Getter +public enum CasetypeEnum implements BaseEnum { + DEFAULT(1, "四次及以上疗程化"), + BEFORE(2, "早前期(INR≤1.5)"), + ; + + private final Integer value; + + private final String desc; + + public static CasetypeEnum getByVal(int val){ + for (CasetypeEnum type:CasetypeEnum.values()){ + if(type.getValue() == val){ + return type; + } + } + return null; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseController.java new file mode 100644 index 0000000..71a1f2f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseController.java @@ -0,0 +1,110 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.module.app.medicalrecord.domain.MedicalRecordDetailVO; +import net.lab1024.sa.admin.module.app.medicalrecord.service.MedicalRecordService; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CancelExamineForm; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CaseplatformCaseQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CaseplatformCaseUpdateForm; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.CaseplatformCaseDetailVO; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.CaseplatformCaseVO; +import net.lab1024.sa.admin.module.business.caseplatformcase.service.CaseplatformCaseService; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartEasyPoiExcelUtil; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.List; + +/** + * 病历表 Controller + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@RestController +@Api(tags = "") +@OperateLog +public class CaseplatformCaseController { + + @Autowired + private CaseplatformCaseService caseplatformCaseService; + + @Autowired + private MedicalRecordService medicalRecordService; + + @ApiOperation("分页查询 @author HMM") + @PostMapping("/caseplatformCase/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid CaseplatformCaseQueryForm queryForm) { + return caseplatformCaseService.queryPage(queryForm); + } + + @ApiOperation("更新 @author HMM") + @PostMapping("/caseplatformCase/update") + public ResponseDTO update(@RequestBody @Valid CaseplatformCaseUpdateForm updateForm) { + return caseplatformCaseService.update(updateForm); + } + + @ApiOperation("详情 @author HMM") + @GetMapping("/caseplatformCase/get/{caseId}") + @PreAuthorize("@saAuth.checkPermission('case-system:case:select')") + public ResponseDTO detail(@PathVariable("caseId") Long caseId) { + return ResponseDTO.ok(medicalRecordService.getDetail(caseId)); + } + + @ApiOperation("审核 @author HMM") + @GetMapping("/caseplatformCase/examine/{caseId}/{status}") + @PreAuthorize("@saAuth.checkPermission('case-system:case:examine')") + public ResponseDTO examine(@PathVariable("caseId") Long caseId, @PathVariable("status") int status) { + caseplatformCaseService.examine(caseId, status); + return ResponseDTO.ok(); + } + + @ApiOperation("结算 @author HMM") + @GetMapping("/caseplatformCase/settlement/{caseId}") + @PreAuthorize("@saAuth.checkPermission('case-system:case:settlement')") + public ResponseDTO settlement(@PathVariable("caseId") Long caseId) { + caseplatformCaseService.settlement(caseId); + return ResponseDTO.ok(); + } + + @ApiOperation("审核拒绝 @author HMM") + @PostMapping("/caseplatformCase/cancelExamine") + @PreAuthorize("@saAuth.checkPermission('case-system:case:examine')") + public ResponseDTO cancelExamine(@RequestBody @Valid CancelExamineForm form) { + caseplatformCaseService.cancelExamine(form); + return ResponseDTO.ok(); + } + + @ApiOperation("导出excle @author HMM") + @GetMapping("/caseplatformCase/exportExcel") + @PreAuthorize("@saAuth.checkPermission('case-system:case:excle')") + public void exportExcel(HttpServletResponse response, @RequestBody @Valid CaseplatformCaseQueryForm queryForm) { + try { + List data = caseplatformCaseService.queryList(queryForm); + List list = new ArrayList<>(); + for(CaseplatformCaseVO vv:data){ + ResponseDTO detail = caseplatformCaseService.getDetail(vv.getId()); + CaseplatformCaseDetailVO data1 = detail.getData(); + list.add(data1); + } + SmartEasyPoiExcelUtil.exportExcel(list, "qwe", "病例", CaseplatformCaseDetailVO.class, "病例导出数据", response); + }catch (Exception e){ + e.printStackTrace(); + } + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseExcelController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseExcelController.java new file mode 100644 index 0000000..537cad7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/controller/CaseplatformCaseExcelController.java @@ -0,0 +1,78 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.controller; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.module.app.medicalrecord.service.MedicalRecordService; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CaseplatformCaseQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.EasyExcelCaseDetailVO; +import net.lab1024.sa.admin.module.business.caseplatformcase.service.CaseplatformCaseService; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.net.URLEncoder; +import java.util.List; + +/** + * 病历表 Controller + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Controller +@Api(tags = "") +public class CaseplatformCaseExcelController { + @Autowired + private CaseplatformCaseService caseplatformCaseService; + + @GetMapping("/caseplatformCase/exportEasyExcel") + public void exportEasyExcel(HttpServletResponse response, @Valid CaseplatformCaseQueryForm queryForm) { + try { + List list = caseplatformCaseService.excelList(queryForm); + // 1设置表头样式 + WriteCellStyle headStyle = new WriteCellStyle(); + // 1.1设置表头数据居中 + headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + + // 2设置表格内容样式 + WriteCellStyle bodyStyle = new WriteCellStyle(); + // 2.1设置表格内容水平居中 + bodyStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + // 2.2设置表格内容垂直居中 + bodyStyle.setVerticalAlignment(VerticalAlignment.CENTER); + + // 3设置表格sheet样式 + WriteSheet sheet = EasyExcel.writerSheet("详细数据").head(EasyExcelCaseDetailVO.class).sheetNo(1).build(); + // 4拿到表格处理对象 + ExcelWriter writer = EasyExcel.write(response.getOutputStream()).needHead(true).excelType(ExcelTypeEnum.XLSX) + // 设置单元格的风格样式 + .registerWriteHandler(new HorizontalCellStyleStrategy(headStyle, bodyStyle)) + .build(); + + // 5写入excel数据 + writer.write(list, sheet); + // 6通知浏览器以附件的形式下载处理,设置返回头要注意文件名有中文 + String fileName = URLEncoder.encode("病例数据", "UTF-8").replaceAll("\\+", "%20"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + response.setContentType("multipart/form-data"); + response.setCharacterEncoding("utf-8"); + writer.finish(); + }catch (Exception e){ + e.printStackTrace(); + } + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CaseCaseSettlConverter.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CaseCaseSettlConverter.java new file mode 100644 index 0000000..cdc18df --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CaseCaseSettlConverter.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.converter; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseSettlementEnum; + +import java.util.Optional; + +public class CaseCaseSettlConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + //对象属性类型(java中数据类型) + return Integer.class; + } + + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + //CellData属性类型(Excel中数据类型) + return CellDataTypeEnum.STRING; + } + + @Override + public Integer convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + return Converter.super.convertToJavaData(cellData, contentProperty, globalConfiguration); + } + + @Override + public WriteCellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + + CaseSettlementEnum byVal = CaseSettlementEnum.getByVal(value); + return new WriteCellData<>(Optional.ofNullable(byVal.getDesc()).orElse("--未知--")); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CaseStatusConverter.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CaseStatusConverter.java new file mode 100644 index 0000000..7163d75 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CaseStatusConverter.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.converter; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; + +import java.util.Optional; + +public class CaseStatusConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + //对象属性类型(java中数据类型) + return Integer.class; + } + + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + //CellData属性类型(Excel中数据类型) + return CellDataTypeEnum.STRING; + } + + @Override + public Integer convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + return Converter.super.convertToJavaData(cellData, contentProperty, globalConfiguration); + } + + @Override + public WriteCellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + + CaseStatusEnum byVal = CaseStatusEnum.getByVal(value); + return new WriteCellData<>(Optional.ofNullable(byVal.getDesc()).orElse("--未知--")); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CasetypeConverter.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CasetypeConverter.java new file mode 100644 index 0000000..4c80660 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/converter/CasetypeConverter.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.converter; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; + +import java.util.Optional; + +public class CasetypeConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + //对象属性类型(java中数据类型) + return Integer.class; + } + + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + //CellData属性类型(Excel中数据类型) + return CellDataTypeEnum.STRING; + } + + @Override + public Integer convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + return Converter.super.convertToJavaData(cellData, contentProperty, globalConfiguration); + } + + @Override + public WriteCellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + + CasetypeEnum byVal = CasetypeEnum.getByVal(value); + return new WriteCellData<>(Optional.ofNullable(byVal.getDesc()).orElse("--未知--")); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/dao/CaseplatformCaseDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/dao/CaseplatformCaseDao.java new file mode 100644 index 0000000..1990598 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/dao/CaseplatformCaseDao.java @@ -0,0 +1,73 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.dao; + +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.entity.CaseplatformCaseEntity; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CancelExamineForm; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CaseplatformCaseQueryForm; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.CaseplatformCaseDetailVO; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.CaseplatformCaseVO; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.EasyExcelCaseDetailVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 病历表 Dao + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Mapper +@Component +public interface CaseplatformCaseDao extends BaseMapper { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") CaseplatformCaseQueryForm queryForm, @Param("provList")List provList); + + List excelList(@Param("queryForm") CaseplatformCaseQueryForm queryForm, @Param("provList")List provList); + + /** + * 获取详情 + * @param case_id + * @return + */ + CaseplatformCaseDetailVO getDetail(Long case_id); + + /** + * 审核 + * @param case_id + * @param status + * @return + */ + @Update("update t_caseplatform_case set status =#{status} where id=#{case_id}") + int examine(@Param("case_id") Long case_id, @Param("status")int status); + + /** + * 结算 + * @param case_id + * @return + */ + @Update("update t_caseplatform_case set settlement_flag =1 where id=#{case_id}") + int settlement(@Param("case_id") Long case_id); + + /** + * 审核拒绝 + * @param form + * @return + */ + @Update("update t_caseplatform_case set status =2,reason=#{form.reason} where id=#{form.caseId}") + int cancelExamine(@Param("form") CancelExamineForm form); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/entity/CaseplatformCaseEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/entity/CaseplatformCaseEntity.java new file mode 100644 index 0000000..2d0e9d5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/entity/CaseplatformCaseEntity.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 病历表 实体类 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@TableName("t_caseplatform_case") +public class CaseplatformCaseEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 关联用户表 + */ + private Long userId; + + /** + * 入院时间 + */ + private LocalDateTime admissionTime; + + /** + * 病历类型 + */ + private Integer caseType; + + /** + * 专家 id + */ + private Long expertId; + + /** + * 结算标识 + */ + private Integer settlementFlag; + + /** + * 0待审核 1审核通过 2审核不通过 + */ + private Integer status; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 修改时间 + */ + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CancelExamineForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CancelExamineForm.java new file mode 100644 index 0000000..306582a --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CancelExamineForm.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +public class CancelExamineForm { + + @ApiModelProperty(value = "病例id", required = true) + @NotNull(message = "病例id 不能为空") + private Long caseId; + + @ApiModelProperty(value = "原因", required = true) + @NotNull(message = "原因 不能为空") + private String reason; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseAddForm.java new file mode 100644 index 0000000..a99afe3 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseAddForm.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDateTime; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Data; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; + +/** + * 病历表 新建表单 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class CaseplatformCaseAddForm { + + @ApiModelProperty(value = "主键", required = true) + @NotNull(message = "主键 不能为空") + private Long id; + + @ApiModelProperty(value = "关联用户表", required = true) + @NotNull(message = "关联用户表 不能为空") + private Long userId; + + @ApiModelProperty(value = "入院时间", required = true) + @NotNull(message = "入院时间 不能为空") + private LocalDateTime admissionTime; + + @ApiModelPropertyEnum(value = CasetypeEnum.class, desc = "病历类型") + @CheckEnum(value = CasetypeEnum.class, message = "病历类型 错误", required = true) + private Integer caseType; + + @ApiModelProperty(value = "创建时间", required = true) + @NotNull(message = "创建时间 不能为空") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseQueryForm.java new file mode 100644 index 0000000..23aa91f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseQueryForm.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.domain.form; + +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseSettlementEnum; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; +import net.lab1024.sa.common.common.domain.PageParam; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; + +/** + * 病历表 分页查询表单 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class CaseplatformCaseQueryForm extends PageParam{ + + @ApiModelProperty(value = "name") + private String name; + + @ApiModelPropertyEnum(value = CasetypeEnum.class, desc = "病历类型") + @CheckEnum(value = CasetypeEnum.class, message = "病历类型 错误") + private Integer caseType; + + @ApiModelPropertyEnum(value = CaseSettlementEnum.class, desc = "结算状态") + @CheckEnum(value = CaseSettlementEnum.class, message = "结算状态 错误") + private Integer settlementFlag; + + @ApiModelPropertyEnum(value = CaseStatusEnum.class, desc = "0待审核 1审核通过 2审核不通过") + @CheckEnum(value = CaseStatusEnum.class, message = "0待审核 1审核通过 2审核不通过 错误") + private Integer status; + + @ApiModelProperty(value = "省份") + private Long provId; + + @ApiModelProperty(value = "市区") + private Long cityId; + + @ApiModelProperty(value = "医院") + private String hospitalUuid; +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseUpdateForm.java new file mode 100644 index 0000000..302bfbd --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/form/CaseplatformCaseUpdateForm.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import javax.validation.constraints.NotNull; +import lombok.Data; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; + +/** + * 病历表 更新表单 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class CaseplatformCaseUpdateForm extends CaseplatformCaseAddForm{ + + @ApiModelProperty(value = "主键", required = true) + @NotNull(message = "主键 不能为空") + private Long id; + + @ApiModelPropertyEnum(value = CaseStatusEnum.class, desc = "0待审核 1审核通过 2审核不通过") + @CheckEnum(value = CaseStatusEnum.class, message = "0待审核 1审核通过 2审核不通过 错误", required = true) + private Integer status; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/CaseplatformCaseDetailVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/CaseplatformCaseDetailVO.java new file mode 100644 index 0000000..0ba6c7a --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/CaseplatformCaseDetailVO.java @@ -0,0 +1,96 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.excel.annotation.ExcelCollection; +import cn.afterturn.easypoi.excel.annotation.ExcelEntity; +import cn.afterturn.easypoi.excel.annotation.ExcelTarget; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.vo.CaseplatformCaseAbstracVO; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.vo.CaseplatformCaseCheckdataVO; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.vo.CaseplatformCaseDpmsVO; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 病历表 列表VO + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@ExcelTarget("caseEntity") +public class CaseplatformCaseDetailVO { + + private Long id; + + @ApiModelProperty(value = "用户关联id") + private Long userId; + + @ApiModelProperty(value = "用户姓名") + @Excel(name = "患者姓名", orderNum = "1", width = 25,needMerge = true) + private String userName; + + @ApiModelProperty(value = "用户id") + @Excel(name = "患者ID", orderNum = "2", width = 25,needMerge = true) + private String uid; + + @ApiModelProperty(value = "入院时间") + @Excel(name = "入院时间", orderNum = "3", databaseFormat = "yyyyMMddHHmmss", format = "yyyy-MM-dd", width = 25,needMerge = true) + private LocalDateTime admissionTime; + + @ApiModelPropertyEnum(value = CasetypeEnum.class, desc = "病历类型") + @Excel(name = "病历类型", orderNum = "4", width = 25, replace = { "四次及以上疗程化_1", "早前期_2" }, isImportField = "true_st",needMerge = true) + private Integer caseType; + + @ApiModelProperty(value = "专家姓名") + @Excel(name = "专家姓名", orderNum = "5", width = 25,needMerge = true) + private String expertName; + + @ApiModelProperty(value = "专家所在省份名称") + @Excel(name = "省份", orderNum = "6", width = 25,needMerge = true) + private String expertProvName; + + @ApiModelProperty(value = "专家所在城市名称") + @Excel(name = "城市", orderNum = "7", width = 25,needMerge = true) + private String expertCityName; + + @ApiModelPropertyEnum(value = CaseStatusEnum.class, desc = "状态") + @Excel(name = "状态", orderNum = "8", width = 25, replace = { "待审核_0", "审核通过_1", "审核拒绝_2" }, isImportField = "true_st",needMerge = true) + private Integer status; + + @ApiModelProperty(value = "创建时间") + @Excel(name = "创建时间", orderNum = "9", databaseFormat = "yyyyMMddHHmmss", format = "yyyy-MM-dd", width = 25,needMerge = true) + private LocalDateTime createTime; + + @ApiModelProperty(value = "修改时间") + private LocalDateTime updateTime; + + @ApiModelProperty(value = "专家所在城市医院") + private String expertHospitalName; + + @ApiModelProperty(value = "结算标识") + private Integer settlementFlag; + /************************ 病历摘要 ********************************/ + + @ApiModelProperty(value = "病历摘要") + @ExcelEntity(id = "caseAbstract") + private CaseplatformCaseAbstracVO caseAbstract; + + /************************ 病历 DPMAS ********************************/ + @ExcelCollection(name = "DPMAS", orderNum = "4") + private List dpmsList; + + /************************ 病历 实验室检测 ********************************/ + + @ApiModelProperty(value = "实验室检测") + @ExcelEntity(id = "caseCheckdata") + private CaseplatformCaseCheckdataVO caseCheckdata; +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/CaseplatformCaseVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/CaseplatformCaseVO.java new file mode 100644 index 0000000..18cd314 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/CaseplatformCaseVO.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.excel.annotation.ExcelTarget; +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDateTime; +import lombok.Data; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +/** + * 病历表 列表VO + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class CaseplatformCaseVO { + + private Long id; + + @ApiModelProperty(value = "用户关联id") + private Long userId; + + @ApiModelProperty(value = "用户姓名") + private String userName; + + @ApiModelProperty(value = "用户id") + private String uid; + + @ApiModelProperty(value = "入院时间") + private LocalDateTime admissionTime; + + @ApiModelPropertyEnum(value = CasetypeEnum.class, desc = "病历类型") + private Integer caseType; + + @ApiModelProperty(value = "专家姓名") + private String expertName; + + @ApiModelProperty(value = "专家所在省份名称") + private String expertProvName; + + @ApiModelProperty(value = "专家所在城市名称") + private String expertCityName; + + @ApiModelPropertyEnum(value = CaseStatusEnum.class, desc = "0待审核 1审核通过 2审核不通过") + private Integer status; + + @ApiModelProperty(value = "专家所在城市医院") + private String expertHospitalName; + + @ApiModelProperty(value = "原因") + private String reason; + + @ApiModelProperty(value = "结算标识") + private Integer settlementFlag; + + @ApiModelProperty(value = "创建时间") + private LocalDateTime createTime; + + @ApiModelProperty(value = "修改时间") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/EasyExcelCaseDetailVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/EasyExcelCaseDetailVO.java new file mode 100644 index 0000000..a361138 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/domain/vo/EasyExcelCaseDetailVO.java @@ -0,0 +1,78 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CasetypeEnum; +import net.lab1024.sa.admin.module.business.caseplatformcase.converter.CaseCaseSettlConverter; +import net.lab1024.sa.admin.module.business.caseplatformcase.converter.CaseStatusConverter; +import net.lab1024.sa.admin.module.business.caseplatformcase.converter.CasetypeConverter; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +import java.time.LocalDateTime; + +/** + * 病历表 列表VO + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ +@Getter +@Setter +@EqualsAndHashCode +public class EasyExcelCaseDetailVO { + + @ExcelIgnore + private Long id; + + @ApiModelProperty(value = "专家姓名") + @ExcelProperty("姓名") + private String expertName; + + @ApiModelProperty(value = "专家所在省份名称") + @ExcelProperty("省份") + private String expertProvName; + + @ApiModelProperty(value = "专家所在城市名称") + @ExcelProperty("城市") + private String expertCityName; + + @ApiModelProperty(value = "专家所在城市医院") + @ExcelProperty("医院") + private String expertHospitalName; + + @ExcelIgnore + @ApiModelProperty(value = "用户关联id") + private Long userId; + + @ApiModelProperty(value = "用户姓名") + @ExcelProperty("患者") + private String userName; + + @ApiModelProperty(value = "用户id") + @ExcelProperty("患者ID") + private String uid; + + @ApiModelPropertyEnum(value = CasetypeEnum.class, desc = "病历类型") + @ExcelProperty(value = "病历类型", converter = CasetypeConverter.class) + private Integer caseType; + + @ApiModelProperty(value = "创建时间") + @ExcelProperty("提交时间") + private LocalDateTime createTime; + + @ApiModelPropertyEnum(value = CaseStatusEnum.class, desc = "状态") + @ExcelProperty(value = "病例状态", converter = CaseStatusConverter.class) + private Integer status; + + @ApiModelProperty(value = "结算标识") + @ExcelProperty(value = "结算状态", converter = CaseCaseSettlConverter.class) + private Integer settlementFlag; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/manager/CaseplatformCaseManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/manager/CaseplatformCaseManager.java new file mode 100644 index 0000000..8eeea5d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/manager/CaseplatformCaseManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.manager; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.business.caseplatformcase.dao.CaseplatformCaseDao; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.entity.CaseplatformCaseEntity; +import org.springframework.stereotype.Service; + +/** + * 病历表 Manager + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ +@Service +public class CaseplatformCaseManager extends ServiceImpl { + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/service/CaseplatformCaseService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/service/CaseplatformCaseService.java new file mode 100644 index 0000000..62c1661 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcase/service/CaseplatformCaseService.java @@ -0,0 +1,169 @@ +package net.lab1024.sa.admin.module.business.caseplatformcase.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.admin.module.business.caseplatformcase.dao.CaseplatformCaseDao; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.entity.CaseplatformCaseEntity; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CancelExamineForm; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CaseplatformCaseAddForm; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CaseplatformCaseQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.form.CaseplatformCaseUpdateForm; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.CaseplatformCaseDetailVO; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.CaseplatformCaseVO; +import net.lab1024.sa.admin.module.business.caseplatformcase.domain.vo.EasyExcelCaseDetailVO; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.vo.CaseplatformCaseAbstracVO; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.service.CaseplatformCaseAbstracService; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.vo.CaseplatformCaseCheckdataVO; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.service.CaseplatformCaseCheckdataService; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.vo.CaseplatformCaseDpmsVO; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.service.CaseplatformCaseDpmsService; +import net.lab1024.sa.admin.module.system.login.domain.LoginEmployeeDetail; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +import static net.lab1024.sa.common.common.code.UserErrorCode.NO_PERMISSION; + +/** + * 病历表 Service + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Service +public class CaseplatformCaseService { + + @Autowired + private CaseplatformCaseDao caseplatformCaseDao; + + @Autowired + private CaseplatformCaseAbstracService abstracService; + + @Autowired + private CaseplatformCaseDpmsService dpmsService; + + @Autowired + private CaseplatformCaseCheckdataService checkdataService; + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public ResponseDTO> queryPage(CaseplatformCaseQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + + LoginEmployeeDetail requestUser = (LoginEmployeeDetail)SmartRequestUtil.getRequestUser(); + List provList = requestUser.getProvList(); + Long provId = queryForm.getProvId(); + if(provId != null){ + boolean match = provList.stream().anyMatch(item -> item.getId().equals(provId)); + if(!match){ + return ResponseDTO.ok(SmartPageUtil.emptyResult(page)); + } + } + List list = caseplatformCaseDao.queryPage(page, queryForm, provList); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return ResponseDTO.ok(pageResult); + } + + public List queryList(CaseplatformCaseQueryForm queryForm) { + LoginEmployeeDetail requestUser = (LoginEmployeeDetail)SmartRequestUtil.getRequestUser(); + List provList = requestUser.getProvList(); + Long provId = queryForm.getProvId(); + if(provId != null){ + boolean match = provList.stream().anyMatch(item -> item.getId().equals(provId)); + if(!match){ + return null; + } + } + List list = caseplatformCaseDao.queryPage(null, queryForm, provList); + return list; + } + + /** + * 不分页导出 excel + * @param queryForm + * @return + */ + public List excelList(CaseplatformCaseQueryForm queryForm) { + LoginEmployeeDetail requestUser = (LoginEmployeeDetail)SmartRequestUtil.getRequestUser(); + List provList = requestUser.getProvList(); + Long provId = queryForm.getProvId(); + if(provId != null){ + boolean match = provList.stream().anyMatch(item -> item.getId().equals(provId)); + if(!match){ + return null; + } + } + List list = caseplatformCaseDao.excelList(queryForm, provList); + return list; + } + + /** + * 添加 + */ + public ResponseDTO add(CaseplatformCaseAddForm addForm) { + CaseplatformCaseEntity caseplatformCaseEntity = SmartBeanUtil.copy(addForm, CaseplatformCaseEntity.class); + caseplatformCaseDao.insert(caseplatformCaseEntity); + return ResponseDTO.ok(); + } + + /** + * 更新 + * + * @param updateForm + * @return + */ + public ResponseDTO update(CaseplatformCaseUpdateForm updateForm) { + CaseplatformCaseEntity caseplatformCaseEntity = SmartBeanUtil.copy(updateForm, CaseplatformCaseEntity.class); + caseplatformCaseDao.updateById(caseplatformCaseEntity); + return ResponseDTO.ok(); + } + + /** + * 审核 + * @param case_id + * @return + */ + public void examine(Long case_id, int status){ + caseplatformCaseDao.examine(case_id, status); + } + + /** + * 结算 + * @param case_id + */ + public void settlement(Long case_id){ + caseplatformCaseDao.settlement(case_id); + } + + /** + * 审核拒绝 + * @param form + */ + public void cancelExamine(CancelExamineForm form){ + caseplatformCaseDao.cancelExamine(form); + } + + public ResponseDTO getDetail(Long case_id){ + CaseplatformCaseDetailVO detail = caseplatformCaseDao.getDetail(case_id); + CaseplatformCaseAbstracVO abstracVO = abstracService.getByCaseId(case_id); + List dpmsVOS = dpmsService.getByCaseId(case_id); + CaseplatformCaseCheckdataVO checkdataVO = checkdataService.getByCaseId(case_id); + detail.setCaseAbstract(abstracVO); + detail.setCaseCheckdata(checkdataVO); + detail.setDpmsList(dpmsVOS); + return ResponseDTO.ok(detail); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/controller/CaseplatformCaseAbstracController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/controller/CaseplatformCaseAbstracController.java new file mode 100644 index 0000000..cdfc560 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/controller/CaseplatformCaseAbstracController.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.controller; + +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.form.CaseplatformCaseAbstracQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.vo.CaseplatformCaseAbstracVO; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.service.CaseplatformCaseAbstracService; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import javax.validation.Valid; + +/** + * 病历摘要表 Controller + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@RestController +@Api(tags = "") +@OperateLog +public class CaseplatformCaseAbstracController { + + @Autowired + private CaseplatformCaseAbstracService caseplatformCaseAbstracService; + + @ApiOperation("分页查询 @author HMM") + @PostMapping("/caseplatformCaseAbstrac/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid CaseplatformCaseAbstracQueryForm queryForm) { + return ResponseDTO.ok(caseplatformCaseAbstracService.queryPage(queryForm)); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/dao/CaseplatformCaseAbstracDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/dao/CaseplatformCaseAbstracDao.java new file mode 100644 index 0000000..20ebbb8 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/dao/CaseplatformCaseAbstracDao.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.dao; + +import java.util.List; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.entity.CaseplatformCaseAbstracEntity; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.form.CaseplatformCaseAbstracQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.vo.CaseplatformCaseAbstracVO; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +/** + * 病历摘要表 Dao + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Mapper +@Component +public interface CaseplatformCaseAbstracDao extends BaseMapper { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") CaseplatformCaseAbstracQueryForm queryForm); + + CaseplatformCaseAbstracVO getByCaseId(Long case_id); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/entity/CaseplatformCaseAbstracEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/entity/CaseplatformCaseAbstracEntity.java new file mode 100644 index 0000000..7d0acf8 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/entity/CaseplatformCaseAbstracEntity.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 病历摘要表 实体类 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@TableName("t_caseplatform_case_abstract") +public class CaseplatformCaseAbstracEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 关联病历表 + */ + private Long caseId; + + /** + * 病历摘要 文字 + */ + private String abstractStr; + + /** + * 病历摘要 图片 + */ + private String abstractImg; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 修改时间 + */ + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/form/CaseplatformCaseAbstracQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/form/CaseplatformCaseAbstracQueryForm.java new file mode 100644 index 0000000..836e24f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/form/CaseplatformCaseAbstracQueryForm.java @@ -0,0 +1,17 @@ +package net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.form; + +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +/** + * 病历摘要表 分页查询表单 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class CaseplatformCaseAbstracQueryForm extends PageParam{ + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/vo/CaseplatformCaseAbstracVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/vo/CaseplatformCaseAbstracVO.java new file mode 100644 index 0000000..4608b6b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/domain/vo/CaseplatformCaseAbstracVO.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.vo; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.excel.annotation.ExcelTarget; +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 病历摘要表 列表VO + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@ExcelTarget("CaseplatformCaseAbstrac") +public class CaseplatformCaseAbstracVO { + + private Long id; + + @ApiModelProperty(value = "关联病历表") + private Long caseId; + + @ApiModelProperty(value = "病历摘要 文字") + @Excel(name = "病历摘要 文字", orderNum = "1",needMerge = true) + private String abstractStr; + + @ApiModelProperty(value = "病历摘要 图片") + //@Excel(name = "病历摘要 图片", orderNum = "1", isImportField = "true_major,true_absent") + private String abstractImg; + + @ApiModelProperty(value = "创建时间") + private LocalDateTime createTime; + + @ApiModelProperty(value = "修改时间") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/manager/CaseplatformCaseAbstracManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/manager/CaseplatformCaseAbstracManager.java new file mode 100644 index 0000000..fe2ce9e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/manager/CaseplatformCaseAbstracManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.manager; + +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.dao.CaseplatformCaseAbstracDao; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.entity.CaseplatformCaseAbstracEntity; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * 病历摘要表 Manager + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ +@Service +public class CaseplatformCaseAbstracManager extends ServiceImpl { + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/service/CaseplatformCaseAbstracService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/service/CaseplatformCaseAbstracService.java new file mode 100644 index 0000000..778101b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcaseabstrac/service/CaseplatformCaseAbstracService.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.dao.CaseplatformCaseAbstracDao; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.form.CaseplatformCaseAbstracQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.vo.CaseplatformCaseAbstracVO; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 病历摘要表 Service + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Service +public class CaseplatformCaseAbstracService { + + @Autowired + private CaseplatformCaseAbstracDao caseplatformCaseAbstracDao; + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public PageResult queryPage(CaseplatformCaseAbstracQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = caseplatformCaseAbstracDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return pageResult; + } + + public CaseplatformCaseAbstracVO getByCaseId(Long case_id){ + return caseplatformCaseAbstracDao.getByCaseId(case_id); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/controller/CaseplatformCaseCheckdataController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/controller/CaseplatformCaseCheckdataController.java new file mode 100644 index 0000000..6bd22ba --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/controller/CaseplatformCaseCheckdataController.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.form.CaseplatformCaseCheckdataQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.vo.CaseplatformCaseCheckdataVO; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.service.CaseplatformCaseCheckdataService; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * 实验室检测 Controller + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@RestController +@Api(tags = "") +@OperateLog +public class CaseplatformCaseCheckdataController { + + @Autowired + private CaseplatformCaseCheckdataService caseplatformCaseCheckdataService; + + @ApiOperation("分页查询 @author HMM") + @PostMapping("/caseplatformCaseCheckdata/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid CaseplatformCaseCheckdataQueryForm queryForm) { + return ResponseDTO.ok(caseplatformCaseCheckdataService.queryPage(queryForm)); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/dao/CaseplatformCaseCheckdataDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/dao/CaseplatformCaseCheckdataDao.java new file mode 100644 index 0000000..7cf14df --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/dao/CaseplatformCaseCheckdataDao.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.entity.CaseplatformCaseCheckdataEntity; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.form.CaseplatformCaseCheckdataQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.vo.CaseplatformCaseCheckdataVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 实验室检测 Dao + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Mapper +@Component +public interface CaseplatformCaseCheckdataDao extends BaseMapper { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") CaseplatformCaseCheckdataQueryForm queryForm); + + CaseplatformCaseCheckdataVO getByCaseId(Long case_id); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/entity/CaseplatformCaseCheckdataEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/entity/CaseplatformCaseCheckdataEntity.java new file mode 100644 index 0000000..150b13d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/entity/CaseplatformCaseCheckdataEntity.java @@ -0,0 +1,152 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 实验室检测 实体类 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@TableName("t_caseplatform_case_checkdata") +public class CaseplatformCaseCheckdataEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 关联病历 + */ + private Long caseId; + + /** + * 治疗前 检测时间 + */ + private LocalDateTime headTime; + + /** + * 治疗后 检测时间 + */ + private LocalDateTime afterTime; + + /** + * 治疗前 总胆红素(umol/L) + */ + private String headTb; + + /** + * 治疗后 总胆红素(umol/L) + */ + private String afterTb; + + /** + * 治疗前 白蛋白(g/L) + */ + private String headAlb; + + /** + * 治疗后 白蛋白(g/L) + */ + private String afterAlb; + + /** + * 治疗前 直接胆红素(umol/L) + */ + private String headDb; + + /** + * 治疗后 直接胆红素(umol/L) + */ + private String afterDb; + + /** + * 治疗前 凝血酶原活动度 (%) + */ + private String headPta; + + /** + * 治疗后 凝血酶原活动度 (%) + */ + private String afterPta; + + /** + * 治疗前 间接胆红素(umol/L) + */ + private String headIb; + + /** + * 治疗后 间接胆红素(umol/L) + */ + private String afterIb; + + /** + * 治疗前 国际标准化比值 (INR) + */ + private String headInr; + + /** + * 治疗后 国际标准化比值 (INR) + */ + private String afterInr; + + /** + * 治疗前 谷丙转氨 (U/L) + */ + private String headAlt; + + /** + * 治疗后 谷丙转氨 (U/L) + */ + private String afterAlt; + + /** + * 治疗前 白介素6(ng/L) + */ + private String headIl6; + + /** + * 治疗后 白介素6(ng/L) + */ + private String afterIl6; + + /** + * 治疗前 谷草转氨酶 (U/L) + */ + private String headAst; + + /** + * 治疗后 谷草转氨酶 (U/L) + */ + private String afterAst; + + /** + * 治疗前 肿瘤坏死因子α(μg/L) + */ + private String headTnf; + + /** + * 治疗后 肿瘤坏死因子α(μg/L) + */ + private String afterTnf; + + /** + * 图片 + */ + private String img; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/form/CaseplatformCaseCheckdataQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/form/CaseplatformCaseCheckdataQueryForm.java new file mode 100644 index 0000000..a9895ff --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/form/CaseplatformCaseCheckdataQueryForm.java @@ -0,0 +1,17 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.form; + +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +/** + * 实验室检测 分页查询表单 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class CaseplatformCaseCheckdataQueryForm extends PageParam{ + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/vo/CaseplatformCaseCheckdataVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/vo/CaseplatformCaseCheckdataVO.java new file mode 100644 index 0000000..c3158d6 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/domain/vo/CaseplatformCaseCheckdataVO.java @@ -0,0 +1,100 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.vo; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 实验室检测 列表VO + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class CaseplatformCaseCheckdataVO { + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "关联病历") + private Long caseId; + + @ApiModelProperty(value = "治疗前 检测时间") + @Excel(name = "创建时间", orderNum = "10", databaseFormat = "yyyyMMddHHmmss", format = "yyyy-MM-dd", width = 25,needMerge = true) + private LocalDateTime headTime; + + @ApiModelProperty(value = "治疗后 检测时间 ") + private LocalDateTime afterTime; + + @ApiModelProperty(value = "治疗前 总胆红素(umol/L)") + @Excel(name = "治疗前 总胆红素", orderNum = "11", width = 25,needMerge = true) + private String headTb; + + @ApiModelProperty(value = "治疗后 总胆红素(umol/L)") + @Excel(name = "治疗后 总胆红素", orderNum = "12", width = 25,needMerge = true) + private String afterTb; + + @ApiModelProperty(value = "治疗前 白蛋白(g/L)") + private String headAlb; + + @ApiModelProperty(value = "治疗后 白蛋白(g/L)") + private String afterAlb; + + @ApiModelProperty(value = "治疗前 直接胆红素(umol/L)") + private String headDb; + + @ApiModelProperty(value = "治疗后 直接胆红素(umol/L)") + private String afterDb; + + @ApiModelProperty(value = "治疗前 凝血酶原活动度 (%)") + private String headPta; + + @ApiModelProperty(value = "治疗后 凝血酶原活动度 (%)") + private String afterPta; + + @ApiModelProperty(value = "治疗前 间接胆红素(umol/L)") + private String headIb; + + @ApiModelProperty(value = "治疗后 间接胆红素(umol/L)") + private String afterIb; + + @ApiModelProperty(value = "治疗前 国际标准化比值 (INR)") + private String headInr; + + @ApiModelProperty(value = "治疗后 国际标准化比值 (INR)") + private String afterInr; + + @ApiModelProperty(value = "治疗前 谷丙转氨 (U/L)") + private String headAlt; + + @ApiModelProperty(value = "治疗后 谷丙转氨 (U/L)") + private String afterAlt; + + @ApiModelProperty(value = "治疗前 白介素6(ng/L)") + private String headIl6; + + @ApiModelProperty(value = "治疗后 白介素6(ng/L)") + private String afterIl6; + + @ApiModelProperty(value = "治疗前 谷草转氨酶 (U/L)") + private String headAst; + + @ApiModelProperty(value = "治疗后 谷草转氨酶 (U/L)") + private String afterAst; + + @ApiModelProperty(value = "治疗前 肿瘤坏死因子α(μg/L)") + private String headTnf; + + @ApiModelProperty(value = "治疗后 肿瘤坏死因子α(μg/L)") + private String afterTnf; + + @ApiModelProperty(value = "图片") + private String img; + + @ApiModelProperty(value = "创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/manager/CaseplatformCaseCheckdataManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/manager/CaseplatformCaseCheckdataManager.java new file mode 100644 index 0000000..9ea53d7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/manager/CaseplatformCaseCheckdataManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.manager; + +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.dao.CaseplatformCaseCheckdataDao; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.entity.CaseplatformCaseCheckdataEntity; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * 实验室检测 Manager + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ +@Service +public class CaseplatformCaseCheckdataManager extends ServiceImpl { + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/service/CaseplatformCaseCheckdataService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/service/CaseplatformCaseCheckdataService.java new file mode 100644 index 0000000..3a6a7e8 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasecheckdata/service/CaseplatformCaseCheckdataService.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.caseplatformcaseabstrac.domain.vo.CaseplatformCaseAbstracVO; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.dao.CaseplatformCaseCheckdataDao; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.form.CaseplatformCaseCheckdataQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.vo.CaseplatformCaseCheckdataVO; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 实验室检测 Service + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Service +public class CaseplatformCaseCheckdataService { + + @Autowired + private CaseplatformCaseCheckdataDao caseplatformCaseCheckdataDao; + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public PageResult queryPage(CaseplatformCaseCheckdataQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = caseplatformCaseCheckdataDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return pageResult; + } + + public CaseplatformCaseCheckdataVO getByCaseId(Long case_id){ + return caseplatformCaseCheckdataDao.getByCaseId(case_id); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/controller/CaseplatformCaseDpmsController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/controller/CaseplatformCaseDpmsController.java new file mode 100644 index 0000000..0bcd0e5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/controller/CaseplatformCaseDpmsController.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasedpms.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.form.CaseplatformCaseDpmsQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.vo.CaseplatformCaseDpmsVO; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.service.CaseplatformCaseDpmsService; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * 病历摘要表 Controller + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@RestController +@Api(tags = "") +@OperateLog +public class CaseplatformCaseDpmsController { + + @Autowired + private CaseplatformCaseDpmsService caseplatformCaseDpmsService; + + @ApiOperation("分页查询 @author HMM") + @PostMapping("/caseplatformCaseDpms/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid CaseplatformCaseDpmsQueryForm queryForm) { + return ResponseDTO.ok(caseplatformCaseDpmsService.queryPage(queryForm)); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/dao/CaseplatformCaseDpmsDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/dao/CaseplatformCaseDpmsDao.java new file mode 100644 index 0000000..c6e9604 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/dao/CaseplatformCaseDpmsDao.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasedpms.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.entity.CaseplatformCaseDpmsEntity; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.form.CaseplatformCaseDpmsQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.vo.CaseplatformCaseDpmsVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 病历摘要表 Dao + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Mapper +@Component +public interface CaseplatformCaseDpmsDao extends BaseMapper { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") CaseplatformCaseDpmsQueryForm queryForm); + + List getByCaseId(Long case_id); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/entity/CaseplatformCaseDpmsEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/entity/CaseplatformCaseDpmsEntity.java new file mode 100644 index 0000000..14c418a --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/entity/CaseplatformCaseDpmsEntity.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 病历摘要表 实体类 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@TableName("t_caseplatform_case_dpms") +public class CaseplatformCaseDpmsEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 关联病历表 + */ + private Long caseId; + + /** + * 治疗时间 + */ + private LocalDateTime treatTime; + + /** + * 图片 + */ + private String img; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/form/CaseplatformCaseDpmsQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/form/CaseplatformCaseDpmsQueryForm.java new file mode 100644 index 0000000..0996a36 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/form/CaseplatformCaseDpmsQueryForm.java @@ -0,0 +1,17 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.form; + +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +/** + * 病历摘要表 分页查询表单 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class CaseplatformCaseDpmsQueryForm extends PageParam{ + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/vo/CaseplatformCaseDpmsVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/vo/CaseplatformCaseDpmsVO.java new file mode 100644 index 0000000..c085256 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/domain/vo/CaseplatformCaseDpmsVO.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.vo; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 病历摘要表 列表VO + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class CaseplatformCaseDpmsVO { + + @ApiModelProperty(value = "主键") + private Long id; + + @ApiModelProperty(value = "关联病历表") + private Long caseId; + + @ApiModelProperty(value = "治疗时间") + @Excel(name = "治疗时间", width = 30, databaseFormat = "yyyyMMddHHmmss", format = "yyyy-MM-dd") + private LocalDateTime treatTime; + + @ApiModelProperty(value = "图片") + @Excel(name = "图片", type = 2,width = 40, imageType = 1) + private String img; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/manager/CaseplatformCaseDpmsManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/manager/CaseplatformCaseDpmsManager.java new file mode 100644 index 0000000..31d79ef --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/manager/CaseplatformCaseDpmsManager.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasedpms.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.dao.CaseplatformCaseDpmsDao; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.entity.CaseplatformCaseDpmsEntity; +import org.springframework.stereotype.Service; + +/** + * 病历摘要表 Manager + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ +@Service +public class CaseplatformCaseDpmsManager extends ServiceImpl { + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/service/CaseplatformCaseDpmsService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/service/CaseplatformCaseDpmsService.java new file mode 100644 index 0000000..398b9c7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformcasedpms/service/CaseplatformCaseDpmsService.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.admin.module.business.caseplatformcasedpms.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.caseplatformcasecheckdata.domain.vo.CaseplatformCaseCheckdataVO; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.dao.CaseplatformCaseDpmsDao; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.form.CaseplatformCaseDpmsQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformcasedpms.domain.vo.CaseplatformCaseDpmsVO; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 病历摘要表 Service + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Service +public class CaseplatformCaseDpmsService { + + @Autowired + private CaseplatformCaseDpmsDao caseplatformCaseDpmsDao; + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public PageResult queryPage(CaseplatformCaseDpmsQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = caseplatformCaseDpmsDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return pageResult; + } + + public List getByCaseId(Long case_id){ + return caseplatformCaseDpmsDao.getByCaseId(case_id); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/constant/SexEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/constant/SexEnum.java new file mode 100644 index 0000000..96657bb --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/constant/SexEnum.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.business.caseplatformuser.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 性别 12 + * + * @Author HMM + * @Date 2024-01-11T15:18:32 + * @Copyright gdxz + */ + +@AllArgsConstructor +@Getter +public enum SexEnum implements BaseEnum { + + ; + + private final Integer value; + + private final String desc; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/controller/CaseplatformUserController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/controller/CaseplatformUserController.java new file mode 100644 index 0000000..cfa384f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/controller/CaseplatformUserController.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.business.caseplatformuser.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.module.business.caseplatformuser.domain.form.CaseplatformUserQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformuser.domain.vo.CaseplatformUserVO; +import net.lab1024.sa.admin.module.business.caseplatformuser.service.CaseplatformUserService; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * 用户表 Controller + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@RestController +@Api(tags = "") +@OperateLog +public class CaseplatformUserController { + + @Autowired + private CaseplatformUserService caseplatformUserService; + + @ApiOperation("分页查询 @author HMM") + @PostMapping("/caseplatformUser/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid CaseplatformUserQueryForm queryForm) { + return ResponseDTO.ok(caseplatformUserService.queryPage(queryForm)); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/dao/CaseplatformUserDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/dao/CaseplatformUserDao.java new file mode 100644 index 0000000..23402b7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/dao/CaseplatformUserDao.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.business.caseplatformuser.dao; + +import java.util.List; +import net.lab1024.sa.admin.module.business.caseplatformuser.domain.entity.CaseplatformUserEntity; +import net.lab1024.sa.admin.module.business.caseplatformuser.domain.form.CaseplatformUserQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformuser.domain.vo.CaseplatformUserVO; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +/** + * 用户表 Dao + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Mapper +@Component +public interface CaseplatformUserDao extends BaseMapper { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") CaseplatformUserQueryForm queryForm); + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/entity/CaseplatformUserEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/entity/CaseplatformUserEntity.java new file mode 100644 index 0000000..470891a --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/entity/CaseplatformUserEntity.java @@ -0,0 +1,87 @@ +package net.lab1024.sa.admin.module.business.caseplatformuser.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 用户表 实体类 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +@TableName("t_caseplatform_user") +public class CaseplatformUserEntity { + + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 患者姓名 + */ + private String name; + + /** + * 患者id + */ + private String uid; + + /** + * 性别 + */ + private Integer sex; + + /** + * 年龄 + */ + private Integer age; + + /** + * 专家uuid + */ + private String expertUuid; + + /** + * 专家姓名 + */ + private String expertName; + + /** + * 专家所在省份id + */ + private Integer expertProvId; + + /** + * 专家所在省份名称 + */ + private String expertProvName; + + /** + * 专家所在城市id + */ + private Integer expertCityId; + + /** + * 专家所在城市名称 + */ + private String expertCityName; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 修改时间 + */ + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/form/CaseplatformUserQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/form/CaseplatformUserQueryForm.java new file mode 100644 index 0000000..594dff6 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/form/CaseplatformUserQueryForm.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.admin.module.business.caseplatformuser.domain.form; + +import net.lab1024.sa.common.common.domain.PageParam; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 用户表 分页查询表单 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class CaseplatformUserQueryForm extends PageParam{ + + @ApiModelProperty(value = "name") + private String name; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/vo/CaseplatformUserVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/vo/CaseplatformUserVO.java new file mode 100644 index 0000000..3639a47 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/domain/vo/CaseplatformUserVO.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.business.caseplatformuser.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDateTime; +import lombok.Data; +import net.lab1024.sa.admin.module.business.caseplatformuser.constant.SexEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +/** + * 用户表 列表VO + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Data +public class CaseplatformUserVO { + + private Long id; + + + @ApiModelProperty(value = "患者姓名") + private String name; + + @ApiModelProperty(value = "患者id") + private String uid; + + @ApiModelPropertyEnum(value = SexEnum.class, desc = "性别") + private Integer sex; + + @ApiModelProperty(value = "年龄") + private Integer age; + + @ApiModelProperty(value = "创建时间") + private LocalDateTime createTime; + + @ApiModelProperty(value = "修改时间") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/manager/CaseplatformUserManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/manager/CaseplatformUserManager.java new file mode 100644 index 0000000..80737e8 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/manager/CaseplatformUserManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.business.caseplatformuser.manager; + +import net.lab1024.sa.admin.module.business.caseplatformuser.domain.entity.CaseplatformUserEntity; +import net.lab1024.sa.admin.module.business.caseplatformuser.dao.CaseplatformUserDao; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * 用户表 Manager + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ +@Service +public class CaseplatformUserManager extends ServiceImpl { + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/service/CaseplatformUserService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/service/CaseplatformUserService.java new file mode 100644 index 0000000..434ffe3 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/caseplatformuser/service/CaseplatformUserService.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.admin.module.business.caseplatformuser.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.caseplatformuser.dao.CaseplatformUserDao; +import net.lab1024.sa.admin.module.business.caseplatformuser.domain.form.CaseplatformUserQueryForm; +import net.lab1024.sa.admin.module.business.caseplatformuser.domain.vo.CaseplatformUserVO; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 用户表 Service + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@Service +public class CaseplatformUserService { + + @Autowired + private CaseplatformUserDao caseplatformUserDao; + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public PageResult queryPage(CaseplatformUserQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = caseplatformUserDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return pageResult; + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.java new file mode 100644 index 0000000..2df51fe --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.admin.module.business.category.constant; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 分类类型 枚举 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@AllArgsConstructor +@Getter +public enum CategoryTypeEnum implements BaseEnum { + + /** + * 1 商品 + */ + GOODS(1, "商品"), + + /** + * 2 自定义 + */ + CUSTOM(2, "自定义"), + + ; + + private final Integer value; + + private final String desc; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/controller/CategoryController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/controller/CategoryController.java new file mode 100644 index 0000000..8c8493a --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/controller/CategoryController.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.admin.module.business.category.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.common.AdminBaseController; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryAddForm; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryTreeQueryForm; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryUpdateForm; +import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO; +import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryVO; +import net.lab1024.sa.admin.module.business.category.service.CategoryService; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 类目 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@OperateLog +@RestController +//@Api(tags = AdminSwaggerTagConst.Business.MANAGER_CATEGORY) +public class CategoryController extends AdminBaseController { + + @Autowired + private CategoryService categoryService; + + @ApiOperation("添加类目 @author 胡克") + @PostMapping("/category/add") + public ResponseDTO add(@RequestBody @Valid CategoryAddForm addForm) { + return categoryService.add(addForm); + } + + @ApiOperation("更新类目 @author 胡克") + @PostMapping("/category/update") + public ResponseDTO update(@RequestBody @Valid CategoryUpdateForm updateForm) { + return categoryService.update(updateForm); + } + + @ApiOperation("查询类目详情 @author 胡克") + @GetMapping("/category/{categoryId}") + public ResponseDTO queryDetail(@PathVariable Long categoryId) { + return categoryService.queryDetail(categoryId); + } + + @ApiOperation("查询类目层级树 @author 胡克") + @PostMapping("/category/tree") + public ResponseDTO> queryTree(@RequestBody @Valid CategoryTreeQueryForm queryForm) { + return categoryService.queryTree(queryForm); + } + + @ApiOperation("删除类目 @author 胡克") + @GetMapping("/category/delete/{categoryId}") + public ResponseDTO delete(@PathVariable Long categoryId) { + return categoryService.delete(categoryId); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.java new file mode 100644 index 0000000..c9ac00f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.java @@ -0,0 +1,72 @@ +package net.lab1024.sa.admin.module.business.category.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 类目 dao + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Component +@Mapper +public interface CategoryDao extends BaseMapper { + + /** + * 根据父级id 类型 查询子类 + * + * @param parentIdList + * @param deletedFlag + * @return + */ + List queryByParentId(@Param("parentIdList") List parentIdList, + @Param("deletedFlag") Boolean deletedFlag); + + /** + * 根据父级id 类型 查询子类 + * + * @param parentIdList + * @param categoryType {@link CategoryTypeEnum} + * @param deletedFlag + * @return + */ + List queryByParentIdAndType(@Param("parentIdList") List parentIdList, + @Param("categoryType") Integer categoryType, + @Param("deletedFlag") Boolean deletedFlag); + + /** + * 某个类型的所有 + * @param categoryType + * @param deletedFlag + * @return + */ + List queryByType(@Param("categoryType") Integer categoryType, + @Param("deletedFlag") Boolean deletedFlag); + + /** + * 根据类型和id查询 + * @param categoryType + * @param categoryId + * @return + */ + CategoryEntity selectByTypeAndId(@Param("categoryType") Integer categoryType, @Param("categoryId") Long categoryId); + + /** + * 查看类目 具体条件 看sql + * + * @param entity + * @return + */ + CategoryEntity selectOne(CategoryEntity entity); + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.java new file mode 100644 index 0000000..5381ab9 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.admin.module.business.category.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 类目 基础属性 DTO 类 + * + * @author 胡克 + * @date 2021/1/20 16:17 + */ +@Data +public class CategoryBaseDTO { + + @ApiModelProperty(value = "类目名称", required = true) + @NotBlank(message = "类目名称不能为空") + @Length(max = 20, message = "类目名称最多20字符") + private String categoryName; + + @ApiModelPropertyEnum(desc = "分类类型", value = CategoryTypeEnum.class) + @CheckEnum(value = CategoryTypeEnum.class, required = true, message = "分类错误") + private Integer categoryType; + + @ApiModelProperty("父级类目id|可选") + private Long parentId; + + @ApiModelProperty("排序|可选") + private Integer sort; + + @ApiModelProperty("备注|可选") + @Length(max = 200, message = "备注最多200字符") + private String remark; + + @ApiModelProperty("禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.java new file mode 100644 index 0000000..7f25e7b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.business.category.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 类目 基础属性 DTO 类 + * + * @author 胡克 + * @date 2021/1/20 16:17 + */ +@Data +public class CategorySimpleDTO { + + @ApiModelProperty("类目id") + private Long categoryId; + + @ApiModelProperty("类目名称") + private String categoryName; + + @ApiModelProperty("类目层级全称") + private String categoryFullName; + + @ApiModelProperty("父级id") + private Long parentId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.java new file mode 100644 index 0000000..f8ee74a --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.admin.module.business.category.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; + +import java.time.LocalDateTime; + +/** + * 类目 实体类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +@TableName("t_category") +public class CategoryEntity { + + @TableId(type = IdType.AUTO) + private Long categoryId; + + /** + * 类目名称 + */ + private String categoryName; + + /** + * 类目 类型 + * + * @see CategoryTypeEnum + */ + private Integer categoryType; + + /** + * 父级类目id + */ + private Long parentId; + + /** + * 是否禁用 + */ + private Boolean disabledFlag; + + /** + * 排序 + */ + private Integer sort; + + /** + * 删除状态 + */ + private Boolean deletedFlag; + + /** + * 备注 + */ + private String remark; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.java new file mode 100644 index 0000000..29a3781 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.admin.module.business.category.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.admin.module.business.category.domain.dto.CategoryBaseDTO; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 类目 添加 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class CategoryAddForm { + + @ApiModelProperty(value = "类目名称", required = true) + @NotBlank(message = "类目名称不能为空") + @Length(max = 20, message = "类目名称最多20字符") + private String categoryName; + + @ApiModelPropertyEnum(desc = "分类类型", value = CategoryTypeEnum.class) + @CheckEnum(value = CategoryTypeEnum.class, required = true, message = "分类错误") + private Integer categoryType; + + @ApiModelProperty("父级类目id|可选") + private Long parentId; + + @ApiModelProperty("排序|可选") + private Integer sort; + + @ApiModelProperty("备注|可选") + @Length(max = 200, message = "备注最多200字符") + private String remark; + + @ApiModelProperty("禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.java new file mode 100644 index 0000000..907bca7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.admin.module.business.category.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +/** + * 类目 层级树查询 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class CategoryTreeQueryForm { + + @ApiModelPropertyEnum(desc = "分类类型|可选", value = CategoryTypeEnum.class) + private Integer categoryType; + + @ApiModelProperty("父级类目id|可选") + private Long parentId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.java new file mode 100644 index 0000000..959c702 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.business.category.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.domain.dto.CategoryBaseDTO; + +import javax.validation.constraints.NotNull; + +/** + * 类目 更新 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class CategoryUpdateForm extends CategoryAddForm { + + @ApiModelProperty("类目id") + @NotNull(message = "类目id不能为空") + private Long categoryId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.java new file mode 100644 index 0000000..db3ecda --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.business.category.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 类目 层级树 vo + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class CategoryTreeVO { + + @ApiModelProperty("类目id") + private Long categoryId; + + @ApiModelProperty("类目名称") + private String categoryName; + + @ApiModelProperty("类目层级全称") + private String categoryFullName; + + @ApiModelProperty("父级id") + private Long parentId; + + @ApiModelProperty("类目id") + private Long value; + + @ApiModelProperty("类目名称") + private String label; + + @ApiModelProperty("子类") + private List children; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.java new file mode 100644 index 0000000..23b7196 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.java @@ -0,0 +1,51 @@ +package net.lab1024.sa.admin.module.business.category.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.admin.module.business.category.domain.dto.CategoryBaseDTO; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * 类目 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class CategoryVO { + + @ApiModelProperty(value = "类目名称", required = true) + private String categoryName; + + @ApiModelPropertyEnum(desc = "分类类型", value = CategoryTypeEnum.class) + private Integer categoryType; + + @ApiModelProperty("父级类目id|可选") + private Long parentId; + + @ApiModelProperty("排序|可选") + private Integer sort; + + @ApiModelProperty("备注|可选") + private String remark; + + @ApiModelProperty("禁用状态") + private Boolean disabledFlag; + + @ApiModelProperty("类目id") + private Long categoryId; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.java new file mode 100644 index 0000000..819d99d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.java @@ -0,0 +1,120 @@ +package net.lab1024.sa.admin.module.business.category.manager; + +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.constant.AdminCacheConst; +import net.lab1024.sa.admin.module.business.category.dao.CategoryDao; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; +import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO; +import net.lab1024.sa.common.common.constant.StringConst; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 类目 查询 缓存 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +@Slf4j +public class CategoryCacheManager { + + + @Autowired + private CategoryDao categoryDao; + + + /** + * 根据类目id 移除缓存 + */ + @CacheEvict(value = {AdminCacheConst.CATEGORY.CATEGORY_ENTITY, AdminCacheConst.CATEGORY.CATEGORY_SUB, AdminCacheConst.CATEGORY.CATEGORY_TREE}, allEntries = true) + public void removeCache() { + log.info("clear CATEGORY ,CATEGORY_SUB ,CATEGORY_TREE"); + } + + /** + * 查詢类目 + * + * @param categoryId + * @return + */ + @Cacheable(AdminCacheConst.CATEGORY.CATEGORY_ENTITY) + public CategoryEntity queryCategory(Long categoryId) { + return categoryDao.selectById(categoryId); + } + + /** + * 查询类目 子级 + * + * @param categoryId + * @return + */ + @Cacheable(AdminCacheConst.CATEGORY.CATEGORY_SUB) + public List querySubCategory(Long categoryId) { + return categoryDao.queryByParentId(Lists.newArrayList(categoryId), false); + } + + + /** + * 查询类目 层级树 + * 优先查询缓存 + * + * @return + */ + @Cacheable(AdminCacheConst.CATEGORY.CATEGORY_TREE) + public List queryCategoryTree(Long parentId, Integer categoryType) { + List allCategoryEntityList = categoryDao.queryByType(categoryType, false); + + List categoryEntityList = allCategoryEntityList.stream().filter(e -> e.getParentId().equals(parentId)).collect(Collectors.toList()); + List treeList = SmartBeanUtil.copyList(categoryEntityList, CategoryTreeVO.class); + treeList.forEach(e -> { + e.setLabel(e.getCategoryName()); + e.setValue(e.getCategoryId()); + e.setCategoryFullName(e.getCategoryName()); + }); + // 递归设置子类 + this.queryAndSetSubCategory(treeList, allCategoryEntityList); + return treeList; + } + + /** + * 递归查询设置类目子类 + * 从缓存查询子类 + * + * @param treeList + */ + private void queryAndSetSubCategory(List treeList, List allCategoryEntityList) { + if (CollectionUtils.isEmpty(treeList)) { + return; + } + List parentIdList = treeList.stream().map(CategoryTreeVO::getValue).collect(Collectors.toList()); + List categoryEntityList = allCategoryEntityList.stream().filter(e -> parentIdList.contains(e.getParentId())).collect(Collectors.toList()); + Map> categorySubMap = categoryEntityList.stream().collect(Collectors.groupingBy(CategoryEntity::getParentId)); + treeList.forEach(e -> { + List childrenEntityList = categorySubMap.getOrDefault(e.getValue(), Lists.newArrayList()); + List childrenVOList = SmartBeanUtil.copyList(childrenEntityList, CategoryTreeVO.class); + childrenVOList.forEach(item -> { + item.setLabel(item.getCategoryName()); + item.setValue(item.getCategoryId()); + item.setCategoryFullName(e.getCategoryFullName() + StringConst.SEPARATOR_SLASH + item.getCategoryName()); + }); + // 递归查询 + this.queryAndSetSubCategory(childrenVOList, allCategoryEntityList); + e.setChildren(childrenVOList); + }); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.java new file mode 100644 index 0000000..4f643e6 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.java @@ -0,0 +1,214 @@ +package net.lab1024.sa.admin.module.business.category.service; + +import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.category.dao.CategoryDao; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; +import net.lab1024.sa.admin.module.business.category.domain.dto.CategorySimpleDTO; +import net.lab1024.sa.admin.module.business.category.manager.CategoryCacheManager; +import net.lab1024.sa.common.common.constant.StringConst; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 类目 查询 业务类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +@Slf4j +public class CategoryQueryService { + + private static final Long DEFAULT_CATEGORY_PARENT_ID = 0L; + + @Autowired + private CategoryDao categoryDao; + + @Autowired + private CategoryCacheManager categoryCacheManager; + + /** + * 根据 id 查询未删除的类目 + * + * @param categoryId + * @return 可能 null + */ + public Optional queryCategory(Long categoryId) { + if (null == categoryId) { + return Optional.empty(); + } + CategoryEntity entity = categoryCacheManager.queryCategory(categoryId); + if (null == entity || entity.getDeletedFlag()) { + return Optional.empty(); + } + return Optional.of(entity); + } + + + /** + * 根据 类目id集合 查询未删除的类目集合 + * + * @param categoryIdList + * @return + */ + public Map queryCategoryList(List categoryIdList) { + if (CollectionUtils.isEmpty(categoryIdList)) { + return Collections.emptyMap(); + } + categoryIdList = categoryIdList.stream().distinct().collect(Collectors.toList()); + Map categoryEntityMap = Maps.newHashMap(); + for (Long categoryId : categoryIdList) { + CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId); + if(categoryEntity != null){ + categoryEntityMap.put(categoryId, categoryEntity); + } + } + return categoryEntityMap; + } + + + /** + * 根据类目id 递归查询该id的所有子类id 递归查询 + * 同时存入缓存 + * 注意:查询出来的集合 不包含传递的父类参数 + * + * @param categoryIdList + */ + public List queryCategorySubId(List categoryIdList) { + if (CollectionUtils.isEmpty(categoryIdList)) { + return Collections.emptyList(); + } + //所有子类 + List categoryEntityList = Lists.newArrayList(); + categoryIdList.forEach(e -> { + categoryEntityList.addAll(categoryCacheManager.querySubCategory(e)); + }); + Map> subTypeMap = categoryEntityList.stream().collect(Collectors.groupingBy(CategoryEntity::getCategoryId)); + // 递归查询子类 + categoryIdList = subTypeMap.values().stream().flatMap(Collection::stream).map(CategoryEntity::getCategoryId).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(categoryIdList)) { + return Lists.newArrayList(); + } + categoryIdList.addAll(this.queryCategorySubId(categoryIdList)); + return categoryIdList; + } + + + /** + * 处理类目名称 + * + * @param categoryIdList + */ + public List queryCategoryName(List categoryIdList) { + if (CollectionUtils.isEmpty(categoryIdList)) { + return null; + } + Map categoryMap = this.queryCategoryList(categoryIdList); + List categoryNameList = Lists.newArrayList(); + categoryIdList.forEach(e -> { + CategoryEntity categoryEntity = categoryMap.get(e); + if (categoryEntity != null) { + categoryNameList.add(categoryMap.get(e).getCategoryName()); + } + }); + return categoryNameList; + } + + /** + * 根据类目id 查询类目名称 + * + * @param categoryId + * @return + */ + public String queryCategoryName(Long categoryId) { + CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId); + if (null == categoryEntity || categoryEntity.getDeletedFlag()) { + return null; + } + return categoryEntity.getCategoryName(); + } + + /** + * 根据类目id 查询类目详情 包含类目全称 如:医考/医师资格/临床执业 + * + * @param categoryId + * @return + */ + public CategorySimpleDTO queryCategoryInfo(Long categoryId) { + CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId); + if (null == categoryEntity || categoryEntity.getDeletedFlag()) { + return null; + } + String fullName = this.queryFullName(categoryId); + // 返回DTO + CategorySimpleDTO categoryDTO = new CategorySimpleDTO(); + categoryDTO.setCategoryId(categoryId); + categoryDTO.setCategoryName(categoryEntity.getCategoryName()); + categoryDTO.setCategoryFullName(fullName); + categoryDTO.setParentId(categoryEntity.getParentId()); + return categoryDTO; + } + + /** + * 递归查询分类和所有父级类目 + * ps:特别注意返回的集合中 包含自己 + * + * @param categoryId + * @return + */ + public List queryCategoryAndParent(Long categoryId) { + List parentCategoryList = Lists.newArrayList(); + CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId); + if (null == categoryEntity || categoryEntity.getDeletedFlag()) { + return parentCategoryList; + } + + // 父级始终放在第一位 + parentCategoryList.add(0, categoryEntity); + Long parentId = categoryEntity.getParentId(); + if (Objects.equals(DEFAULT_CATEGORY_PARENT_ID, parentId)) { + return parentCategoryList; + } + parentCategoryList.addAll(0, this.queryCategoryAndParent(parentId)); + return parentCategoryList; + } + + /** + * 查询 分类全称 如:医考/医师资格/临床执业 + * + * @param categoryId + * @return + */ + public String queryFullName(Long categoryId) { + List parentCategoryList = this.queryCategoryAndParent(categoryId); + // 拼接父级类目名称 斜杠分隔返回 + List nameList = parentCategoryList.stream().map(CategoryEntity::getCategoryName).collect(Collectors.toList()); + return StrUtil.join(StringConst.SEPARATOR_SLASH, nameList); + } + + /** + * 查询 分类全称 如:医考/医师资格/临床执业 + * + * @param categoryIdList + * @return + */ + public Map queryFullName(List categoryIdList) { + if (CollectionUtils.isEmpty(categoryIdList)) { + return Collections.EMPTY_MAP; + } + // 循环内查询的缓存 还ok + return categoryIdList.stream().collect(Collectors.toMap(Function.identity(), this::queryFullName)); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryService.java new file mode 100644 index 0000000..2dd1ae4 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryService.java @@ -0,0 +1,220 @@ +package net.lab1024.sa.admin.module.business.category.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.business.category.dao.CategoryDao; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryAddForm; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryTreeQueryForm; +import net.lab1024.sa.admin.module.business.category.domain.form.CategoryUpdateForm; +import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO; +import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryVO; +import net.lab1024.sa.admin.module.business.category.manager.CategoryCacheManager; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +/** + * 类目 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021/08/05 21:26:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +public class CategoryService { + + @Autowired + private CategoryDao categoryDao; + + @Autowired + private CategoryQueryService categoryQueryService; + + @Autowired + private CategoryCacheManager categoryCacheManager; + + /** + * 添加类目 + * + * @author 胡克 + * @date 2021/1/20 17:17 + */ + public ResponseDTO add(CategoryAddForm addForm) { + // 校验类目 + CategoryEntity categoryEntity = SmartBeanUtil.copy(addForm, CategoryEntity.class); + ResponseDTO res = this.checkCategory(categoryEntity, false); + if (!res.getOk()) { + return res; + } + // 没有父类则使用默认父类 + Long parentId = null == addForm.getParentId() ? NumberUtils.LONG_ZERO : addForm.getParentId(); + categoryEntity.setParentId(parentId); + categoryEntity.setSort(null == addForm.getSort() ? 0 : addForm.getSort()); + categoryEntity.setDeletedFlag(false); + + // 保存数据 + categoryDao.insert(categoryEntity); + + // 更新缓存 + categoryCacheManager.removeCache(); + return ResponseDTO.ok(); + } + + /** + * 更新类目 + * 不能更新父级类目 + * + * @author 胡克 + * @date 2021/1/20 17:17 + */ + public ResponseDTO update(CategoryUpdateForm updateForm) { + // 校验类目 + Long categoryId = updateForm.getCategoryId(); + Optional optional = categoryQueryService.queryCategory(categoryId); + if (!optional.isPresent()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + CategoryEntity categoryEntity = SmartBeanUtil.copy(updateForm, CategoryEntity.class); + + /** + * 不更新类目类型 + * 不更新父类id + */ + Integer categoryType = optional.get().getCategoryType(); + categoryEntity.setCategoryType(categoryType); + categoryEntity.setParentId(optional.get().getParentId()); + + ResponseDTO responseDTO = this.checkCategory(categoryEntity, true); + if (!responseDTO.getOk()) { + return responseDTO; + } + categoryDao.updateById(categoryEntity); + + // 更新缓存 + categoryCacheManager.removeCache(); + return ResponseDTO.ok(); + } + + /** + * 新增/更新 类目时的 校验 + * + * @param categoryEntity + * @param isUpdate + * @return + */ + private ResponseDTO checkCategory(CategoryEntity categoryEntity, boolean isUpdate) { + // 校验父级是否存在 + Long parentId = categoryEntity.getParentId(); + Integer categoryType = categoryEntity.getCategoryType(); + if (null != parentId) { + if (Objects.equals(categoryEntity.getCategoryId(), parentId)) { + return ResponseDTO.userErrorParam("父级类目怎么和自己相同了"); + } + if (!Objects.equals(parentId, NumberUtils.LONG_ZERO)) { + Optional optional = categoryQueryService.queryCategory(parentId); + if (!optional.isPresent()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST, "父级类目不存在~"); + } + + CategoryEntity parent = optional.get(); + if (!Objects.equals(categoryType, parent.getCategoryType())) { + return ResponseDTO.userErrorParam("与父级类目类型不一致"); + } + } + + } else { + // 如果没有父类 使用默认父类 + parentId = NumberUtils.LONG_ZERO; + } + + // 校验同父类下 名称是否重复 + CategoryEntity queryEntity = new CategoryEntity(); + queryEntity.setParentId(parentId); + queryEntity.setCategoryType(categoryType); + queryEntity.setCategoryName(categoryEntity.getCategoryName()); + queryEntity.setDeletedFlag(false); + queryEntity = categoryDao.selectOne(queryEntity); + if (null != queryEntity) { + if (isUpdate) { + if (!Objects.equals(queryEntity.getCategoryId(), categoryEntity.getCategoryId())) { + return ResponseDTO.userErrorParam("同级下已存在相同类目~"); + } + } else { + return ResponseDTO.userErrorParam("同级下已存在相同类目~"); + } + } + return ResponseDTO.ok(); + } + + /** + * 查询 类目详情 + * + * @param categoryId + * @return + */ + public ResponseDTO queryDetail(Long categoryId) { + Optional optional = categoryQueryService.queryCategory(categoryId); + if (!optional.isPresent()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + CategoryVO adminVO = SmartBeanUtil.copy(optional.get(), CategoryVO.class); + return ResponseDTO.ok(adminVO); + } + + /** + * 根据父级id 查询所有子类 返回层级树 + * 如果父类id 为空 返回所有类目层级 + * + * @param queryForm + * @return + */ + public ResponseDTO> queryTree(CategoryTreeQueryForm queryForm) { + if (null == queryForm.getParentId()) { + if (null == queryForm.getCategoryType()) { + return ResponseDTO.userErrorParam("类目类型不能为空"); + } + queryForm.setParentId(NumberUtils.LONG_ZERO); + } + List treeList = categoryCacheManager.queryCategoryTree(queryForm.getParentId(), queryForm.getCategoryType()); + return ResponseDTO.ok(treeList); + } + + /** + * 删除类目 + * 如果有未删除的子类 则无法删除 + * + * @param categoryId + * @return + */ + public ResponseDTO delete(Long categoryId) { + Optional optional = categoryQueryService.queryCategory(categoryId); + if (!optional.isPresent()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + List categorySubId = categoryQueryService.queryCategorySubId(Lists.newArrayList(categoryId)); + if (CollectionUtils.isNotEmpty(categorySubId)) { + return ResponseDTO.userErrorParam("请先删除子级类目"); + } + + // 更新数据 + CategoryEntity categoryEntity = new CategoryEntity(); + categoryEntity.setCategoryId(categoryId); + categoryEntity.setDeletedFlag(true); + categoryDao.updateById(categoryEntity); + + // 更新缓存 + categoryCacheManager.removeCache(); + return ResponseDTO.ok(); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.java new file mode 100644 index 0000000..8638da7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.admin.module.business.goods.constant; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 商品状态 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@AllArgsConstructor +@Getter +public enum GoodsStatusEnum implements BaseEnum { + + /** + * 1 预约中 + */ + APPOINTMENT(1, "预约中"), + + /** + * 2 售卖 + */ + SELL(2, "售卖中"), + + /** + * 3 售罄 + */ + SELL_OUT(3, "售罄"), + + + ; + + private final Integer value; + + private final String desc; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java new file mode 100644 index 0000000..06e13e6 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java @@ -0,0 +1,75 @@ +package net.lab1024.sa.admin.module.business.goods.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.common.AdminBaseController; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsAddForm; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsUpdateForm; +import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO; +import net.lab1024.sa.admin.module.business.goods.service.GoodsService; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.domain.ValidateList; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * 商品业务 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@OperateLog +@RestController +//@Api(tags = AdminSwaggerTagConst.Business.MANAGER_GOODS) +public class GoodsController extends AdminBaseController { + + @Autowired + private GoodsService goodsService; + + @ApiOperation("分页查询 @author 胡克") + @PostMapping("/goods/query") + @PreAuthorize("@saAuth.checkPermission('goods:query')") + public ResponseDTO> query(@RequestBody @Valid GoodsQueryForm queryForm) { + return goodsService.query(queryForm); + } + + @ApiOperation("添加商品 @author 胡克") + @PostMapping("/goods/add") + @PreAuthorize("@saAuth.checkPermission('goods:add')") + public ResponseDTO add(@RequestBody @Valid GoodsAddForm addForm) { + return goodsService.add(addForm); + } + + @ApiOperation("更新商品 @author 胡克") + @PostMapping("/goods/update") + @PreAuthorize("@saAuth.checkPermission('goods:update')") + public ResponseDTO update(@RequestBody @Valid GoodsUpdateForm updateForm) { + return goodsService.update(updateForm); + } + + @ApiOperation("删除 @author 卓大") + @GetMapping("/goods/delete/{goodsId}") + @PreAuthorize("@saAuth.checkPermission('goods:delete')") + public ResponseDTO delete(@PathVariable Long goodsId) { + return goodsService.delete(goodsId); + } + + @ApiOperation("批量 @author 卓大") + @PostMapping("/goods/batchDelete") + @PreAuthorize("@saAuth.checkPermission('goods:batchDelete')") + public ResponseDTO batchDelete(@RequestBody @Valid ValidateList idList) { + return goodsService.batchDelete(idList); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.java new file mode 100644 index 0000000..a0872ca --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.business.goods.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm; +import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 商品 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Mapper +@Component +public interface GoodsDao extends BaseMapper { + + /** + * 分页 查询商品 + * + * @param page + * @param query + * @return + */ + List query(Page page, @Param("query") GoodsQueryForm query); + + /** + * 批量更新删除状态 + */ + + void batchUpdateDeleted(@Param("goodsIdList")List goodsIdList,@Param("deletedFlag")Boolean deletedFlag); + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.java new file mode 100644 index 0000000..a2878a6 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.java @@ -0,0 +1,75 @@ +package net.lab1024.sa.admin.module.business.goods.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.admin.module.business.category.dao.CategoryDao; +import net.lab1024.sa.common.module.support.datatracer.annoation.DataTracerFieldBigDecimal; +import net.lab1024.sa.common.module.support.datatracer.annoation.DataTracerFieldLabel; +import net.lab1024.sa.common.module.support.datatracer.annoation.DataTracerFieldSql; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 商品 实体类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +@TableName("t_goods") +public class GoodsEntity { + + @TableId(type = IdType.AUTO) + private Long goodsId; + + /** + * 商品状态:[1:预约中,2:售卖中,3:售罄] + */ + private Integer goodsStatus; + + /** + * 商品分类 + */ + private Long categoryId; + + /** + * 商品名称 + */ + private String goodsName; + + /** + * 产地 + */ + private String place; + + /** + * 商品价格 + */ + private BigDecimal price; + + + /** + * 上架状态 + */ + private Boolean shelvesFlag; + + /** + * 删除状态 + */ + private Boolean deletedFlag; + + /** + * 备注 + */ + private String remark; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.java new file mode 100644 index 0000000..2747427 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.java @@ -0,0 +1,57 @@ +package net.lab1024.sa.admin.module.business.goods.domain.form; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum; +import net.lab1024.sa.common.common.json.deserializer.DictValueVoDeserializer; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * 商品 添加表单 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class GoodsAddForm { + + @ApiModelProperty("商品分类") + @NotNull(message = "商品分类不能为空") + private Long categoryId; + + @ApiModelProperty("商品名称") + @NotBlank(message = "商品名称不能为空") + private String goodsName; + + @ApiModelPropertyEnum(GoodsStatusEnum.class) + @CheckEnum(message = "商品状态错误", value = GoodsStatusEnum.class, required = true) + private Integer goodsStatus; + + @ApiModelProperty("产地") + @NotBlank(message = "产地 不能为空 ") + @JsonDeserialize(using = DictValueVoDeserializer.class) + private String place; + + @ApiModelProperty("商品价格") + @NotNull(message = "商品价格不能为空") + @DecimalMin(value = "0", message = "商品价格最低0") + private BigDecimal price; + + @ApiModelProperty("上架状态") + @NotNull(message = "上架状态不能为空") + private Boolean shelvesFlag; + + @ApiModelProperty("备注|可选") + private String remark; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.java new file mode 100644 index 0000000..e25e352 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.admin.module.business.goods.domain.form; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum; +import net.lab1024.sa.common.common.domain.PageParam; +import net.lab1024.sa.common.common.json.deserializer.DictValueVoDeserializer; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +/** + * 商品 分页查询 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class GoodsQueryForm extends PageParam { + + @ApiModelProperty("商品分类") + private Integer categoryId; + + @ApiModelProperty("搜索词") + @Length(max = 30, message = "搜索词最多30字符") + private String searchWord; + + @ApiModelPropertyEnum(GoodsStatusEnum.class) + @CheckEnum(message = "商品状态错误", value = GoodsStatusEnum.class, required = false) + private Integer goodsStatus; + + @ApiModelProperty("产地") + private String place; + + @ApiModelProperty("上架状态") + private Boolean shelvesFlag; + + @ApiModelProperty(hidden = true) + private Boolean deletedFlag; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.java new file mode 100644 index 0000000..f72656e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.business.goods.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 商品 更新表单 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class GoodsUpdateForm extends GoodsAddForm { + + @ApiModelProperty("商品id") + @NotNull(message = "商品id不能为空") + private Long goodsId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.java new file mode 100644 index 0000000..fe7eaaf --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.admin.module.business.goods.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum; +import net.lab1024.sa.common.common.json.serializer.DictValueVoSerializer; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 商品 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class GoodsVO { + + @ApiModelProperty("商品分类") + private Long categoryId; + + @ApiModelProperty("商品名称") + private String goodsName; + + @ApiModelPropertyEnum(GoodsStatusEnum.class) + private Integer goodsStatus; + + @ApiModelProperty("产地") + @JsonSerialize(using = DictValueVoSerializer.class) + private String place; + + @ApiModelProperty("商品价格") + private BigDecimal price; + + @ApiModelProperty("上架状态") + private Boolean shelvesFlag; + + @ApiModelProperty("备注|可选") + private String remark; + + @ApiModelProperty("商品id") + private Long goodsId; + + @ApiModelProperty("商品分类") + private String categoryName; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/manager/GoodsManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/manager/GoodsManager.java new file mode 100644 index 0000000..898b6aa --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/manager/GoodsManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.business.goods.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.business.goods.dao.GoodsDao; +import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity; +import org.springframework.stereotype.Service; + +/** + * 商品 manager + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +public class GoodsManager extends ServiceImpl { + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/service/GoodsService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/service/GoodsService.java new file mode 100644 index 0000000..dfbdd03 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/service/GoodsService.java @@ -0,0 +1,168 @@ +package net.lab1024.sa.admin.module.business.goods.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum; +import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity; +import net.lab1024.sa.admin.module.business.category.service.CategoryQueryService; +import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum; +import net.lab1024.sa.admin.module.business.goods.dao.GoodsDao; +import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsAddForm; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm; +import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsUpdateForm; +import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO; +import net.lab1024.sa.admin.module.business.goods.manager.GoodsManager; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 商品 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-10-25 20:26:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +public class GoodsService { + @Autowired + private GoodsDao goodsDao; + + @Autowired + private CategoryQueryService categoryQueryService; + + @Autowired + private DataTracerService dataTracerService; + + /** + * 添加商品 + * + * @param addForm + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO add(GoodsAddForm addForm) { + // 商品校验 + ResponseDTO res = this.checkGoods(addForm, null); + if (!res.getOk()) { + return res; + } + GoodsEntity goodsEntity = SmartBeanUtil.copy(addForm, GoodsEntity.class); + goodsEntity.setDeletedFlag(Boolean.FALSE); + goodsDao.insert(goodsEntity); + dataTracerService.insert(goodsEntity.getGoodsId(), DataTracerTypeEnum.GOODS); + return ResponseDTO.ok(); + } + + /** + * 更新商品 + * + * @param updateForm + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO update(GoodsUpdateForm updateForm) { + // 商品校验 + ResponseDTO res = this.checkGoods(updateForm, updateForm.getGoodsId()); + if (!res.getOk()) { + return res; + } + GoodsEntity originEntity = goodsDao.selectById(updateForm.getGoodsId()); + GoodsEntity goodsEntity = SmartBeanUtil.copy(updateForm, GoodsEntity.class); + goodsDao.updateById(goodsEntity); + dataTracerService.update(updateForm.getGoodsId(), DataTracerTypeEnum.GOODS, originEntity, goodsEntity); + return ResponseDTO.ok(); + } + + /** + * 添加/更新 商品校验 + * + * @param addForm + * @param goodsId 不为空 代表更新商品 + * @return + */ + private ResponseDTO checkGoods(GoodsAddForm addForm, Long goodsId) { + // 校验类目id + Long categoryId = addForm.getCategoryId(); + Optional optional = categoryQueryService.queryCategory(categoryId); + if (!optional.isPresent() || !CategoryTypeEnum.GOODS.equalsValue(optional.get().getCategoryType())) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST, "商品类目不存在~"); + } + + return ResponseDTO.ok(); + } + + /** + * 删除 + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO delete(Long goodsId) { + GoodsEntity goodsEntity = goodsDao.selectById(goodsId); + if (goodsEntity == null) { + return ResponseDTO.userErrorParam("商品不存在"); + } + + if (!goodsEntity.getGoodsStatus().equals(GoodsStatusEnum.SELL_OUT.getValue())) { + return ResponseDTO.userErrorParam("只有售罄的商品才可以删除"); + } + + batchDelete(Arrays.asList(goodsId)); + dataTracerService.batchDelete(Arrays.asList(goodsId), DataTracerTypeEnum.GOODS); + return ResponseDTO.ok(); + } + + /** + * 批量删除 + */ + public ResponseDTO batchDelete(List goodsIdList) { + if (CollectionUtils.isEmpty(goodsIdList)) { + return ResponseDTO.ok(); + } + + goodsDao.batchUpdateDeleted(goodsIdList, Boolean.TRUE); + return ResponseDTO.ok(); + } + + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public ResponseDTO> query(GoodsQueryForm queryForm) { + queryForm.setDeletedFlag(false); + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = goodsDao.query(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + if (pageResult.getEmptyFlag()) { + return ResponseDTO.ok(pageResult); + } + // 查询分类名称 + List categoryIdList = list.stream().map(GoodsVO::getCategoryId).distinct().collect(Collectors.toList()); + Map categoryMap = categoryQueryService.queryCategoryList(categoryIdList); + list.forEach(e -> { + CategoryEntity categoryEntity = categoryMap.get(e.getCategoryId()); + if (categoryEntity != null) { + e.setCategoryName(categoryEntity.getCategoryName()); + } + }); + return ResponseDTO.ok(pageResult); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java new file mode 100644 index 0000000..b4afd17 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java @@ -0,0 +1,74 @@ +package net.lab1024.sa.admin.module.business.oa.bank; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankCreateForm; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankUpdateForm; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankVO; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * OA办公-OA银行信息 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@RestController +//@Api(tags = {AdminSwaggerTagConst.Business.OA_BANK}) +public class BankController { + + @Autowired + private BankService bankService; + + @ApiOperation(value = "分页查询银行信息 @author 善逸") + @PostMapping("/oa/bank/page/query") + public ResponseDTO> queryByPage(@RequestBody @Valid BankQueryForm queryDTO) { + return bankService.queryByPage(queryDTO); + } + + @ApiOperation(value = "根据企业ID查询银行信息列表 @author 善逸") + @GetMapping("/oa/bank/query/list/{enterpriseId}") + public ResponseDTO> queryList(@PathVariable Long enterpriseId) { + return bankService.queryList(enterpriseId); + } + + @ApiOperation(value = "查询银行信息详情 @author 善逸") + @GetMapping("/oa/bank/get/{bankId}") + public ResponseDTO getDetail(@PathVariable Long bankId) { + return bankService.getDetail(bankId); + } + + @ApiOperation(value = "新建银行信息 @author 善逸") + @PostMapping("/oa/bank/create") + public ResponseDTO createBank(@RequestBody @Valid BankCreateForm createVO) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + createVO.setCreateUserId(requestUser.getUserId()); + createVO.setCreateUserName(requestUser.getUserName()); + return bankService.createBank(createVO); + } + + @ApiOperation(value = "编辑银行信息 @author 善逸") + @PostMapping("/oa/bank/update") + public ResponseDTO updateBank(@RequestBody @Valid BankUpdateForm updateVO) { + return bankService.updateBank(updateVO); + } + + @ApiOperation(value = "删除银行信息 @author 善逸") + @GetMapping("/oa/bank/delete/{bankId}") + public ResponseDTO deleteBank(@PathVariable Long bankId) { + return bankService.deleteBank(bankId); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankDao.java new file mode 100644 index 0000000..a45d406 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankDao.java @@ -0,0 +1,61 @@ +package net.lab1024.sa.admin.module.business.oa.bank; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankEntity; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm; +import net.lab1024.sa.admin.module.business.oa.bank.domain.BankVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * OA办公-OA银行信息 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Mapper +@Component +public interface BankDao extends BaseMapper { + + /** + * 根据账号查询 + * @param enterpriseId + * @param accountNumber + * @param excludeBankId + * @param deletedFlag + * @return + */ + BankEntity queryByAccountNumber(@Param("enterpriseId") Long enterpriseId, @Param("accountNumber") String accountNumber, @Param("excludeBankId") Long excludeBankId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 删除银行信息 + * + * @param bankId + * @param deletedFlag + */ + void deleteBank(@Param("bankId") Long bankId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 银行信息分页查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") BankQueryForm queryForm); + + /** + * 查询银行信息详情 + * @param bankId + * @param deletedFlag + * @return + */ + BankVO getDetail(@Param("bankId") Long bankId, @Param("deletedFlag") Boolean deletedFlag); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankService.java new file mode 100644 index 0000000..48c120b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankService.java @@ -0,0 +1,162 @@ +package net.lab1024.sa.admin.module.business.oa.bank; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.oa.bank.domain.*; +import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseDao; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerConst; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Objects; + +/** + * OA办公-OA银行信息 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +@Slf4j +public class BankService { + + @Autowired + private BankDao bankDao; + @Autowired + private EnterpriseDao enterpriseDao; + + @Autowired + private DataTracerService dataTracerService; + + /** + * 分页查询银行信息 + * + * @param queryDTO + * @return + */ + public ResponseDTO> queryByPage(BankQueryForm queryDTO) { + queryDTO.setDeletedFlag(Boolean.FALSE); + Page page = SmartPageUtil.convert2PageQuery(queryDTO); + List bankVOS = bankDao.queryPage(page, queryDTO); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, bankVOS); + return ResponseDTO.ok(pageResult); + } + + /** + * 根据企业ID查询不分页的银行列表 + * + * @param enterpriseId + * @return + */ + public ResponseDTO> queryList(Long enterpriseId) { + BankQueryForm queryDTO = new BankQueryForm(); + queryDTO.setEnterpriseId(enterpriseId); + queryDTO.setDeletedFlag(Boolean.FALSE); + List bankVOS = bankDao.queryPage(null, queryDTO); + return ResponseDTO.ok(bankVOS); + } + + /** + * 查询银行信息详情 + * + * @param bankId + * @return + */ + public ResponseDTO getDetail(Long bankId) { + // 校验银行信息是否存在 + BankVO bankVO = bankDao.getDetail(bankId, Boolean.FALSE); + if (Objects.isNull(bankVO)) { + return ResponseDTO.userErrorParam("银行信息不存在"); + } + return ResponseDTO.ok(bankVO); + } + + /** + * 新建银行信息 + * + * @param createVO + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO createBank(BankCreateForm createVO) { + Long enterpriseId = createVO.getEnterpriseId(); + // 校验企业是否存在 + EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId); + if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("企业不存在"); + } + // 验证银行信息账号是否重复 + BankEntity validateBank = bankDao.queryByAccountNumber(enterpriseId, createVO.getAccountNumber(), null, Boolean.FALSE); + if (Objects.nonNull(validateBank)) { + return ResponseDTO.userErrorParam("银行信息账号重复"); + } + // 数据插入 + BankEntity insertBank = SmartBeanUtil.copy(createVO, BankEntity.class); + bankDao.insert(insertBank); + dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "新增银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(insertBank)); + return ResponseDTO.ok(); + } + + /** + * 编辑银行信息 + * + * @param updateVO + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateBank(BankUpdateForm updateVO) { + Long enterpriseId = updateVO.getEnterpriseId(); + // 校验企业是否存在 + EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId); + if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("企业不存在"); + } + Long bankId = updateVO.getBankId(); + // 校验银行信息是否存在 + BankEntity bankDetail = bankDao.selectById(bankId); + if (Objects.isNull(bankDetail) || bankDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("银行信息不存在"); + } + // 验证银行信息账号是否重复 + BankEntity validateBank = bankDao.queryByAccountNumber(updateVO.getEnterpriseId(), updateVO.getAccountNumber(), bankId, Boolean.FALSE); + if (Objects.nonNull(validateBank)) { + return ResponseDTO.userErrorParam("银行信息账号重复"); + } + // 数据编辑 + BankEntity updateBank = SmartBeanUtil.copy(updateVO, BankEntity.class); + bankDao.updateById(updateBank); + dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "更新银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(bankDetail, updateBank)); + return ResponseDTO.ok(); + } + + + /** + * 删除银行信息 + * + * @param bankId + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO deleteBank(Long bankId) { + // 校验银行信息是否存在 + BankEntity bankDetail = bankDao.selectById(bankId); + if (Objects.isNull(bankDetail) || bankDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("银行信息不存在"); + } + bankDao.deleteBank(bankId, Boolean.TRUE); + dataTracerService.addTrace(bankDetail.getEnterpriseId(), DataTracerTypeEnum.OA_ENTERPRISE, "删除银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(bankDetail)); + return ResponseDTO.ok(); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.java new file mode 100644 index 0000000..031ceb7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.admin.module.business.oa.bank.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * OA办公-银行信息新建 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class BankCreateForm { + + @ApiModelProperty("开户银行") + @NotBlank(message = "开户银行不能为空") + @Length(max = 200, message = "开户银行最多200字符") + private String bankName; + + @ApiModelProperty("账户名称") + @NotBlank(message = "账户名称不能为空") + @Length(max = 200, message = "账户名称最多200字符") + private String accountName; + + @ApiModelProperty("账号") + @NotBlank(message = "账号不能为空") + @Length(max = 200, message = "账号最多200字符") + private String accountNumber; + + @ApiModelProperty("备注") + @Length(max = 500, message = "备注最多500字符") + private String remark; + + @ApiModelProperty("是否对公") + @NotNull(message = "是否对公不能为空") + private Boolean businessFlag; + + @ApiModelProperty("企业") + @NotNull(message = "企业不能为空") + private Long enterpriseId; + + @ApiModelProperty("禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; + + @ApiModelProperty(value = "创建人", hidden = true) + private Long createUserId; + + @ApiModelProperty(value = "创建人", hidden = true) + private String createUserName; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.java new file mode 100644 index 0000000..0b3ec08 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.java @@ -0,0 +1,95 @@ +package net.lab1024.sa.admin.module.business.oa.bank.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.common.module.support.datatracer.annoation.DataTracerFieldLabel; + +import java.time.LocalDateTime; + +/** + * OA办公-OA银行信息 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +@TableName("t_oa_bank") +public class BankEntity { + + /** + * 银行信息ID + */ + @TableId(type = IdType.AUTO) + @DataTracerFieldLabel("银行信息ID") + private Long bankId; + + /** + * 开户银行 + */ + @DataTracerFieldLabel("开户银行") + private String bankName; + + /** + * 账户名称 + */ + @DataTracerFieldLabel("账户名称") + private String accountName; + + /** + * 账号 + */ + @DataTracerFieldLabel("账号") + private String accountNumber; + + /** + * 备注 + */ + @DataTracerFieldLabel("备注") + private String remark; + + /** + * 是否对公 + */ + @DataTracerFieldLabel("是否对公") + private Boolean businessFlag; + + /** + * 企业ID + */ + private Long enterpriseId; + + /** + * 禁用状态 + */ + @DataTracerFieldLabel("禁用状态") + private Boolean disabledFlag; + + /** + * 删除状态 + */ + private Boolean deletedFlag; + + /** + * 创建人ID + */ + private Long createUserId; + + /** + * 创建人ID + */ + private String createUserName; + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.java new file mode 100644 index 0000000..839b02f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.business.oa.bank.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; + +/** + * OA办公-OA银行信息查询 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class BankQueryForm extends PageParam { + + @ApiModelProperty("企业ID") + private Long enterpriseId; + + @ApiModelProperty("关键字") + @Length(max = 200, message = "关键字最多200字符") + private String keywords; + + @ApiModelProperty("开始时间") + private LocalDate startTime; + + @ApiModelProperty("结束时间") + private LocalDate endTime; + + @ApiModelProperty("禁用状态") + private Boolean disabledFlag; + + @ApiModelProperty(value = "删除状态", hidden = true) + private Boolean deletedFlag; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.java new file mode 100644 index 0000000..db8a2c7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.business.oa.bank.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * OA办公-银行信息更新 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class BankUpdateForm extends BankCreateForm { + + @ApiModelProperty("银行信息ID") + @NotNull(message = "银行信息ID不能为空") + private Long bankId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.java new file mode 100644 index 0000000..5cfcb5b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.admin.module.business.oa.bank.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * OA办公-OA银行信息 + * + * @Author 1024创新实验室:善逸 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class BankVO { + + @ApiModelProperty("银行信息ID") + private Long bankId; + + @ApiModelProperty("开户银行") + private String bankName; + + @ApiModelProperty("账户名称") + private String accountName; + + @ApiModelProperty("账号") + private String accountNumber; + + @ApiModelProperty("备注") + private String remark; + + @ApiModelProperty("是否对公") + private Boolean businessFlag; + + @ApiModelProperty("企业ID") + private Long enterpriseId; + + @ApiModelProperty("企业名称") + private String enterpriseName; + + @ApiModelProperty("禁用状态") + private Boolean disabledFlag; + + @ApiModelProperty("创建人ID") + private Long createUserId; + + @ApiModelProperty("创建人名称") + private String createUserName; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java new file mode 100644 index 0000000..76eccb4 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java @@ -0,0 +1,115 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.*; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO; +import net.lab1024.sa.common.common.annoation.SaAuth; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 企业 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Slf4j +@RestController +@OperateLog +//@Api(tags = {AdminSwaggerTagConst.Business.OA_ENTERPRISE}) +public class EnterpriseController { + + @Autowired + private EnterpriseService enterpriseService; + + @ApiOperation(value = "分页查询企业模块 @author 开云") + @PostMapping("/oa/enterprise/page/query") + @SaAuth + public ResponseDTO> queryByPage(@RequestBody @Valid EnterpriseQueryForm queryDTO) { + return enterpriseService.queryByPage(queryDTO); + } + + @ApiOperation(value = "查询企业详情 @author 开云") + @GetMapping("/oa/enterprise/get/{enterpriseId}") + @SaAuth + public ResponseDTO getDetail(@PathVariable Long enterpriseId) { + return ResponseDTO.ok(enterpriseService.getDetail(enterpriseId)); + } + + @ApiOperation(value = "新建企业 @author 开云") + @PostMapping("/oa/enterprise/create") + @SaAuth + public ResponseDTO createEnterprise(@RequestBody @Valid EnterpriseCreateForm createVO) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + createVO.setCreateUserId(requestUser.getUserId()); + createVO.setCreateUserName(requestUser.getUserName()); + return enterpriseService.createEnterprise(createVO); + } + + @ApiOperation(value = "编辑企业 @author 开云") + @PostMapping("/oa/enterprise/update") + @SaAuth + public ResponseDTO updateEnterprise(@RequestBody @Valid EnterpriseUpdateForm updateVO) { + return enterpriseService.updateEnterprise(updateVO); + } + + @ApiOperation(value = "删除企业 @author 开云") + @GetMapping("/oa/enterprise/delete/{enterpriseId}") + @SaAuth + public ResponseDTO deleteEnterprise(@PathVariable Long enterpriseId) { + return enterpriseService.deleteEnterprise(enterpriseId); + } + + @ApiOperation(value = "企业列表查询 @author 开云") + @GetMapping("/oa/enterprise/query/list") + @SaAuth + public ResponseDTO> queryList(@RequestParam(value = "type", required = false) Integer type) { + return enterpriseService.queryList(type); + } + + + @ApiOperation(value = "企业添加员工 @author 罗伊") + @PostMapping("/oa/enterprise/employee/add") + @SaAuth + public ResponseDTO addEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) { + return enterpriseService.addEmployee(enterpriseEmployeeForm); + } + + @ApiOperation(value = "查询企业全部员工 @author 罗伊") + @PostMapping("/oa/enterprise/employee/list") + @SaAuth + public ResponseDTO> employeeList(@RequestBody @Valid List enterpriseIdList) { + return ResponseDTO.ok(enterpriseService.employeeList(enterpriseIdList)); + } + + @ApiOperation(value = "分页查询企业员工 @author 卓大") + @PostMapping("/oa/enterprise/employee/queryPage") + @SaAuth + public ResponseDTO> queryPageEmployeeList(@RequestBody @Valid EnterpriseEmployeeQueryForm queryForm) { + return ResponseDTO.ok(enterpriseService.queryPageEmployeeList(queryForm)); + } + + + @ApiOperation(value = "企业删除员工 @author 罗伊") + @PostMapping("/oa/enterprise/employee/delete") + @SaAuth + public ResponseDTO deleteEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) { + return enterpriseService.deleteEmployee(enterpriseEmployeeForm); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseEmployeeManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseEmployeeManager.java new file mode 100644 index 0000000..1ac3fd5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseEmployeeManager.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseEmployeeDao; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity; +import org.springframework.stereotype.Service; + +/** + * 企业员工关系 manager + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +public class EnterpriseEmployeeManager extends ServiceImpl { +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseService.java new file mode 100644 index 0000000..b065d3b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseService.java @@ -0,0 +1,252 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise; + +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseDao; +import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseEmployeeDao; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.*; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.common.module.support.datatracer.domain.form.DataTracerForm; +import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 企业 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +@Slf4j +public class EnterpriseService { + + @Autowired + private EnterpriseDao enterpriseDao; + + @Autowired + private EnterpriseEmployeeDao enterpriseEmployeeDao; + + @Autowired + private EnterpriseEmployeeManager enterpriseEmployeeManager; + + @Autowired + private DataTracerService dataTracerService; + + @Autowired + private DepartmentService departmentService; + + /** + * 分页查询企业模块 + * + * @param queryDTO + * @return + */ + public ResponseDTO> queryByPage(EnterpriseQueryForm queryDTO) { + queryDTO.setDeletedFlag(Boolean.FALSE); + Page page = SmartPageUtil.convert2PageQuery(queryDTO); + List enterpriseVOS = enterpriseDao.queryPage(page, queryDTO); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, enterpriseVOS); + return ResponseDTO.ok(pageResult); + } + + /** + * 查询企业详情 + * + * @param enterpriseId + * @return + */ + public EnterpriseVO getDetail(Long enterpriseId) { + EnterpriseVO enterpriseDetail = enterpriseDao.getDetail(enterpriseId, Boolean.FALSE); + return enterpriseDetail; + } + + /** + * 新建企业 + * + * @param createVO + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO createEnterprise(EnterpriseCreateForm createVO) { + // 验证企业名称是否重复 + EnterpriseEntity validateEnterprise = enterpriseDao.queryByEnterpriseName(createVO.getEnterpriseName(), null, Boolean.FALSE); + if (Objects.nonNull(validateEnterprise)) { + return ResponseDTO.userErrorParam("企业名称重复"); + } + // 数据插入 + EnterpriseEntity insertEnterprise = SmartBeanUtil.copy(createVO, EnterpriseEntity.class); + enterpriseDao.insert(insertEnterprise); + dataTracerService.insert(insertEnterprise.getEnterpriseId(), DataTracerTypeEnum.OA_ENTERPRISE); + return ResponseDTO.ok(); + } + + /** + * 编辑企业 + * + * @param updateVO + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateEnterprise(EnterpriseUpdateForm updateVO) { + Long enterpriseId = updateVO.getEnterpriseId(); + // 校验企业是否存在 + EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId); + if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("企业不存在"); + } + // 验证企业名称是否重复 + EnterpriseEntity validateEnterprise = enterpriseDao.queryByEnterpriseName(updateVO.getEnterpriseName(), enterpriseId, Boolean.FALSE); + if (Objects.nonNull(validateEnterprise)) { + return ResponseDTO.userErrorParam("企业名称重复"); + } + // 数据编辑 + EnterpriseEntity updateEntity = SmartBeanUtil.copy(enterpriseDetail, EnterpriseEntity.class); + SmartBeanUtil.copyProperties(updateVO, updateEntity); + enterpriseDao.updateById(updateEntity); + + //变更记录 + DataTracerForm dataTracerForm = DataTracerForm.builder() + .dataId(updateVO.getEnterpriseId()) + .type(DataTracerTypeEnum.OA_ENTERPRISE) + .content("修改企业信息") + .diffOld(dataTracerService.getChangeContent(enterpriseDetail)) + .diffNew(dataTracerService.getChangeContent(updateEntity)) + .build(); + + dataTracerService.addTrace(dataTracerForm); + return ResponseDTO.ok(); + } + + + /** + * 删除企业 + * + * @param enterpriseId + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO deleteEnterprise(Long enterpriseId) { + // 校验企业是否存在 + EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId); + if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("企业不存在"); + } + enterpriseDao.deleteEnterprise(enterpriseId, Boolean.TRUE); + dataTracerService.delete(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE); + return ResponseDTO.ok(); + } + + /** + * 企业列表查询 + * + * @return + */ + public ResponseDTO> queryList(Integer type) { + List enterpriseListVOS = enterpriseDao.queryList(type, Boolean.FALSE, Boolean.FALSE); + return ResponseDTO.ok(enterpriseListVOS); + } + + //----------------------------------------- 以下为员工相关-------------------------------------------- + + /** + * 企业添加员工 + * + * @param enterpriseEmployeeForm + * @return + */ + public synchronized ResponseDTO addEmployee(EnterpriseEmployeeForm enterpriseEmployeeForm) { + Long enterpriseId = enterpriseEmployeeForm.getEnterpriseId(); + EnterpriseEntity enterpriseEntity = enterpriseDao.selectById(enterpriseId); + if (enterpriseEntity == null || enterpriseEntity.getDeletedFlag()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + //过滤掉已存在的员工 + List waitAddEmployeeIdList = enterpriseEmployeeForm.getEmployeeIdList(); + List enterpriseEmployeeEntityList = enterpriseEmployeeDao.selectByEnterpriseAndEmployeeIdList(enterpriseId, waitAddEmployeeIdList); + if (CollectionUtils.isNotEmpty(enterpriseEmployeeEntityList)) { + List existEmployeeIdList = enterpriseEmployeeEntityList.stream().map(EnterpriseEmployeeEntity::getEmployeeId).collect(Collectors.toList()); + waitAddEmployeeIdList = waitAddEmployeeIdList.stream().filter(e -> !existEmployeeIdList.contains(e)).collect(Collectors.toList()); + } + if (CollectionUtils.isEmpty(waitAddEmployeeIdList)) { + return ResponseDTO.ok(); + } + List batchAddList = Lists.newArrayList(); + for (Long employeeId : waitAddEmployeeIdList) { + EnterpriseEmployeeEntity enterpriseEmployeeEntity = new EnterpriseEmployeeEntity(); + enterpriseEmployeeEntity.setEnterpriseId(enterpriseId); + enterpriseEmployeeEntity.setEmployeeId(employeeId); + batchAddList.add(enterpriseEmployeeEntity); + } + enterpriseEmployeeManager.saveBatch(batchAddList); + return ResponseDTO.ok(); + } + + /** + * 企业删除员工 + * + * @param enterpriseEmployeeForm + * @return + */ + public synchronized ResponseDTO deleteEmployee(EnterpriseEmployeeForm enterpriseEmployeeForm) { + Long enterpriseId = enterpriseEmployeeForm.getEnterpriseId(); + EnterpriseEntity enterpriseEntity = enterpriseDao.selectById(enterpriseId); + if (enterpriseEntity == null || enterpriseEntity.getDeletedFlag()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + List waitDeleteEmployeeIdList = enterpriseEmployeeForm.getEmployeeIdList(); + enterpriseEmployeeDao.deleteByEnterpriseAndEmployeeIdList(enterpriseId, waitDeleteEmployeeIdList); + return ResponseDTO.ok(); + } + + /** + * 企业下员工列表 + * + * @param enterpriseIdList + * @return + */ + public List employeeList(List enterpriseIdList) { + if (CollectionUtils.isEmpty(enterpriseIdList)) { + return Lists.newArrayList(); + } + List enterpriseEmployeeVOList = enterpriseEmployeeDao.selectByEnterpriseIdList(enterpriseIdList); + return enterpriseEmployeeVOList; + } + + /** + * 分页查询企业员工 + * + * @param queryForm + * @return + */ + public PageResult queryPageEmployeeList(EnterpriseEmployeeQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List enterpriseEmployeeVOList = enterpriseEmployeeDao.queryPageEmployeeList(page, queryForm); + for (EnterpriseEmployeeVO enterpriseEmployeeVO : enterpriseEmployeeVOList) { + enterpriseEmployeeVO.setDepartmentName(departmentService.getDepartmentPath(enterpriseEmployeeVO.getDepartmentId())); + } + return SmartPageUtil.convert2PageResult(page, enterpriseEmployeeVOList); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.java new file mode 100644 index 0000000..ddbf5f7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.constant; + + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 企业类型 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +public enum EnterpriseTypeEnum implements BaseEnum { + + NORMAL(1, "有限企业"), + + FOREIGN(2, "外资企业"), + ; + + private Integer value; + private String desc; + + EnterpriseTypeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.java new file mode 100644 index 0000000..5b58609 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.java @@ -0,0 +1,72 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.EnterpriseQueryForm; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 企业 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Mapper +@Component +public interface EnterpriseDao extends BaseMapper { + + /** + * 根据企业名称查询 + * + * @param enterpriseName + * @param excludeEnterpriseId + * @param deletedFlag + * @return + */ + EnterpriseEntity queryByEnterpriseName(@Param("enterpriseName") String enterpriseName, @Param("excludeEnterpriseId") Long excludeEnterpriseId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 删除企业 + * + * @param enterpriseId + * @param deletedFlag + */ + void deleteEnterprise(@Param("enterpriseId") Long enterpriseId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 企业分页查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") EnterpriseQueryForm queryForm); + + /** + * 查询企业详情 + * + * @param enterpriseId + * @return + */ + EnterpriseVO getDetail(@Param("enterpriseId") Long enterpriseId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 查询列表 + * + * @param type + * @param disabledFlag + * @param deletedFlag + * @return + */ + List queryList(@Param("type") Integer type, @Param("disabledFlag") Boolean disabledFlag, @Param("deletedFlag") Boolean deletedFlag); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.java new file mode 100644 index 0000000..9380871 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.java @@ -0,0 +1,88 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.EnterpriseEmployeeQueryForm; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; + +/** + * 企业员工 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Mapper +@Component +public interface EnterpriseEmployeeDao extends BaseMapper { + + + /** + * 根据员工查询 + * @param employeeIdList + * @return + */ + List selectByEmployeeIdList(@Param("employeeIdList")Collection employeeIdList); + + /** + * 查询员工关联的企业 + * @param employeeId + * @return + */ + List selectEnterpriseIdByEmployeeId(@Param("employeeId")Long employeeId); + /** + * 根据企业查询 + * @param enterpriseIdList + * @return + */ + List selectByEnterpriseIdList(@Param("enterpriseIdList")Collection enterpriseIdList); + /** + * 根据企业查询 + * @param enterpriseId + * @return + */ + List selectByEnterpriseId(@Param("enterpriseId")Long enterpriseId); + + /** + * 查询企业下的所有员工id + * @param enterpriseIdList + * @return + */ + List selectEmployeeIdByEnterpriseIdList(@Param("enterpriseIdList")Collection enterpriseIdList); + /** + * 根据员工删除 + * @param enterpriseId + * @param employeeIdList + */ + void deleteByEnterpriseAndEmployeeIdList(@Param("enterpriseId")Long enterpriseId, @Param("employeeIdList")Collection employeeIdList); + + /** + * 根据员工查询 + * @param enterpriseId + * @param employeeIdList + */ + List selectByEnterpriseAndEmployeeIdList(@Param("enterpriseId")Long enterpriseId, @Param("employeeIdList")Collection employeeIdList); + + /** + * 删除某员工关联的所有企业 + * @param employeeId + */ + void deleteByEmployeeId(@Param("employeeId")Long employeeId); + + /** + * 分页查询企业员工 + * @param page + * @param queryForm + * @return + */ + List queryPageEmployeeList(Page page,@Param("queryForm") EnterpriseEmployeeQueryForm queryForm); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.java new file mode 100644 index 0000000..a4c9b8e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.java @@ -0,0 +1,51 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 企业员工 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +@TableName("t_oa_enterprise_employee") +@NoArgsConstructor +public class EnterpriseEmployeeEntity { + + @TableId(type = IdType.AUTO) + private Long enterpriseEmployeeId; + + /** + * 企业ID + */ + private Long enterpriseId; + /** + * 员工 + */ + private Long employeeId; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + public EnterpriseEmployeeEntity(Long enterpriseId, Long employeeId) { + this.enterpriseId = enterpriseId; + this.employeeId = employeeId; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.java new file mode 100644 index 0000000..67b4c48 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.java @@ -0,0 +1,153 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum; +import net.lab1024.sa.common.module.support.datatracer.annoation.DataTracerFieldEnum; +import net.lab1024.sa.common.module.support.datatracer.annoation.DataTracerFieldLabel; + +import java.time.LocalDateTime; + +/** + * 企业 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +@TableName("t_oa_enterprise") +public class EnterpriseEntity { + + /** + * 企业ID + */ + @TableId(type = IdType.AUTO) + private Long enterpriseId; + + /** + * 企业名称 + */ + @DataTracerFieldLabel("企业名称") + private String enterpriseName; + + /** + * 企业logo + */ + @DataTracerFieldLabel("企业logo") + private String enterpriseLogo; + + /** + * 统一社会信用代码 + */ + @DataTracerFieldLabel("统一社会信用代码") + private String unifiedSocialCreditCode; + + /** + * 类型 + * + * @see EnterpriseTypeEnum + */ + @DataTracerFieldLabel("类型") + @DataTracerFieldEnum(enumClass = EnterpriseTypeEnum.class) + private Integer type; + + /** + * 联系人 + */ + @DataTracerFieldLabel("联系人") + private String contact; + + /** + * 联系人电话 + */ + @DataTracerFieldLabel("联系人电话") + private String contactPhone; + + /** + * 邮箱 + */ + @DataTracerFieldLabel("邮箱") + private String email; + + /** + * 省份 + */ + private Integer province; + + /** + * 省份名称 + */ + @DataTracerFieldLabel("省份名称") + private String provinceName; + + /** + * 城市 + */ + private Integer city; + + /** + * 城市名称 + */ + @DataTracerFieldLabel("城市名称") + private String cityName; + + /** + * 区县 + */ + private Integer district; + + /** + * 区县名称 + */ + @DataTracerFieldLabel("区县名称") + private String districtName; + + /** + * 详细地址 + */ + @DataTracerFieldLabel("详细地址") + private String address; + + /** + * 营业执照 + */ + @DataTracerFieldLabel("营业执照") + private String businessLicense; + + /** + * 禁用状态 + */ + @DataTracerFieldLabel("禁用状态") + private Boolean disabledFlag; + + /** + * 删除状态 + */ + @DataTracerFieldLabel("删除状态") + private Boolean deletedFlag; + + /** + * 创建人ID + */ + private Long createUserId; + + /** + * 创建人ID + */ + private String createUserName; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.java new file mode 100644 index 0000000..a64a2e6 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.java @@ -0,0 +1,98 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum; +import net.lab1024.sa.common.common.json.deserializer.FileKeyVoDeserializer; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.util.SmartVerificationUtil; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +/** + * OA企业模块创建 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class EnterpriseCreateForm { + + @ApiModelProperty("企业名称") + @NotBlank(message = "企业名称不能为空") + @Length(max = 200, message = "企业名称最多200字符") + private String enterpriseName; + + @ApiModelProperty("企业logo") + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String enterpriseLogo; + + @ApiModelProperty("统一社会信用代码") + @NotBlank(message = "统一社会信用代码不能为空") + @Length(max = 200, message = "统一社会信用代码最多200字符") + private String unifiedSocialCreditCode; + + @ApiModelProperty("联系人") + @NotBlank(message = "联系人不能为空") + @Length(max = 100, message = "联系人最多100字符") + private String contact; + + @ApiModelProperty("联系人电话") + @NotBlank(message = "联系人电话不能为空") + @Pattern(regexp = SmartVerificationUtil.PHONE_REGEXP, message = "手机号格式不正确") + private String contactPhone; + + @ApiModelPropertyEnum(desc = "类型", value = EnterpriseTypeEnum.class) + @CheckEnum(message = "类型不正确", value = EnterpriseTypeEnum.class) + private Integer type; + + @ApiModelProperty("邮箱") + @Pattern(regexp = SmartVerificationUtil.EMAIL, message = "邮箱格式不正确") + private String email; + + @ApiModelProperty("省份") + private Integer province; + + @ApiModelProperty("省份名称") + private String provinceName; + + @ApiModelProperty("城市") + private Integer city; + + @ApiModelProperty("城市名称") + private String cityName; + + @ApiModelProperty("区县") + private Integer district; + + @ApiModelProperty("区县名称") + private String districtName; + + @ApiModelProperty("详细地址") + @Length(max = 500, message = "详细地址最多500字符") + private String address; + + @ApiModelProperty("营业执照") + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String businessLicense; + + @ApiModelProperty("禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; + + @ApiModelProperty(value = "创建人", hidden = true) + private Long createUserId; + + @ApiModelProperty(value = "创建人", hidden = true) + private String createUserName; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.java new file mode 100644 index 0000000..8489795 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 企业员工 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class EnterpriseEmployeeForm { + + @ApiModelProperty("企业id") + @NotNull(message = "企业id不能为空") + private Long enterpriseId; + + @ApiModelProperty("员工信息id") + @NotEmpty(message = "员工信息id不能为空") + private List employeeIdList; +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.java new file mode 100644 index 0000000..33b6a73 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 查询企业员工 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-20 21:06:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class EnterpriseEmployeeQueryForm extends PageParam { + + @ApiModelProperty("搜索词") + @Length(max = 20, message = "搜索词最多20字符") + private String keyword; + + @ApiModelProperty("公司Id") + @NotNull(message = "公司id 不能为空") + private Long enterpriseId; + + @ApiModelProperty(value = "删除标识", hidden = true) + private Boolean deletedFlag; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.java new file mode 100644 index 0000000..06fd578 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; + +/** + * OA企业模块分页查询 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class EnterpriseQueryForm extends PageParam { + + @ApiModelProperty("关键字") + @Length(max = 200, message = "关键字最多200字符") + private String keywords; + + @ApiModelProperty("开始时间") + private LocalDate startTime; + + @ApiModelProperty("结束时间") + private LocalDate endTime; + + @ApiModelProperty("禁用状态") + private Boolean disabledFlag; + + @ApiModelProperty(value = "删除状态", hidden = true) + private Boolean deletedFlag; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.java new file mode 100644 index 0000000..200e15e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * OA企业模块编辑 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class EnterpriseUpdateForm extends EnterpriseCreateForm { + + @ApiModelProperty("企业ID") + @NotNull(message = "企业ID不能为空") + private Long enterpriseId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.java new file mode 100644 index 0000000..0e37ee5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 企业员工信息 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class EnterpriseEmployeeVO { + + private Long enterpriseEmployeeId; + + @ApiModelProperty("企业ID") + private Long enterpriseId; + + @ApiModelProperty("企业名称") + private String enterpriseName; + + @ApiModelProperty("员工") + private Long employeeId; + + @ApiModelProperty("登录账号") + private String loginName; + + @ApiModelProperty("员工名称") + private String actualName; + + @ApiModelProperty("手机号码") + private String phone; + + @ApiModelProperty("部门id") + private Long departmentId; + + @ApiModelProperty("是否被禁用") + private Boolean disabledFlag; + + @ApiModelProperty("部门名称") + private String departmentName; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.java new file mode 100644 index 0000000..806ff89 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * OA企业模块列表 + * + * @author lihaifan + * @date 2022/6/23 14:31 + */ +@Data +public class EnterpriseListVO { + + @ApiModelProperty("企业ID") + private Long enterpriseId; + + @ApiModelProperty("企业名称") + private String enterpriseName; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.java new file mode 100644 index 0000000..a8ab7b5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.java @@ -0,0 +1,86 @@ +package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +import java.time.LocalDateTime; + +/** + * 企业信息 + * + * @Author 1024创新实验室: 开云 + * @Date 2022/7/28 20:37:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class EnterpriseVO { + + @ApiModelProperty("企业ID") + private Long enterpriseId; + + @ApiModelProperty("企业名称") + private String enterpriseName; + + @ApiModelProperty("企业logo") + private String enterpriseLogo; + + @ApiModelProperty("统一社会信用代码") + private String unifiedSocialCreditCode; + + @ApiModelPropertyEnum(desc = "类型", value = EnterpriseTypeEnum.class) + private Integer type; + + @ApiModelProperty("联系人") + private String contact; + + @ApiModelProperty("联系人电话") + private String contactPhone; + + @ApiModelProperty("邮箱") + private String email; + + @ApiModelProperty("省份") + private Integer province; + + @ApiModelProperty("省份名称") + private String provinceName; + + @ApiModelProperty("城市") + private Integer city; + + @ApiModelProperty("城市名称") + private String cityName; + + @ApiModelProperty("区县") + private Integer district; + + @ApiModelProperty("区县名称") + private String districtName; + + @ApiModelProperty("详细地址") + private String address; + + @ApiModelProperty("营业执照") + private String businessLicense; + + @ApiModelProperty("禁用状态") + private Boolean disabledFlag; + + @ApiModelProperty("创建人ID") + private Long createUserId; + + @ApiModelProperty("创建人名称") + private String createUserName; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java new file mode 100644 index 0000000..dbb17f3 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java @@ -0,0 +1,80 @@ +package net.lab1024.sa.admin.module.business.oa.invoice; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceAddForm; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceQueryForm; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceUpdateForm; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceVO; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * OA发票信息 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Slf4j +@RestController +@OperateLog +//@Api(tags = {AdminSwaggerTagConst.Business.OA_INVOICE}) +public class InvoiceController { + + @Autowired + private InvoiceService invoiceService; + + @ApiOperation(value = "分页查询发票信息 @author 善逸") + @PostMapping("/oa/invoice/page/query") + public ResponseDTO> queryByPage(@RequestBody @Valid InvoiceQueryForm queryDTO) { + return invoiceService.queryByPage(queryDTO); + } + + @ApiOperation(value = "查询发票信息详情 @author 善逸") + @GetMapping("/oa/invoice/get/{invoiceId}") + public ResponseDTO getDetail(@PathVariable Long invoiceId) { + return invoiceService.getDetail(invoiceId); + } + + @ApiOperation(value = "新建发票信息 @author 善逸") + @PostMapping("/oa/invoice/create") + public ResponseDTO createInvoice(@RequestBody @Valid InvoiceAddForm createVO) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + createVO.setCreateUserId(requestUser.getUserId()); + createVO.setCreateUserName(requestUser.getUserName()); + return invoiceService.createInvoice(createVO); + } + + @ApiOperation(value = "编辑发票信息 @author 善逸") + @PostMapping("/oa/invoice/update") + public ResponseDTO updateInvoice(@RequestBody @Valid InvoiceUpdateForm updateVO) { + return invoiceService.updateInvoice(updateVO); + } + + @ApiOperation(value = "删除发票信息 @author 善逸") + @GetMapping("/invoice/delete/{invoiceId}") + public ResponseDTO deleteInvoice(@PathVariable Long invoiceId) { + return invoiceService.deleteInvoice(invoiceId); + } + + @ApiOperation(value = "查询列表 @author lidoudou") + @GetMapping("/oa/invoice/query/list/{enterpriseId}") + public ResponseDTO> queryList(@PathVariable Long enterpriseId) { + return invoiceService.queryList(enterpriseId); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceDao.java new file mode 100644 index 0000000..371a4ed --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceDao.java @@ -0,0 +1,61 @@ +package net.lab1024.sa.admin.module.business.oa.invoice; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceEntity; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceQueryForm; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * OA发票信息 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Mapper +@Component +public interface InvoiceDao extends BaseMapper { + + /** + * 根据账号查询 + * @param enterpriseId + * @param accountNumber + * @param excludeInvoiceId + * @param deletedFlag + * @return + */ + InvoiceEntity queryByAccountNumber(@Param("enterpriseId") Long enterpriseId, @Param("accountNumber") String accountNumber, @Param("excludeInvoiceId") Long excludeInvoiceId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 删除发票信息 + * + * @param invoiceId + * @param deletedFlag + */ + void deleteInvoice(@Param("invoiceId") Long invoiceId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 发票信息分页查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") InvoiceQueryForm queryForm); + + /** + * 查询发票信息详情 + * @param invoiceId + * @param deletedFlag + * @return + */ + InvoiceVO getDetail(@Param("invoiceId") Long invoiceId, @Param("deletedFlag") Boolean deletedFlag); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceService.java new file mode 100644 index 0000000..70afe51 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceService.java @@ -0,0 +1,158 @@ +package net.lab1024.sa.admin.module.business.oa.invoice; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.oa.enterprise.EnterpriseService; +import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO; +import net.lab1024.sa.admin.module.business.oa.invoice.domain.*; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerConst; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Objects; + +/** + * OA发票信息 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +@Slf4j +public class InvoiceService { + + @Autowired + private InvoiceDao invoiceDao; + + @Autowired + private EnterpriseService enterpriseService; + + @Autowired + private DataTracerService dataTracerService; + + /** + * 分页查询发票信息 + * + * @param queryDTO + * @return + */ + public ResponseDTO> queryByPage(InvoiceQueryForm queryDTO) { + queryDTO.setDeletedFlag(Boolean.FALSE); + Page page = SmartPageUtil.convert2PageQuery(queryDTO); + List invoiceVOS = invoiceDao.queryPage(page, queryDTO); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, invoiceVOS); + return ResponseDTO.ok(pageResult); + } + + public ResponseDTO> queryList(Long enterpriseId) { + InvoiceQueryForm queryForm = new InvoiceQueryForm(); + queryForm.setDeletedFlag(Boolean.FALSE); + queryForm.setDisabledFlag(Boolean.FALSE); + queryForm.setEnterpriseId(enterpriseId); + List invoiceList = invoiceDao.queryPage(null, queryForm); + return ResponseDTO.ok(invoiceList); + } + + /** + * 查询发票信息详情 + * + * @param invoiceId + * @return + */ + public ResponseDTO getDetail(Long invoiceId) { + // 校验发票信息是否存在 + InvoiceVO invoiceVO = invoiceDao.getDetail(invoiceId, Boolean.FALSE); + if (Objects.isNull(invoiceVO)) { + return ResponseDTO.userErrorParam("发票信息不存在"); + } + return ResponseDTO.ok(invoiceVO); + } + + /** + * 新建发票信息 + * + * @param createVO + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO createInvoice(InvoiceAddForm createVO) { + Long enterpriseId = createVO.getEnterpriseId(); + // 校验企业是否存在 + EnterpriseVO enterpriseVO = enterpriseService.getDetail(enterpriseId); + if (Objects.isNull(enterpriseVO)) { + return ResponseDTO.userErrorParam("企业不存在"); + } + // 验证发票信息账号是否重复 + InvoiceEntity validateInvoice = invoiceDao.queryByAccountNumber(enterpriseId, createVO.getAccountNumber(), null, Boolean.FALSE); + if (Objects.nonNull(validateInvoice)) { + return ResponseDTO.userErrorParam("发票信息账号重复"); + } + // 数据插入 + InvoiceEntity insertInvoice = SmartBeanUtil.copy(createVO, InvoiceEntity.class); + invoiceDao.insert(insertInvoice); + dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "新增发票:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(insertInvoice)); + return ResponseDTO.ok(); + } + + /** + * 编辑发票信息 + * + * @param updateVO + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateInvoice(InvoiceUpdateForm updateVO) { + Long enterpriseId = updateVO.getEnterpriseId(); + // 校验企业是否存在 + EnterpriseVO enterpriseVO = enterpriseService.getDetail(enterpriseId); + if (Objects.isNull(enterpriseVO)) { + return ResponseDTO.userErrorParam("企业不存在"); + } + Long invoiceId = updateVO.getInvoiceId(); + // 校验发票信息是否存在 + InvoiceEntity invoiceDetail = invoiceDao.selectById(invoiceId); + if (Objects.isNull(invoiceDetail) || invoiceDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("发票信息不存在"); + } + // 验证发票信息账号是否重复 + InvoiceEntity validateInvoice = invoiceDao.queryByAccountNumber(updateVO.getEnterpriseId(), updateVO.getAccountNumber(), invoiceId, Boolean.FALSE); + if (Objects.nonNull(validateInvoice)) { + return ResponseDTO.userErrorParam("发票信息账号重复"); + } + // 数据编辑 + InvoiceEntity updateInvoice = SmartBeanUtil.copy(updateVO, InvoiceEntity.class); + invoiceDao.updateById(updateInvoice); + dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "更新发票:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(invoiceDetail, updateInvoice)); + return ResponseDTO.ok(); + } + + + /** + * 删除发票信息 + + * @param invoiceId + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO deleteInvoice(Long invoiceId) { + // 校验发票信息是否存在 + InvoiceEntity invoiceDetail = invoiceDao.selectById(invoiceId); + if (Objects.isNull(invoiceDetail) || invoiceDetail.getDeletedFlag()) { + return ResponseDTO.userErrorParam("发票信息不存在"); + } + invoiceDao.deleteInvoice(invoiceId, Boolean.TRUE); + dataTracerService.addTrace(invoiceDetail.getEnterpriseId(), DataTracerTypeEnum.OA_ENTERPRISE, "删除发票:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(invoiceDetail)); + return ResponseDTO.ok(); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.java new file mode 100644 index 0000000..0a87ede --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * OA发票信息新建 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class InvoiceAddForm { + + @ApiModelProperty("开票抬头") + @NotBlank(message = "开票抬头不能为空") + @Length(max = 200, message = "开票抬头最多200字符") + private String invoiceHeads; + + @ApiModelProperty("纳税人识别号") + @NotBlank(message = "纳税人识别号不能为空") + @Length(max = 200, message = "纳税人识别号最多200字符") + private String taxpayerIdentificationNumber; + + @ApiModelProperty("银行账户") + @NotBlank(message = "银行账户不能为空") + @Length(max = 200, message = "银行账户最多200字符") + private String accountNumber; + + @ApiModelProperty("开户行") + @NotBlank(message = "开户行不能为空") + @Length(max = 200, message = "开户行最多200字符") + private String bankName; + + @ApiModelProperty("启用状态") + @NotNull(message = "启用状态不能为空") + private Boolean disabledFlag; + + @ApiModelProperty("备注") + @Length(max = 500, message = "备注最多500字符") + private String remark; + + @ApiModelProperty("企业") + @NotNull(message = "企业不能为空") + private Long enterpriseId; + + @ApiModelProperty(value = "创建人", hidden = true) + private Long createUserId; + + @ApiModelProperty(value = "创建人名称", hidden = true) + private String createUserName; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.java new file mode 100644 index 0000000..bc7d563 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.java @@ -0,0 +1,98 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.common.module.support.datatracer.annoation.DataTracerFieldLabel; + +import java.time.LocalDateTime; + +/** + * OA发票信息 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +@TableName("t_oa_invoice") +public class InvoiceEntity { + + /** + * 发票信息ID + */ + @TableId(type = IdType.AUTO) + private Long invoiceId; + + /** + * 开票抬头 + */ + @DataTracerFieldLabel("开票抬头") + private String invoiceHeads; + + /** + * 纳税人识别号 + */ + @DataTracerFieldLabel("纳税人识别号") + private String taxpayerIdentificationNumber; + + /** + * 银行账户 + */ + @DataTracerFieldLabel("银行账户") + private String accountNumber; + + /** + * 开户行 + */ + @DataTracerFieldLabel("开户行") + private String bankName; + + /** + * 备注 + */ + @DataTracerFieldLabel("备注") + private String remark; + + /** + * 企业ID + */ + private Long enterpriseId; + + /** + * 禁用状态 + */ + @DataTracerFieldLabel("禁用状态") + private Boolean disabledFlag; + + /** + * 删除状态 + */ + @DataTracerFieldLabel("删除状态") + private Boolean deletedFlag; + + /** + * 创建人ID + */ + private Long createUserId; + + /** + * 创建人ID + */ + private String createUserName; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.java new file mode 100644 index 0000000..0883bd3 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; + +/** + * OA发票信息查询 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class InvoiceQueryForm extends PageParam { + + @ApiModelProperty("企业ID") + private Long enterpriseId; + + @ApiModelProperty("关键字") + @Length(max = 200, message = "关键字最多200字符") + private String keywords; + + @ApiModelProperty("开始时间") + private LocalDate startTime; + + @ApiModelProperty("结束时间") + private LocalDate endTime; + + @ApiModelProperty("禁用状态") + private Boolean disabledFlag; + + @ApiModelProperty(value = "删除状态", hidden = true) + private Boolean deletedFlag; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.java new file mode 100644 index 0000000..053d493 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * OA发票信息编辑 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class InvoiceUpdateForm extends InvoiceAddForm { + + @ApiModelProperty("发票信息ID") + @NotNull(message = "发票信息ID不能为空") + private Long invoiceId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.java new file mode 100644 index 0000000..2c8fb0e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.admin.module.business.oa.invoice.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * OA发票信息 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-06-23 19:32:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class InvoiceVO { + + @ApiModelProperty("发票信息ID") + private Long invoiceId; + + @ApiModelProperty("开票抬头") + private String invoiceHeads; + + @ApiModelProperty("纳税人识别号") + private String taxpayerIdentificationNumber; + + @ApiModelProperty("银行账户") + private String accountNumber; + + @ApiModelProperty("开户行") + private String bankName; + + @ApiModelProperty("备注") + private String remark; + + @ApiModelProperty("企业") + private Long enterpriseId; + + @ApiModelProperty("企业名称") + private String enterpriseName; + + @ApiModelProperty("禁用状态") + private Boolean disabledFlag; + + @ApiModelProperty("创建人ID") + private Long createUserId; + + @ApiModelProperty("创建人名称") + private String createUserName; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.java new file mode 100644 index 0000000..27f4d16 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.admin.module.business.oa.notice.constant; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 公告、通知 可见范围类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Getter +@AllArgsConstructor +public enum NoticeVisibleRangeDataTypeEnum implements BaseEnum { + + EMPLOYEE(1, "员工"), + + DEPARTMENT(2, "部门"), + + ; + + private final Integer value; + + private final String desc; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java new file mode 100644 index 0000000..8e70863 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java @@ -0,0 +1,135 @@ +package net.lab1024.sa.admin.module.business.oa.notice.controller; + +import cn.hutool.extra.servlet.ServletUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.*; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.*; +import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeEmployeeService; +import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeService; +import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeTypeService; +import net.lab1024.sa.common.common.annoation.SaAuth; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; + +/** + * 公告、通知、新闻等等 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat 卓大1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +//@Api(tags = AdminSwaggerTagConst.Business.OA_NOTICE) +@RestController +public class NoticeController { + + @Autowired + private NoticeService noticeService; + + @Autowired + private NoticeTypeService noticeTypeService; + + @Autowired + private NoticeEmployeeService noticeEmployeeService; + + // --------------------- 通知公告类型 ------------------------- + + @ApiOperation("通知公告类型-获取全部 @author 卓大") + @GetMapping("/oa/noticeType/getAll") + public ResponseDTO> getAll() { + return ResponseDTO.ok(noticeTypeService.getAll()); + } + + @ApiOperation("通知公告类型-添加 @author 卓大") + @GetMapping("/oa/noticeType/add/{name}") + public ResponseDTO add(@PathVariable String name) { + return noticeTypeService.add(name); + } + + @ApiOperation("通知公告类型-修改 @author 卓大") + @GetMapping("/oa/noticeType/update/{noticeTypeId}/{name}") + public ResponseDTO update(@PathVariable Long noticeTypeId, @PathVariable String name) { + return noticeTypeService.update(noticeTypeId, name); + } + + @ApiOperation("通知公告类型-删除 @author 卓大") + @GetMapping("/oa/noticeType/delete/{noticeTypeId}") + public ResponseDTO deleteNoticeType(@PathVariable Long noticeTypeId) { + return noticeTypeService.delete(noticeTypeId); + } + + // --------------------- 【管理】通知公告------------------------- + + @ApiOperation("【管理】通知公告-分页查询 @author 卓大") + @PostMapping("/oa/notice/query") + @SaAuth + public ResponseDTO> query(@RequestBody @Valid NoticeQueryForm queryForm) { + return ResponseDTO.ok(noticeService.query(queryForm)); + } + + @ApiOperation("【管理】通知公告-添加 @author 卓大") + @PostMapping("/oa/notice/add") + @RepeatSubmit + @SaAuth + public ResponseDTO add(@RequestBody @Valid NoticeAddForm addForm) { + addForm.setCreateUserId(SmartRequestUtil.getRequestUserId()); + return noticeService.add(addForm); + } + + @ApiOperation("【管理】通知公告-更新 @author 卓大") + @PostMapping("/oa/notice/update") + @RepeatSubmit + @SaAuth + public ResponseDTO update(@RequestBody @Valid NoticeUpdateForm updateForm) { + return noticeService.update(updateForm); + } + + @ApiOperation("【管理】通知公告-更新详情 @author 卓大") + @GetMapping("/oa/notice/getUpdateVO/{noticeId}") + @SaAuth + public ResponseDTO getUpdateFormVO(@PathVariable Long noticeId) { + return ResponseDTO.ok(noticeService.getUpdateFormVO(noticeId)); + } + + @ApiOperation("【管理】通知公告-删除 @author 卓大") + @GetMapping("/oa/notice/delete/{noticeId}") + @SaAuth + public ResponseDTO delete(@PathVariable Long noticeId) { + return noticeService.delete(noticeId); + } + + // --------------------- 【员工】查看 通知公告 ------------------------- + @ApiOperation("【员工】通知公告-查看详情 @author 卓大") + @GetMapping("/oa/notice/employee/view/{noticeId}") + public ResponseDTO view(@PathVariable Long noticeId, HttpServletRequest request) { + return noticeEmployeeService.view( + SmartRequestUtil.getRequestUserId(), + noticeId, + ServletUtil.getClientIP(request), + request.getHeader("User-Agent") + ); + } + + @ApiOperation("【员工】通知公告-查询全部 @author 卓大") + @PostMapping("/oa/notice/employee/query") + public ResponseDTO> queryEmployeeNotice(@RequestBody @Valid NoticeEmployeeQueryForm noticeEmployeeQueryForm) { + return noticeEmployeeService.queryList(SmartRequestUtil.getRequestUserId(), noticeEmployeeQueryForm); + } + + @ApiOperation("【员工】通知公告-查询 查看记录 @author 卓大") + @PostMapping("/oa/notice/employee/queryViewRecord") + public ResponseDTO> queryViewRecord(@RequestBody @Valid NoticeViewRecordQueryForm noticeViewRecordQueryForm) { + return ResponseDTO.ok(noticeEmployeeService.queryViewRecord(noticeViewRecordQueryForm)); + } +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.java new file mode 100644 index 0000000..aba1019 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.java @@ -0,0 +1,144 @@ +package net.lab1024.sa.admin.module.business.oa.notice.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeEntity; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeEmployeeQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeViewRecordQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeVisibleRangeForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeEmployeeVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeViewRecordVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVisibleRangeVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 公告、通知、新闻等等 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Mapper +@Component +public interface NoticeDao extends BaseMapper { + + // ================================= 数据范围相关 【子表】 ================================= + + /** + * 保存可见范围 + * + * @param noticeId + * @param visibleRangeFormList + */ + void insertVisibleRange(@Param("noticeId") Long noticeId, @Param("visibleRangeFormList") List visibleRangeFormList); + + /** + * 删除可见范围 + * + * @param noticeId + */ + void deleteVisibleRange(@Param("noticeId") Long noticeId); + + /** + * 相关可见范围 + * + * @param noticeId + */ + List queryVisibleRange(@Param("noticeId") Long noticeId); + + // ================================= 通知公告【主表】 相关 ================================= + + /** + * 后管分页查询资讯 + * + * @param page + * @param queryForm + * @return + */ + List query(Page page, @Param("query") NoticeQueryForm queryForm); + + + /** + * 更新删除状态 + * + * @param noticeId + */ + void updateDeletedFlag(@Param("noticeId") Long noticeId); + + // ================================= 通知公告【员工查看】 相关 ================================= + + /** + * 查询 员工 查看到的通知公告 + * + * @param page + * @param requestEmployeeId + * @param noticeEmployeeQueryForm + * @return + */ + List queryEmployeeNotice(Page page, + @Param("requestEmployeeId") Long requestEmployeeId, + @Param("query") NoticeEmployeeQueryForm noticeEmployeeQueryForm, + @Param("requestEmployeeDepartmentIdList") List requestEmployeeDepartmentIdList, + @Param("deletedFlag") boolean deletedFlag, + @Param("administratorFlag") boolean administratorFlag, + @Param("departmentDataType") Integer departmentDataType, + @Param("employeeDataType") Integer employeeDataType + + ); + + /** + * 查询 员工 未读的通知公告 + * + * @param page + * @param requestEmployeeId + * @param noticeEmployeeQueryForm + * @return + */ + List queryEmployeeNotViewNotice(Page page, + @Param("requestEmployeeId") Long requestEmployeeId, + @Param("query") NoticeEmployeeQueryForm noticeEmployeeQueryForm, + @Param("requestEmployeeDepartmentIdList") List requestEmployeeDepartmentIdList, + @Param("deletedFlag") boolean deletedFlag, + @Param("administratorFlag") boolean administratorFlag, + @Param("departmentDataType") Integer departmentDataType, + @Param("employeeDataType") Integer employeeDataType + + ); + + long viewRecordCount(@Param("noticeId")Long noticeId, @Param("employeeId")Long employeeId); + + /** + * 查询通知、公告的 查看记录 + * @param page + * @param noticeViewRecordQueryForm + * @return + */ + List queryNoticeViewRecordList(Page page,@Param("queryForm") NoticeViewRecordQueryForm noticeViewRecordQueryForm); + + /** + * 保存查看记录 + * @param noticeId + * @param employeeId + * @param ip + * @param userAgent + */ + void insertViewRecord(@Param("noticeId") Long noticeId, @Param("employeeId") Long employeeId, @Param("ip") String ip, @Param("userAgent") String userAgent,@Param("pageViewCount") Integer pageViewCount); + + /** + * 更新查看记录 + * @param noticeId + * @param requestEmployeeId + * @param ip + * @param userAgent + */ + void updateViewRecord(@Param("noticeId")Long noticeId, @Param("employeeId")Long requestEmployeeId,@Param("ip") String ip, @Param("userAgent")String userAgent); + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.java new file mode 100644 index 0000000..456fe4d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.admin.module.business.oa.notice.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeTypeEntity; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +/** + * 通知公告类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Mapper +@Component +public interface NoticeTypeDao extends BaseMapper { + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.java new file mode 100644 index 0000000..7dfaa51 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.java @@ -0,0 +1,99 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 通知公告 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +@TableName("t_notice") +public class NoticeEntity { + + @TableId(type = IdType.AUTO) + private Long noticeId; + + /** + * 类型 + */ + private Long noticeTypeId; + + /** + * 标题 + */ + private String title; + + /** + * 是否全部可见 + */ + private Boolean allVisibleFlag; + + /** + * 是否定时发布 + */ + private Boolean scheduledPublishFlag; + + /** + * 发布时间 + */ + private LocalDateTime publishTime; + + /** + * 内容 纯文本 + */ + private String contentText; + + /** + * 内容 html + */ + private String contentHtml; + + /** + * 附件 + * 多个英文逗号分隔 + */ + private String attachment; + + /** + * 页面浏览量 + */ + private Integer pageViewCount; + + /** + * 用户浏览量 + */ + private Integer userViewCount; + + /** + * 来源 + */ + private String source; + + /** + * 作者 + */ + private String author; + + /** + * 文号 + */ + private String documentNumber; + + private Boolean deletedFlag; + + private Long createUserId; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.java new file mode 100644 index 0000000..c749dce --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 通知公告类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +@TableName("t_notice_type") +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class NoticeTypeEntity { + + @TableId(type = IdType.AUTO) + private Long noticeTypeId; + + /** + * 名称 + */ + private String noticeTypeName; + + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.java new file mode 100644 index 0000000..b83ba79 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.java @@ -0,0 +1,78 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.json.deserializer.FileKeyVoDeserializer; +import org.hibernate.validator.constraints.Length; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 通知公告 添加表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeAddForm { + + @ApiModelProperty("标题") + @NotBlank(message = "标题不能为空") + @Length(max = 200, message = "标题最多200字符") + private String title; + + @ApiModelProperty("分类") + @NotNull(message = "分类不能为空") + private Long noticeTypeId; + + @ApiModelProperty("是否全部可见") + @NotNull(message = "是否全部可见不能为空") + private Boolean allVisibleFlag; + + @ApiModelProperty("是否定时发布") + @NotNull(message = "是否定时发布不能为空") + private Boolean scheduledPublishFlag; + + @ApiModelProperty("发布时间") + @NotNull(message = "发布时间不能为空") + private LocalDateTime publishTime; + + @ApiModelProperty("纯文本内容") + @NotNull(message = "文本内容不能为空") + private String contentText; + + @ApiModelProperty("html内容") + @NotNull(message = "html内容不能为空") + private String contentHtml; + + @ApiModelProperty("附件,多个英文逗号分隔|可选") + @Length(max = 1000, message = "最多1000字符") + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String attachment; + + @ApiModelProperty("作者") + @NotBlank(message = "作者不能为空") + private String author; + + @ApiModelProperty("来源") + @NotBlank(message = "标题不能为空") + private String source; + + @ApiModelProperty("文号") + private String documentNumber; + + @ApiModelProperty(hidden = true) + private Long createUserId; + + @ApiModelProperty("可见范围设置|可选") + @Valid + private List visibleRangeList; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.java new file mode 100644 index 0000000..0374861 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +import java.time.LocalDate; + +/** + * 通知公告 员工查询表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeEmployeeQueryForm extends PageParam { + + @ApiModelProperty("标题、作者、来源、文号") + private String keywords; + + @ApiModelProperty("分类") + private Long noticeTypeId; + + @ApiModelProperty("发布-开始时间") + private LocalDate publishTimeBegin; + + @ApiModelProperty("未读标识") + private Boolean notViewFlag; + + @ApiModelProperty("发布-截止时间") + private LocalDate publishTimeEnd; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.java new file mode 100644 index 0000000..c319b2b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +import java.time.LocalDate; + +/** + * 通知公告 管理查询表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeQueryForm extends PageParam { + + @ApiModelProperty("分类") + private Long noticeTypeId; + + @ApiModelProperty("标题、作者、来源") + private String keywords; + + @ApiModelProperty("文号") + private String documentNumber; + + @ApiModelProperty("创建人") + private Long createUserId; + + @ApiModelProperty("删除标识") + private Boolean deletedFlag; + + @ApiModelProperty("创建-开始时间") + private LocalDate createTimeBegin; + + @ApiModelProperty("创建-截止时间") + private LocalDate createTimeEnd; + + @ApiModelProperty("发布-开始时间") + private LocalDate publishTimeBegin; + + @ApiModelProperty("发布-截止时间") + private LocalDate publishTimeEnd; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.java new file mode 100644 index 0000000..c2ecb57 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 通知公告 更新表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeUpdateForm extends NoticeAddForm { + + @ApiModelProperty("id") + @NotNull(message = "通知id不能为空") + private Long noticeId; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.java new file mode 100644 index 0000000..7ac41f2 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +import javax.validation.constraints.NotNull; + +/** + * 通知公告 阅读记录查询 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeViewRecordQueryForm extends PageParam { + + @ApiModelProperty("通知公告id") + @NotNull(message = "通知公告id不能为空") + private Long noticeId; + + @ApiModelProperty("部门id") + private Long departmentId; + + @ApiModelProperty("关键字") + private String keywords; + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.java new file mode 100644 index 0000000..7a3b061 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; + +import javax.validation.constraints.NotNull; + +/** + * 通知公告 可见范围数据 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class NoticeVisibleRangeForm { + + @ApiModelPropertyEnum(NoticeVisibleRangeDataTypeEnum.class) + @CheckEnum(value = NoticeVisibleRangeDataTypeEnum.class, required = true, message = "数据类型错误") + private Integer dataType; + + @ApiModelProperty("员工/部门id") + @NotNull(message = "员工/部门id不能为空") + private Long dataId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.java new file mode 100644 index 0000000..588a285 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.java @@ -0,0 +1,82 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * 通知公告 详情 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeDetailVO { + + @ApiModelProperty("id") + private Long noticeId; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("分类") + private Long noticeTypeId; + + @ApiModelProperty("分类名称") + private Long noticeTypeName; + + @ApiModelProperty("是否全部可见") + @NotNull(message = "是否全部可见不能为空") + private Boolean allVisibleFlag; + + @ApiModelProperty("是否定时发布") + @NotNull(message = "是否定时发布不能为空") + private Boolean scheduledPublishFlag; + + @ApiModelProperty("纯文本内容") + private String contentText; + + @ApiModelProperty("html内容") + private String contentHtml; + + @ApiModelProperty("附件") + private String attachment; + + @ApiModelProperty("发布时间") + @NotNull(message = "发布时间不能为空") + private LocalDateTime publishTime; + + @ApiModelProperty("作者") + @NotBlank(message = "作者不能为空") + private String author; + + @ApiModelProperty("来源") + @NotBlank(message = "标题不能为空") + private String source; + + @ApiModelProperty("文号") + private String documentNumber; + + @ApiModelProperty("页面浏览量") + private Integer pageViewCount; + + @ApiModelProperty("用户浏览量") + private Integer userViewCount; + + @ApiModelProperty("创建人名称") + private Long createUserName; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.java new file mode 100644 index 0000000..b86044a --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDate; + +/** + * 通知公告 员工查看 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeEmployeeVO extends NoticeVO { + + @ApiModelProperty("是否查看") + private Boolean viewFlag; + + @ApiModelProperty("发布日期") + private LocalDate publishDate; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.java new file mode 100644 index 0000000..6aa9ee1 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 通知公告 类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeTypeVO { + + @ApiModelProperty("通知类型id") + private Long noticeTypeId; + + @ApiModelProperty("通知类型-名称") + private String noticeTypeName; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.java new file mode 100644 index 0000000..9857d8e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 用于更新 【通知、公告】 的 VO 对象 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeUpdateFormVO extends NoticeVO { + + @ApiModelProperty("纯文本内容") + private String contentText; + + @ApiModelProperty("html内容") + private String contentHtml; + + @ApiModelProperty("附件") + private String attachment; + + @ApiModelProperty("可见范围") + private List visibleRangeList; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.java new file mode 100644 index 0000000..570fa92 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.java @@ -0,0 +1,75 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.time.LocalDateTime; + + +/** + * 新闻、公告 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeVO { + + @ApiModelProperty("id") + private Long noticeId; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("分类") + private Long noticeTypeId; + + @ApiModelProperty("分类名称") + private String noticeTypeName; + + @ApiModelProperty("是否全部可见") + private Boolean allVisibleFlag; + + @ApiModelProperty("是否定时发布") + private Boolean scheduledPublishFlag; + + @ApiModelProperty("发布状态") + private Boolean publishFlag; + + @ApiModelProperty("发布时间") + private LocalDateTime publishTime; + + @ApiModelProperty("作者") + @NotBlank(message = "作者不能为空") + private String author; + + @ApiModelProperty("来源") + @NotBlank(message = "标题不能为空") + private String source; + + @ApiModelProperty("文号") + private String documentNumber; + + @ApiModelProperty("页面浏览量") + private Integer pageViewCount; + + @ApiModelProperty("用户浏览量") + private Integer userViewCount; + + @ApiModelProperty("删除标识") + private Boolean deletedFlag; + + @ApiModelProperty("创建人名称") + private String createUserName; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.java new file mode 100644 index 0000000..5b76125 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 浏览记录 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeViewRecordVO { + + @ApiModelProperty("员工ID") + private Long employeeId; + + @ApiModelProperty("员工姓名") + private String employeeName; + + @ApiModelProperty("员工部门名称") + private String departmentName; + + @ApiModelProperty("查看次数") + private Integer pageViewCount; + + @ApiModelProperty("首次ip") + private String firstIp; + + @ApiModelProperty("首次用户设备等标识") + private String firstUserAgent; + + @ApiModelProperty("首次查看时间") + private LocalDateTime createTime; + + @ApiModelProperty("最后一次 ip") + private String lastIp; + + @ApiModelProperty("最后一次 用户设备等标识") + private String lastUserAgent; + + @ApiModelProperty("最后一次查看时间") + private LocalDateTime updateTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.java new file mode 100644 index 0000000..cd3ad23 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.admin.module.business.oa.notice.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +/** + * 新闻、公告 可见范围数据 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class NoticeVisibleRangeVO { + + @ApiModelPropertyEnum(NoticeVisibleRangeDataTypeEnum.class) + private Integer dataType; + + @ApiModelProperty("员工/部门id") + private Long dataId; + + @ApiModelProperty("员工/部门 名称") + private String dataName; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.java new file mode 100644 index 0000000..662dca0 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.admin.module.business.oa.notice.manager; + +import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeDao; +import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeEntity; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeVisibleRangeForm; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 通知、公告 manager + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +public class NoticeManager { + + @Autowired + private NoticeDao noticeDao; + + @Autowired + private DataTracerService dataTracerService; + + /** + * 保存 + * + * @param noticeEntity + * @param visibleRangeFormList + */ + @Transactional(rollbackFor = Throwable.class) + public void save(NoticeEntity noticeEntity, List visibleRangeFormList) { + noticeDao.insert(noticeEntity); + Long noticeId = noticeEntity.getNoticeId(); + // 保存可见范围 + if (CollectionUtils.isNotEmpty(visibleRangeFormList)) { + noticeDao.insertVisibleRange(noticeId, visibleRangeFormList); + } + dataTracerService.insert(noticeId, DataTracerTypeEnum.OA_NOTICE); + } + + /** + * 更新 + * + * @param noticeEntity + * @param visibleRangeList + */ + @Transactional(rollbackFor = Throwable.class) + public void update(NoticeEntity old, NoticeEntity noticeEntity, List visibleRangeList) { + noticeDao.updateById(noticeEntity); + Long noticeId = noticeEntity.getNoticeId(); + // 保存可见范围 + if (CollectionUtils.isNotEmpty(visibleRangeList)) { + noticeDao.deleteVisibleRange(noticeId); + noticeDao.insertVisibleRange(noticeId, visibleRangeList); + } + dataTracerService.update(noticeId, DataTracerTypeEnum.OA_NOTICE, old, noticeEntity); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.java new file mode 100644 index 0000000..f3c9019 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.java @@ -0,0 +1,159 @@ +package net.lab1024.sa.admin.module.business.oa.notice.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum; +import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeDao; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeEmployeeQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeViewRecordQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.*; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.employee.service.EmployeeService; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + + +/** + * 员工查看 通知。公告 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +public class NoticeEmployeeService { + + @Autowired + private NoticeDao noticeDao; + + @Autowired + private NoticeService noticeService; + + @Autowired + private DepartmentService departmentService; + + @Autowired + private EmployeeService employeeService; + + /** + * 查询我的 通知、公告清单 + * + * @return + */ + public ResponseDTO> queryList(Long requestEmployeeId, NoticeEmployeeQueryForm noticeEmployeeQueryForm) { + Page page = SmartPageUtil.convert2PageQuery(noticeEmployeeQueryForm); + + //获取请求人的 部门及其子部门 + List employeeDepartmentIdList = Lists.newArrayList(); + EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId); + if (employeeEntity.getDepartmentId() != null) { + employeeDepartmentIdList = departmentService.selfAndChildrenIdList(employeeEntity.getDepartmentId()); + } + + List noticeList = null; + //只查询未读的 + if (noticeEmployeeQueryForm.getNotViewFlag() != null && noticeEmployeeQueryForm.getNotViewFlag()) { + noticeList = noticeDao.queryEmployeeNotViewNotice(page, + requestEmployeeId, + noticeEmployeeQueryForm, + employeeDepartmentIdList, + false, + employeeEntity.getAdministratorFlag(), + NoticeVisibleRangeDataTypeEnum.DEPARTMENT.getValue(), + NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue()); + } else { + // 查询全部 + noticeList = noticeDao.queryEmployeeNotice(page, + requestEmployeeId, + noticeEmployeeQueryForm, + employeeDepartmentIdList, + false, + employeeEntity.getAdministratorFlag(), + NoticeVisibleRangeDataTypeEnum.DEPARTMENT.getValue(), + NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue()); + } + // 设置发布日期 + noticeList.forEach(notice -> notice.setPublishDate(notice.getPublishTime().toLocalDate())); + + return ResponseDTO.ok(SmartPageUtil.convert2PageResult(page, noticeList)); + } + + + /** + * 查询我的 待查看的 通知、公告清单 + * + * @return + */ + public ResponseDTO view(Long requestEmployeeId, Long noticeId, String ip, String userAgent) { + NoticeUpdateFormVO updateFormVO = noticeService.getUpdateFormVO(noticeId); + if (updateFormVO == null || Boolean.TRUE.equals(updateFormVO.getDeletedFlag())) { + return ResponseDTO.userErrorParam("通知公告不存在"); + } + + EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId); + if (!updateFormVO.getAllVisibleFlag() && !checkVisibleRange(updateFormVO.getVisibleRangeList(), requestEmployeeId, employeeEntity.getDepartmentId())) { + return ResponseDTO.userErrorParam("对不起,您没有权限查看内容"); + } + + NoticeDetailVO noticeDetailVO = SmartBeanUtil.copy(updateFormVO, NoticeDetailVO.class); + long viewCount = noticeDao.viewRecordCount(noticeId, requestEmployeeId); + if (viewCount == 0) { + noticeDao.insertViewRecord(noticeId, requestEmployeeId, ip, userAgent, 1); + } else { + noticeDao.updateViewRecord(noticeId, requestEmployeeId, ip, userAgent); + } + + return ResponseDTO.ok(noticeDetailVO); + } + + /** + * 校验是否有查看权限的范围 + * + * @param visibleRangeList + * @param employeeId + * @param departmentId + * @return + */ + public boolean checkVisibleRange(List visibleRangeList, Long employeeId, Long departmentId) { + // 员工范围 + boolean anyMatch = visibleRangeList.stream().anyMatch(e -> NoticeVisibleRangeDataTypeEnum.EMPLOYEE.equalsValue(e.getDataType()) && Objects.equals(e.getDataId(), employeeId)); + if (anyMatch) { + return true; + } + + //部门范围 + List visibleDepartmentIdList = visibleRangeList.stream().filter(e -> NoticeVisibleRangeDataTypeEnum.DEPARTMENT.equalsValue(e.getDataType())) + .map(NoticeVisibleRangeVO::getDataId).collect(Collectors.toList()); + + for (Long visibleDepartmentId : visibleDepartmentIdList) { + List departmentIdList = departmentService.selfAndChildrenIdList(visibleDepartmentId); + if (departmentIdList.contains(departmentId)) { + return true; + } + } + return false; + } + + /** + * 分页查询 查看记录 + * + * @param noticeViewRecordQueryForm + * @return + */ + public PageResult queryViewRecord(NoticeViewRecordQueryForm noticeViewRecordQueryForm) { + Page page = SmartPageUtil.convert2PageQuery(noticeViewRecordQueryForm); + List noticeViewRecordVOS = noticeDao.queryNoticeViewRecordList(page, noticeViewRecordQueryForm); + return SmartPageUtil.convert2PageResult(page, noticeViewRecordVOS); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.java new file mode 100644 index 0000000..dbe3b31 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.java @@ -0,0 +1,250 @@ +package net.lab1024.sa.admin.module.business.oa.notice.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum; +import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeDao; +import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeEntity; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeAddForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeQueryForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeUpdateForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeVisibleRangeForm; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeTypeVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeUpdateFormVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVO; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVisibleRangeVO; +import net.lab1024.sa.admin.module.business.oa.notice.manager.NoticeManager; +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.common.common.constant.StringConst; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 通知。公告 后台管理业务 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +public class NoticeService { + + @Autowired + private NoticeDao noticeDao; + + @Autowired + private NoticeManager noticeManager; + + @Autowired + private EmployeeDao employeeDao; + + @Autowired + private DepartmentDao departmentDao; + + @Autowired + private DepartmentService departmentService; + + @Autowired + private NoticeTypeService noticeTypeService; + + @Autowired + private DataTracerService dataTracerService; + + /** + * 查询 通知、公告 + * + * @param queryForm + * @return + */ + public PageResult query(NoticeQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = noticeDao.query(page, queryForm); + LocalDateTime now = LocalDateTime.now(); + list.forEach(e -> e.setPublishFlag(e.getPublishTime().isBefore(now))); + return SmartPageUtil.convert2PageResult(page, list); + } + + /** + * 添加 + * + * @param addForm + * @return + */ + public ResponseDTO add(NoticeAddForm addForm) { + // 校验并获取可见范围 + ResponseDTO validate = this.checkAndBuildVisibleRange(addForm); + if (!validate.getOk()) { + return ResponseDTO.error(validate); + } + + // build 资讯 + NoticeEntity noticeEntity = SmartBeanUtil.copy(addForm, NoticeEntity.class); + // 发布时间:不是定时发布时 默认为 当前 + if (!addForm.getScheduledPublishFlag()) { + noticeEntity.setPublishTime(LocalDateTime.now()); + } + // 保存数据 + noticeManager.save(noticeEntity, addForm.getVisibleRangeList()); + return ResponseDTO.ok(); + } + + /** + * 校验并返回可见范围 + * + * @param form + * @return + */ + private ResponseDTO checkAndBuildVisibleRange(NoticeAddForm form) { + // 校验资讯分类 + NoticeTypeVO noticeType = noticeTypeService.getByNoticeTypeId(form.getNoticeTypeId()); + if (noticeType == null) { + return ResponseDTO.userErrorParam("分类不存在"); + } + + if (form.getAllVisibleFlag()) { + return ResponseDTO.ok(); + } + + /** + * 校验可见范围 + * 非全部可见时 校验选择的员工|部门 + */ + List visibleRangeUpdateList = form.getVisibleRangeList(); + if (CollectionUtils.isEmpty(visibleRangeUpdateList)) { + return ResponseDTO.userErrorParam("未设置可见范围"); + } + + // 校验可见范围-> 员工 + List employeeIdList = visibleRangeUpdateList.stream() + .filter(e -> NoticeVisibleRangeDataTypeEnum.EMPLOYEE.equalsValue(e.getDataType())) + .map(NoticeVisibleRangeForm::getDataId) + .distinct().collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(employeeIdList)) { + employeeIdList = employeeIdList.stream().distinct().collect(Collectors.toList()); + List dbEmployeeIdList = employeeDao.selectBatchIds(employeeIdList).stream().map(EmployeeEntity::getEmployeeId).collect(Collectors.toList()); + Collection subtract = CollectionUtils.subtract(employeeIdList, dbEmployeeIdList); + if (subtract.size() > 0) { + return ResponseDTO.userErrorParam("员工id不存在:" + subtract); + } + } + + // 校验可见范围-> 部门 + List deptIdList = visibleRangeUpdateList.stream() + .filter(e -> NoticeVisibleRangeDataTypeEnum.DEPARTMENT.equalsValue(e.getDataType())) + .map(NoticeVisibleRangeForm::getDataId) + .distinct().collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(deptIdList)) { + deptIdList = deptIdList.stream().distinct().collect(Collectors.toList()); + List dbDeptIdList = departmentDao.selectBatchIds(deptIdList).stream().map(DepartmentEntity::getDepartmentId).collect(Collectors.toList()); + Collection subtract = CollectionUtils.subtract(deptIdList, dbDeptIdList); + if (subtract.size() > 0) { + return ResponseDTO.userErrorParam("部门id不存在:" + subtract); + } + } + return ResponseDTO.ok(); + } + + + /** + * 更新 + * + * @param updateForm + * @return + */ + public ResponseDTO update(NoticeUpdateForm updateForm) { + + NoticeEntity oldNoticeEntity = noticeDao.selectById(updateForm.getNoticeId()); + if (oldNoticeEntity == null) { + return ResponseDTO.userErrorParam("通知不存在"); + } + + // 校验并获取可见范围 + ResponseDTO res = this.checkAndBuildVisibleRange(updateForm); + if (!res.getOk()) { + return ResponseDTO.error(res); + } + + // 更新 + NoticeEntity noticeEntity = SmartBeanUtil.copy(updateForm, NoticeEntity.class); + noticeManager.update(oldNoticeEntity, noticeEntity, updateForm.getVisibleRangeList()); + return ResponseDTO.ok(); + } + + + /** + * 删除 + * + * @param noticeId + * @return + */ + public ResponseDTO delete(Long noticeId) { + NoticeEntity noticeEntity = noticeDao.selectById(noticeId); + if (null == noticeEntity || noticeEntity.getDeletedFlag()) { + return ResponseDTO.userErrorParam("通知公告不存在"); + } + // 更新删除状态 + noticeDao.updateDeletedFlag(noticeId); + dataTracerService.delete(noticeId, DataTracerTypeEnum.OA_NOTICE); + return ResponseDTO.ok(); + } + + /** + * 获取更新表单用的详情 + * + * @param noticeId + * @return + */ + public NoticeUpdateFormVO getUpdateFormVO(Long noticeId) { + NoticeEntity noticeEntity = noticeDao.selectById(noticeId); + if (null == noticeEntity) { + return null; + } + + NoticeUpdateFormVO updateFormVO = SmartBeanUtil.copy(noticeEntity, NoticeUpdateFormVO.class); + if (!updateFormVO.getAllVisibleFlag()) { + List noticeVisibleRangeList = noticeDao.queryVisibleRange(noticeId); + List employeeIdList = noticeVisibleRangeList.stream().filter(e -> NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue().equals(e.getDataType())) + .map(NoticeVisibleRangeVO::getDataId) + .collect(Collectors.toList()); + + Map employeeMap = null; + if (CollectionUtils.isNotEmpty(employeeIdList)) { + employeeMap = employeeDao.selectBatchIds(employeeIdList).stream().collect(Collectors.toMap(EmployeeEntity::getEmployeeId, Function.identity())); + } else { + employeeMap = new HashMap<>(); + } + for (NoticeVisibleRangeVO noticeVisibleRange : noticeVisibleRangeList) { + if (noticeVisibleRange.getDataType().equals(NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue())) { + EmployeeEntity employeeEntity = employeeMap.get(noticeVisibleRange.getDataId()); + noticeVisibleRange.setDataName(employeeEntity == null ? StringConst.EMPTY : employeeEntity.getActualName()); + } else { + DepartmentVO departmentVO = departmentService.getDepartmentById(noticeVisibleRange.getDataId()); + noticeVisibleRange.setDataName(departmentVO == null ? StringConst.EMPTY : departmentVO.getName()); + } + } + updateFormVO.setVisibleRangeList(noticeVisibleRangeList); + } + return updateFormVO; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.java new file mode 100644 index 0000000..23da736 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.java @@ -0,0 +1,87 @@ +package net.lab1024.sa.admin.module.business.oa.notice.service; + +import cn.hutool.core.util.StrUtil; +import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeTypeDao; +import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeTypeEntity; +import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeTypeVO; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 通知。公告 类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 21:40:39 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Service +public class NoticeTypeService { + + @Autowired + private NoticeTypeDao noticeTypeDao; + + /** + * 查询全部 + * @return + */ + public List getAll() { + return SmartBeanUtil.copyList(noticeTypeDao.selectList(null), NoticeTypeVO.class); + } + + public NoticeTypeVO getByNoticeTypeId(Long noticceTypeId) { + return SmartBeanUtil.copy(noticeTypeDao.selectById(noticceTypeId), NoticeTypeVO.class); + } + + public synchronized ResponseDTO add(String name) { + if (StrUtil.isBlank(name)) { + return ResponseDTO.userErrorParam("类型名称不能为空"); + } + + List noticeTypeEntityList = noticeTypeDao.selectList(null); + if (!CollectionUtils.isEmpty(noticeTypeEntityList)) { + boolean exist = noticeTypeEntityList.stream().map(NoticeTypeEntity::getNoticeTypeName).collect(Collectors.toSet()).contains(name); + if (exist) { + return ResponseDTO.userErrorParam("类型名称已经存在"); + } + } + noticeTypeDao.insert(NoticeTypeEntity.builder().noticeTypeName(name).build()); + return ResponseDTO.ok(); + } + + public synchronized ResponseDTO update(Long noticeTypeId, String name) { + if (StrUtil.isBlank(name)) { + return ResponseDTO.userErrorParam("类型名称不能为空"); + } + + NoticeTypeEntity noticeTypeEntity = noticeTypeDao.selectById(noticeTypeId); + if (noticeTypeEntity == null) { + return ResponseDTO.userErrorParam("类型名称不存在"); + } + + List noticeTypeEntityList = noticeTypeDao.selectList(null); + if (!CollectionUtils.isEmpty(noticeTypeEntityList)) { + Optional optionalNoticeTypeEntity = noticeTypeEntityList.stream().filter(e -> e.getNoticeTypeName().equals(name)).findFirst(); + if (optionalNoticeTypeEntity.isPresent() && !optionalNoticeTypeEntity.get().getNoticeTypeId().equals(noticeTypeId)) { + return ResponseDTO.userErrorParam("类型名称已经存在"); + } + } + noticeTypeEntity.setNoticeTypeName(name); + noticeTypeDao.updateById(noticeTypeEntity); + return ResponseDTO.ok(); + } + + public synchronized ResponseDTO delete(Long noticeTypeId) { + noticeTypeDao.deleteById(noticeTypeId); + return ResponseDTO.ok(); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/controller/StatisticsController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/controller/StatisticsController.java new file mode 100644 index 0000000..c9a18c4 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/controller/StatisticsController.java @@ -0,0 +1,65 @@ +package net.lab1024.sa.admin.module.business.statistics.controller; + + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.module.business.statistics.domain.HospitalQureyForm; +import net.lab1024.sa.admin.module.business.statistics.domain.HospitalVO; +import net.lab1024.sa.admin.module.business.statistics.domain.StatisticsExpertQueryForm; +import net.lab1024.sa.admin.module.business.statistics.domain.StatisticsExpertVO; +import net.lab1024.sa.admin.module.business.statistics.domain.SystemActualEcharsData; +import net.lab1024.sa.admin.module.business.statistics.domain.SystemActualNumQueryForm; +import net.lab1024.sa.admin.module.business.statistics.domain.SystemActualNumVO; +import net.lab1024.sa.admin.module.business.statistics.service.StatisticsService; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import java.util.List; + +/** + * 统计 + * + * @Author HMM + * @Date 2024-01-11 15:18:32 + * @Copyright gdxz + */ + +@RestController +@Api(tags = "") +@OperateLog +public class StatisticsController { + + @Autowired + private StatisticsService statisticsService; + + @ApiOperation("病例统计分页查询 @author HMM") + @PostMapping("/statistics/expert/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid StatisticsExpertQueryForm queryForm) { + return statisticsService.queryPage(queryForm); + } + + @ApiOperation("医院列表查询 @author HMM") + @PostMapping("/statistics/getHospitalList") + public ResponseDTO> getHospitalList(@RequestBody @Valid HospitalQureyForm queryForm) { + return ResponseDTO.ok(statisticsService.getHospitalList(queryForm)); + } + + @ApiOperation("医院列表查询 @author HMM") + @PostMapping("/statistics/case/getSystemActualNum") + public ResponseDTO getSystemActualNum(@RequestBody @Valid SystemActualNumQueryForm queryForm) { + return ResponseDTO.ok(statisticsService.getSystemActualNum(queryForm)); + } + + @ApiOperation("病例 echar @author HMM") + @PostMapping("/statistics/case/getSystemActualEcharsData") + public ResponseDTO> getSystemActualEcharsData(@RequestBody @Valid SystemActualNumQueryForm queryForm) { + return ResponseDTO.ok(statisticsService.getSystemActualEcharsData(queryForm)); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/dao/StatisticsDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/dao/StatisticsDao.java new file mode 100644 index 0000000..3147547 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/dao/StatisticsDao.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.admin.module.business.statistics.dao; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.admin.module.business.statistics.domain.HospitalQureyForm; +import net.lab1024.sa.admin.module.business.statistics.domain.HospitalVO; +import net.lab1024.sa.admin.module.business.statistics.domain.StatisticsExpertQueryForm; +import net.lab1024.sa.admin.module.business.statistics.domain.StatisticsExpertVO; +import net.lab1024.sa.admin.module.business.statistics.domain.SystemActualEcharsData; +import net.lab1024.sa.admin.module.business.statistics.domain.SystemActualNumQueryForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Mapper +@Component +public interface StatisticsDao { + + List queryPage(Page page, @Param("queryForm") StatisticsExpertQueryForm queryForm, @Param("provList")List provList); + + List getHospitalList(@Param("queryForm") HospitalQureyForm queryForm, @Param("provList")List provList); + + /** + * echar + * @param queryForm + * @return + */ + List getSystemActualEcharsData(@Param("queryForm") SystemActualNumQueryForm queryForm, @Param("provList")List provList); + + /** + * 参与项目的医生数量 + * @return + */ + List getExpertNum(@Param("queryForm") SystemActualNumQueryForm queryForm, @Param("provList")List provList); + + /** + * 根据状态查询数量 + * @param status + * @return + */ + Integer getStatusNum(@Param("queryForm") SystemActualNumQueryForm queryForm, @Param("status") int status, @Param("provList")List provList); + + /** + * 已结算数量 + * @return + */ + Integer getSettlementNum(@Param("queryForm") SystemActualNumQueryForm queryForm, @Param("provList")List provList); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/HospitalQureyForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/HospitalQureyForm.java new file mode 100644 index 0000000..2a5bae9 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/HospitalQureyForm.java @@ -0,0 +1,14 @@ +package net.lab1024.sa.admin.module.business.statistics.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class HospitalQureyForm { + + @ApiModelProperty(value = "省份") + private Long provId; + + @ApiModelProperty(value = "市区") + private Long cityId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/HospitalVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/HospitalVO.java new file mode 100644 index 0000000..f41e09e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/HospitalVO.java @@ -0,0 +1,15 @@ +package net.lab1024.sa.admin.module.business.statistics.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class HospitalVO { + + @ApiModelProperty(value = "医院名称") + private String name; + + @ApiModelProperty(value = "医院uuid") + private String uuid; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/StatisticsExpertQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/StatisticsExpertQueryForm.java new file mode 100644 index 0000000..418d951 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/StatisticsExpertQueryForm.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.admin.module.business.statistics.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +@Data +public class StatisticsExpertQueryForm extends PageParam { + + @ApiModelProperty(value = "排序") + private int sort; + + @ApiModelProperty(value = "省份") + private Long provId; + + @ApiModelProperty(value = "市区") + private Long cityId; + + @ApiModelProperty(value = "医院") + private String hospitalUuid; + + @ApiModelProperty(value = "搜索") + private String name; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/StatisticsExpertVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/StatisticsExpertVO.java new file mode 100644 index 0000000..d30a372 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/StatisticsExpertVO.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.business.statistics.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class StatisticsExpertVO { + + @ApiModelProperty(value = "专家ID") + private Long id; + + @ApiModelProperty(value = "专家UUID") + private String uuid; + + @ApiModelProperty(value = "专家姓名") + private String name; + + @ApiModelProperty(value = "省份") + private String provName; + + @ApiModelProperty(value = "市区") + private String cityName; + + @ApiModelProperty(value = "专家医院名称") + private String hospitalName; + + @ApiModelProperty(value = "总数量") + private Integer total; + + @ApiModelProperty(value = "专家通过数量") + private Integer passNum; + + @ApiModelProperty(value = "专家待审核数量") + private Integer waitNum; + + @ApiModelProperty(value = "专家待修改数量") + private Integer refuseNum; + + @ApiModelProperty(value = "已结算数量") + private Integer settlementNum; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualEcharsData.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualEcharsData.java new file mode 100644 index 0000000..913a780 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualEcharsData.java @@ -0,0 +1,14 @@ +package net.lab1024.sa.admin.module.business.statistics.domain; + +import lombok.Data; + +/** + * 实时数据的echars data + */ +@Data +public class SystemActualEcharsData { + + private Integer statisticsDate; + + private Integer num; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualNumQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualNumQueryForm.java new file mode 100644 index 0000000..e2f4342 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualNumQueryForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.business.statistics.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class SystemActualNumQueryForm { + + @ApiModelProperty(value = "省份") + private Long provId; + + @ApiModelProperty(value = "市区") + private Long cityId; + + @ApiModelProperty(value = "医院") + private String hospitalUuid; + + @ApiModelProperty(value = "开始时间") + private Integer beginDate; + + @ApiModelProperty(value = "结束时间") + private Integer endDate; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualNumVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualNumVO.java new file mode 100644 index 0000000..c283460 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/domain/SystemActualNumVO.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.business.statistics.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class SystemActualNumVO { + + @ApiModelProperty(value = "参与医生数量") + private Integer expertNum; + + @ApiModelProperty(value = "已通过数量") + private Integer passNum; + + @ApiModelProperty(value = "专家待审核数量") + private Integer waitNum; + + @ApiModelProperty(value = "专家待修改数量") + private Integer refuseNum; + + @ApiModelProperty(value = "已结算数量") + private Integer settlementNum; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/service/StatisticsService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/service/StatisticsService.java new file mode 100644 index 0000000..056c8c6 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/statistics/service/StatisticsService.java @@ -0,0 +1,117 @@ +package net.lab1024.sa.admin.module.business.statistics.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.admin.module.business.caseplatformcase.constant.CaseStatusEnum; +import net.lab1024.sa.admin.module.business.statistics.dao.StatisticsDao; +import net.lab1024.sa.admin.module.business.statistics.domain.HospitalQureyForm; +import net.lab1024.sa.admin.module.business.statistics.domain.HospitalVO; +import net.lab1024.sa.admin.module.business.statistics.domain.StatisticsExpertQueryForm; +import net.lab1024.sa.admin.module.business.statistics.domain.StatisticsExpertVO; +import net.lab1024.sa.admin.module.business.statistics.domain.SystemActualEcharsData; +import net.lab1024.sa.admin.module.business.statistics.domain.SystemActualNumQueryForm; +import net.lab1024.sa.admin.module.business.statistics.domain.SystemActualNumVO; +import net.lab1024.sa.admin.module.system.login.domain.LoginEmployeeDetail; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class StatisticsService { + + @Autowired + private StatisticsDao statisticsDao; + + public ResponseDTO> queryPage(StatisticsExpertQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + LoginEmployeeDetail requestUser = (LoginEmployeeDetail) SmartRequestUtil.getRequestUser(); + List provList = requestUser.getProvList(); + Long provId = queryForm.getProvId(); + if(provId != null){ + boolean match = provList.stream().anyMatch(item -> item.getId().equals(provId)); + if(!match){ + return ResponseDTO.ok(SmartPageUtil.emptyResult(page)); + } + } + List list = statisticsDao.queryPage(page, queryForm, provList); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return ResponseDTO.ok(pageResult); + } + + public List getHospitalList(HospitalQureyForm queryForm) { + LoginEmployeeDetail requestUser = (LoginEmployeeDetail)SmartRequestUtil.getRequestUser(); + List provList = requestUser.getProvList(); + Long provId = queryForm.getProvId(); + if(provId != null){ + boolean match = provList.stream().anyMatch(item -> item.getId().equals(provId)); + if(!match){ + return null; + } + } + List list = statisticsDao.getHospitalList(queryForm, provList); + return list; + } + + /** + * 项目统计 + * @param queryForm + * @return + */ + public SystemActualNumVO getSystemActualNum(SystemActualNumQueryForm queryForm){ + SystemActualNumVO data = new SystemActualNumVO(); + LoginEmployeeDetail requestUser = (LoginEmployeeDetail)SmartRequestUtil.getRequestUser(); + List provList = requestUser.getProvList(); + + Long provId = queryForm.getProvId(); + if(provId != null){ + boolean match = provList.stream().anyMatch(item -> item.getId().equals(provId)); + if(!match){ + data.setSettlementNum(0); + data.setRefuseNum(0); + data.setPassNum(0); + data.setWaitNum(0); + data.setExpertNum(0); + return data; + } + } + + List expertNumList = statisticsDao.getExpertNum(queryForm, provList); + int expertNum = expertNumList == null?0:expertNumList.size(); + Integer waitNum = statisticsDao.getStatusNum(queryForm, CaseStatusEnum.WAIT.getValue(), provList); + waitNum = waitNum == null?0:waitNum; + Integer passNum = statisticsDao.getStatusNum(queryForm, CaseStatusEnum.PASS.getValue(), provList); + passNum = passNum == null?0:passNum; + Integer refuseNum = statisticsDao.getStatusNum(queryForm, CaseStatusEnum.REFUSE.getValue(), provList); + refuseNum = refuseNum == null?0:refuseNum; + Integer settlementNum = statisticsDao.getSettlementNum(queryForm, provList); + settlementNum = settlementNum == null?0:settlementNum; + + data.setSettlementNum(settlementNum); + data.setRefuseNum(refuseNum); + data.setPassNum(passNum); + data.setWaitNum(waitNum); + data.setExpertNum(expertNum); + return data; + } + + public List getSystemActualEcharsData(SystemActualNumQueryForm queryForm){ + LoginEmployeeDetail requestUser = (LoginEmployeeDetail)SmartRequestUtil.getRequestUser(); + List provList = requestUser.getProvList(); + Long provId = queryForm.getProvId(); + if(provId != null){ + boolean match = provList.stream().anyMatch(item -> item.getId().equals(provId)); + if(!match){ + return null; + } + } + List systemActualEcharsData = statisticsDao.getSystemActualEcharsData(queryForm, provList); + return systemActualEcharsData; + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/dao/TokenDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/dao/TokenDao.java new file mode 100644 index 0000000..31f645a --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/dao/TokenDao.java @@ -0,0 +1,15 @@ +package net.lab1024.sa.admin.module.business.token.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.business.token.domain.entity.TokenEntity; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +@Component +@Mapper +public interface TokenDao extends BaseMapper { + + TokenEntity getByTokenKey(String captchaKey); + + int delByTokenKey(String captchaKey); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/domain/entity/TokenEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/domain/entity/TokenEntity.java new file mode 100644 index 0000000..88d6121 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/domain/entity/TokenEntity.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.admin.module.business.token.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@TableName("t_token") +public class TokenEntity { + + @TableId(type = IdType.ASSIGN_UUID) + private String tokenUuid; + private String tokenKey; + private String tokenText; + private LocalDateTime exprireDate; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/service/TokenService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/service/TokenService.java new file mode 100644 index 0000000..9048e82 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/token/service/TokenService.java @@ -0,0 +1,276 @@ +package net.lab1024.sa.admin.module.business.token.service; + +import cn.hutool.core.date.LocalDateTimeUtil; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.JwtBuilder; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.business.token.dao.TokenDao; +import net.lab1024.sa.admin.module.business.token.domain.entity.TokenEntity; +import net.lab1024.sa.common.common.domain.SystemEnvironment; +import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.constant.RedisKeyConst; +import net.lab1024.sa.common.module.support.token.JwtConst; +import net.lab1024.sa.common.module.support.token.LoginDeviceEnum; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.Map; + +@Slf4j +@Service +public class TokenService { + + private static final long MINUTE_TIME_MILLI = 60 * 1000; + + @Autowired + private TokenDao tokenDao; + + @Autowired + private SystemEnvironment systemEnvironment; + + @Value("${token.key}") + private String tokenKey; + + @Value("${token.admin-expire-minute}") + private Integer adminTokenExpire; + + @Value("${token.app-expire-minute}") + private Integer appTokenExpire; + + public String generateRedisKey(String prefix, String key) { + SystemEnvironmentEnum currentEnvironment = systemEnvironment.getCurrentEnvironment(); + return systemEnvironment.getProjectName() + RedisKeyConst.SEPARATOR + currentEnvironment.getValue() + RedisKeyConst.SEPARATOR + prefix + key; + } + + /** + * 生成Token,并存入redis + * + * @param userId + * @param userName + * @param userTypeEnum + * @param loginDeviceEnum + * @param superPasswordFlag 特殊万能密码标识 + * @return + */ + public String generateToken(Long userId, String userName, UserTypeEnum userTypeEnum, LoginDeviceEnum loginDeviceEnum, Boolean superPasswordFlag) { + long nowTimeMilli = System.currentTimeMillis(); + Claims jwtClaims = Jwts.claims(); + jwtClaims.put(JwtConst.CLAIM_ID_KEY, userId); + jwtClaims.put(JwtConst.CLAIM_NAME_KEY, userName); + jwtClaims.put(JwtConst.CLAIM_USER_TYPE_KEY, userTypeEnum.getValue()); + jwtClaims.put(JwtConst.CLAIM_DEVICE_KEY, loginDeviceEnum.getValue()); + jwtClaims.put(JwtConst.CLAIM_SUPER_PASSWORD_FLAG, superPasswordFlag); + JwtBuilder jwtBuilder = Jwts.builder() + .setClaims(jwtClaims) + .setIssuedAt(new Date(nowTimeMilli)) + .signWith(SignatureAlgorithm.HS512, tokenKey); + + // 如果是万能密码,则不需要记录到redis中;万能密码最多半个小时有效期 + if (superPasswordFlag) { + jwtBuilder.setExpiration(new Date(nowTimeMilli + (MINUTE_TIME_MILLI * 1000 / 2))); + return jwtBuilder.compact(); + } + + //过期时长有redis来控制, + //if(userTypeEnum.equals(UserTypeEnum.ADMIN_EMPLOYEE)){ + // jwtBuilder.setExpiration(new Date(nowTimeMilli + adminTokenExpire * MINUTE_TIME_MILLI)); + //}else if(userTypeEnum.equals(UserTypeEnum.EXPERT)){ + // jwtBuilder.setExpiration(new Date(nowTimeMilli + appTokenExpire * MINUTE_TIME_MILLI)); + //} + + String token = jwtBuilder.compact(); + String redisKey = this.generateTokenRedisKey(userId, userTypeEnum.getValue(), loginDeviceEnum.getValue()); + + tokenDao.delByTokenKey(redisKey); + TokenEntity tokenEntity = new TokenEntity(); + tokenEntity.setTokenText(token); + tokenEntity.setTokenKey(redisKey); + if(userTypeEnum.equals(UserTypeEnum.ADMIN_EMPLOYEE)){ + tokenEntity.setExprireDate(LocalDateTimeUtil.offset(LocalDateTime.now(), adminTokenExpire, ChronoUnit.MINUTES)); + }else if(userTypeEnum.equals(UserTypeEnum.EXPERT)){ + tokenEntity.setExprireDate(LocalDateTimeUtil.offset(LocalDateTime.now(), appTokenExpire, ChronoUnit.MINUTES)); + } + tokenDao.insert(tokenEntity); + return token; + } + + /** + * 生成登录信息: 含设备信息 + * + * @param userId + * @param device + * @return + */ + private String generateTokenRedisKey(Long userId, Integer userType, Integer device) { + String userKey = userType + "_" + userId + "_" + device; + return generateRedisKey(RedisKeyConst.Support.TOKEN, userKey); + } + + + /** + * 强制移除 此用户各端的登录信息 + * + * @param token + */ + public void removeToken(String token) { + Map tokenData = this.decryptTokenData(token); + if (MapUtils.isEmpty(tokenData)) { + return; + } + + //特殊账号 + if (tokenData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG) != null) { + try { + Boolean superPasswordFlag = Boolean.valueOf(tokenData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG).toString()); + if (superPasswordFlag) { + return; + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return; + } + } + + boolean isValid = this.checkRedisToken(tokenData, token); + if (!isValid) { + return; + } + + Long userId = Long.valueOf(tokenData.get(JwtConst.CLAIM_ID_KEY).toString()); + Integer userType = Integer.valueOf(tokenData.get(JwtConst.CLAIM_USER_TYPE_KEY).toString()); + Integer device = Integer.valueOf(tokenData.get(JwtConst.CLAIM_DEVICE_KEY).toString()); + + String redisKey = this.generateTokenRedisKey(userId, userType, device); + tokenDao.delByTokenKey(redisKey); + } + + /** + * 解析并校验token信息 获取 userId + * + * @param token + * @return + */ + public Map getUserIdAndValidateToken(String token) { + Map parseJwtData = this.decryptTokenData(token); + boolean isValid = this.checkRedisToken(parseJwtData, token); + if (!isValid) { + return null; + } + //Long userId = Long.valueOf(parseJwtData.get(JwtConst.CLAIM_ID_KEY).toString()); + return parseJwtData; + } + + /** + * 解密和解析token + * + * @param token + * @return + */ + private Map decryptTokenData(String token) { + try { + return Jwts.parser() + .setSigningKey(tokenKey) + .parseClaimsJws(token) + .getBody(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 校验token是否有效 + * + * @param token + * @return + */ + private boolean checkRedisToken(Map parseJwtData, String token) { + if (MapUtils.isEmpty(parseJwtData)) { + return false; + } + //特殊账号 + if (parseJwtData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG) != null) { + try { + Boolean superPasswordFlag = Boolean.valueOf(parseJwtData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG).toString()); + if (superPasswordFlag) { + return true; + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } + + Long userId = null; + Integer userType = null, device = null; + + if (null != parseJwtData.get(JwtConst.CLAIM_ID_KEY)) { + userId = NumberUtils.toLong(parseJwtData.get(JwtConst.CLAIM_ID_KEY).toString(), -1); + userId = userId == -1 ? null : userId; + } + + if (null != parseJwtData.get(JwtConst.CLAIM_USER_TYPE_KEY)) { + userType = NumberUtils.toInt(parseJwtData.get(JwtConst.CLAIM_USER_TYPE_KEY).toString(), -1); + userType = userType == -1 ? null : userType; + } + + if (null != parseJwtData.get(JwtConst.CLAIM_DEVICE_KEY)) { + device = NumberUtils.toInt(parseJwtData.get(JwtConst.CLAIM_DEVICE_KEY).toString(), -1); + device = device == -1 ? null : device; + } + + if (userId == null || userType == null || device == null) { + return false; + } + + String redisKey = this.generateTokenRedisKey(userId, userType, device); + TokenEntity byTokenKey = tokenDao.getByTokenKey(redisKey); + if(byTokenKey == null){ + return false; + } + LocalDateTime exprireDate = byTokenKey.getExprireDate(); + LocalDateTime now = LocalDateTimeUtil.now(); + boolean atter = now.isAfter(exprireDate); + if(atter){ + exprireDate = null; + now = null; + byTokenKey = null; + parseJwtData = null; + return false; + } + String tokenText = byTokenKey.getTokenText(); + + if(token.equals(tokenText)){ + //这里给token续期 + if(userType.equals(UserTypeEnum.ADMIN_EMPLOYEE.getValue())){ + byTokenKey.setExprireDate(LocalDateTimeUtil.offset(LocalDateTime.now(), adminTokenExpire, ChronoUnit.MINUTES)); + }else if(userType.equals(UserTypeEnum.EXPERT.getValue())){ + byTokenKey.setExprireDate(LocalDateTimeUtil.offset(LocalDateTime.now(), appTokenExpire, ChronoUnit.MINUTES)); + } + tokenDao.updateById(byTokenKey); + } + exprireDate = null; + now = null; + byTokenKey = null; + parseJwtData = null; + return token.equals(tokenText); + } + + /** + * 批量移除用户所有设备的token + */ + public void batchRemoveRedisToken(Long userId, UserTypeEnum userTypeEnum) { + for (LoginDeviceEnum device : LoginDeviceEnum.values()) { + tokenDao.delByTokenKey(this.generateTokenRedisKey(userId, userTypeEnum.getValue(), device.getValue())); + } + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/DataScope.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/DataScope.java new file mode 100644 index 0000000..7ba2870 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/DataScope.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.admin.module.system.datascope; + + +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeWhereInTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.strategy.DataScopePowerStrategy; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 数据范围 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-03-18 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface DataScope { + + DataScopeTypeEnum dataScopeType() ; + + DataScopeWhereInTypeEnum whereInType() default DataScopeWhereInTypeEnum.EMPLOYEE; + + /** + * DataScopeWhereInTypeEnum.CUSTOM_STRATEGY类型 才可使用joinSqlImplClazz属性 + * @return + */ + Class joinSqlImplClazz() default DataScopePowerStrategy.class; + + /** + * 多个参数已逗号分隔,本属性主要用于joinSqlImplClazz 实现类跟进参数进行不同的范围控制,如不使用CUSTOM_STRATEGY,可不做配置 + * @return + */ + String paramName() default ""; + /** + * + * 第几个where 条件 从0开始 + * @return + */ + int whereIndex() default 0; + + /** + * DataScopeWhereInTypeEnum为CUSTOM_STRATEGY类型时,此属性无效 + * @return + */ + String joinSql() default ""; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/DataScopeController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/DataScopeController.java new file mode 100644 index 0000000..da13231 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/DataScopeController.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.system.datascope; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.common.AdminBaseController; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeAndViewTypeVO; +import net.lab1024.sa.admin.module.system.datascope.service.DataScopeService; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 查询支持的数据范围类型 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-03-18 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@OperateLog +@RestController +//@Api(tags = {AdminSwaggerTagConst.System.SYSTEM_DATA_SCOPE}) +public class DataScopeController extends AdminBaseController { + + @Autowired + private DataScopeService dataScopeService; + + @ApiOperation(value = "获取当前系统所配置的所有数据范围 @author 罗伊") + @GetMapping("/dataScope/list") + public ResponseDTO> dataScopeList() { + return dataScopeService.dataScopeList(); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin.java new file mode 100644 index 0000000..2c2f39d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/MyBatisPlugin.java @@ -0,0 +1,186 @@ +package net.lab1024.sa.admin.module.system.datascope; + +import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Maps; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeSqlConfig; +import net.lab1024.sa.admin.module.system.datascope.service.DataScopeSqlConfigService; +import net.lab1024.sa.common.common.domain.DataScopePlugin; +import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.mapping.*; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Invocation; +import org.apache.ibatis.plugin.Plugin; +import org.apache.ibatis.plugin.Signature; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * mybaits sql 拦截 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-03-18 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Intercepts({@Signature(type = org.apache.ibatis.executor.Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})}) +@Component +public class MyBatisPlugin extends DataScopePlugin { + + @Autowired + private ApplicationContext applicationContext; + + @Override + public Object intercept(Invocation invocation) throws Throwable { + + MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; + Object parameter = invocation.getArgs()[1]; + + BoundSql boundSql = mappedStatement.getBoundSql(parameter); + String originalSql = boundSql.getSql().trim(); + String id = mappedStatement.getId(); + List methodStrList = StrUtil.split(id, "."); + String path = methodStrList.get(methodStrList.size() - 2) + "." + methodStrList.get(methodStrList.size() - 1); + DataScopeSqlConfigService dataScopeSqlConfigService = this.dataScopeSqlConfigService(); + if (dataScopeSqlConfigService == null) { + return invocation.proceed(); + } + DataScopeSqlConfig sqlConfigDTO = dataScopeSqlConfigService.getSqlConfig(path); + if (sqlConfigDTO != null) { + Map paramMap = this.getParamList(sqlConfigDTO.getParamName(), parameter); + BoundSql newBoundSql = copyFromBoundSql(mappedStatement, boundSql, this.joinSql(originalSql, paramMap, sqlConfigDTO)); + ParameterMap map = mappedStatement.getParameterMap(); + MappedStatement newMs = copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql), map); + invocation.getArgs()[0] = newMs; + } + + Object obj = invocation.proceed(); + return obj; + } + + + private Map getParamList(String paramName, Object parameter) { + Map paramMap = Maps.newHashMap(); + if (StringUtils.isEmpty(paramName)) { + return paramMap; + } + if (parameter == null) { + return paramMap; + } + if (parameter instanceof Map) { + String[] paramNameArray = paramName.split(","); + Map parameterMap = (Map) parameter; + for (String param : paramNameArray) { + if(parameterMap.containsKey(param)){ + paramMap.put(param, parameterMap.get(param)); + } + } + } + return paramMap; + } + + private String joinSql(String sql, Map paramMap, DataScopeSqlConfig sqlConfigDTO) { + if (null == sqlConfigDTO) { + return sql; + } + String appendSql = this.dataScopeSqlConfigService().getJoinSql(paramMap, sqlConfigDTO); + if (StringUtils.isEmpty(appendSql)) { + return sql; + } + Integer appendSqlWhereIndex = sqlConfigDTO.getWhereIndex(); + String where = "where"; + String order = "order by"; + String group = "group by"; + int whereIndex = StringUtils.ordinalIndexOf(sql.toLowerCase(), where, appendSqlWhereIndex + 1); + int orderIndex = sql.toLowerCase().indexOf(order); + int groupIndex = sql.toLowerCase().indexOf(group); + if (whereIndex > -1) { + String subSql = sql.substring(0, whereIndex + where.length() + 1); + subSql = subSql + " " + appendSql + " AND " + sql.substring(whereIndex + where.length() + 1); + return subSql; + } + + if (groupIndex > -1) { + String subSql = sql.substring(0, groupIndex); + subSql = subSql + " where " + appendSql + " " + sql.substring(groupIndex); + return subSql; + } + if (orderIndex > -1) { + String subSql = sql.substring(0, orderIndex); + subSql = subSql + " where " + appendSql + " " + sql.substring(orderIndex); + return subSql; + } + sql += " where " + appendSql; + return sql; + } + + public DataScopeSqlConfigService dataScopeSqlConfigService() { + return (DataScopeSqlConfigService) applicationContext.getBean("dataScopeSqlConfigService"); + } + + public class BoundSqlSqlSource implements SqlSource { + + BoundSql boundSql; + + public BoundSqlSqlSource(BoundSql boundSql) { + this.boundSql = boundSql; + } + + @Override + public BoundSql getBoundSql(Object parameterObject) { + return boundSql; + } + } + + /** + * 复制MappedStatement对象 + */ + private MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource, ParameterMap parameterMap) { + + MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType()); + builder.resource(ms.getResource()); + builder.fetchSize(ms.getFetchSize()); + builder.statementType(ms.getStatementType()); + builder.keyGenerator(ms.getKeyGenerator()); + builder.timeout(ms.getTimeout()); + builder.parameterMap(parameterMap); + builder.resultMaps(ms.getResultMaps()); + builder.resultSetType(ms.getResultSetType()); + builder.cache(ms.getCache()); + builder.flushCacheRequired(ms.isFlushCacheRequired()); + builder.useCache(ms.isUseCache()); + return builder.build(); + } + + /** + * 复制BoundSql对象 + */ + private BoundSql copyFromBoundSql(MappedStatement ms, BoundSql boundSql, String sql) { + BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), sql, boundSql.getParameterMappings(), boundSql.getParameterObject()); + for (ParameterMapping mapping : boundSql.getParameterMappings()) { + String prop = mapping.getProperty(); + if (boundSql.hasAdditionalParameter(prop)) { + newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop)); + } + } + return newBoundSql; + } + + @Override + public Object plugin(Object arg0) { + return Plugin.wrap(arg0, this); + } + + @Override + public void setProperties(Properties arg0) { + + } + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeTypeEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeTypeEnum.java new file mode 100644 index 0000000..9130631 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeTypeEnum.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.admin.module.system.datascope.constant; + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 数据范围 类型 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/28 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public enum DataScopeTypeEnum implements BaseEnum { + + /** + * 系统通知 + */ + NOTICE(1, 20, "系统通知", "系统通知数据范围"), + ; + + private Integer value; + + private Integer sort; + + private String name; + + private String desc; + + DataScopeTypeEnum(Integer value, Integer sort, String name, String desc) { + this.value = value; + this.sort = sort; + this.name = name; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + + public Integer getSort() { + return sort; + } + + @Override + public String getDesc() { + return desc; + } + + public String getName() { + return name; + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeViewTypeEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeViewTypeEnum.java new file mode 100644 index 0000000..1ef6930 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeViewTypeEnum.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.admin.module.system.datascope.constant; + + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + + +/** + * 数据范围 种类 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/28 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public enum DataScopeViewTypeEnum implements BaseEnum { + + ME(0, 0, "本人"), + + DEPARTMENT(1, 5, "本部门"), + + DEPARTMENT_AND_SUB(2, 10, "本部门及下属子部门"), + + ALL(10, 100, "全部"); + + + + private Integer value; + private Integer level; + private String desc; + + DataScopeViewTypeEnum(Integer value, Integer level, String desc) { + this.value = value; + this.level = level; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + + public Integer getLevel() { + return level; + } + + @Override + public String getDesc() { + return desc; + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeWhereInTypeEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeWhereInTypeEnum.java new file mode 100644 index 0000000..dd9293d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/constant/DataScopeWhereInTypeEnum.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.admin.module.system.datascope.constant; + + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 数据范围 sql where + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/28 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public enum DataScopeWhereInTypeEnum implements BaseEnum { + + EMPLOYEE(0, "以员工IN"), + + DEPARTMENT(1, "以部门IN"), + + CUSTOM_STRATEGY(2, "自定义策略"); + + private Integer value; + private String desc; + + DataScopeWhereInTypeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeAndViewTypeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeAndViewTypeVO.java new file mode 100644 index 0000000..51bd3f5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeAndViewTypeVO.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.system.datascope.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 数据范围 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/28 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DataScopeAndViewTypeVO { + + @ApiModelProperty("数据范围类型") + private Integer dataScopeType; + + @ApiModelProperty("数据范围名称") + private String dataScopeTypeName; + + @ApiModelProperty("描述") + private String dataScopeTypeDesc; + + @ApiModelProperty("顺序") + private Integer dataScopeTypeSort; + + @ApiModelProperty("可见范围列表") + private List viewTypeList; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO.java new file mode 100644 index 0000000..01919e9 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeDTO.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.admin.module.system.datascope.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; + +/** + * 数据范围 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/28 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@Builder +public class DataScopeDTO { + + @ApiModelProperty("数据范围类型") + private Integer dataScopeType; + + @ApiModelProperty("数据范围名称") + private String dataScopeTypeName; + + @ApiModelProperty("描述") + private String dataScopeTypeDesc; + + @ApiModelProperty("顺序") + private Integer dataScopeTypeSort; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeSqlConfig.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeSqlConfig.java new file mode 100644 index 0000000..63686b3 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeSqlConfig.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.system.datascope.domain; + +import lombok.Data; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeWhereInTypeEnum; + +/** + * 数据范围 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/28 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DataScopeSqlConfig { + + /** + * 数据范围类型 + * {@link DataScopeTypeEnum} + */ + private DataScopeTypeEnum dataScopeType; + + /** + * join sql 具体实现类 + */ + private Class joinSqlImplClazz; + + private String joinSql; + + private Integer whereIndex; + + private String paramName; + + /** + * whereIn类型 + * {@link DataScopeWhereInTypeEnum} + */ + private DataScopeWhereInTypeEnum dataScopeWhereInType; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO.java new file mode 100644 index 0000000..22231d2 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/domain/DataScopeViewTypeVO.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.admin.module.system.datascope.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Builder; +import lombok.Data; + +/** + * 数据范围 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/28 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@Builder +public class DataScopeViewTypeVO { + + @ApiModelProperty("可见范围") + private Integer viewType; + + @ApiModelProperty("可见范围名称") + private String viewTypeName; + + @ApiModelProperty("级别,用于表示范围大小") + private Integer viewTypeLevel; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeService.java new file mode 100644 index 0000000..7353706 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeService.java @@ -0,0 +1,75 @@ +package net.lab1024.sa.admin.module.system.datascope.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeViewTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeAndViewTypeVO; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeDTO; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeViewTypeVO; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; + +/** + * 数据范围 保存 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/28 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class DataScopeService { + + /** + * 获取所有可以进行数据范围配置的信息 + * + * @return + */ + public ResponseDTO> dataScopeList() { + List dataScopeList = this.getDataScopeType(); + List dataScopeAndTypeList = SmartBeanUtil.copyList(dataScopeList, DataScopeAndViewTypeVO.class); + List typeList = this.getViewType(); + dataScopeAndTypeList.forEach(e -> { + e.setViewTypeList(typeList); + }); + return ResponseDTO.ok(dataScopeAndTypeList); + } + + /** + * 获取当前系统存在的数据可见范围 + * + * @return + */ + public List getViewType() { + List viewTypeList = Lists.newArrayList(); + DataScopeViewTypeEnum[] enums = DataScopeViewTypeEnum.class.getEnumConstants(); + DataScopeViewTypeVO dataScopeViewTypeDTO; + for (DataScopeViewTypeEnum viewTypeEnum : enums) { + dataScopeViewTypeDTO = DataScopeViewTypeVO.builder().viewType(viewTypeEnum.getValue()).viewTypeLevel(viewTypeEnum.getLevel()).viewTypeName(viewTypeEnum.getDesc()).build(); + viewTypeList.add(dataScopeViewTypeDTO); + } + Comparator comparator = (h1, h2) -> h1.getViewTypeLevel().compareTo(h2.getViewTypeLevel()); + viewTypeList.sort(comparator); + return viewTypeList; + } + + public List getDataScopeType() { + List dataScopeTypeList = Lists.newArrayList(); + DataScopeTypeEnum[] enums = DataScopeTypeEnum.class.getEnumConstants(); + DataScopeDTO dataScopeDTO; + for (DataScopeTypeEnum typeEnum : enums) { + dataScopeDTO = + DataScopeDTO.builder().dataScopeType(typeEnum.getValue()).dataScopeTypeDesc(typeEnum.getDesc()).dataScopeTypeName(typeEnum.getName()).dataScopeTypeSort(typeEnum.getSort()).build(); + dataScopeTypeList.add(dataScopeDTO); + } + Comparator comparator = (h1, h2) -> h1.getDataScopeTypeSort().compareTo(h2.getDataScopeTypeSort()); + dataScopeTypeList.sort(comparator); + return dataScopeTypeList; + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.java new file mode 100644 index 0000000..fc98e24 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeSqlConfigService.java @@ -0,0 +1,149 @@ +package net.lab1024.sa.admin.module.system.datascope.service; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeViewTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeWhereInTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeSqlConfig; +import net.lab1024.sa.admin.module.system.datascope.DataScope; +import net.lab1024.sa.admin.module.system.datascope.strategy.DataScopePowerStrategy; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.reflections.Reflections; +import org.reflections.scanners.MethodAnnotationsScanner; +import org.reflections.util.ClasspathHelper; +import org.reflections.util.ConfigurationBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * sql配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/28 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Service +public class DataScopeSqlConfigService { + + /** + * 注解joinsql 参数 + */ + private static final String EMPLOYEE_PARAM = "#employeeIds"; + + private static final String DEPARTMENT_PARAM = "#departmentIds"; + + private ConcurrentHashMap dataScopeMethodMap = new ConcurrentHashMap<>(); + + @Autowired + private DataScopeViewService dataScopeViewService; + + @Value("${swagger.package}") + private String scanPackage; + + + @Autowired + private ApplicationContext applicationContext; + + + @PostConstruct + private void initDataScopeMethodMap() { + this.refreshDataScopeMethodMap(); + } + + /** + * 刷新 所有添加数据范围注解的接口方法配置 + * + * @return + */ + private Map refreshDataScopeMethodMap() { + Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forPackage(scanPackage)).setScanners(new MethodAnnotationsScanner())); + Set methods = reflections.getMethodsAnnotatedWith(DataScope.class); + for (Method method : methods) { + DataScope dataScopeAnnotation = method.getAnnotation(DataScope.class); + if (dataScopeAnnotation != null) { + DataScopeSqlConfig configDTO = new DataScopeSqlConfig(); + configDTO.setDataScopeType(dataScopeAnnotation.dataScopeType()); + configDTO.setJoinSql(dataScopeAnnotation.joinSql()); + configDTO.setWhereIndex(dataScopeAnnotation.whereIndex()); + configDTO.setDataScopeWhereInType(dataScopeAnnotation.whereInType()); + configDTO.setParamName(dataScopeAnnotation.paramName()); + configDTO.setJoinSqlImplClazz(dataScopeAnnotation.joinSqlImplClazz()); + dataScopeMethodMap.put(method.getDeclaringClass().getSimpleName() + "." + method.getName(), configDTO); + } + } + return dataScopeMethodMap; + } + + /** + * 根据调用的方法获取,此方法的配置信息 + * + * @param method + * @return + */ + public DataScopeSqlConfig getSqlConfig(String method) { + DataScopeSqlConfig sqlConfigDTO = this.dataScopeMethodMap.get(method); + return sqlConfigDTO; + } + + /** + * 组装需要拼接的sql + * @param paramMap + * @param sqlConfigDTO + * @return + */ + public String getJoinSql(Map paramMap, DataScopeSqlConfig sqlConfigDTO) { + DataScopeTypeEnum dataScopeTypeEnum = sqlConfigDTO.getDataScopeType(); + String joinSql = sqlConfigDTO.getJoinSql(); + Long employeeId = SmartRequestUtil.getRequestUserId(); + if (employeeId == null) { + return ""; + } + if (DataScopeWhereInTypeEnum.CUSTOM_STRATEGY == sqlConfigDTO.getDataScopeWhereInType()) { + Class strategyClass = sqlConfigDTO.getJoinSqlImplClazz(); + if (strategyClass == null) { + log.warn("data scope custom strategy class is null"); + return ""; + } + DataScopePowerStrategy powerStrategy = (DataScopePowerStrategy) applicationContext.getBean(sqlConfigDTO.getJoinSqlImplClazz()); + if (powerStrategy == null) { + log.warn("data scope custom strategy class:{} ,bean is null", sqlConfigDTO.getJoinSqlImplClazz()); + return ""; + } + DataScopeViewTypeEnum viewTypeEnum = dataScopeViewService.getEmployeeDataScopeViewType(dataScopeTypeEnum, employeeId); + return powerStrategy.getCondition(viewTypeEnum,paramMap, sqlConfigDTO); + } + if (DataScopeWhereInTypeEnum.EMPLOYEE == sqlConfigDTO.getDataScopeWhereInType()) { + List canViewEmployeeIds = dataScopeViewService.getCanViewEmployeeId(dataScopeTypeEnum, employeeId); + if (CollectionUtils.isEmpty(canViewEmployeeIds)) { + return ""; + } + String employeeIds = StringUtils.join(canViewEmployeeIds, ","); + String sql = joinSql.replaceAll(EMPLOYEE_PARAM, employeeIds); + return sql; + } + if (DataScopeWhereInTypeEnum.DEPARTMENT == sqlConfigDTO.getDataScopeWhereInType()) { + List canViewDepartmentIds = dataScopeViewService.getCanViewDepartmentId(dataScopeTypeEnum, employeeId); + if (CollectionUtils.isEmpty(canViewDepartmentIds)) { + return ""; + } + String departmentIds = StringUtils.join(canViewDepartmentIds, ","); + String sql = joinSql.replaceAll(DEPARTMENT_PARAM, departmentIds); + return sql; + } + return ""; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeViewService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeViewService.java new file mode 100644 index 0000000..6ec1c40 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/service/DataScopeViewService.java @@ -0,0 +1,162 @@ +package net.lab1024.sa.admin.module.system.datascope.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.role.dao.RoleDataScopeDao; +import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleDataScopeEntity; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeViewTypeEnum; +import net.lab1024.sa.common.common.util.SmartEnumUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 数据范围 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/28 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class DataScopeViewService { + + @Autowired + private RoleEmployeeDao roleEmployeeDao; + + @Autowired + private RoleDataScopeDao roleDataScopeDao; + + @Autowired + private EmployeeDao employeeDao; + + @Autowired + private DepartmentService departmentService; + + /** + * 获取某人可以查看的所有人员信息 + * + * @param dataScopeTypeEnum + * @param employeeId + * @return + */ + public List getCanViewEmployeeId(DataScopeTypeEnum dataScopeTypeEnum, Long employeeId) { + DataScopeViewTypeEnum viewType = this.getEmployeeDataScopeViewType(dataScopeTypeEnum, employeeId); + if (DataScopeViewTypeEnum.ME == viewType) { + return this.getMeEmployeeIdList(employeeId); + } + if (DataScopeViewTypeEnum.DEPARTMENT == viewType) { + return this.getDepartmentEmployeeIdList(employeeId); + } + if (DataScopeViewTypeEnum.DEPARTMENT_AND_SUB == viewType) { + return this.getDepartmentAndSubEmployeeIdList(employeeId); + } + return Lists.newArrayList(); + } + + /** + * 获取某人可以查看的所有部门信息 + * + * @param dataScopeTypeEnum + * @param employeeId + * @return + */ + public List getCanViewDepartmentId(DataScopeTypeEnum dataScopeTypeEnum, Long employeeId) { + DataScopeViewTypeEnum viewType = this.getEmployeeDataScopeViewType(dataScopeTypeEnum, employeeId); + if (DataScopeViewTypeEnum.ME == viewType) { + return this.getMeDepartmentIdList(employeeId); + } + if (DataScopeViewTypeEnum.DEPARTMENT == viewType) { + return this.getMeDepartmentIdList(employeeId); + } + if (DataScopeViewTypeEnum.DEPARTMENT_AND_SUB == viewType) { + return this.getDepartmentAndSubIdList(employeeId); + } + return Lists.newArrayList(); + } + + public List getMeDepartmentIdList(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + return Lists.newArrayList(employeeEntity.getDepartmentId()); + } + + public List getDepartmentAndSubIdList(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + List allDepartmentIds = departmentService.selfAndChildrenIdList(employeeEntity.getDepartmentId()); + return allDepartmentIds; + } + + /** + * 根据员工id 获取各数据范围最大的可见范围 map + * + * @param employeeId + * @return + */ + public DataScopeViewTypeEnum getEmployeeDataScopeViewType(DataScopeTypeEnum dataScopeTypeEnum, Long employeeId) { + if (employeeId == null) { + return DataScopeViewTypeEnum.ME; + } + + List roleIdList = roleEmployeeDao.selectRoleIdByEmployeeId(employeeId); + //未设置角色 默认本人 + if (CollectionUtils.isEmpty(roleIdList)) { + return DataScopeViewTypeEnum.ME; + } + //未设置角色数据范围 默认本人 + List dataScopeRoleList = roleDataScopeDao.listByRoleIdList(roleIdList); + if (CollectionUtils.isEmpty(dataScopeRoleList)) { + return DataScopeViewTypeEnum.ME; + } + Map> listMap = dataScopeRoleList.stream().collect(Collectors.groupingBy(RoleDataScopeEntity::getDataScopeType)); + List viewLevelList = listMap.getOrDefault(dataScopeTypeEnum.getValue(), Lists.newArrayList()); + if (CollectionUtils.isEmpty(viewLevelList)) { + return DataScopeViewTypeEnum.ME; + } + RoleDataScopeEntity maxLevel = viewLevelList.stream().max(Comparator.comparing(e -> SmartEnumUtil.getEnumByValue(e.getViewType(), DataScopeViewTypeEnum.class).getLevel())).get(); + return SmartEnumUtil.getEnumByValue(maxLevel.getViewType(), DataScopeViewTypeEnum.class); + } + + /** + * 获取本人相关 可查看员工id + * + * @param employeeId + * @return + */ + private List getMeEmployeeIdList(Long employeeId) { + return Lists.newArrayList(employeeId); + } + + /** + * 获取本部门相关 可查看员工id + * + * @param employeeId + * @return + */ + private List getDepartmentEmployeeIdList(Long employeeId) { + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + List employeeIdList = employeeDao.getEmployeeIdByDepartmentId(employeeEntity.getDepartmentId(), false); + return employeeIdList; + } + + /** + * 获取本部门及下属子部门相关 可查看员工id + * + * @param employeeId + * @return + */ + private List getDepartmentAndSubEmployeeIdList(Long employeeId) { + List allDepartmentIds = getDepartmentAndSubIdList(employeeId); + List employeeIdList = employeeDao.getEmployeeIdByDepartmentIdList(allDepartmentIds, false); + return employeeIdList; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/strategy/DataScopePowerStrategy.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/strategy/DataScopePowerStrategy.java new file mode 100644 index 0000000..4611fd5 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/datascope/strategy/DataScopePowerStrategy.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.admin.module.system.datascope.strategy; + +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeViewTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.domain.DataScopeSqlConfig; + +import java.util.Map; + +/** + * 数据范围策略 ,使用DataScopeWhereInTypeEnum.CUSTOM_STRATEGY类型,DataScope注解的joinSql属性无用 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/28 20:59:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public abstract class DataScopePowerStrategy { + + /** + * 获取joinsql 字符串 + * @param viewTypeEnum + * @param paramMap + * @param sqlConfigDTO + * @return + */ + public abstract String getCondition(DataScopeViewTypeEnum viewTypeEnum, Map paramMap, DataScopeSqlConfig sqlConfigDTO); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.java new file mode 100644 index 0000000..57b2e53 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/controller/DepartmentController.java @@ -0,0 +1,71 @@ +package net.lab1024.sa.admin.module.system.department.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.common.AdminBaseController; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.department.domain.form.DepartmentAddForm; +import net.lab1024.sa.admin.module.system.department.domain.form.DepartmentUpdateForm; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentTreeVO; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 部门 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-12 20:37:48 + * @Wechat 卓大1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@OperateLog +@RestController +//@Api(tags = {AdminSwaggerTagConst.System.SYSTEM_DEPARTMENT}) +public class DepartmentController extends AdminBaseController { + + @Autowired + private DepartmentService departmentService; + + @ApiOperation(value = "查询部门树形列表 @author 卓大") + @GetMapping("/department/treeList") + public ResponseDTO> departmentTree() { + return departmentService.departmentTree(); + } + + @ApiOperation(value = "添加部门 @author 卓大") + @PostMapping("/department/add") + @PreAuthorize("@saAuth.checkPermission('system:department:add')") + public ResponseDTO addDepartment(@Valid @RequestBody DepartmentAddForm createDTO) { + return departmentService.addDepartment(createDTO); + } + + @ApiOperation(value = "更新部门 @author 卓大") + @PostMapping("/department/update") + @PreAuthorize("@saAuth.checkPermission('system:department:update')") + public ResponseDTO updateDepartment(@Valid @RequestBody DepartmentUpdateForm updateDTO) { + return departmentService.updateDepartment(updateDTO); + } + + @ApiOperation(value = "删除部门 @author 卓大") + @GetMapping("/department/delete/{departmentId}") + @PreAuthorize("@saAuth.checkPermission('system:department:delete')") + public ResponseDTO deleteDepartment(@PathVariable Long departmentId) { + return departmentService.deleteDepartment(departmentId); + } + + @ApiOperation(value = "查询部门列表 @author 卓大") + @GetMapping("/department/listAll") + public ResponseDTO> listAll() { + return ResponseDTO.ok(departmentService.listAll()); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/dao/DepartmentDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/dao/DepartmentDao.java new file mode 100644 index 0000000..25c395c --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/dao/DepartmentDao.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.system.department.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 部门 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-12 20:37:48 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Component +@Mapper +public interface DepartmentDao extends BaseMapper { + + /** + * 根据部门id,查询此部门直接子部门的数量 + * + * @param departmentId + * @return int 子部门的数量 + */ + Integer countSubDepartment(@Param("departmentId") Long departmentId); + + /** + * 获取全部部门列表 + * + * @return + */ + List listAll(); + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/entity/DepartmentEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/entity/DepartmentEntity.java new file mode 100644 index 0000000..28f9431 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/entity/DepartmentEntity.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.admin.module.system.department.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 部门实体类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-12 20:37:48 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName(value = "t_department") +public class DepartmentEntity { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long departmentId; + + /** + * 部门名称 + */ + private String name; + + /** + * 负责人员工 id + */ + private Long managerId; + + /** + * 部门父级id + */ + private Long parentId; + + /** + * 排序 + */ + private Integer sort; + + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentAddForm.java new file mode 100644 index 0000000..4a10c4c --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentAddForm.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.admin.module.system.department.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; + +/** + * 部门 添加表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-12 20:37:48 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DepartmentAddForm { + + @ApiModelProperty("部门名称") + @Length(min = 1, max = 50, message = "请输入正确的部门名称(1-50个字符)") + @NotNull(message = "请输入正确的部门名称(1-50个字符)") + private String name; + + @ApiModelProperty("排序") + @NotNull(message = "排序值") + private Integer sort; + + @ApiModelProperty("部门负责人id") + private Long managerId; + + @ApiModelProperty("上级部门id (可选)") + private Long parentId; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentUpdateForm.java new file mode 100644 index 0000000..a951681 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/form/DepartmentUpdateForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.system.department.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 部门 更新表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-12 20:37:48 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DepartmentUpdateForm extends DepartmentAddForm { + + @ApiModelProperty("部门id") + @NotNull(message = "部门id不能为空") + private Long departmentId; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentEmployeeTreeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentEmployeeTreeVO.java new file mode 100644 index 0000000..aba7b26 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentEmployeeTreeVO.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.admin.module.system.department.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; + +import java.util.List; + +/** + * 部门 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-12 20:37:48 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DepartmentEmployeeTreeVO extends DepartmentVO { + + @ApiModelProperty("部门员工列表") + private List employees; + + @ApiModelProperty("子部门") + private List children; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentTreeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentTreeVO.java new file mode 100644 index 0000000..4efef78 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentTreeVO.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.admin.module.system.department.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 部门 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-12 20:37:48 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DepartmentTreeVO extends DepartmentVO { + + @ApiModelProperty("同级上一个元素id") + private Long preId; + + @ApiModelProperty("同级下一个元素id") + private Long nextId; + + @ApiModelProperty("子部门") + private List children; + + @ApiModelProperty("自己和所有递归子部门的id集合") + private List selfAndAllChildrenIdList; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentVO.java new file mode 100644 index 0000000..5f546fc --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/domain/vo/DepartmentVO.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.admin.module.system.department.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 部门 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-12 20:37:48 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DepartmentVO { + + @ApiModelProperty("部门id") + private Long departmentId; + + @ApiModelProperty("部门名称") + private String name; + + @ApiModelProperty("部门负责人姓名") + private String managerName; + + @ApiModelProperty("部门负责人id") + private Long managerId; + + @ApiModelProperty("父级部门id") + private Long parentId; + + @ApiModelProperty("排序") + private Integer sort; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/manager/DepartmentCacheManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/manager/DepartmentCacheManager.java new file mode 100644 index 0000000..f1fc093 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/manager/DepartmentCacheManager.java @@ -0,0 +1,249 @@ +package net.lab1024.sa.admin.module.system.department.manager; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.constant.AdminCacheConst; +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentTreeVO; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 部门 缓存相关 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-12 20:37:48 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Service +public class DepartmentCacheManager { + + @Autowired + private DepartmentDao departmentDao; + + private void logClearInfo(String cache) { + log.info("clear " + cache); + } + + // ----------------------- 清空缓存 ----------------------- + @CacheEvict(value = {AdminCacheConst.Department.DEPARTMENT_LIST_CACHE, AdminCacheConst.Department.DEPARTMENT_MAP_CACHE, AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE, AdminCacheConst.Department.DEPARTMENT_TREE_CACHE, AdminCacheConst.Department.DEPARTMENT_PATH_CACHE,}, allEntries = true) + public void clearCache() { + logClearInfo(AdminCacheConst.Department.DEPARTMENT_LIST_CACHE); + } + + // ----------------------- 查询 ----------------------- + + /** + * 部门列表 + * + * @return + */ + @Cacheable(AdminCacheConst.Department.DEPARTMENT_LIST_CACHE) + public List getDepartmentList() { + List departmentVOList = departmentDao.listAll(); + return departmentVOList; + } + + /** + * 部门map + * + * @return + */ + @Cacheable(AdminCacheConst.Department.DEPARTMENT_MAP_CACHE) + public Map getDepartmentMap() { + return departmentDao.listAll().stream().collect(Collectors.toMap(DepartmentVO::getDepartmentId, Function.identity())); + } + + + /** + * 缓存部门树结构 + * + * @return + */ + @Cacheable(AdminCacheConst.Department.DEPARTMENT_TREE_CACHE) + public List getDepartmentTree() { + List departmentVOList = departmentDao.listAll(); + return this.buildTree(departmentVOList); + } + + /** + * 缓存某个部门的下级id列表 + * + * @param departmentId + * @return + */ + @Cacheable(AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE) + public List getDepartmentSelfAndChildren(Long departmentId) { + List departmentVOList = departmentDao.listAll(); + List idList = this.selfAndChildrenIdList(departmentId, departmentVOList); + return idList; + } + + + /** + * 部门的路径名称 + * + * @return + */ + @Cacheable(AdminCacheConst.Department.DEPARTMENT_PATH_CACHE) + public Map getDepartmentPathMap() { + List departmentVOList = departmentDao.listAll(); + Map departmentMap = departmentVOList.stream().collect(Collectors.toMap(DepartmentVO::getDepartmentId, Function.identity())); + + Map pathNameMap = Maps.newHashMap(); + for (DepartmentVO departmentVO : departmentVOList) { + String pathName = this.buildDepartmentPath(departmentVO, departmentMap); + pathNameMap.put(departmentVO.getDepartmentId(), pathName); + } + + return pathNameMap; + } + + /** + * 构建父级考点路径 + * + * @param departmentVO + * @param departmentMap + */ + private String buildDepartmentPath(DepartmentVO departmentVO, Map departmentMap) { + if (Objects.equals(departmentVO.getParentId(), NumberUtils.LONG_ZERO)) { + return departmentVO.getName(); + } + //父节点 + DepartmentVO parentDepartment = departmentMap.get(departmentVO.getParentId()); + if (parentDepartment == null) { + return departmentVO.getName(); + } + String pathName = buildDepartmentPath(parentDepartment, departmentMap); + return pathName + "/" + departmentVO.getName(); + + } + // ---------------------- 构造树的一些方法 ------------------------------ + + /** + * 构建部门树结构 + * + * @param voList + * @return + */ + public List buildTree(List voList) { + if (CollectionUtils.isEmpty(voList)) { + return Lists.newArrayList(); + } + List rootList = voList.stream().filter(e -> e.getParentId() == null || Objects.equals(e.getParentId(), NumberUtils.LONG_ZERO)).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(rootList)) { + return Lists.newArrayList(); + } + List treeVOList = SmartBeanUtil.copyList(rootList, DepartmentTreeVO.class); + this.recursiveBuildTree(treeVOList, voList); + return treeVOList; + } + + /** + * 构建所有根节点的下级树形结构 + * + * @param nodeList + * @param + */ + private void recursiveBuildTree(List nodeList, List allDepartmentList) { + int nodeSize = nodeList.size(); + for (int i = 0; i < nodeSize; i++) { + int preIndex = i - 1; + int nextIndex = i + 1; + DepartmentTreeVO node = nodeList.get(i); + if (preIndex > -1) { + node.setPreId(nodeList.get(preIndex).getDepartmentId()); + } + if (nextIndex < nodeSize) { + node.setNextId(nodeList.get(nextIndex).getDepartmentId()); + } + + ArrayList selfAndAllChildrenIdList = Lists.newArrayList(); + selfAndAllChildrenIdList.add(node.getDepartmentId()); + node.setSelfAndAllChildrenIdList(selfAndAllChildrenIdList); + + List children = getChildren(node.getDepartmentId(), allDepartmentList); + if (CollectionUtils.isNotEmpty(children)) { + node.setChildren(children); + this.recursiveBuildTree(children, allDepartmentList); + } + } + } + + + /** + * 获取子元素 + * + * @param departmentId + * @param voList + * @return + */ + private List getChildren(Long departmentId, List voList) { + List childrenEntityList = voList.stream().filter(e -> departmentId.equals(e.getParentId())).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(childrenEntityList)) { + return Lists.newArrayList(); + } + return SmartBeanUtil.copyList(childrenEntityList, DepartmentTreeVO.class); + } + + + /** + * 通过部门id,获取当前以及下属部门 + * + * @param departmentId + * @param voList + */ + public List selfAndChildrenIdList(Long departmentId, List voList) { + List selfAndChildrenIdList = Lists.newArrayList(); + if (CollectionUtils.isEmpty(voList)) { + return selfAndChildrenIdList; + } + selfAndChildrenIdList.add(departmentId); + List children = this.getChildren(departmentId, voList); + if (CollectionUtils.isEmpty(children)) { + return selfAndChildrenIdList; + } + List childrenIdList = children.stream().map(DepartmentTreeVO::getDepartmentId).collect(Collectors.toList()); + selfAndChildrenIdList.addAll(childrenIdList); + for (Long childId : childrenIdList) { + this.selfAndChildrenRecursion(selfAndChildrenIdList, childId, voList); + } + return selfAndChildrenIdList; + } + + /** + * 递归查询 + * + * @param selfAndChildrenIdList + * @param departmentId + * @param voList + */ + public void selfAndChildrenRecursion(List selfAndChildrenIdList, Long departmentId, List voList) { + List children = this.getChildren(departmentId, voList); + if (CollectionUtils.isEmpty(children)) { + return; + } + List childrenIdList = children.stream().map(DepartmentTreeVO::getDepartmentId).collect(Collectors.toList()); + selfAndChildrenIdList.addAll(childrenIdList); + for (Long childId : childrenIdList) { + this.selfAndChildrenRecursion(selfAndChildrenIdList, childId, voList); + } + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/manager/DepartmentManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/manager/DepartmentManager.java new file mode 100644 index 0000000..8bc49a9 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/manager/DepartmentManager.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.admin.module.system.department.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import org.springframework.stereotype.Service; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; + +/** + * 部门 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-12 20:37:48 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class DepartmentManager extends ServiceImpl { + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/service/DepartmentService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/service/DepartmentService.java new file mode 100644 index 0000000..c82c98d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/department/service/DepartmentService.java @@ -0,0 +1,210 @@ +package net.lab1024.sa.admin.module.system.department.service; + +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.department.domain.form.DepartmentAddForm; +import net.lab1024.sa.admin.module.system.department.domain.form.DepartmentUpdateForm; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentTreeVO; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.admin.module.system.department.manager.DepartmentCacheManager; +import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * 部门 service + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-12 20:37:48 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class DepartmentService { + + @Autowired + private DepartmentDao departmentDao; + + @Autowired + private EmployeeDao employeeDao; + + @Autowired + private DepartmentCacheManager departmentCacheManager; + + // ---------------------------- 增加、修改、删除 ---------------------------- + + /** + * 新增添加部门 + * + * @param departmentAddForm + * @return AjaxResult + */ + + public ResponseDTO addDepartment(DepartmentAddForm departmentAddForm) { + DepartmentEntity departmentEntity = SmartBeanUtil.copy(departmentAddForm, DepartmentEntity.class); + departmentDao.insert(departmentEntity); + this.clearCache(); + return ResponseDTO.ok(); + } + + + /** + * 更新部门信息 + * + * @param updateDTO + * @return + */ + public ResponseDTO updateDepartment(DepartmentUpdateForm updateDTO) { + if (updateDTO.getParentId() == null) { + return ResponseDTO.userErrorParam("父级部门id不能为空"); + } + DepartmentEntity entity = departmentDao.selectById(updateDTO.getDepartmentId()); + if (entity == null) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + DepartmentEntity departmentEntity = SmartBeanUtil.copy(updateDTO, DepartmentEntity.class); + departmentEntity.setSort(updateDTO.getSort()); + departmentDao.updateById(departmentEntity); + this.clearCache(); + return ResponseDTO.ok(); + } + + /** + * 根据id删除部门 + * 1、需要判断当前部门是否有子部门,有子部门则不允许删除 + * 2、需要判断当前部门是否有员工,有员工则不能删除 + * + * @param departmentId + * @return + */ + public ResponseDTO deleteDepartment(Long departmentId) { + DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); + if (null == departmentEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + // 是否有子级部门 + int subDepartmentNum = departmentDao.countSubDepartment(departmentId); + if (subDepartmentNum > 0) { + return ResponseDTO.userErrorParam("请先删除子级部门"); + } + + // 是否有未删除员工 + int employeeNum = employeeDao.countByDepartmentId(departmentId); + if (employeeNum > 0) { + return ResponseDTO.userErrorParam("请先删除部门员工"); + } + departmentDao.deleteById(departmentId); + // 清除缓存 + this.clearCache(); + return ResponseDTO.ok(); + } + + /** + * 清除自身以及下级的id列表缓存 + */ + private void clearCache() { + departmentCacheManager.clearCache(); + } + + // ---------------------------- 查询 ---------------------------- + + /** + * 获取部门树形结构 + * + * @return + */ + public ResponseDTO> departmentTree() { + List treeVOList = departmentCacheManager.getDepartmentTree(); + return ResponseDTO.ok(treeVOList); + } + + + /** + * 自身以及所有下级的部门id列表 + * + * @param departmentId + * @return + */ + public List selfAndChildrenIdList(Long departmentId) { + return departmentCacheManager.getDepartmentSelfAndChildren(departmentId); + } + + + /** + * 获取所有部门 + * + * @return + */ + public List listAll() { + return departmentCacheManager.getDepartmentList(); + } + + + /** + * 获取部门 + * + * @param departmentId + */ + public DepartmentVO getDepartmentById(Long departmentId) { + return departmentCacheManager.getDepartmentMap().get(departmentId); + } + + /** + * 获取部门路径:/公司/研发部/产品组 + * + * @param departmentId + */ + public String getDepartmentPath(Long departmentId) { + return departmentCacheManager.getDepartmentPathMap().get(departmentId); + } + + /** + * 查询全部父级部门(不包含自己) + * + * @param departmentId + * @return + * @author listen + */ + public List queryAllParentDepartment(Long departmentId) { + List list = new ArrayList<>(); + + Map departmentMap = departmentCacheManager.getDepartmentMap(); + DepartmentVO departmentVO = departmentMap.get(departmentId); + while (departmentVO != null) { + list.add(departmentVO); + departmentVO = departmentMap.get(departmentVO.getParentId()); + } + Collections.reverse(list); + return list; + } + + /** + * 查询全部父级部门(不包含自己) + * + * @param departmentId + * @return + * @author listen + */ + public List queryAllParentDepartmentIdList(Long departmentId) { + List list = new ArrayList<>(); + + Map departmentMap = departmentCacheManager.getDepartmentMap(); + DepartmentVO departmentVO = departmentMap.get(departmentId); + while (departmentVO != null) { + list.add(departmentVO.getDepartmentId()); + departmentVO = departmentMap.get(departmentVO.getParentId()); + } + Collections.reverse(list); + return list; + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.java new file mode 100644 index 0000000..5822773 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/controller/EmployeeController.java @@ -0,0 +1,118 @@ +package net.lab1024.sa.admin.module.system.employee.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.common.AdminBaseController; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.admin.module.system.employee.domain.form.*; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import net.lab1024.sa.admin.module.system.employee.service.EmployeePermissionService; +import net.lab1024.sa.admin.module.system.employee.service.EmployeeService; +import net.lab1024.sa.admin.module.system.login.domain.LoginEmployeeDetail; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 员工 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-12-09 22:57:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@RestController +@OperateLog +//@Api(tags = {AdminSwaggerTagConst.System.SYSTEM_EMPLOYEE}) +public class EmployeeController extends AdminBaseController { + + @Autowired + private EmployeeService employeeService; + @Autowired + private EmployeePermissionService employeePermissionService; + + @PostMapping("/employee/query") + @ApiOperation(value = "员工管理查询 @author 卓大") + public ResponseDTO> query(@Valid @RequestBody EmployeeQueryForm query) { + return employeeService.queryEmployee(query); + } + + @ApiOperation(value = "添加员工(返回添加员工的密码) @author 卓大") + @PostMapping("/employee/add") + @PreAuthorize("@saAuth.checkPermission('system:employee:add,case-system:employee:add')") + public ResponseDTO addEmployee(@Valid @RequestBody EmployeeAddForm employeeAddForm) { + return employeeService.addEmployee(employeeAddForm); + } + + @ApiOperation(value = "更新员工 @author 卓大") + @PostMapping("/employee/update") + @PreAuthorize("@saAuth.checkPermission('system:employee:update,case-system:employee:update')") + public ResponseDTO updateEmployee(@Valid @RequestBody EmployeeUpdateForm employeeUpdateForm) { + return employeeService.updateEmployee(employeeUpdateForm); + } + + @ApiOperation(value = "更新员工禁用/启用状态 @author 卓大") + @GetMapping("/employee/update/disabled/{employeeId}") + @PreAuthorize("@saAuth.checkPermission('system:employee:disabled,case-system:employee:disabled')") + public ResponseDTO updateDisableFlag(@PathVariable Long employeeId) { + return employeeService.updateDisableFlag(employeeId); + } + + @ApiOperation(value = "批量删除员工 @author 卓大") + @PostMapping("/employee/update/batch/delete") + @PreAuthorize("@saAuth.checkPermission('system:employee:delete')") + public ResponseDTO batchUpdateDeleteFlag(@RequestBody List employeeIdList) { + return employeeService.batchUpdateDeleteFlag(employeeIdList); + } + + @ApiOperation(value = "批量调整员工部门 @author 卓大") + @PostMapping("/employee/update/batch/department") + @PreAuthorize("@saAuth.checkPermission('system:employee:department:update')") + public ResponseDTO batchUpdateDepartment(@Valid @RequestBody EmployeeBatchUpdateDepartmentForm batchUpdateDepartmentForm) { + return employeeService.batchUpdateDepartment(batchUpdateDepartmentForm); + } + + @ApiOperation(value = "修改密码 @author 卓大") + @PostMapping("/employee/update/password") + public ResponseDTO updatePassword(@Valid @RequestBody EmployeeUpdatePasswordForm updatePasswordForm) { + updatePasswordForm.setEmployeeId(SmartRequestUtil.getRequestUserId()); + return employeeService.updatePassword(updatePasswordForm); + } + + @ApiOperation(value = "重置员工密码 @author 卓大") + @GetMapping("/employee/update/password/reset/{employeeId}") + @PreAuthorize("@saAuth.checkPermission('system:employee:password:reset,case-system:employee:password:reset')") + public ResponseDTO resetPassword(@PathVariable Long employeeId) { + return employeeService.resetPassword(employeeId); + } + + @ApiOperation(value = "查询员工-根据部门id @author 卓大") + @GetMapping("/employee/getAllEmployeeByDepartmentId/{departmentId}") + public ResponseDTO> getAllEmployeeByDepartmentId(@PathVariable Long departmentId) { + return employeeService.getAllEmployeeByDepartmentId(departmentId, Boolean.FALSE); + } + + @ApiOperation("查询所有员工 @author 卓大") + @GetMapping("/employee/queryAll") + public ResponseDTO> queryAllEmployee(@RequestParam(value = "disabledFlag", required = false) Boolean disabledFlag) { + return employeeService.queryAllEmployee(disabledFlag); + } + + @ApiOperation("查询员工省份 @author 卓大") + @GetMapping("/employee/getRoleProv") + public ResponseDTO> getRoleProv() { + LoginEmployeeDetail requestUser = (LoginEmployeeDetail) SmartRequestUtil.getRequestUser(); + return ResponseDTO.ok(employeePermissionService.getRoleProvByRoleId(requestUser.getUserId(), requestUser.getAdministratorFlag())); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/dao/EmployeeDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/dao/EmployeeDao.java new file mode 100644 index 0000000..b40b480 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/dao/EmployeeDao.java @@ -0,0 +1,171 @@ +package net.lab1024.sa.admin.module.system.employee.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.employee.domain.form.EmployeeQueryForm; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; + +/** + * 员工 dao + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-12-09 22:57:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface EmployeeDao extends BaseMapper { + /** + * 查询员工列表 + * + * @param page + * @param queryForm + * @return + */ + List queryEmployee(Page page, @Param("queryForm") EmployeeQueryForm queryForm, @Param("departmentIdList") List departmentIdList); + + /** + * 查询员工 + */ + List selectEmployeeByDisabledAndDeleted(@Param("disabledFlag") Boolean disabledFlag, @Param("deletedFlag") Boolean deletedFlag); + + + /** + * 更新单个 + * + * @param employeeId + * @param disabledFlag + */ + void updateDisableFlag(@Param("employeeId") Long employeeId, @Param("disabledFlag") Boolean disabledFlag); + + + /** + * 通过登录名查询 + * + * @param loginName + * @param disabledFlag + * @return + */ + EmployeeEntity getByLoginName(@Param("loginName") String loginName, + @Param("disabledFlag") Boolean disabledFlag); + + + /** + * 通过姓名查询 + * + * @param actualName + * @param disabledFlag + * @return + */ + EmployeeEntity getByActualName(@Param("actualName") String actualName, + @Param("disabledFlag") Boolean disabledFlag + ); + + /** + * 通过手机号查询 + * + * @param phone + * @param disabledFlag + * @return + */ + EmployeeEntity getByPhone(@Param("phone") String phone, @Param("disabledFlag") Boolean disabledFlag); + + /** + * 获取所有员工 + * + * @return + */ + List listAll(); + + /** + * 获取某个部门员工数 + * + * @param departmentId + * @return + */ + Integer countByDepartmentId(@Param("departmentId") Long departmentId); + + /** + * 获取一批员工 + * + * @param employeeIds + * @return + */ + List getEmployeeByIds(@Param("employeeIds") Collection employeeIds); + + + /** + * 查询单个员工信息 + * + * @param employeeId + * @return + */ + EmployeeVO getEmployeeById(@Param("employeeId") Long employeeId); + + + /** + * 获取某个部门的员工 + * + * @param departmentId + * @param disabledFlag + * @return + */ + List selectByDepartmentId(@Param("departmentId") Long departmentId, @Param("disabledFlag") Boolean disabledFlag); + + + /** + * 查询某些部门下用户名是xxx的员工 + * + * @param departmentIdList + * @param actualName + * @param disabledFlag + * @return + */ + List selectByActualName(@Param("departmentIdList") List departmentIdList, @Param("actualName") String actualName, @Param("disabledFlag") Boolean disabledFlag); + + + /** + * 获取某批部门的员工Id + * + * @param departmentIds + * @return + */ + List getEmployeeIdByDepartmentIdList(@Param("departmentIds") List departmentIds, @Param("disabledFlag") Boolean disabledFlag); + + /** + * 获取所有 + * + * @param leaveFlag + * @param disabledFlag + * @return + */ + List getEmployeeId(@Param("leaveFlag") Boolean leaveFlag, @Param("disabledFlag") Boolean disabledFlag); + + /** + * 获取某个部门的员工Id + * + * @param departmentId + * @param disabledFlag + * @return + */ + List getEmployeeIdByDepartmentId(@Param("departmentId") Long departmentId, @Param("disabledFlag") Boolean disabledFlag); + + /** + * 员工重置密码 + * + * @param employeeId + * @param password + * @return + */ + Integer updatePassword(@Param("employeeId") Long employeeId, @Param("password") String password); + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/entity/EmployeeEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/entity/EmployeeEntity.java new file mode 100644 index 0000000..b66b596 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/entity/EmployeeEntity.java @@ -0,0 +1,81 @@ +package net.lab1024.sa.admin.module.system.employee.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 员工 实体表 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-12-09 22:57:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_employee") +public class EmployeeEntity { + + @TableId(type = IdType.AUTO) + private Long employeeId; + + /** + * 登录账号 + */ + private String loginName; + + /** + * 登录密码 + */ + private String loginPwd; + + /** + * 员工名称 + */ + private String actualName; + + /** + * 性别 + */ + private Integer gender; + + /** + * 手机号码 + */ + private String phone; + + /** + * 部门id + */ + private Long departmentId; + + /** + * 是否为超级管理员: 0 不是,1是 + */ + private Boolean administratorFlag; + + /** + * 是否被禁用 0否1是 + */ + private Boolean disabledFlag; + + /** + * 是否删除0否 1是 + */ + private Boolean deletedFlag; + + /** + * 备注 + */ + private String remark; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeAddForm.java new file mode 100644 index 0000000..09bf252 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeAddForm.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.enumeration.GenderEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; +import net.lab1024.sa.common.common.util.SmartVerificationUtil; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import java.util.List; + +/** + * 添加员工 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-20 21:06:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class EmployeeAddForm { + + @ApiModelProperty("姓名") + @NotNull(message = "姓名不能为空") + @Length(max = 30, message = "姓名最多30字符") + private String actualName; + + @ApiModelProperty("登录账号") + @NotNull(message = "登录账号不能为空") + @Length(max = 30, message = "登录账号最多30字符") + private String loginName; + + @ApiModelPropertyEnum(GenderEnum.class) + @CheckEnum(value = GenderEnum.class, message = "性别错误") + private Integer gender; + + @ApiModelProperty("部门id") + @NotNull(message = "部门id不能为空") + private Long departmentId; + + @ApiModelProperty("是否启用") + @NotNull(message = "是否被禁用不能为空") + private Boolean disabledFlag; + + @ApiModelProperty("手机号") + @NotNull(message = "手机号不能为空") + @Pattern(regexp = SmartVerificationUtil.PHONE_REGEXP, message = "手机号格式不正确") + private String phone; + + @ApiModelProperty("角色列表") + private List roleIdList; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeBatchUpdateDepartmentForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeBatchUpdateDepartmentForm.java new file mode 100644 index 0000000..4a9de07 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeBatchUpdateDepartmentForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 员工更新部门 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-20 21:06:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class EmployeeBatchUpdateDepartmentForm { + + @ApiModelProperty("员工id") + @NotEmpty(message = "员工id不能为空") + @Size(max = 99, message = "一次最多调整99个员工") + private List employeeIdList; + + @ApiModelProperty("部门ID") + @NotNull(message = "部门ID不能为空") + private Long departmentId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeQueryForm.java new file mode 100644 index 0000000..8315f20 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeQueryForm.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 员工列表 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-20 21:06:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class EmployeeQueryForm extends PageParam { + + @ApiModelProperty("搜索词") + @Length(max = 20, message = "搜索词最多20字符") + private String keyword; + + @ApiModelProperty("部门id") + private Long departmentId; + + @ApiModelProperty("是否禁用") + private Boolean disabledFlag; + + @ApiModelProperty("员工id集合") + @Size(max = 99, message = "最多查询99个员工") + private List employeeIdList; + + @ApiModelProperty(value = "删除标识", hidden = true) + private Boolean deletedFlag; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateForm.java new file mode 100644 index 0000000..860a66d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 更新员工 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-20 21:06:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class EmployeeUpdateForm extends EmployeeAddForm { + + @ApiModelProperty("员工id") + @NotNull(message = "员工id不能为空") + private Long employeeId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdatePasswordForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdatePasswordForm.java new file mode 100644 index 0000000..a557a43 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdatePasswordForm.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.util.SmartVerificationUtil; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +/** + * 修改密码所需参数 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-20 21:06:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class EmployeeUpdatePasswordForm { + + @ApiModelProperty(hidden = true) + private Long employeeId; + + @ApiModelProperty("原密码") + @NotBlank(message = "原密码不能为空哦") + private String oldPassword; + + @ApiModelProperty("新密码") + @NotBlank(message = "新密码不能为空哦") + @Pattern(regexp = SmartVerificationUtil.PWD_REGEXP, message = "新密码至少1个大写字母,1个小写字母和1个数字,6-32位") + private String newPassword; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateRoleForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateRoleForm.java new file mode 100644 index 0000000..4672565 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/form/EmployeeUpdateRoleForm.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.admin.module.system.employee.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 员工更新角色 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-20 20:55:13 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class EmployeeUpdateRoleForm { + + @ApiModelProperty("员工id") + @NotNull(message = "员工id不能为空") + private Long employeeId; + + @ApiModelProperty("角色ids") + @Size(max = 99, message = "角色最多99") + private List roleIdList; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/vo/EmployeeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/vo/EmployeeVO.java new file mode 100644 index 0000000..108a81d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/domain/vo/EmployeeVO.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.admin.module.system.employee.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.enumeration.GenderEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 员工信息 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-21 23:05:56 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class EmployeeVO { + + @ApiModelProperty("主键id") + private Long employeeId; + + @ApiModelProperty("登录账号") + private String loginName; + + @ApiModelPropertyEnum(GenderEnum.class) + private Integer gender; + + @ApiModelProperty("员工名称") + private String actualName; + + @ApiModelProperty("手机号码") + private String phone; + + @ApiModelProperty("部门id") + private Long departmentId; + + @ApiModelProperty("是否被禁用") + private Boolean disabledFlag; + + @ApiModelProperty("是否 超级管理员") + private Boolean administratorFlag; + + @ApiModelProperty("部门名称") + private String departmentName; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("角色列表") + private List roleIdList; + + @ApiModelProperty("角色名称列表") + private List roleNameList; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/manager/EmployeeManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/manager/EmployeeManager.java new file mode 100644 index 0000000..32c075b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/manager/EmployeeManager.java @@ -0,0 +1,91 @@ +package net.lab1024.sa.admin.module.system.employee.manager; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao; +import net.lab1024.sa.admin.module.system.login.service.LoginService; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity; +import net.lab1024.sa.admin.module.system.role.manager.RoleEmployeeManager; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 员工 manager + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-12-29 21:52:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class EmployeeManager extends ServiceImpl { + + @Autowired + private EmployeeDao employeeDao; + + @Autowired + private RoleEmployeeManager roleEmployeeManager; + + @Autowired + @Lazy + private LoginService loginService; + + /** + * 保存员工 + * + * @param employee + */ + @Transactional(rollbackFor = Throwable.class) + public void saveEmployee(EmployeeEntity employee, List roleIdList) { + // 保存员工 获得id + employeeDao.insert(employee); + + if (CollectionUtils.isNotEmpty(roleIdList)) { + List roleEmployeeList = roleIdList.stream().map(e -> new RoleEmployeeEntity(e, employee.getEmployeeId())).collect(Collectors.toList()); + roleEmployeeManager.saveBatch(roleEmployeeList); + } + } + + /** + * 更新员工 + * + * @param employee + */ + @Transactional(rollbackFor = Throwable.class) + public void updateEmployee(EmployeeEntity employee, List roleIdList) { + // 保存员工 获得id + employeeDao.updateById(employee); + + if (CollectionUtils.isNotEmpty(roleIdList)) { + List roleEmployeeList = roleIdList.stream().map(e -> new RoleEmployeeEntity(e, employee.getEmployeeId())).collect(Collectors.toList()); + this.updateEmployeeRole(employee.getEmployeeId(), roleEmployeeList); + } + + //刷新员工权限信息 + loginService.removeLoginUserDetailCache(employee.getEmployeeId()); + } + + /** + * 更新员工角色 + * + * @param employeeId + * @param roleEmployeeList + */ + @Transactional(rollbackFor = Throwable.class) + public void updateEmployeeRole(Long employeeId, List roleEmployeeList) { + roleEmployeeManager.getBaseMapper().deleteByEmployeeId(employeeId); + + if (CollectionUtils.isNotEmpty(roleEmployeeList)) { + roleEmployeeManager.saveBatch(roleEmployeeList); + } + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeePermissionService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeePermissionService.java new file mode 100644 index 0000000..2eb77ed --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeePermissionService.java @@ -0,0 +1,104 @@ +package net.lab1024.sa.admin.module.system.employee.service; + +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.admin.module.business.area.service.AreaService; +import net.lab1024.sa.admin.module.system.menu.constant.MenuPermsTypeEnum; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService; +import net.lab1024.sa.admin.module.system.role.service.RoleMenuService; +import net.lab1024.sa.admin.module.system.role.service.RoleProvService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 员工权限校验 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-12-29 21:52:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class EmployeePermissionService { + + @Autowired + private RoleEmployeeService roleEmployeeService; + + @Autowired + private RoleMenuService roleMenuService; + + @Autowired + private RoleProvService roleProvService; + + @Autowired + private AreaService areaService; + + /** + * 构建权限集合 + * + * @param menuAndPointsList + */ + public Set buildAuthorities(List menuAndPointsList) { + HashSet permissionList = new HashSet<>(); + for (MenuVO menu : menuAndPointsList) { + if(menu.getPermsType() == null){ + continue; + } + + String perms = null; + if(menu.getPermsType().equals(MenuPermsTypeEnum.SPRING_SECURITY.getValue())){ + perms = menu.getWebPerms(); + }else{ + perms = menu.getApiPerms(); + } + + if (StringUtils.isEmpty(perms)) { + continue; + } + //接口权限 + String[] split = perms.split(","); + for (String perm : split) { + permissionList.add(perm); + } + } + + Set authorities = new HashSet<>(); + authorities.addAll(permissionList.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toSet())); + return authorities; + } + + /** + * 查询用户拥有的前端菜单项 用于登陆返回 前端动态路由配置 + * + * @param employeeId + * @return + */ + public List getEmployeeMenuAndPointsList(Long employeeId, Boolean administratorFlag) { + List roleIdList = roleEmployeeService.getRoleIdList(employeeId); + return roleMenuService.getMenuList(roleIdList, administratorFlag); + } + + + public List getRoleProvByRoleId(Long employeeId, Boolean administratorFlag){ + if(administratorFlag){ + return areaService.provList(); + } + List roleIdList = roleEmployeeService.getRoleIdList(employeeId); + List data = new ArrayList<>(); + for(Long employ:roleIdList){ + data.addAll(roleProvService.getRoleProvByRoleId(employ)); + } + return data; + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.java new file mode 100644 index 0000000..542c4d7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/employee/service/EmployeeService.java @@ -0,0 +1,399 @@ +package net.lab1024.sa.admin.module.system.employee.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.business.token.service.TokenService; +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.employee.domain.form.*; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import net.lab1024.sa.admin.module.system.employee.manager.EmployeeManager; +import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleEmployeeVO; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.RandomStringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 员工 service + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-12-29 21:52:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class EmployeeService { + + private static final String PASSWORD_SALT_FORMAT = "smart_%s_admin_$^&*"; + + @Autowired + private EmployeeDao employeeDao; + + @Autowired + private DepartmentDao departmentDao; + + @Autowired + private EmployeeManager employeeManager; + + @Autowired + private RoleEmployeeDao roleEmployeeDao; + + @Autowired + private DepartmentService departmentService; + + @Autowired + private TokenService tokenService; + + + public EmployeeEntity getById(Long employeeId) { + return employeeDao.selectById(employeeId); + } + + + /** + * 查询员工列表 + * + * @param employeeQueryForm + * @return + */ + public ResponseDTO> queryEmployee(EmployeeQueryForm employeeQueryForm) { + employeeQueryForm.setDeletedFlag(false); + Page pageParam = SmartPageUtil.convert2PageQuery(employeeQueryForm); + + List departmentIdList = new ArrayList<>(); + if (employeeQueryForm.getDepartmentId() != null) { + departmentIdList.addAll(departmentService.selfAndChildrenIdList(employeeQueryForm.getDepartmentId())); + } + + List employeeList = employeeDao.queryEmployee(pageParam, employeeQueryForm, departmentIdList); + if (CollectionUtils.isEmpty(employeeList)) { + PageResult PageResult = SmartPageUtil.convert2PageResult(pageParam, employeeList); + return ResponseDTO.ok(PageResult); + } + + List employeeIdList = employeeList.stream().map(EmployeeVO::getEmployeeId).collect(Collectors.toList()); + // 查询员工角色 + List roleEmployeeEntityList = roleEmployeeDao.selectRoleByEmployeeIdList(employeeIdList); + Map> employeeRoleIdListMap = roleEmployeeEntityList.stream().collect(Collectors.groupingBy(RoleEmployeeVO::getEmployeeId, Collectors.mapping(RoleEmployeeVO::getRoleId, Collectors.toList()))); + Map> employeeRoleNameListMap = roleEmployeeEntityList.stream().collect(Collectors.groupingBy(RoleEmployeeVO::getEmployeeId, Collectors.mapping(RoleEmployeeVO::getRoleName, Collectors.toList()))); + + employeeList.forEach(e -> { + e.setRoleIdList(employeeRoleIdListMap.getOrDefault(e.getEmployeeId(), Lists.newArrayList())); + e.setRoleNameList(employeeRoleNameListMap.getOrDefault(e.getEmployeeId(), Lists.newArrayList())); + e.setDepartmentName(departmentService.getDepartmentPath(e.getDepartmentId())); + }); + PageResult PageResult = SmartPageUtil.convert2PageResult(pageParam, employeeList); + return ResponseDTO.ok(PageResult); + } + + /** + * 新增员工 + * + * @param employeeAddForm + * @return + */ + public synchronized ResponseDTO addEmployee(EmployeeAddForm employeeAddForm) { + // 校验名称是否重复 + EmployeeEntity employeeEntity = employeeDao.getByLoginName(employeeAddForm.getLoginName(), null); + if (null != employeeEntity) { + return ResponseDTO.userErrorParam("登录名重复"); + } + // 校验姓名是否重复 + employeeEntity = employeeDao.getByActualName(employeeAddForm.getActualName(), null); + if (null != employeeEntity) { + return ResponseDTO.userErrorParam("姓名重复"); + } + // 校验电话是否存在 + employeeEntity = employeeDao.getByPhone(employeeAddForm.getPhone(), null); + if (null != employeeEntity) { + return ResponseDTO.userErrorParam("手机号已存在"); + } + // 部门是否存在 + Long departmentId = employeeAddForm.getDepartmentId(); + DepartmentEntity department = departmentDao.selectById(departmentId); + if (department == null) { + return ResponseDTO.userErrorParam("部门不存在"); + } + + EmployeeEntity entity = SmartBeanUtil.copy(employeeAddForm, EmployeeEntity.class); + // 设置密码 默认密码 + String password = randomPassword(); + entity.setLoginPwd(getEncryptPwd(password)); + + // 保存数据 + entity.setDeletedFlag(Boolean.FALSE); + employeeManager.saveEmployee(entity, employeeAddForm.getRoleIdList()); + + return ResponseDTO.ok(password); + } + + /** + * 更新员工 + * + * @param employeeUpdateForm + * @return + */ + public synchronized ResponseDTO updateEmployee(EmployeeUpdateForm employeeUpdateForm) { + + Long employeeId = employeeUpdateForm.getEmployeeId(); + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (null == employeeEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + // 部门是否存在 + Long departmentId = employeeUpdateForm.getDepartmentId(); + DepartmentEntity departmentEntity = departmentDao.selectById(departmentId); + if (departmentEntity == null) { + return ResponseDTO.userErrorParam("部门不存在"); + } + + + EmployeeEntity existEntity = employeeDao.getByLoginName(employeeUpdateForm.getLoginName(), null); + if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) { + return ResponseDTO.userErrorParam("登录名重复"); + } + + existEntity = employeeDao.getByPhone(employeeUpdateForm.getPhone(), null); + if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) { + return ResponseDTO.userErrorParam("手机号已存在"); + } + + existEntity = employeeDao.getByActualName(employeeUpdateForm.getActualName(), null); + if (null != existEntity && !Objects.equals(existEntity.getEmployeeId(), employeeId)) { + return ResponseDTO.userErrorParam("姓名重复"); + } + + // 不更新密码 + EmployeeEntity entity = SmartBeanUtil.copy(employeeUpdateForm, EmployeeEntity.class); + entity.setLoginPwd(null); + + // 更新数据 + employeeManager.updateEmployee(entity, employeeUpdateForm.getRoleIdList()); + + return ResponseDTO.ok(); + } + + /** + * 更新禁用/启用状态 + * + * @param employeeId + * @return + */ + public ResponseDTO updateDisableFlag(Long employeeId) { + if (null == employeeId) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (null == employeeEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + boolean disableFlag=!employeeEntity.getDisabledFlag(); + employeeEntity.setDisabledFlag(disableFlag); + employeeDao.updateDisableFlag(employeeId, disableFlag); + + if (employeeEntity.getDisabledFlag()) { + tokenService.batchRemoveRedisToken(employeeId, UserTypeEnum.ADMIN_EMPLOYEE); + } + + return ResponseDTO.ok(); + } + + /** + * 批量删除员工 + * + * @param employeeIdList 员工ID列表 + * @return + */ + public ResponseDTO batchUpdateDeleteFlag(List employeeIdList) { + if (CollectionUtils.isEmpty(employeeIdList)) { + return ResponseDTO.ok(); + } + List employeeEntityList = employeeManager.listByIds(employeeIdList); + if (CollectionUtils.isEmpty(employeeEntityList)) { + return ResponseDTO.ok(); + } + // 更新删除 + List deleteList = employeeIdList.stream().map(e -> { + EmployeeEntity updateEmployee = new EmployeeEntity(); + updateEmployee.setEmployeeId(e); + updateEmployee.setDeletedFlag(true); + return updateEmployee; + }).collect(Collectors.toList()); + employeeManager.updateBatchById(deleteList); + + for (Long employeeId : employeeIdList) { + tokenService.batchRemoveRedisToken(employeeId, UserTypeEnum.ADMIN_EMPLOYEE); + } + return ResponseDTO.ok(); + } + + + /** + * 批量更新部门 + * + * @param batchUpdateDepartmentForm + * @return + */ + public ResponseDTO batchUpdateDepartment(EmployeeBatchUpdateDepartmentForm batchUpdateDepartmentForm) { + List employeeIdList = batchUpdateDepartmentForm.getEmployeeIdList(); + List employeeEntityList = employeeDao.selectBatchIds(employeeIdList); + if (employeeIdList.size() != employeeEntityList.size()) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + // 更新 + List updateList = employeeIdList.stream().map(e -> { + EmployeeEntity updateEmployee = new EmployeeEntity(); + updateEmployee.setEmployeeId(e); + updateEmployee.setDepartmentId(batchUpdateDepartmentForm.getDepartmentId()); + return updateEmployee; + }).collect(Collectors.toList()); + employeeManager.updateBatchById(updateList); + + return ResponseDTO.ok(); + } + + + /** + * 更新密码 + * + * @param updatePasswordForm + * @return + */ + public ResponseDTO updatePassword(EmployeeUpdatePasswordForm updatePasswordForm) { + Long employeeId = updatePasswordForm.getEmployeeId(); + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (employeeEntity == null) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + // 校验原始密码 + String encryptPwd = getEncryptPwd(updatePasswordForm.getOldPassword()); + if (!Objects.equals(encryptPwd, employeeEntity.getLoginPwd())) { + return ResponseDTO.userErrorParam("原密码有误,请重新输入"); + } + + // 新旧密码相同 + String newPassword = updatePasswordForm.getNewPassword(); + if (Objects.equals(updatePasswordForm.getOldPassword(), newPassword)) { + return ResponseDTO.ok(); + } + + // 更新密码 + EmployeeEntity updateEntity = new EmployeeEntity(); + updateEntity.setEmployeeId(employeeId); + updateEntity.setLoginPwd(getEncryptPwd(newPassword)); + employeeDao.updateById(updateEntity); + + //删除token信息 + tokenService.batchRemoveRedisToken(employeeId, UserTypeEnum.ADMIN_EMPLOYEE); + return ResponseDTO.ok(); + } + + /** + * 获取某个部门的员工信息 + * + * @param departmentId + * @return + */ + public ResponseDTO> getAllEmployeeByDepartmentId(Long departmentId, Boolean disabledFlag) { + List employeeEntityList = employeeDao.selectByDepartmentId(departmentId, disabledFlag); + if (disabledFlag != null) { + employeeEntityList = employeeEntityList.stream().filter(e -> e.getDisabledFlag().equals(disabledFlag)).collect(Collectors.toList()); + } + + if (CollectionUtils.isEmpty(employeeEntityList)) { + return ResponseDTO.ok(Collections.emptyList()); + } + + DepartmentVO department = departmentService.getDepartmentById(departmentId); + + List voList = employeeEntityList.stream().map(e -> { + EmployeeVO employeeVO = SmartBeanUtil.copy(e, EmployeeVO.class); + if (department != null) { + employeeVO.setDepartmentName(department.getName()); + } + return employeeVO; + }).collect(Collectors.toList()); + return ResponseDTO.ok(voList); + } + + + /** + * 重置密码 + * + * @param employeeId + * @return + */ + public ResponseDTO resetPassword(Long employeeId) { + + EmployeeEntity employeeEntity = employeeDao.selectById(employeeId); + if (null == employeeEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + String password = randomPassword(); + System.out.println("重置password = " + password); + employeeDao.updatePassword(employeeId, getEncryptPwd(password)); + + //删除token信息 + tokenService.batchRemoveRedisToken(employeeId, UserTypeEnum.ADMIN_EMPLOYEE); + return ResponseDTO.ok(password); + } + + private String randomPassword() { + return RandomStringUtils.randomAlphanumeric(28); + } + + /** + * 获取 加密后 的密码 + * + * @param password + * @return + */ + public static String getEncryptPwd(String password) { + return DigestUtils.md5Hex(String.format(PASSWORD_SALT_FORMAT, password)); + } + + + /** + * 查询全部员工 + * + * @return + */ + public ResponseDTO> queryAllEmployee(Boolean disabledFlag) { + List employeeList = employeeDao.selectEmployeeByDisabledAndDeleted(disabledFlag, Boolean.FALSE); + return ResponseDTO.ok(employeeList); + } + + /** + * 根据登录名获取员工 + * + * @param loginName + * @return + */ + public EmployeeEntity getByLoginName(String loginName) { + return employeeDao.getByLoginName(loginName, null); + } + + public static void main(String[] args) { + System.out.println(getEncryptPwd("123456")); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/controller/LoginController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/controller/LoginController.java new file mode 100644 index 0000000..34bc7b7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/controller/LoginController.java @@ -0,0 +1,90 @@ +package net.lab1024.sa.admin.module.system.login.controller; + +import cn.hutool.extra.servlet.ServletUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.login.domain.LoginEmployeeDetail; +import net.lab1024.sa.admin.module.system.login.domain.LoginForm; +import net.lab1024.sa.admin.module.system.login.service.LoginService; +import net.lab1024.sa.common.common.annoation.NoNeedLogin; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.constant.RequestHeaderConst; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.captcha.domain.CaptchaVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +/** + * 员工登录 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2021-12-15 21:05:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@RestController +//@Api(tags = {AdminSwaggerTagConst.System.SYSTEM_LOGIN}) +public class LoginController { + + @Autowired + private LoginService loginService; + + @NoNeedLogin + @PostMapping("/login") + @ApiOperation("登录 @author 卓大") + public ResponseDTO login(@Valid @RequestBody LoginForm loginForm) { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + String ip = ServletUtil.getClientIP(request); + String userAgent = ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT); + return loginService.login(loginForm, ip, userAgent); + } + + @GetMapping("/login/refresh") + @ApiOperation("刷新用户信息(包含用户基础信息、权限信息等等) @author 卓大") + public ResponseDTO refresh() { + loginService.removeLoginUserDetailCache(SmartRequestUtil.getRequestUserId()); + return ResponseDTO.ok(); + } + + @GetMapping("/login/getLoginInfo") + @ApiOperation("获取登录结果信息 @author 卓大") + public ResponseDTO getLoginInfo() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null) { + return ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID); + } + + Object principal = authentication.getPrincipal(); + if (!(principal instanceof LoginEmployeeDetail)) { + return ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID); + } + + LoginEmployeeDetail loginEmployeeDetail = (LoginEmployeeDetail) authentication.getPrincipal(); + loginEmployeeDetail.setLoginPassword(null); + return ResponseDTO.ok(loginEmployeeDetail); + } + + @ApiOperation("退出登陆 @author 卓大") + @GetMapping("/login/logout") + public ResponseDTO logout(@RequestHeader(value = RequestHeaderConst.TOKEN, required = false) String token) { + return loginService.logout(token, SmartRequestUtil.getRequestUser()); + } + + @ApiOperation("获取验证码 @author 卓大") + @GetMapping("/login/getCaptcha") + @NoNeedLogin + public ResponseDTO getCaptcha() { + return loginService.getCaptcha(); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginEmployeeDetail.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginEmployeeDetail.java new file mode 100644 index 0000000..3a2732e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginEmployeeDetail.java @@ -0,0 +1,169 @@ +package net.lab1024.sa.admin.module.system.login.domain; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.enumeration.GenderEnum; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.time.LocalDateTime; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * 员工登录 + * + * @Author 1024创新实验室: 善逸 + * @Date 2021/8/4 21:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class LoginEmployeeDetail implements UserDetails, RequestUser { + + @ApiModelProperty("token") + private String token; + + @ApiModelProperty("员工id") + private Long employeeId; + + @ApiModelPropertyEnum(UserTypeEnum.class) + private UserTypeEnum userType; + + @ApiModelProperty("登录账号") + private String loginName; + + @ApiModelProperty("员工名称") + private String actualName; + + @ApiModelPropertyEnum(GenderEnum.class) + private Integer gender; + + @ApiModelProperty("手机号码") + private String phone; + + @ApiModelProperty("部门id") + private Long departmentId; + + @ApiModelProperty("部门名称") + private String departmentName; + + @ApiModelProperty("是否为超管") + private Boolean administratorFlag; + + @ApiModelProperty("菜单列表") + private List menuList; + + @JsonIgnore + private String loginPassword; + + @ApiModelProperty("上次登录id") + private String lastLoginIp; + + @ApiModelProperty("上次登录user-agent") + private String lastLoginUserAgent; + + @ApiModelProperty("上次登录时间") + private LocalDateTime lastLoginTime; + + @ApiModelProperty("请求ip") + private String ip; + + @ApiModelProperty("请求user-agent") + private String userAgent; + + @ApiModelProperty("省份权限") + private List ProvList; + + /** + * security 权限串 + */ + private Set authorities; + + @Override + public Collection getAuthorities() { + return authorities; + } + + @Override + @JsonIgnore + public String getPassword() { + return this.loginPassword; + } + + @Override + public String getUsername() { + return this.getLoginName(); + } + + /** + * 账户是否未过期,过期无法验证 + */ + @Override + public boolean isAccountNonExpired() { + return true; + } + + /** + * 指定用户是否解锁,锁定的用户无法进行身份验证 + * + * @return + */ + @Override + public boolean isAccountNonLocked() { + return true; + } + + /** + * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 + * + * @return + */ + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + /** + * 是否可用 ,禁用的用户不能身份验证 + * + * @return + */ + @Override + public boolean isEnabled() { + return true; + } + + @Override + public Long getUserId() { + return employeeId; + } + + @Override + public String getUserName() { + return actualName; + } + + @Override + public UserTypeEnum getUserType() { + return userType; + } + + @Override + public String getIp() { + return this.ip; + } + + @Override + public String getUserAgent() { + return this.userAgent; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginForm.java new file mode 100644 index 0000000..e189f99 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/domain/LoginForm.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.system.login.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.util.SmartVerificationUtil; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.captcha.domain.CaptchaForm; +import net.lab1024.sa.common.module.support.token.LoginDeviceEnum; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + +/** + * 员工登录 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-19 11:49:45 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class LoginForm extends CaptchaForm { + + @ApiModelProperty("登录名") + @NotBlank(message = "登录名不能为空") + @Length(max = 30, message = "登录账号最多30字符") + private String loginName; + + @ApiModelProperty("密码") + @NotBlank(message = "密码不能为空") + //@Pattern(regexp = SmartVerificationUtil.PWD_REGEXP, message = "密码至少1个大写字母,1个小写字母和1个数字,6-32位") + private String password; + + @ApiModelProperty(value = "登录终端") + @ApiModelPropertyEnum(LoginDeviceEnum.class) + @CheckEnum(value = LoginDeviceEnum.class, required = true, message = "此终端不允许登录") + private Integer loginDevice; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/service/LoginService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/service/LoginService.java new file mode 100644 index 0000000..d704145 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/login/service/LoginService.java @@ -0,0 +1,338 @@ +package net.lab1024.sa.admin.module.system.login.service; + +import cn.hutool.extra.servlet.ServletUtil; +import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertEntity; +import net.lab1024.sa.admin.module.app.expert.service.ExpertService; +import net.lab1024.sa.admin.module.business.captcha.service.CaptchaService; +import net.lab1024.sa.admin.module.business.token.service.TokenService; +import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO; +import net.lab1024.sa.admin.module.system.department.service.DepartmentService; +import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity; +import net.lab1024.sa.admin.module.system.employee.service.EmployeePermissionService; +import net.lab1024.sa.admin.module.system.employee.service.EmployeeService; +import net.lab1024.sa.admin.module.system.login.domain.LoginEmployeeDetail; +import net.lab1024.sa.admin.module.system.login.domain.LoginForm; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.common.common.constant.RequestHeaderConst; +import net.lab1024.sa.common.common.constant.StringConst; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartEnumUtil; +import net.lab1024.sa.common.module.support.captcha.domain.CaptchaVO; +import net.lab1024.sa.common.module.support.config.ConfigKeyEnum; +import net.lab1024.sa.common.module.support.config.ConfigService; +import net.lab1024.sa.common.module.support.loginlog.LoginLogResultEnum; +import net.lab1024.sa.common.module.support.loginlog.LoginLogService; +import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogEntity; +import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogVO; +import net.lab1024.sa.common.module.support.token.JwtConst; +import net.lab1024.sa.common.module.support.token.LoginDeviceEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentMap; + +/** + * 员工 登录服务 + * + * @Author 1024创新实验室: 开云 + * @Date 2021-12-01 22:56:34 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Slf4j +@Service +public class LoginService { + + @Autowired + private EmployeeService employeeService; + + @Autowired + private DepartmentService departmentService; + + @Autowired + private TokenService tokenService; + + @Autowired + private CaptchaService captchaService; + + @Autowired + private EmployeePermissionService employeePermissionService; + + @Autowired + private ConfigService configService; + + @Autowired + private LoginLogService loginLogService; + + @Autowired + private ExpertService expertService; + + /** + * 登录信息二级缓存 + */ + private ConcurrentMap loginUserDetailCache = new ConcurrentLinkedHashMap.Builder().maximumWeightedCapacity(1000).build(); + + + private ConcurrentMap loginExpertEntityCache = new ConcurrentLinkedHashMap.Builder().maximumWeightedCapacity(1000).build(); + + /** + * 获取验证码 + * + * @return + */ + public ResponseDTO getCaptcha() { + return ResponseDTO.ok(captchaService.generateCaptcha()); + } + + /** + * 员工登陆 + * + * @param loginForm + * @return 返回用户登录信息 + */ + public ResponseDTO login(LoginForm loginForm, String ip, String userAgent) { + LoginDeviceEnum loginDeviceEnum = SmartEnumUtil.getEnumByValue(loginForm.getLoginDevice(), LoginDeviceEnum.class); + if (loginDeviceEnum == null) { + return ResponseDTO.userErrorParam("登录设备暂不支持!"); + } + // 校验 图形验证码 + ResponseDTO checkCaptcha = captchaService.checkCaptcha(loginForm); + if (!checkCaptcha.getOk()) { + + return ResponseDTO.error(checkCaptcha); + } + + /** + * 验证账号和账号状态 + */ + EmployeeEntity employeeEntity = employeeService.getByLoginName(loginForm.getLoginName()); + if (null == employeeEntity) { + return ResponseDTO.userErrorParam("登录名不存在!"); + } + + if (employeeEntity.getDisabledFlag()) { + saveLoginLog(employeeEntity, ip, userAgent, "账号已禁用", LoginLogResultEnum.LOGIN_FAIL); + return ResponseDTO.userErrorParam("您的账号已被禁用,请联系工作人员!"); + } + /** + * 验证密码: + * 1、万能密码 + * 2、真实密码 + */ + String superPassword = EmployeeService.getEncryptPwd(configService.getConfigValue(ConfigKeyEnum.SUPER_PASSWORD)); + String requestPassword = EmployeeService.getEncryptPwd(loginForm.getPassword()); + if (!(superPassword.equals(requestPassword) || employeeEntity.getLoginPwd().equals(requestPassword))) { + saveLoginLog(employeeEntity, ip, userAgent, "密码错误", LoginLogResultEnum.LOGIN_FAIL); + return ResponseDTO.userErrorParam("登录名或密码错误!"); + } + + // 生成 登录token,保存token + Boolean superPasswordFlag = superPassword.equals(requestPassword); + String token = tokenService.generateToken(employeeEntity.getEmployeeId(), employeeEntity.getActualName(), UserTypeEnum.ADMIN_EMPLOYEE, loginDeviceEnum, superPasswordFlag); + + //获取员工登录信息 + LoginEmployeeDetail loginEmployeeDetail = loadLoginInfo(employeeEntity); + loginEmployeeDetail.setToken(token); + + // 放入缓存 + loginUserDetailCache.put(employeeEntity.getEmployeeId(), loginEmployeeDetail); + + //保存登录记录 + saveLoginLog(employeeEntity, ip, userAgent, superPasswordFlag ? "万能密码登录" : loginDeviceEnum.getDesc(), LoginLogResultEnum.LOGIN_SUCCESS); + + return ResponseDTO.ok(loginEmployeeDetail); + } + + + /** + * 获取登录的用户信息 + * + * @return + */ + private LoginEmployeeDetail loadLoginInfo(EmployeeEntity employeeEntity) { + LoginEmployeeDetail loginEmployeeDetail = SmartBeanUtil.copy(employeeEntity, LoginEmployeeDetail.class); + loginEmployeeDetail.setUserType(UserTypeEnum.ADMIN_EMPLOYEE); + + //部门信息 + DepartmentVO department = departmentService.getDepartmentById(employeeEntity.getDepartmentId()); + loginEmployeeDetail.setDepartmentName(null == department ? StringConst.EMPTY : department.getName()); + + /** + * 获取前端菜单和后端权限 + * 1、从数据库获取所有的权限 + * 2、拼凑成菜单和后端权限 + */ + List menuAndPointsList = employeePermissionService.getEmployeeMenuAndPointsList(employeeEntity.getEmployeeId(), employeeEntity.getAdministratorFlag()); + //前端菜单 + loginEmployeeDetail.setMenuList(menuAndPointsList); + //后端权限 + loginEmployeeDetail.setAuthorities(employeePermissionService.buildAuthorities(menuAndPointsList)); + + //省份权限 + loginEmployeeDetail.setProvList(employeePermissionService.getRoleProvByRoleId(employeeEntity.getEmployeeId(), employeeEntity.getAdministratorFlag())); + + //上次登录信息 + LoginLogVO loginLogVO = loginLogService.queryLastByUserId(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE); + if (loginLogVO != null) { + loginEmployeeDetail.setLastLoginIp(loginLogVO.getLoginIp()); + loginEmployeeDetail.setLastLoginTime(loginLogVO.getCreateTime()); + loginEmployeeDetail.setLastLoginUserAgent(loginLogVO.getUserAgent()); + } + + return loginEmployeeDetail; + } + + /** + * 修改权限后需要重置登录用户的权限 + */ + public void refreashAuthorities(){ + loginUserDetailCache.forEach((id, loginEmployeeDetail) -> { + + List menuAndPointsList = employeePermissionService.getEmployeeMenuAndPointsList(id, loginEmployeeDetail.getAdministratorFlag()); + //前端菜单 + loginEmployeeDetail.setMenuList(menuAndPointsList); + //后端权限 + loginEmployeeDetail.setAuthorities(employeePermissionService.buildAuthorities(menuAndPointsList)); + //省份权限 + loginEmployeeDetail.setProvList(employeePermissionService.getRoleProvByRoleId(id, loginEmployeeDetail.getAdministratorFlag())); + }); + } + + /** + * 保存登录日志 + * + * @param employeeEntity + * @param ip + * @param userAgent + */ + private void saveLoginLog(EmployeeEntity employeeEntity, String ip, String userAgent, String remark, LoginLogResultEnum result) { + LoginLogEntity loginEntity = LoginLogEntity.builder() + .userId(employeeEntity.getEmployeeId()) + .userType(UserTypeEnum.ADMIN_EMPLOYEE.getValue()) + .userName(employeeEntity.getActualName()) + .userAgent(userAgent) + .loginIp(ip) + .remark(remark) + .loginResult(result.getValue()) + .createTime(LocalDateTime.now()) + .build(); + loginLogService.log(loginEntity); + } + + + /** + * 移除用户信息缓存 + * + * @param requestUserId + */ + public void removeLoginUserDetailCache(Long requestUserId) { + loginUserDetailCache.remove(requestUserId); + } + + /** + * 根据登陆token 获取员请求工信息 + * + * @param + * @return + */ + public UserDetails getLoginUserDetail(String token, HttpServletRequest request) { + Map parseJwtData = tokenService.getUserIdAndValidateToken(token); + if(parseJwtData == null){ + return null; + } + Long requestUserId = Long.valueOf(parseJwtData.get(JwtConst.CLAIM_ID_KEY).toString()); + if (requestUserId == null) { + return null; + } + Integer requestUserType = (Integer) parseJwtData.get(JwtConst.CLAIM_USER_TYPE_KEY); + if(requestUserType.equals(UserTypeEnum.ADMIN_EMPLOYEE.getValue())){ + // 查询用户信息 + LoginEmployeeDetail loginEmployeeDetail = loginUserDetailCache.get(requestUserId); + if (loginEmployeeDetail == null) { + // 员工基本信息 + EmployeeEntity employeeEntity = employeeService.getById(requestUserId); + if (employeeEntity == null) { + return null; + } + + loginEmployeeDetail = this.loadLoginInfo(employeeEntity); + loginEmployeeDetail.setToken(token); + loginUserDetailCache.put(requestUserId, loginEmployeeDetail); + } + + //更新请求ip和user agent + loginEmployeeDetail.setUserAgent(ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT)); + loginEmployeeDetail.setIp(ServletUtil.getClientIP(request)); + + return loginEmployeeDetail; + }else if(requestUserType.equals(UserTypeEnum.EXPERT.getValue())){ + + ExpertEntity expertEntity = loginExpertEntityCache.get(requestUserId); + if(expertEntity == null){ + ExpertEntity expertInfo = expertService.getById(requestUserId); + if(expertInfo == null){ + return null; + } + expertInfo.setToken(token); + loginExpertEntityCache.put(requestUserId, expertInfo); + expertEntity = expertInfo; + } + expertEntity.setIp(ServletUtil.getClientIP(request)); + return expertEntity; + }else{ + return null; + } + } + + + /** + * 退出登陆,清除token缓存 + * + * @return + */ + public ResponseDTO logout(String token, RequestUser requestUser) { + loginUserDetailCache.remove(requestUser.getUserId()); + tokenService.removeToken(token); + //保存登出日志 + saveLogoutLog(requestUser, requestUser.getIp(), requestUser.getUserAgent()); + return ResponseDTO.ok(); + } + + /** + * app退出登陆,清除token缓存 + * + * @return + */ + public ResponseDTO appLogout(String token, RequestUser requestUser) { + loginExpertEntityCache.remove(requestUser.getUserId()); + tokenService.removeToken(token); + return ResponseDTO.app_ok(); + } + + /** + * 保存登出日志 + */ + private void saveLogoutLog(RequestUser requestUser, String ip, String userAgent) { + LoginLogEntity loginEntity = LoginLogEntity.builder() + .userId(requestUser.getUserId()) + .userType(requestUser.getUserType().getValue()) + .userName(requestUser.getUserName()) + .userAgent(userAgent) + .loginIp(ip) + .loginResult(LoginLogResultEnum.LOGIN_OUT.getValue()) + .createTime(LocalDateTime.now()) + .build(); + loginLogService.log(loginEntity); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuPermsTypeEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuPermsTypeEnum.java new file mode 100644 index 0000000..c277026 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuPermsTypeEnum.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.admin.module.system.menu.constant; + + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 权限类型 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public enum MenuPermsTypeEnum implements BaseEnum { + /** + * SpringSecurity模式 + */ + SPRING_SECURITY(1, "SpringSecurity模式"), + /** + * URL模式 + */ + URL(2, "URL模式"), + + ; + + private Integer value; + + private String desc; + + + MenuPermsTypeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.java new file mode 100644 index 0000000..06c2154 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/constant/MenuTypeEnum.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.admin.module.system.menu.constant; + + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 菜单类型枚举 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public enum MenuTypeEnum implements BaseEnum { + /** + * 目录 + */ + CATALOG(1, "目录"), + /** + * 菜单 + */ + MENU(2, "菜单"), + /** + * 功能点 + */ + POINTS(3, "功能点"); + + private Integer value; + + private String desc; + + + MenuTypeEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/controller/MenuController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/controller/MenuController.java new file mode 100644 index 0000000..201698b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/controller/MenuController.java @@ -0,0 +1,86 @@ +package net.lab1024.sa.admin.module.system.menu.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.common.AdminBaseController; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuAddForm; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuUpdateForm; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuTreeVO; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.admin.module.system.menu.service.MenuService; +import net.lab1024.sa.common.common.domain.RequestUrlVO; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@OperateLog +@RestController +//@Api(tags = {AdminSwaggerTagConst.System.SYSTEM_MENU}) +public class MenuController extends AdminBaseController { + + @Autowired + private MenuService menuService; + + @ApiOperation(value = "添加菜单 @author 卓大") + @PostMapping("/menu/add") + @PreAuthorize("@saAuth.checkPermission('system:menu:add')") + public ResponseDTO addMenu(@RequestBody @Valid MenuAddForm menuAddForm) { + menuAddForm.setCreateUserId(SmartRequestUtil.getRequestUserId()); + return menuService.addMenu(menuAddForm); + } + + @ApiOperation(value = "更新菜单 @author 卓大") + @PostMapping("/menu/update") + @PreAuthorize("@saAuth.checkPermission('system:menu:update')") + public ResponseDTO updateMenu(@RequestBody @Valid MenuUpdateForm menuUpdateForm) { + menuUpdateForm.setUpdateUserId(SmartRequestUtil.getRequestUserId()); + return menuService.updateMenu(menuUpdateForm); + } + + @ApiOperation(value = "批量删除菜单 @author 卓大") + @GetMapping("/menu/batchDelete") + @PreAuthorize("@saAuth.checkPermission('system:menu:delete,system:menu:batch:delete')") + public ResponseDTO batchDeleteMenu(@RequestParam("menuIdList") List menuIdList) { + return menuService.batchDeleteMenu(menuIdList, SmartRequestUtil.getRequestUserId()); + } + + @ApiOperation(value = "查询菜单列表 @author 卓大") + @GetMapping("/menu/query") + public ResponseDTO> queryMenuList() { + return ResponseDTO.ok(menuService.queryMenuList(null)); + } + + @ApiOperation(value = "查询菜单详情 @author 卓大") + @GetMapping("/menu/detail/{menuId}") + public ResponseDTO getMenuDetail(@PathVariable Long menuId) { + return menuService.getMenuDetail(menuId); + } + + @ApiOperation(value = "查询菜单树 @author 卓大") + @GetMapping("/menu/tree") + public ResponseDTO> queryMenuTree(@RequestParam("onlyMenu") Boolean onlyMenu) { + return menuService.queryMenuTree(onlyMenu); + } + + @ApiOperation(value = "获取所有请求路径 @author 卓大") + @GetMapping("/menu/auth/url") + public ResponseDTO> getAuthUrl() { + return menuService.getAuthUrl(); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/dao/MenuDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/dao/MenuDao.java new file mode 100644 index 0000000..468046b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/dao/MenuDao.java @@ -0,0 +1,105 @@ +package net.lab1024.sa.admin.module.system.menu.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; +import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; + +import java.util.List; + +/** + * 菜单 dao + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface MenuDao extends BaseMapper { + + /** + * 根据名称查询同一级下的菜单 + * + * @param menuName 菜单名 + * @param parentId 父级id + * @param deletedFlag 是否删除 + * @return + */ + MenuEntity getByMenuName(@Param("menuName") String menuName, @Param("parentId") Long parentId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 根据前端权限字符串查询菜单 + * + * @param webPerms 前端权限字符串 + * @param deletedFlag 是否删除 + * @return + */ + MenuEntity getByWebPerms(@Param("webPerms") String webPerms, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 根据菜单ID删除菜单(逻辑删除) + * + * @param menuIdList 菜单id集合 + * @param updateUserId 操作人id + * @param deletedFlag 是否删除 + */ + void deleteByMenuIdList(@Param("menuIdList") List menuIdList, @Param("updateUserId") Long updateUserId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 查询菜单列表 + * + * @param deletedFlag 是否删除 + * @param disabledFlag 是否禁用 + * @param menuTypeList 菜单类型集合 + * @return + */ + List queryMenuList(@Param("deletedFlag") Boolean deletedFlag, @Param("disabledFlag") Boolean disabledFlag, @Param("menuTypeList") List menuTypeList); + + + /** + * 根据菜单ID 查询功能点列表 + * + * @param menuId 菜单id + * @param menuType 菜单类型 + * @param deletedFlag 删除标记 + * @return + */ + List getPointListByMenuId(@Param("menuId") Long menuId, @Param("menuType") Integer menuType, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 根据员工ID查询菜单列表 + * + * @param deletedFlag 是否删除 + * @param disabledFlag 禁用标识 + * @param employeeId 员工id + * @return + */ + List queryMenuByEmployeeId(@Param("deletedFlag") Boolean deletedFlag, + @Param("disabledFlag") Boolean disabledFlag, + @Param("employeeId") Long employeeId); + + /** + * 根据菜单类型查询 + * + * @param menuType 菜单类型 + * @param deletedFlag 删除 + * @param disabledFlag 禁用 + * @return + */ + List queryMenuByType(@Param("menuType") Integer menuType, + @Param("deletedFlag") Boolean deletedFlag, + @Param("disabledFlag") Boolean disabledFlag); + + /** + * 查询孩子id + * + * @param menuIdList + * @return + */ + List selectMenuIdByParentIdList(@Param("menuIdList") List menuIdList); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/entity/MenuEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/entity/MenuEntity.java new file mode 100644 index 0000000..41fd306 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/entity/MenuEntity.java @@ -0,0 +1,139 @@ +package net.lab1024.sa.admin.module.system.menu.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.admin.module.system.menu.constant.MenuPermsTypeEnum; +import net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; + +import java.time.LocalDateTime; + +/** + * 菜单 表 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName(value = "t_menu") +public class MenuEntity { + + /** + * 菜单ID + */ + @TableId(type = IdType.AUTO) + private Long menuId; + + /** + * 菜单名称 + */ + private String menuName; + + /** + * 类型 + * + * @see MenuTypeEnum + */ + private Integer menuType; + + /** + * 父菜单ID + */ + private Long parentId; + + /** + * 显示顺序 + */ + private Integer sort; + + /** + * 路由地址 + */ + private String path; + + /** + * 组件路径 + */ + private String component; + + /** + * 是否为外链 + */ + private Boolean frameFlag; + + /** + * 外链地址 + */ + private String frameUrl; + + /** + * 是否缓存 + */ + private Boolean cacheFlag; + + /** + * 显示状态 + */ + private Boolean visibleFlag; + + /** + * 禁用状态 + */ + private Boolean disabledFlag; + + /** + * 后端权限字符串 + */ + private String apiPerms; + + /** + * 权限类型 + */ + private Integer permsType; + + /** + * 前端权限字符串 + */ + private String webPerms; + + /** + * 菜单图标 + */ + private String icon; + + /** + * 功能点关联菜单ID + */ + private Long contextMenuId; + + /** + * 删除状态 + */ + private Boolean deletedFlag; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 创建人 + */ + private Long createUserId; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 更新人 + */ + private Long updateUserId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuAddForm.java new file mode 100644 index 0000000..afc8e25 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuAddForm.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.system.menu.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 菜单 添加表单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class MenuAddForm extends MenuBaseForm { + + @ApiModelProperty(hidden = true) + private Long createUserId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuBaseForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuBaseForm.java new file mode 100644 index 0000000..f404535 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuBaseForm.java @@ -0,0 +1,86 @@ +package net.lab1024.sa.admin.module.system.menu.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.system.menu.constant.MenuPermsTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import org.hibernate.validator.constraints.Length; +import net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 菜单基础 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class MenuBaseForm { + + @ApiModelProperty("菜单名称") + @NotBlank(message = "菜单名称不能为空") + @Length(max = 30, message = "菜单名称最多30个字符") + private String menuName; + + @ApiModelPropertyEnum(value = MenuTypeEnum.class, desc = "类型") + @CheckEnum(value = MenuTypeEnum.class, message = "类型错误") + private Integer menuType; + + @ApiModelProperty("父菜单ID 无上级可传0") + @NotNull(message = "父菜单ID不能为空") + private Long parentId; + + @ApiModelProperty("显示顺序") + private Integer sort; + + @ApiModelProperty("路由地址") + private String path; + + @ApiModelProperty("组件路径") + private String component; + + @ApiModelProperty("是否为外链") + @NotNull(message = "是否为外链不能为空") + private Boolean frameFlag; + + @ApiModelProperty("外链地址") + private String frameUrl; + + @ApiModelProperty("是否缓存") + @NotNull(message = "是否缓存不能为空") + private Boolean cacheFlag; + + @ApiModelProperty("显示状态") + @NotNull(message = "显示状态不能为空") + private Boolean visibleFlag; + + @ApiModelProperty("禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; + + @ApiModelPropertyEnum(value = MenuPermsTypeEnum.class, desc = "权限类型 ") + @CheckEnum(value = MenuPermsTypeEnum.class, message = "权限类型") + private Integer permsType; + + @ApiModelProperty("前端权限字符串") + private String webPerms; + + @ApiModelProperty("后端端权限字符串") + private String apiPerms; + + @ApiModelProperty("后端接口权限集合(拆分)") + private List apiPermsList; + + @ApiModelProperty("菜单图标") + private String icon; + + @ApiModelProperty("功能点关联菜单ID") + private Long contextMenuId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuPointsOperateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuPointsOperateForm.java new file mode 100644 index 0000000..edf28ae --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuPointsOperateForm.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.system.menu.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 菜单功能点操作Form + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class MenuPointsOperateForm { + + @ApiModelProperty("菜单ID") + private Long menuId; + + @ApiModelProperty("功能点名称") + @NotBlank(message = "功能点不能为空") + @Length(max = 30, message = "功能点最多30个字符") + private String menuName; + + @ApiModelProperty("禁用状态") + @NotNull(message = "禁用状态不能为空") + private Boolean disabledFlag; + + @ApiModelProperty("后端接口权限集合") + private List apiPermsList; + + @ApiModelProperty("权限字符串") + private String webPerms; + + @ApiModelProperty("功能点关联菜单ID") + private Long contextMenuId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuUpdateForm.java new file mode 100644 index 0000000..c0a39f1 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/form/MenuUpdateForm.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.system.menu.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 菜单 更新Form + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class MenuUpdateForm extends MenuBaseForm { + + @ApiModelProperty("菜单ID") + @NotNull(message = "菜单ID不能为空") + private Long menuId; + + @ApiModelProperty(hidden = true) + private Long updateUserId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuSimpleTreeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuSimpleTreeVO.java new file mode 100644 index 0000000..560aca3 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuSimpleTreeVO.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.admin.module.system.menu.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 简易的菜单VO + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class MenuSimpleTreeVO { + + @ApiModelProperty("菜单ID") + private Long menuId; + + @ApiModelProperty("菜单名称") + private String menuName; + + @ApiModelProperty("功能点关联菜单ID") + private Long contextMenuId; + + @ApiModelProperty("父级菜单ID") + private Long parentId; + + @ApiModelProperty("菜单类型") + private Integer menuType; + + @ApiModelProperty("子菜单") + private List children; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuTreeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuTreeVO.java new file mode 100644 index 0000000..0930c96 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuTreeVO.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.admin.module.system.menu.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class MenuTreeVO extends MenuVO{ + + @ApiModelProperty("菜单子集") + private List children; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuVO.java new file mode 100644 index 0000000..d8e68ad --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/domain/vo/MenuVO.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.system.menu.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuBaseForm; + +import java.time.LocalDateTime; + +/** + * 菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 22:04:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class MenuVO extends MenuBaseForm { + + @ApiModelProperty("菜单ID") + private Long menuId; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("创建人") + private Long createUserId; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; + + @ApiModelProperty("更新人") + private Long updateUserId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/manager/MenuManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/manager/MenuManager.java new file mode 100644 index 0000000..d57c81d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/manager/MenuManager.java @@ -0,0 +1,70 @@ +package net.lab1024.sa.admin.module.system.menu.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum; +import net.lab1024.sa.admin.module.system.menu.dao.MenuDao; +import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 菜单Manager层 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-06 23:45:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class MenuManager extends ServiceImpl { + + /** + * 添加菜单 + * + * @param menuEntity + * @param pointEntityList + */ + @Transactional(rollbackFor = Exception.class) + public void addMenu(MenuEntity menuEntity, List pointEntityList) { + //添加菜单 + save(menuEntity); + //构建功能点 + pointEntityList.forEach(e -> { + e.setParentId(menuEntity.getMenuId()); + e.setMenuType(MenuTypeEnum.POINTS.getValue()); + e.setCreateUserId(menuEntity.getCreateUserId()); + }); + //批量添加功能点 + saveBatch(pointEntityList); + } + + /** + * 更新菜单 + * + * @param menuEntity + * @param savePointList + * @param deletePointList + * @param updatePointList + */ + @Transactional(rollbackFor = Exception.class) + public void updateMenu(MenuEntity menuEntity, List savePointList, List deletePointList, List updatePointList) { + //更新菜单 + updateById(menuEntity); + //构建新增功能点 + savePointList.forEach(e -> { + e.setParentId(menuEntity.getMenuId()); + e.setMenuType(MenuTypeEnum.POINTS.getValue()); + //因为更新操作人在menuEntity的UpdateUserId字段 + e.setCreateUserId(menuEntity.getUpdateUserId()); + }); + //批量添加功能点 + saveBatch(savePointList); + //批量删除功能点 + updateBatchById(deletePointList); + //批量更新功能点 + updateBatchById(updatePointList); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuService.java new file mode 100644 index 0000000..4b3fa69 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/menu/service/MenuService.java @@ -0,0 +1,290 @@ +package net.lab1024.sa.admin.module.system.menu.service; + +import cn.hutool.core.collection.CollectionUtil; +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum; +import net.lab1024.sa.admin.module.system.menu.dao.MenuDao; +import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuAddForm; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuBaseForm; +import net.lab1024.sa.admin.module.system.menu.domain.form.MenuUpdateForm; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuTreeVO; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.common.common.code.SystemErrorCode; +import net.lab1024.sa.common.common.domain.RequestUrlVO; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-08 22:15:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class MenuService { + + @Autowired + private MenuDao menuDao; + + @Autowired + private List authUrl; + + /** + * 添加菜单 + * + * @param menuAddForm + * @return + */ + public synchronized ResponseDTO addMenu(MenuAddForm menuAddForm) { + // 校验菜单名称 + if (this.validateMenuName(menuAddForm)) { + return ResponseDTO.userErrorParam("菜单名称已存在"); + } + // 校验前端权限字符串 + if (this.validateWebPerms(menuAddForm)) { + return ResponseDTO.userErrorParam("权限字符串已存在"); + } + MenuEntity menuEntity = SmartBeanUtil.copy(menuAddForm, MenuEntity.class); + // 处理接口权限 + List permsList = menuAddForm.getApiPermsList(); + if (!CollectionUtils.isEmpty(permsList)) { + String perms = StringUtils.join(permsList, ","); + menuEntity.setApiPerms(perms); + } + menuDao.insert(menuEntity); + return ResponseDTO.ok(); + } + + /** + * 更新菜单 + * + * @param menuUpdateForm + * @return + */ + public synchronized ResponseDTO updateMenu(MenuUpdateForm menuUpdateForm) { + //校验菜单是否存在 + MenuEntity selectMenu = menuDao.selectById(menuUpdateForm.getMenuId()); + if (selectMenu == null) { + return ResponseDTO.userErrorParam("菜单不存在"); + } + if (selectMenu.getDeletedFlag()) { + return ResponseDTO.userErrorParam("菜单已被删除"); + } + //校验菜单名称 + if (this.validateMenuName(menuUpdateForm)) { + return ResponseDTO.userErrorParam("菜单名称已存在"); + } + // 校验前端权限字符串 + if (this.validateWebPerms(menuUpdateForm)) { + return ResponseDTO.userErrorParam("权限字符串已存在"); + } + if (menuUpdateForm.getMenuId().equals(menuUpdateForm.getParentId())) { + return ResponseDTO.userErrorParam("上级菜单不能为自己"); + } + MenuEntity menuEntity = SmartBeanUtil.copy(menuUpdateForm, MenuEntity.class); + // 处理接口权限 + List permsList = menuUpdateForm.getApiPermsList(); + if (!CollectionUtils.isEmpty(permsList)) { + String perms = StringUtils.join(permsList, ","); + menuEntity.setApiPerms(perms); + } + menuDao.updateById(menuEntity); + return ResponseDTO.ok(); + } + + + /** + * 批量删除菜单 + * + * @param menuIdList + * @param employeeId + * @return + */ + public synchronized ResponseDTO batchDeleteMenu(List menuIdList, Long employeeId) { + if (CollectionUtils.isEmpty(menuIdList)) { + return ResponseDTO.userErrorParam("所选菜单不能为空"); + } + menuDao.deleteByMenuIdList(menuIdList, employeeId, Boolean.TRUE); + //孩子节点也需要删除 + this.recursiveDeleteChildren(menuIdList, employeeId); + return ResponseDTO.ok(); + } + + private void recursiveDeleteChildren(List menuIdList, Long employeeId) { + List childrenMenuIdList = menuDao.selectMenuIdByParentIdList(menuIdList); + if (CollectionUtil.isEmpty(childrenMenuIdList)) { + return; + } + menuDao.deleteByMenuIdList(childrenMenuIdList, employeeId, Boolean.TRUE); + recursiveDeleteChildren(childrenMenuIdList, employeeId); + } + + /** + * 校验菜单名称 + * + * @param menuDTO + * @param + * @return true 重复 false 未重复 + */ + public Boolean validateMenuName(T menuDTO) { + MenuEntity menu = menuDao.getByMenuName(menuDTO.getMenuName(), menuDTO.getParentId(), Boolean.FALSE); + if (menuDTO instanceof MenuAddForm) { + return menu != null; + } + if (menuDTO instanceof MenuUpdateForm) { + Long menuId = ((MenuUpdateForm) menuDTO).getMenuId(); + return menu != null && menu.getMenuId().longValue() != menuId.longValue(); + } + return true; + } + + /** + * 校验前端权限字符串 + * + * @param menuDTO + * @param + * @return true 重复 false 未重复 + */ + public Boolean validateWebPerms(T menuDTO) { + MenuEntity menu = menuDao.getByWebPerms(menuDTO.getWebPerms(), Boolean.FALSE); + if (menuDTO instanceof MenuAddForm) { + return menu != null; + } + if (menuDTO instanceof MenuUpdateForm) { + Long menuId = ((MenuUpdateForm) menuDTO).getMenuId(); + return menu != null && menu.getMenuId().longValue() != menuId.longValue(); + } + return true; + } + + /** + * 查询菜单列表 + * + * @return + */ + public List queryMenuList(Boolean disabledFlag) { + List menuVOList = menuDao.queryMenuList(Boolean.FALSE, disabledFlag, null); + //根据ParentId进行分组 + Map> parentMap = menuVOList.stream().collect(Collectors.groupingBy(MenuVO::getParentId, Collectors.toList())); + List filterMenuVOList = this.filterNoParentMenu(parentMap, NumberUtils.LONG_ZERO); + return filterMenuVOList; + } + + /** + * 过滤没有上级菜单的菜单列表 + * + * @param parentMap + * @param parentId + * @return + */ + private List filterNoParentMenu(Map> parentMap, Long parentId) { + // 获取本级菜单树List + List res = parentMap.getOrDefault(parentId, Lists.newArrayList()); + List childMenu = Lists.newArrayList(); + // 循环遍历下级菜单 + res.forEach(e -> { + //处理接口权限 + String perms = e.getApiPerms(); + if (StringUtils.isBlank(perms)) { + e.setApiPermsList(Lists.newArrayList()); + } else { + List permsList = Lists.newArrayList(StringUtils.split(perms, ",")); + e.setApiPermsList(permsList); + } + List menuList = this.filterNoParentMenu(parentMap, e.getMenuId()); + childMenu.addAll(menuList); + }); + res.addAll(childMenu); + return res; + } + + /** + * 查询菜单树 + * + * @param onlyMenu 不查询功能点 + * @return + */ + public ResponseDTO> queryMenuTree(Boolean onlyMenu) { + List menuTypeList = Lists.newArrayList(); + if (onlyMenu) { + menuTypeList = Lists.newArrayList(MenuTypeEnum.CATALOG.getValue(), MenuTypeEnum.MENU.getValue()); + } + List menuVOList = menuDao.queryMenuList(Boolean.FALSE, null, menuTypeList); + //根据ParentId进行分组 + Map> parentMap = menuVOList.stream().collect(Collectors.groupingBy(MenuVO::getParentId, Collectors.toList())); + List menuTreeVOList = this.buildMenuTree(parentMap, NumberUtils.LONG_ZERO); + return ResponseDTO.ok(menuTreeVOList); + } + + /** + * 构建菜单树 + * + * @return + */ + List buildMenuTree(Map> parentMap, Long parentId) { + // 获取本级菜单树List + List res = parentMap.getOrDefault(parentId, Lists.newArrayList()).stream() + .map(e -> SmartBeanUtil.copy(e, MenuTreeVO.class)).collect(Collectors.toList()); + // 循环遍历下级菜单 + res.forEach(e -> { + //处理接口权限 + String perms = e.getApiPerms(); + if (StringUtils.isBlank(perms)) { + e.setApiPermsList(Lists.newArrayList()); + } else { + List permsList = Lists.newArrayList(StringUtils.split(perms, ",")); + e.setApiPermsList(permsList); + } + e.setChildren(this.buildMenuTree(parentMap, e.getMenuId())); + }); + return res; + } + + /** + * 查询菜单详情 + * + * @param menuId + * @return + */ + public ResponseDTO getMenuDetail(Long menuId) { + //校验菜单是否存在 + MenuEntity selectMenu = menuDao.selectById(menuId); + if (selectMenu == null) { + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, "菜单不存在"); + } + if (selectMenu.getDeletedFlag()) { + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, "菜单已被删除"); + } + MenuVO menuVO = SmartBeanUtil.copy(selectMenu, MenuVO.class); + //处理接口权限 + String perms = menuVO.getApiPerms(); + if (!StringUtils.isBlank(perms)) { + List permsList = Lists.newArrayList(StringUtils.split(perms, ",")); + menuVO.setApiPermsList(permsList); + } + return ResponseDTO.ok(menuVO); + } + + /** + * 获取系统所有请求路径 + * + * @return + */ + public ResponseDTO> getAuthUrl() { + return ResponseDTO.ok(authUrl); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleController.java new file mode 100644 index 0000000..b698551 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleController.java @@ -0,0 +1,70 @@ +package net.lab1024.sa.admin.module.system.role.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.common.AdminBaseController; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleAddForm; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO; +import net.lab1024.sa.admin.module.system.role.service.RoleService; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 角色 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-12-14 19:40:28 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@OperateLog +@RestController +//@Api(tags = {AdminSwaggerTagConst.System.SYSTEM_ROLE}) +public class RoleController extends AdminBaseController { + + @Autowired + private RoleService roleService; + + @ApiOperation("添加角色 @author 卓大") + @PostMapping("/role/add") + @PreAuthorize("@saAuth.checkPermission('system:role:add,project:role:add')") + public ResponseDTO addRole(@Valid @RequestBody RoleAddForm roleAddForm) { + return roleService.addRole(roleAddForm); + } + + @ApiOperation("删除角色 @author 卓大") + @GetMapping("/role/delete/{roleId}") + @PreAuthorize("@saAuth.checkPermission('system:role:delete,project:role:delete')") + public ResponseDTO deleteRole(@PathVariable Long roleId) { + return roleService.deleteRole(roleId); + } + + @ApiOperation("更新角色 @author 卓大") + @PostMapping("/role/update") + @PreAuthorize("@saAuth.checkPermission('system:role:update,project:role:update')") + public ResponseDTO updateRole(@Valid @RequestBody RoleUpdateForm roleUpdateDTO) { + return roleService.updateRole(roleUpdateDTO); + } + + @ApiOperation("获取角色数据 @author 卓大") + @GetMapping("/role/get/{roleId}") + public ResponseDTO getRole(@PathVariable("roleId") Long roleId) { + return roleService.getRoleById(roleId); + } + + @ApiOperation("获取所有角色 @author 卓大") + @GetMapping("/role/getAll") + public ResponseDTO> getAllRole() { + return roleService.getAllRole(); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.java new file mode 100644 index 0000000..f607924 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleDataScopeController.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.admin.module.system.role.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.common.AdminBaseController; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleDataScopeUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleDataScopeVO; +import net.lab1024.sa.admin.module.system.role.service.RoleDataScopeService; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 角色的数据权限配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-02-26 22:09:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@OperateLog +@RestController +//@Api(tags = {AdminSwaggerTagConst.System.SYSTEM_ROLE_DATA_SCOPE}) +public class RoleDataScopeController extends AdminBaseController { + + @Autowired + private RoleDataScopeService roleDataScopeService; + + @ApiOperation(value = "获取某角色所设置的数据范围 @author 卓大") + @GetMapping("/role/dataScope/getRoleDataScopeList/{roleId}") + public ResponseDTO> dataScopeListByRole(@PathVariable Long roleId) { + return roleDataScopeService.getRoleDataScopeList(roleId); + } + + @ApiOperation(value = "批量设置某角色数据范围 @author 卓大") + @PostMapping("/role/dataScope/updateRoleDataScopeList") + @PreAuthorize("@saAuth.checkPermission('system:role:dataScope:update')") + public ResponseDTO updateRoleDataScopeList(@RequestBody @Valid RoleDataScopeUpdateForm roleDataScopeUpdateForm) { + return roleDataScopeService.updateRoleDataScopeList(roleDataScopeUpdateForm); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.java new file mode 100644 index 0000000..6428968 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleEmployeeController.java @@ -0,0 +1,77 @@ +package net.lab1024.sa.admin.module.system.role.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.common.AdminBaseController; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeQueryForm; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleSelectedVO; +import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 角色的员工 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-02-26 22:09:59 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@OperateLog +@RestController +//@Api(tags = {AdminSwaggerTagConst.System.SYSTEM_ROLE_EMPLOYEE}) +public class RoleEmployeeController extends AdminBaseController { + + @Autowired + private RoleEmployeeService roleEmployeeService; + + @ApiOperation(value = "查询某个角色下的员工列表 @author 卓大") + @PostMapping("/role/employee/queryEmployee") + public ResponseDTO> queryEmployee(@Valid @RequestBody RoleEmployeeQueryForm roleEmployeeQueryForm) { + return roleEmployeeService.queryEmployee(roleEmployeeQueryForm); + } + + @ApiOperation(value = "获取某个角色下的所有员工列表(无分页) @author 卓大") + @GetMapping("/role/employee/getAllEmployeeByRoleId/{roleId}") + public ResponseDTO> listAllEmployeeRoleId(@PathVariable Long roleId) { + return ResponseDTO.ok(roleEmployeeService.getAllEmployeeByRoleId(roleId)); + } + + @ApiOperation(value = "从角色成员列表中移除员工 @author 卓大") + @GetMapping("/role/employee/removeEmployee") + @PreAuthorize("@saAuth.checkPermission('system:role:employee:delete')") + public ResponseDTO removeEmployee(Long employeeId, Long roleId) { + return roleEmployeeService.removeRoleEmployee(employeeId, roleId); + } + + @ApiOperation(value = "从角色成员列表中批量移除员工 @author 卓大") + @PostMapping("/role/employee/batchRemoveRoleEmployee") + @PreAuthorize("@saAuth.checkPermission('system:role:employee:batch:delete')") + public ResponseDTO batchRemoveEmployee(@Valid @RequestBody RoleEmployeeUpdateForm updateForm) { + return roleEmployeeService.batchRemoveRoleEmployee(updateForm); + } + + @ApiOperation(value = "角色成员列表中批量添加员工 @author 卓大") + @PostMapping("/role/employee/batchAddRoleEmployee") + @PreAuthorize("@saAuth.checkPermission('system:role:employee:add')") + public ResponseDTO addEmployeeList(@Valid @RequestBody RoleEmployeeUpdateForm addForm) { + return roleEmployeeService.batchAddRoleEmployee(addForm); + } + + @ApiOperation(value = "获取员工所有选中的角色和所有角色 @author 卓大") + @GetMapping("/role/employee/getRoles/{employeeId}") + public ResponseDTO> getRoleByEmployeeId(@PathVariable Long employeeId) { + return ResponseDTO.ok(roleEmployeeService.getRoleInfoListByEmployeeId(employeeId)); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.java new file mode 100644 index 0000000..4485df7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleMenuController.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.admin.module.system.role.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.common.AdminBaseController; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleMenuUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleMenuTreeVO; +import net.lab1024.sa.admin.module.system.role.service.RoleMenuService; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * 角色的菜单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-02-26 21:34:01 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@OperateLog +@RestController +//@Api(tags = {AdminSwaggerTagConst.System.SYSTEM_ROLE_MENU}) +public class RoleMenuController extends AdminBaseController { + + @Autowired + private RoleMenuService roleMenuService; + + @ApiOperation("更新角色权限 @author 卓大") + @PostMapping("/role/menu/updateRoleMenu") + @PreAuthorize("@saAuth.checkPermission('system:role:menu:update')") + public ResponseDTO updateRoleMenu(@Valid @RequestBody RoleMenuUpdateForm updateDTO) { + return roleMenuService.updateRoleMenu(updateDTO); + } + + @ApiOperation("获取角色关联菜单权限 @author 卓大") + @GetMapping("/role/menu/getRoleSelectedMenu/{roleId}") + public ResponseDTO getRoleSelectedMenu(@PathVariable Long roleId) { + return roleMenuService.getRoleSelectedMenu(roleId); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleProvCntroller.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleProvCntroller.java new file mode 100644 index 0000000..cee0861 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/controller/RoleProvCntroller.java @@ -0,0 +1,55 @@ +package net.lab1024.sa.admin.module.system.role.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.admin.common.AdminBaseController; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleMenuUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleProvUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleMenuTreeVO; +import net.lab1024.sa.admin.module.system.role.service.RoleMenuService; +import net.lab1024.sa.admin.module.system.role.service.RoleProvService; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import java.util.List; + +/** + * 角色的菜单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-02-26 21:34:01 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@OperateLog +@RestController +//@Api(tags = {AdminSwaggerTagConst.System.SYSTEM_ROLE_PROV}) +public class RoleProvCntroller extends AdminBaseController { + + @Autowired + private RoleProvService roleProvService; + + @ApiOperation("更新角色省份权限 @author 卓大") + @PostMapping("/role/prov/updateRoleProv") + @PreAuthorize("@saAuth.checkPermission('system:role:prov:update,project:role:prov:update')") + public ResponseDTO updateRoleProv(@Valid @RequestBody RoleProvUpdateForm updateDTO) { + roleProvService.updateRoleProv(updateDTO); + return ResponseDTO.ok(); + } + + @ApiOperation("获取角色关省份单权限 @author 卓大") + @GetMapping("/role/prov/getRoleProv/{roleId}") + public ResponseDTO> getRoleProv(@PathVariable Long roleId) { + return ResponseDTO.ok(roleProvService.getRoleProv(roleId)); + } +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDao.java new file mode 100644 index 0000000..47df8b1 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDao.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.admin.module.system.role.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleProvUpdateForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEntity; + +import java.util.List; + +/** + * 角色 dao + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-02-26 21:34:01 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface RoleDao extends BaseMapper { + + /** + * 根据角色名称查询 + * @param roleName + * @return + */ + RoleEntity getByRoleName(@Param("roleName") String roleName); + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDataScopeDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDataScopeDao.java new file mode 100644 index 0000000..281694e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleDataScopeDao.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.admin.module.system.role.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleDataScopeEntity; + +import java.util.List; + + +/** + * 角色 数据权限 dao + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-02-26 21:34:01 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface RoleDataScopeDao extends BaseMapper { + + /** + * 获取某个角色的设置信息 + * @param roleId + * @return + */ + List listByRoleId(@Param("roleId") Long roleId); + + /** + * 获取某批角色的所有数据范围配置信息 + * @param roleIdList + * @return + */ + List listByRoleIdList(@Param("roleIdList") List roleIdList); + + /** + * 删除某个角色的设置信息 + * @param roleId + * @return + */ + void deleteByRoleId(@Param("roleId") Long roleId); + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleEmployeeDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleEmployeeDao.java new file mode 100644 index 0000000..a2eaf95 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleEmployeeDao.java @@ -0,0 +1,95 @@ +package net.lab1024.sa.admin.module.system.role.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeQueryForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleEmployeeVO; + +import java.util.List; + + +/** + * 角色 员工 dao + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-03-07 18:54:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface RoleEmployeeDao extends BaseMapper { + + /** + * 根据员工id 查询所有的角色 + * @param employeeId + * @return + */ + List selectRoleIdByEmployeeId(@Param("employeeId") Long employeeId); + + /** + * 根据员工id 查询所有的角色 + * @param employeeIdList + * @return + */ + List selectRoleIdByEmployeeIdList(@Param("employeeIdList") List employeeIdList); + + /** + * 根据员工id 查询所有的角色 + * @param employeeIdList + * @return + */ + List selectRoleByEmployeeIdList(@Param("employeeIdList") List employeeIdList); + + /** + * 查询角色下的人员id + * @param roleIdList + * @return + */ + List selectEmployeeIdByRoleIdList(@Param("roleIdList") List roleIdList); + /** + * + * @param page + * @param roleEmployeeQueryForm + * @return + */ + List selectRoleEmployeeByName(Page page, @Param("queryForm") RoleEmployeeQueryForm roleEmployeeQueryForm); + + /** + * + * @param roleId + * @return + */ + List selectEmployeeByRoleId(@Param("roleId") Long roleId); + /** + * 根据员工信息删除 + * @param employeeId + */ + void deleteByEmployeeId(@Param("employeeId") Long employeeId); + + /** + * 删除某个角色的所有关系 + * @param roleId + */ + void deleteByRoleId(@Param("roleId")Long roleId); + + /** + * 根据员工和 角色删除关系 + * @param employeeId + * @param roleId + */ + void deleteByEmployeeIdRoleId(@Param("employeeId") Long employeeId,@Param("roleId")Long roleId); + + /** + * 批量删除某个角色下的某批用户的关联关系 + * @param roleId + * @param employeeIds + */ + void batchDeleteEmployeeRole(@Param("roleId") Long roleId,@Param("employeeIds")List employeeIds); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleMenuDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleMenuDao.java new file mode 100644 index 0000000..aed7cdd --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleMenuDao.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.admin.module.system.role.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleMenuEntity; + +import java.util.List; + +/** + * 角色 菜单 dao + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-07 18:54:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface RoleMenuDao extends BaseMapper { + + /** + * 根据角色ID删除菜单权限 + * + * @param roleId + */ + void deleteByRoleId(@Param("roleId") Long roleId); + + /** + * 根据角色ID查询选择的菜单权限 + * + * @param roleId + * @return + */ + List queryMenuIdByRoleId(@Param("roleId") Long roleId); + + /** + * 根据角色ID集合查询选择的菜单权限 + * + * @param roleIdList + * @return + */ + List selectMenuListByRoleIdList(@Param("roleIdList") List roleIdList, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 查询所有的菜单角色 + * + * @return + */ + List queryAllRoleMenu(); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleProvDao.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleProvDao.java new file mode 100644 index 0000000..34c07ef --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/dao/RoleProvDao.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.system.role.dao; + +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleProvUpdateForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 角色 菜单 dao + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-07 18:54:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface RoleProvDao { + /** + * + * @param updateDTO + * @return + */ + int addRoleProvByRoleId(@Param("updateDTO") RoleProvUpdateForm updateDTO); + + int deleteRoleProvByRoleId(Long roleId); + + List queryRoleProvByRoleId(Long roleId); + + List getRoleProvByRoleId(Long roleId); +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleDataScopeEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleDataScopeEntity.java new file mode 100644 index 0000000..1f2514e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleDataScopeEntity.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.admin.module.system.role.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeTypeEnum; +import net.lab1024.sa.admin.module.system.datascope.constant.DataScopeViewTypeEnum; + +import java.time.LocalDateTime; + +/** + * 数据范围与角色关系 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-03-07 18:54:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_role_data_scope") +public class RoleDataScopeEntity { + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long id; + /** + * 数据范围id + * {@link DataScopeTypeEnum} + */ + private Integer dataScopeType; + /** + * 数据范围类型 + * {@link DataScopeViewTypeEnum} + */ + private Integer viewType; + /** + * 角色id + */ + private Long roleId; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEmployeeEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEmployeeEntity.java new file mode 100644 index 0000000..4a8b9c4 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEmployeeEntity.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.system.role.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 角色 员工关系 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-03-07 18:54:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_role_employee") +public class RoleEmployeeEntity { + + @TableId(type = IdType.AUTO) + private Long id; + + private Long roleId; + + private Long employeeId; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; + + public RoleEmployeeEntity() { + } + + public RoleEmployeeEntity(Long roleId, Long employeeId) { + this.roleId = roleId; + this.employeeId = employeeId; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEntity.java new file mode 100644 index 0000000..7d963f7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleEntity.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.system.role.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 角色 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-03-07 18:54:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_role") +public class RoleEntity { + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long roleId; + + private String roleName; + + private String remark; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleMenuEntity.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleMenuEntity.java new file mode 100644 index 0000000..36b0d80 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/entity/RoleMenuEntity.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.admin.module.system.role.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 角色 菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-03-16 23:00:57 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_role_menu") +public class RoleMenuEntity { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long roleMenuId; + + /** + * 角色 id + */ + private Long roleId; + + /** + * 菜单 id + */ + private Long menuId; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleAddForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleAddForm.java new file mode 100644 index 0000000..f34113e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleAddForm.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotNull; + +/** + * 角色 添加表单 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-02-26 19:09:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleAddForm { + + /** + * 角色名称 + */ + @ApiModelProperty("角色名称") + @NotNull(message = "角色名称不能为空") + @Length(min = 1, max = 20, message = "角色名称(1-20)个字符") + private String roleName; + + /** + * 角色描述 + */ + @ApiModelProperty("角色描述") + @Length(max = 255, message = "角色描述最多255个字符") + private String remark; + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm.java new file mode 100644 index 0000000..6dbff70 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleDataScopeUpdateForm.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 角色的数据范围更新 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleDataScopeUpdateForm { + + @ApiModelProperty("角色id") + @NotNull(message = "角色id不能为空") + private Long roleId; + + @ApiModelProperty("设置信息") + @Valid + private List dataScopeItemList; + + + @Data + public static class RoleUpdateDataScopeListFormItem { + + @ApiModelProperty("数据范围类型") + @NotNull(message = "数据范围类型不能为空") + private Integer dataScopeType; + + @ApiModelProperty("可见范围") + @NotNull(message = "可见范围不能为空") + private Integer viewType; + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeQueryForm.java new file mode 100644 index 0000000..c517d1f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeQueryForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +/** + * 角色的员工查询 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleEmployeeQueryForm extends PageParam { + + @ApiModelProperty("关键字") + private String keywords; + + @ApiModelProperty("角色id") + private String roleId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeUpdateForm.java new file mode 100644 index 0000000..3b5f965 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleEmployeeUpdateForm.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 角色的员工更新 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleEmployeeUpdateForm { + + @ApiModelProperty("角色id") + @NotNull(message = "角色id不能为空") + protected Long roleId; + + @ApiModelProperty(value = "员工id集合") + @NotEmpty(message = "员工id不能为空") + protected List employeeIdList; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleMenuUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleMenuUpdateForm.java new file mode 100644 index 0000000..559f67a --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleMenuUpdateForm.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 角色的菜单更新 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleMenuUpdateForm { + + /** + * 角色id + */ + @ApiModelProperty("角色id") + @NotNull(message = "角色id不能为空") + private Long roleId; + + /** + * 菜单ID 集合 + */ + @ApiModelProperty("菜单ID集合") + @NotNull(message = "菜单ID不能为空") + private List menuIdList; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleProvUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleProvUpdateForm.java new file mode 100644 index 0000000..be4300e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleProvUpdateForm.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 角色 省份 + */ +@Data +public class RoleProvUpdateForm { + + /** + * 角色id + */ + @ApiModelProperty("角色id") + @NotNull(message = "角色id不能为空") + private Long roleId; + + /** + * 菜单ID 集合 + */ + @ApiModelProperty("省份ID集合") + @NotNull(message = "省份ID不能为空") + private List provIdList; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleQueryForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleQueryForm.java new file mode 100644 index 0000000..a1f935f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleQueryForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +/** + * 角色 查询 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-02-26 19:09:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleQueryForm extends PageParam { + + @ApiModelProperty("角色名称") + private String roleName; + + @ApiModelProperty("角色id") + private String roleId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleUpdateForm.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleUpdateForm.java new file mode 100644 index 0000000..0b937f2 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/form/RoleUpdateForm.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.admin.module.system.role.domain.form; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 角色更新修改 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-02-26 19:09:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleUpdateForm extends RoleAddForm { + + /** + * 角色id + */ + @ApiModelProperty("角色id") + @NotNull(message = "角色id不能为空") + protected Long roleId; + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleDataScopeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleDataScopeVO.java new file mode 100644 index 0000000..dd11deb --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleDataScopeVO.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.admin.module.system.role.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 角色的数据范围 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleDataScopeVO { + + @ApiModelProperty("数据范围id") + private Integer dataScopeType; + + @ApiModelProperty("可见范围") + private Integer viewType; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleEmployeeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleEmployeeVO.java new file mode 100644 index 0000000..04e63e3 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleEmployeeVO.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.admin.module.system.role.domain.vo; + +import lombok.Data; + +/** + * 角色的员工 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleEmployeeVO { + + private Long roleId; + + private Long employeeId; + + private String roleName; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleMenuTreeVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleMenuTreeVO.java new file mode 100644 index 0000000..0401348 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleMenuTreeVO.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.admin.module.system.role.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuSimpleTreeVO; + +import java.util.List; + +/** + * 角色菜单树 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleMenuTreeVO { + + @ApiModelProperty("角色ID") + private Long roleId; + + @ApiModelProperty("菜单列表") + private List menuTreeList; + + @ApiModelProperty("选中的菜单ID") + private List selectedMenuId; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleSelectedVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleSelectedVO.java new file mode 100644 index 0000000..e820484 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleSelectedVO.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.system.role.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 选择角色 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleSelectedVO extends RoleVO { + + @ApiModelProperty("角色名称") + private Boolean selected; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleVO.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleVO.java new file mode 100644 index 0000000..7edd1ad --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/domain/vo/RoleVO.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.admin.module.system.role.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 角色 + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RoleVO { + + @ApiModelProperty("角色ID") + private Long roleId; + + @ApiModelProperty("角色名称") + private String roleName; + + @ApiModelProperty("角色备注") + private String remark; +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleDataScopeManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleDataScopeManager.java new file mode 100644 index 0000000..1b2aab9 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleDataScopeManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.admin.module.system.role.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.system.role.dao.RoleDataScopeDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleDataScopeEntity; +import org.springframework.stereotype.Service; + +/** + * 角色 数据范围 manager + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class RoleDataScopeManager extends ServiceImpl { + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleEmployeeManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleEmployeeManager.java new file mode 100644 index 0000000..c470c87 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleEmployeeManager.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.admin.module.system.role.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity; + +import java.util.List; + +/** + * 角色员工 manager + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-04-08 21:53:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class RoleEmployeeManager extends ServiceImpl { + + /** + * 保存 角色员工 + * + * @param roleId + * @param roleEmployeeList + */ + @Transactional(rollbackFor = Throwable.class) + public void saveRoleEmployee(Long roleId, List roleEmployeeList) { + this.getBaseMapper().deleteByRoleId(roleId); + if (CollectionUtils.isNotEmpty(roleEmployeeList)) { + this.saveBatch(roleEmployeeList); + } + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleMenuManager.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleMenuManager.java new file mode 100644 index 0000000..32fbe64 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/manager/RoleMenuManager.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.admin.module.system.role.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.admin.module.system.role.dao.RoleMenuDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleMenuEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 角色-菜单 manager + * + * @Author 1024创新实验室: 善逸 + * @Date 2022-04-09 19:05:49 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class RoleMenuManager extends ServiceImpl { + + @Autowired + private RoleMenuDao roleMenuDao; + + /** + * 更新角色权限 + * + * @param roleId + * @param roleMenuEntityList + */ + @Transactional(rollbackFor = Exception.class) + public void updateRoleMenu(Long roleId, List roleMenuEntityList) { + // 根据角色ID删除菜单权限 + roleMenuDao.deleteByRoleId(roleId); + // 批量添加菜单权限 + saveBatch(roleMenuEntityList); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleDataScopeService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleDataScopeService.java new file mode 100644 index 0000000..3cc655b --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleDataScopeService.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.admin.module.system.role.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleDataScopeUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleDataScopeVO; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleDataScopeEntity; +import net.lab1024.sa.admin.module.system.role.manager.RoleDataScopeManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.List; + +/** + * 角色-数据范围 + * + * @Author 1024创新实验室: 善逸 + * @Date 2021-10-22 23:17:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class RoleDataScopeService { + + @Autowired + private RoleDataScopeManager roleDataScopeManager; + + + /** + * 获取某个角色的数据范围设置信息 + * + * @param roleId + * @return + */ + public ResponseDTO> getRoleDataScopeList(Long roleId) { + List roleDataScopeEntityList = roleDataScopeManager.getBaseMapper().listByRoleId(roleId); + if (CollectionUtils.isEmpty(roleDataScopeEntityList)) { + return ResponseDTO.ok(Lists.newArrayList()); + } + List roleDataScopeList = SmartBeanUtil.copyList(roleDataScopeEntityList, RoleDataScopeVO.class); + return ResponseDTO.ok(roleDataScopeList); + } + + /** + * 批量设置某个角色的数据范围设置信息 + * + * @param roleDataScopeUpdateForm + * @return + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateRoleDataScopeList(RoleDataScopeUpdateForm roleDataScopeUpdateForm) { + List batchSetList = roleDataScopeUpdateForm.getDataScopeItemList(); + if (CollectionUtils.isEmpty(batchSetList)) { + return ResponseDTO.error(UserErrorCode.PARAM_ERROR, "缺少配置信息"); + } + List roleDataScopeEntityList = SmartBeanUtil.copyList(batchSetList, RoleDataScopeEntity.class); + roleDataScopeEntityList.forEach(e -> e.setRoleId(roleDataScopeUpdateForm.getRoleId())); + roleDataScopeManager.getBaseMapper().deleteByRoleId(roleDataScopeUpdateForm.getRoleId()); + roleDataScopeManager.saveBatch(roleDataScopeEntityList); + return ResponseDTO.ok(); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.java new file mode 100644 index 0000000..51bf64d --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleEmployeeService.java @@ -0,0 +1,153 @@ +package net.lab1024.sa.admin.module.system.role.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.admin.module.system.role.dao.RoleDao; +import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEntity; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeQueryForm; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleEmployeeUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleSelectedVO; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.constant.StringConst; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao; +import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity; +import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity; +import net.lab1024.sa.admin.module.system.role.manager.RoleEmployeeManager; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 角色-员工 + * + * @Author 1024创新实验室: 善逸 + * @Date 2021-10-22 23:17:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class RoleEmployeeService { + + @Autowired + private RoleEmployeeDao roleEmployeeDao; + @Autowired + private RoleDao roleDao; + @Autowired + private DepartmentDao departmentDao; + @Autowired + private RoleEmployeeManager roleEmployeeManager; + + /** + * 通过角色id,分页获取成员员工列表 + * + * @param roleEmployeeQueryForm + * @return + */ + public ResponseDTO> queryEmployee(RoleEmployeeQueryForm roleEmployeeQueryForm) { + Page page = SmartPageUtil.convert2PageQuery(roleEmployeeQueryForm); + List employeeDTOS = roleEmployeeDao.selectRoleEmployeeByName(page, roleEmployeeQueryForm) + .stream() + .filter(Objects::nonNull) + .collect(Collectors.toList()); + List departmentIdList = employeeDTOS.stream().filter(e -> e != null && e.getDepartmentId() != null).map(EmployeeVO::getDepartmentId).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(departmentIdList)) { + List departmentEntities = departmentDao.selectBatchIds(departmentIdList); + Map departmentIdNameMap = departmentEntities.stream().collect(Collectors.toMap(DepartmentEntity::getDepartmentId, DepartmentEntity::getName)); + employeeDTOS.forEach(e -> { + e.setDepartmentName(departmentIdNameMap.getOrDefault(e.getDepartmentId(), StringConst.EMPTY)); + }); + } + PageResult PageResult = SmartPageUtil.convert2PageResult(page, employeeDTOS, EmployeeVO.class); + return ResponseDTO.ok(PageResult); + } + + public List getAllEmployeeByRoleId(Long roleId) { + return roleEmployeeDao.selectEmployeeByRoleId(roleId); + } + + /** + * 移除员工角色 + * + * @param employeeId + * @param roleId + * @return ResponseDTO + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO removeRoleEmployee(Long employeeId, Long roleId) { + if (null == employeeId || null == roleId) { + return ResponseDTO.userErrorParam(); + } + roleEmployeeDao.deleteByEmployeeIdRoleId(employeeId, roleId); + return ResponseDTO.ok(); + } + + /** + * 批量删除角色的成员员工 + * + * @param roleEmployeeUpdateForm + * @return ResponseDTO + */ + public ResponseDTO batchRemoveRoleEmployee(RoleEmployeeUpdateForm roleEmployeeUpdateForm) { + roleEmployeeDao.batchDeleteEmployeeRole(roleEmployeeUpdateForm.getRoleId(), roleEmployeeUpdateForm.getEmployeeIdList()); + return ResponseDTO.ok(); + } + + /** + * 批量添加角色的成员员工 + * + * @param roleEmployeeUpdateForm + * @return + */ + public ResponseDTO batchAddRoleEmployee(RoleEmployeeUpdateForm roleEmployeeUpdateForm) { + Long roleId = roleEmployeeUpdateForm.getRoleId(); + List employeeIdList = roleEmployeeUpdateForm.getEmployeeIdList(); + // 保存新的角色员工 + List roleEmployeeList = null; + if (CollectionUtils.isNotEmpty(employeeIdList)) { + roleEmployeeList = employeeIdList.stream() + .map(employeeId -> new RoleEmployeeEntity(roleId, employeeId)) + .collect(Collectors.toList()); + } + // 保存数据 + roleEmployeeManager.saveRoleEmployee(roleId, roleEmployeeList); + return ResponseDTO.ok(); + } + + /** + * 通过员工id获取员工角色 + * + * @param employeeId + * @return + */ + public List getRoleInfoListByEmployeeId(Long employeeId) { + List roleIds = roleEmployeeDao.selectRoleIdByEmployeeId(employeeId); + List roleList = roleDao.selectList(null); + List result = SmartBeanUtil.copyList(roleList, RoleSelectedVO.class); + result.stream().forEach(item -> item.setSelected(roleIds.contains(item.getRoleId()))); + return result; + } + + /** + * 根据员工id 查询角色id集合 + * + * @param employeeId + * @return + */ + public List getRoleIdList(Long employeeId) { + return roleEmployeeDao.selectRoleIdByEmployeeId(employeeId); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.java new file mode 100644 index 0000000..3f9933f --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleMenuService.java @@ -0,0 +1,139 @@ +package net.lab1024.sa.admin.module.system.role.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.admin.module.system.login.service.LoginService; +import net.lab1024.sa.admin.module.system.menu.dao.MenuDao; +import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuSimpleTreeVO; +import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO; +import net.lab1024.sa.admin.module.system.role.dao.RoleDao; +import net.lab1024.sa.admin.module.system.role.dao.RoleMenuDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEntity; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleMenuEntity; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleMenuUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleMenuTreeVO; +import net.lab1024.sa.admin.module.system.role.manager.RoleMenuManager; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 角色-菜单 + * + * @Author 1024创新实验室: 善逸 + * @Date 2021-10-22 23:17:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class RoleMenuService { + + @Autowired + private RoleDao roleDao; + @Autowired + private RoleMenuDao roleMenuDao; + @Autowired + private RoleMenuManager roleMenuManager; + @Autowired + private MenuDao menuDao; + + @Autowired + @Lazy + private LoginService loginService; + + /** + * 更新角色权限 + * + * @param roleMenuUpdateForm + * @return + */ + public ResponseDTO updateRoleMenu(RoleMenuUpdateForm roleMenuUpdateForm) { + //查询角色是否存在 + Long roleId = roleMenuUpdateForm.getRoleId(); + RoleEntity roleEntity = roleDao.selectById(roleId); + if (null == roleEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + List roleMenuEntityList = Lists.newArrayList(); + RoleMenuEntity roleMenuEntity; + for (Long menuId : roleMenuUpdateForm.getMenuIdList()) { + roleMenuEntity = new RoleMenuEntity(); + roleMenuEntity.setRoleId(roleId); + roleMenuEntity.setMenuId(menuId); + roleMenuEntityList.add(roleMenuEntity); + } + roleMenuManager.updateRoleMenu(roleMenuUpdateForm.getRoleId(), roleMenuEntityList); + + //修改权限后需要重置登录用户的权限 + loginService.refreashAuthorities(); + return ResponseDTO.ok(); + } + + /** + * 根据角色id集合,查询其所有的菜单权限 + * + * @param roleIdList + * @return + */ + public List getMenuList(List roleIdList, Boolean administratorFlag) { + //管理员返回所有菜单 + if(administratorFlag){ + List menuEntityList = roleMenuDao.selectMenuListByRoleIdList(Lists.newArrayList(), false); + return SmartBeanUtil.copyList(menuEntityList, MenuVO.class); + } + //非管理员 无角色 返回空菜单 + if (CollectionUtils.isEmpty(roleIdList)) { + return new ArrayList<>(); + } + List menuEntityList = roleMenuDao.selectMenuListByRoleIdList(roleIdList, false); + return SmartBeanUtil.copyList(menuEntityList, MenuVO.class); + } + + + /** + * 获取角色关联菜单权限 + * + * @param roleId + * @return + */ + public ResponseDTO getRoleSelectedMenu(Long roleId) { + RoleMenuTreeVO res = new RoleMenuTreeVO(); + res.setRoleId(roleId); + //查询角色ID选择的菜单权限 + List selectedMenuId = roleMenuDao.queryMenuIdByRoleId(roleId); + res.setSelectedMenuId(selectedMenuId); + //查询菜单权限 + List menuVOList = menuDao.queryMenuList(Boolean.FALSE, Boolean.FALSE, null); + Map> parentMap = menuVOList.stream().collect(Collectors.groupingBy(MenuVO::getParentId, Collectors.toList())); + List menuTreeList = this.buildMenuTree(parentMap, NumberUtils.LONG_ZERO); + res.setMenuTreeList(menuTreeList); + return ResponseDTO.ok(res); + } + + /** + * 构建菜单树 + * + * @return + */ + private List buildMenuTree(Map> parentMap, Long parentId) { + // 获取本级菜单树List + List res = parentMap.getOrDefault(parentId, Lists.newArrayList()).stream() + .map(e -> SmartBeanUtil.copy(e, MenuSimpleTreeVO.class)).collect(Collectors.toList()); + // 循环遍历下级菜单 + res.forEach(e -> { + e.setChildren(this.buildMenuTree(parentMap, e.getMenuId())); + }); + return res; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleProvService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleProvService.java new file mode 100644 index 0000000..7dd010e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleProvService.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.admin.module.system.role.service; + +import net.lab1024.sa.admin.module.business.area.domain.vo.ProvVO; +import net.lab1024.sa.admin.module.system.login.service.LoginService; +import net.lab1024.sa.admin.module.system.role.dao.RoleDao; +import net.lab1024.sa.admin.module.system.role.dao.RoleProvDao; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleProvUpdateForm; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 设置角色-省份权限表 + */ +@Service +public class RoleProvService { + + @Autowired + private RoleProvDao roleProvDao; + + @Autowired + @Lazy + private LoginService loginService; + + @Transactional + public void updateRoleProv(RoleProvUpdateForm updateDTO){ + Long roleId = updateDTO.getRoleId(); + roleProvDao.deleteRoleProvByRoleId(roleId); + List provIdList = updateDTO.getProvIdList(); + if(provIdList != null && provIdList.size() > 0){ + roleProvDao.addRoleProvByRoleId(updateDTO); + } + + //修改权限后需要重置登录用户的权限 + loginService.refreashAuthorities(); + } + + public List getRoleProv(Long roleId){ + List data = roleProvDao.queryRoleProvByRoleId(roleId); + return data; + } + + public List getRoleProvByRoleId(Long roleId){ + return roleProvDao.getRoleProvByRoleId(roleId); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleService.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleService.java new file mode 100644 index 0000000..031d75e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/role/service/RoleService.java @@ -0,0 +1,119 @@ +package net.lab1024.sa.admin.module.system.role.service; + +import net.lab1024.sa.admin.module.system.role.dao.RoleDao; +import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao; +import net.lab1024.sa.admin.module.system.role.dao.RoleMenuDao; +import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEntity; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleAddForm; +import net.lab1024.sa.admin.module.system.role.domain.form.RoleUpdateForm; +import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 角色 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-08-16 20:19:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class RoleService { + + @Autowired + private RoleDao roleDao; + + @Autowired + private RoleMenuDao roleMenuDao; + + @Autowired + private RoleEmployeeDao roleEmployeeDao; + + /** + * 新增添加角色 + * + * @param roleAddForm + * @return ResponseDTO + */ + public ResponseDTO addRole(RoleAddForm roleAddForm) { + RoleEntity existRoleEntity = roleDao.getByRoleName(roleAddForm.getRoleName()); + if (null != existRoleEntity) { + return ResponseDTO.userErrorParam("角色名称重复"); + } + RoleEntity roleEntity = SmartBeanUtil.copy(roleAddForm, RoleEntity.class); + roleDao.insert(roleEntity); + return ResponseDTO.ok(); + } + + /** + * 根据角色id 删除 + * + * @param roleId + * @return ResponseDTO + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO deleteRole(Long roleId) { + RoleEntity roleEntity = roleDao.selectById(roleId); + if (null == roleEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + roleDao.deleteById(roleId); + roleMenuDao.deleteByRoleId(roleId); + roleEmployeeDao.deleteByRoleId(roleId); + return ResponseDTO.ok(); + } + + /** + * 更新角色 + * + * @param roleUpdateForm + * @return ResponseDTO + */ + @Transactional(rollbackFor = Exception.class) + public ResponseDTO updateRole(RoleUpdateForm roleUpdateForm) { + if (null == roleDao.selectById(roleUpdateForm.getRoleId())) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + RoleEntity existRoleEntity = roleDao.getByRoleName(roleUpdateForm.getRoleName()); + if (null != existRoleEntity && !existRoleEntity.getRoleId().equals(roleUpdateForm.getRoleId())) { + return ResponseDTO.userErrorParam("角色名称重复"); + } + RoleEntity roleEntity = SmartBeanUtil.copy(roleUpdateForm, RoleEntity.class); + roleDao.updateById(roleEntity); + return ResponseDTO.ok(); + } + + /** + * 根据id获取角色数据 + * + * @param roleId + * @return ResponseDTO + */ + public ResponseDTO getRoleById(Long roleId) { + RoleEntity roleEntity = roleDao.selectById(roleId); + if (null == roleEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + RoleVO role = SmartBeanUtil.copy(roleEntity, RoleVO.class); + return ResponseDTO.ok(role); + } + + /** + * 获取所有角色列表 + * + * @return ResponseDTO + */ + public ResponseDTO> getAllRole() { + List roleEntityList = roleDao.selectList(null); + List roleList = SmartBeanUtil.copyList(roleEntityList, RoleVO.class); + return ResponseDTO.ok(roleList); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminCacheController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminCacheController.java new file mode 100644 index 0000000..b710b13 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminCacheController.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.cache.CacheService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 缓存 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021/10/11 20:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@RestController +//@Api(tags = {SwaggerTagConst.Support.CACHE}) +public class AdminCacheController extends SupportBaseController { + + @Autowired + private CacheService cacheService; + + @ApiOperation(value = "获取所有缓存 @author 罗伊") + @GetMapping("/cache/names") + public ResponseDTO> cacheNames() { + return ResponseDTO.ok(cacheService.cacheNames()); + } + + + @ApiOperation(value = "移除某个缓存 @author 罗伊") + @PreAuthorize("@saAuth.checkPermission('support:cache:delete')") + @GetMapping("/cache/remove/{cacheName}") + public ResponseDTO removeCache(@PathVariable String cacheName) { + cacheService.removeCache(cacheName); + return ResponseDTO.ok(); + } + + + @ApiOperation(value = "获取某个缓存的所有key @author 罗伊") + @PreAuthorize("@saAuth.checkPermission('support:cache:keys')") + @GetMapping("/cache/keys/{cacheName}") + public ResponseDTO> cacheKeys(@PathVariable String cacheName) { + return ResponseDTO.ok(cacheService.cacheKey(cacheName)); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.java new file mode 100644 index 0000000..983d9c4 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminChangeLogController.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.domain.ValidateList; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.changelog.domain.form.ChangeLogAddForm; +import net.lab1024.sa.common.module.support.changelog.domain.form.ChangeLogUpdateForm; +import net.lab1024.sa.common.module.support.changelog.service.ChangeLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * 系统更新日志 Controller + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@RestController +//@Api(tags = SwaggerTagConst.Support.CHANGE_LOG) +public class AdminChangeLogController { + + @Autowired + private ChangeLogService changeLogService; + + @ApiOperation("添加 @author 卓大") + @PostMapping("/changeLog/add") + @PreAuthorize("@saAuth.checkPermission('changeLog:add')") + public ResponseDTO add(@RequestBody @Valid ChangeLogAddForm addForm) { + return changeLogService.add(addForm); + } + + @ApiOperation("更新 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('changeLog:update')") + @PostMapping("/changeLog/update") + public ResponseDTO update(@RequestBody @Valid ChangeLogUpdateForm updateForm) { + return changeLogService.update(updateForm); + } + + @ApiOperation("批量删除 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('changeLog:batchDelete')") + @PostMapping("/changeLog/batchDelete") + public ResponseDTO batchDelete(@RequestBody ValidateList idList) { + return changeLogService.batchDelete(idList); + } + + @ApiOperation("单个删除 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('changeLog:delete')") + @GetMapping("/changeLog/delete/{changeLogId}") + public ResponseDTO batchDelete(@PathVariable Long changeLogId) { + return changeLogService.delete(changeLogId); + } +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminConfigController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminConfigController.java new file mode 100644 index 0000000..e80b065 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminConfigController.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.config.ConfigService; +import net.lab1024.sa.common.module.support.config.domain.ConfigAddForm; +import net.lab1024.sa.common.module.support.config.domain.ConfigQueryForm; +import net.lab1024.sa.common.module.support.config.domain.ConfigUpdateForm; +import net.lab1024.sa.common.module.support.config.domain.ConfigVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * 配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Api(tags = {SwaggerTagConst.Support.CONFIG}) +@RestController +public class AdminConfigController extends SupportBaseController { + + @Autowired + private ConfigService configService; + + @ApiOperation("分页查询系统配置 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('support:config:query')") + @PostMapping("/config/query") + public ResponseDTO> querySystemConfigPage(@RequestBody @Valid ConfigQueryForm queryForm) { + return configService.queryConfigPage(queryForm); + } + + @ApiOperation("添加配置参数 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('support:config:add')") + @PostMapping("/config/add") + public ResponseDTO addSystemConfig(@RequestBody @Valid ConfigAddForm configAddForm) { + return configService.add(configAddForm); + } + + @ApiOperation("修改配置参数 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('support:config:update,case-support:config:update')") + @PostMapping("/config/update") + public ResponseDTO updateSystemConfig(@RequestBody @Valid ConfigUpdateForm updateForm) { + return configService.updateSystemConfig(updateForm); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminDictController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminDictController.java new file mode 100644 index 0000000..90c0600 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminDictController.java @@ -0,0 +1,79 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.dict.domain.form.*; +import net.lab1024.sa.common.module.support.dict.domain.vo.DictKeyVO; +import net.lab1024.sa.common.module.support.dict.service.DictService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import java.util.List; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Api(tags = {SwaggerTagConst.Support.DICT}) +@RestController +public class AdminDictController extends SupportBaseController { + + @Autowired + private DictService dictService; + + @ApiOperation("分页查询数据字典KEY - @author 罗伊") + @PostMapping("/dict/key/query") + public ResponseDTO> keyQuery(@Valid @RequestBody DictKeyQueryForm queryForm) { + return dictService.keyQuery(queryForm); + } + + + @ApiOperation("数据字典KEY-添加- @author 罗伊") + @PostMapping("/dict/key/add") + public ResponseDTO keyAdd(@Valid @RequestBody DictKeyAddForm keyAddForm) { + return dictService.keyAdd(keyAddForm); + } + + @ApiOperation("数据字典Value-添加- @author 罗伊") + @PostMapping("/dict/value/add") + public ResponseDTO valueAdd(@Valid @RequestBody DictValueAddForm valueAddForm) { + return dictService.valueAdd(valueAddForm); + } + + @ApiOperation("数据字典KEY-更新- @author 罗伊") + @PostMapping("/dict/key/edit") + public ResponseDTO keyEdit(@Valid @RequestBody DictKeyUpdateForm keyUpdateForm) { + return dictService.keyEdit(keyUpdateForm); + } + + @ApiOperation("数据字典Value-更新- @author 罗伊") + @PostMapping("/dict/value/edit") + public ResponseDTO valueEdit(@Valid @RequestBody DictValueUpdateForm valueUpdateForm) { + return dictService.valueEdit(valueUpdateForm); + } + + @ApiOperation("数据字典KEY-删除- @author 罗伊") + @PostMapping("/dict/key/delete") + public ResponseDTO keyDelete(@RequestBody List keyIdList) { + return dictService.keyDelete(keyIdList); + } + + @ApiOperation("数据字典Value-删除- @author 罗伊") + @PostMapping("/dict/value/delete") + public ResponseDTO valueDelete(@RequestBody List valueIdList) { + return dictService.valueDelete(valueIdList); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminFileController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminFileController.java new file mode 100644 index 0000000..619f8fd --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminFileController.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.file.domain.form.FileQueryForm; +import net.lab1024.sa.common.module.support.file.domain.vo.FileVO; +import net.lab1024.sa.common.module.support.file.service.FileService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * 文件服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@RestController +//@Api(tags = {SwaggerTagConst.Support.FILE}) +public class AdminFileController extends SupportBaseController { + + @Autowired + private FileService fileService; + + @ApiOperation("分页查询 @author 1024创新实验室-主任-卓大") + @PreAuthorize("@saAuth.checkPermission('support:file:query')") + @PostMapping("/file/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid FileQueryForm queryForm) { + return ResponseDTO.ok(fileService.queryPage(queryForm)); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHeartBeatController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHeartBeatController.java new file mode 100644 index 0000000..c5f0003 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHeartBeatController.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.heartbeat.HeartBeatService; +import net.lab1024.sa.common.module.support.heartbeat.domain.HeartBeatRecordQueryForm; +import net.lab1024.sa.common.module.support.heartbeat.domain.HeartBeatRecordVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Api(tags = {SwaggerTagConst.Support.HEART_BEAT}) +@RestController +public class AdminHeartBeatController extends SupportBaseController { + + @Autowired + private HeartBeatService heartBeatService; + + @PostMapping("/heartBeat/query") + @ApiOperation("查询心跳记录 @author 卓大") + public ResponseDTO> query(@RequestBody @Valid HeartBeatRecordQueryForm pageParam) { + return heartBeatService.pageQuery(pageParam); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.java new file mode 100644 index 0000000..5069fc0 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminHelpDocController.java @@ -0,0 +1,108 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.*; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocDetailVO; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocVO; +import net.lab1024.sa.common.module.support.helpdoc.service.HelpDocCatalogService; +import net.lab1024.sa.common.module.support.helpdoc.service.HelpDocService; +import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Api(tags = SwaggerTagConst.Support.HELP_DOC, hidden = true) +@RestController +public class AdminHelpDocController extends SupportBaseController { + + @Autowired + private HelpDocService helpDocService; + + @Autowired + private HelpDocCatalogService helpDocCatalogService; + + // --------------------- 帮助文档 【目录管理】 ------------------------- + + + @ApiOperation("帮助文档目录-添加 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDocCatalog:addCategory')") + @PostMapping("/helpDoc/helpDocCatalog/add") + public ResponseDTO addHelpDocCatalog(@RequestBody @Valid HelpDocCatalogAddForm helpDocCatalogAddForm) { + return helpDocCatalogService.add(helpDocCatalogAddForm); + } + + @ApiOperation("帮助文档目录-更新 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDocCatalog:edit')") + @PostMapping("/helpDoc/helpDocCatalog/update") + public ResponseDTO updateHelpDocCatalog(@RequestBody @Valid HelpDocCatalogUpdateForm helpDocCatalogUpdateForm) { + return helpDocCatalogService.update(helpDocCatalogUpdateForm); + } + + @ApiOperation("帮助文档目录-删除 @author 卓大") + @GetMapping("/helpDoc/helpDocCatalog/delete/{helpDocCatalogId}") + public ResponseDTO deleteHelpDocCatalog(@PathVariable Long helpDocCatalogId) { + return helpDocCatalogService.delete(helpDocCatalogId); + } + + // --------------------- 帮助文档 【管理:增、删、查、改】------------------------- + + @ApiOperation("【管理】帮助文档-分页查询 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDoc:query')") + @PostMapping("/helpDoc/query") + public ResponseDTO> query(@RequestBody @Valid HelpDocQueryForm queryForm) { + return ResponseDTO.ok(helpDocService.query(queryForm)); + } + + @ApiOperation("【管理】帮助文档-获取详情 @author 卓大") + @GetMapping("/helpDoc/getDetail/{helpDocId}") + public ResponseDTO getDetail(@PathVariable Long helpDocId) { + return ResponseDTO.ok(helpDocService.getDetail(helpDocId)); + } + + @ApiOperation("【管理】帮助文档-添加 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDoc:add')") + @PostMapping("/helpDoc/add") + @RepeatSubmit + public ResponseDTO add(@RequestBody @Valid HelpDocAddForm addForm) { + return helpDocService.add(addForm); + } + + @ApiOperation("【管理】帮助文档-更新 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDoc:update')") + @PostMapping("/helpDoc/update") + @RepeatSubmit + public ResponseDTO update(@RequestBody @Valid HelpDocUpdateForm updateForm) { + return helpDocService.update(updateForm); + } + + @ApiOperation("【管理】帮助文档-删除 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('helpDoc:delete')") + @GetMapping("/helpDoc/delete/{helpDocId}") + public ResponseDTO delete(@PathVariable Long helpDocId) { + return helpDocService.delete(helpDocId); + } + + @ApiOperation("【管理】帮助文档-根据关联id查询 @author 卓大") + @GetMapping("/helpDoc/queryHelpDocByRelationId/{relationId}") + public ResponseDTO> queryHelpDocByRelationId(@PathVariable Long relationId) { + return ResponseDTO.ok(helpDocService.queryHelpDocByRelationId(relationId)); + } + +} \ No newline at end of file diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.java new file mode 100644 index 0000000..ee6fbd3 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminLoginLogController.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.loginlog.LoginLogService; +import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogQueryForm; +import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * 登录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@RestController +//@Api(tags = {SwaggerTagConst.Support.LOGIN_LOG}) +public class AdminLoginLogController extends SupportBaseController { + + @Autowired + private LoginLogService loginLogService; + + @ApiOperation(value = "分页查询 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('loginLog:query')") + @PostMapping("/loginLog/page/query") + public ResponseDTO> queryByPage(@RequestBody LoginLogQueryForm queryForm) { + return loginLogService.queryByPage(queryForm); + } + + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.java new file mode 100644 index 0000000..b264203 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminOperateLogController.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.operatelog.OperateLogService; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogQueryForm; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +/** + * 操作日志 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@RestController +//@Api(tags = {SwaggerTagConst.Support.OPERATE_LOG}) +public class AdminOperateLogController extends SupportBaseController { + + @Autowired + private OperateLogService operateLogService; + + @ApiOperation(value = "分页查询 @author 罗伊") + @PreAuthorize("@saAuth.checkPermission('operateLog:query')") + @PostMapping("/operateLog/page/query") + public ResponseDTO> queryByPage(@RequestBody OperateLogQueryForm queryForm) { + return operateLogService.queryByPage(queryForm); + } + + @ApiOperation(value = "详情 @author 罗伊") + @PreAuthorize("@saAuth.checkPermission('operateLog:detail')") + @GetMapping("/operateLog/detail/{operateLogId}") + public ResponseDTO detail(@PathVariable Long operateLogId) { + return operateLogService.detail(operateLogId); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminReloadController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminReloadController.java new file mode 100644 index 0000000..54cd48e --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminReloadController.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.reload.ReloadService; +import net.lab1024.sa.common.module.support.reload.domain.ReloadForm; +import net.lab1024.sa.common.module.support.reload.domain.ReloadItemVO; +import net.lab1024.sa.common.module.support.reload.domain.ReloadResultVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * reload (内存热加载、钩子等) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@RestController +//@Api(tags = {SwaggerTagConst.Support.RELOAD}) +public class AdminReloadController extends SupportBaseController { + + @Autowired + private ReloadService reloadService; + + @ApiOperation(value = "查询reload列表 @author 开云") + @GetMapping("/reload/query") + public ResponseDTO> query() { + return reloadService.query(); + } + + @ApiOperation(value = "获取reload result @author 开云") + @PreAuthorize("@saAuth.checkPermission('support:reload:result')") + @GetMapping("/reload/result/{tag}") + public ResponseDTO> queryReloadResult(@PathVariable("tag") String tag) { + return reloadService.queryReloadItemResult(tag); + } + + @ApiOperation(value = "通过tag更新标识 @author 开云") + @PreAuthorize("@saAuth.checkPermission('support:reload:execute')") + @PostMapping("/reload/update") + public ResponseDTO updateByTag(@RequestBody @Valid ReloadForm reloadForm) { + return reloadService.updateByTag(reloadForm); + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.java new file mode 100644 index 0000000..f87f328 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/system/support/AdminSerialNumberController.java @@ -0,0 +1,74 @@ +package net.lab1024.sa.admin.module.system.support; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartEnumUtil; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.serialnumber.constant.SerialNumberIdEnum; +import net.lab1024.sa.common.module.support.serialnumber.dao.SerialNumberDao; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberEntity; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberGenerateForm; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberRecordEntity; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberRecordQueryForm; +import net.lab1024.sa.common.module.support.serialnumber.service.SerialNumberRecordService; +import net.lab1024.sa.common.module.support.serialnumber.service.SerialNumberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import java.util.List; + +/** + * 单据序列号 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Api(tags = SwaggerTagConst.Support.SERIAL_NUMBER) +@RestController +public class AdminSerialNumberController extends SupportBaseController { + + @Autowired + private SerialNumberDao serialNumberDao; + + @Autowired + private SerialNumberService serialNumberService; + + @Autowired + private SerialNumberRecordService serialNumberRecordService; + + @ApiOperation("生成单号 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('support:serial:number:generate')") + @PostMapping("/serialNumber/generate") + public ResponseDTO> generate(@RequestBody @Valid SerialNumberGenerateForm generateForm) { + SerialNumberIdEnum serialNumberIdEnum = SmartEnumUtil.getEnumByValue(generateForm.getSerialNumberId(), SerialNumberIdEnum.class); + if (null == serialNumberIdEnum) { + return ResponseDTO.userErrorParam("SerialNumberId,不存在" + generateForm.getSerialNumberId()); + } + return ResponseDTO.ok(serialNumberService.generate(serialNumberIdEnum, generateForm.getCount())); + } + + @ApiOperation("获取所有单号定义 @author 卓大") + @GetMapping("/serialNumber/all") + public ResponseDTO> getAll() { + return ResponseDTO.ok(serialNumberDao.selectList(null)); + } + + @ApiOperation("获取生成记录 @author 卓大") + @PreAuthorize("@saAuth.checkPermission('support:serial:number:record')") + @PostMapping("/serialNumber/queryRecord") + public ResponseDTO> queryRecord(@RequestBody @Valid SerialNumberRecordQueryForm queryForm) { + return ResponseDTO.ok(serialNumberRecordService.query(queryForm)); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/config/WxMaConfiguration.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/config/WxMaConfiguration.java new file mode 100644 index 0000000..9698522 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/config/WxMaConfiguration.java @@ -0,0 +1,131 @@ +package net.lab1024.sa.admin.module.wx.miniapp.config; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; +import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; +import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; +import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; +import cn.binarywang.wx.miniapp.message.WxMaMessageHandler; +import cn.binarywang.wx.miniapp.message.WxMaMessageRouter; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.error.WxRuntimeException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.io.File; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Binary Wang + */ +@Slf4j +@Configuration +@EnableConfigurationProperties(WxMaProperties.class) +public class WxMaConfiguration { + private final WxMaProperties properties; + + @Autowired + public WxMaConfiguration(WxMaProperties properties) { + this.properties = properties; + } + + @Bean + public WxMaService wxMaService() { + List configs = this.properties.getConfigs(); + if (configs == null) { + throw new WxRuntimeException("添加下相关配置,注意别配错了!"); + } + WxMaService maService = new WxMaServiceImpl(); + maService.setMultiConfigs( + configs.stream() + .map(a -> { + WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl(); +// WxMaDefaultConfigImpl config = new WxMaRedisConfigImpl(new JedisPool()); + // 使用上面的配置时,需要同时引入jedis-lock的依赖,否则会报类无法找到的异常 + config.setAppid(a.getAppid()); + config.setSecret(a.getSecret()); + config.setToken(a.getToken()); + config.setAesKey(a.getAesKey()); + config.setMsgDataFormat(a.getMsgDataFormat()); + return config; + }).collect(Collectors.toMap(WxMaDefaultConfigImpl::getAppid, a -> a, (o, n) -> o))); + return maService; + } + + @Bean + public WxMaMessageRouter wxMaMessageRouter(WxMaService wxMaService) { + final WxMaMessageRouter router = new WxMaMessageRouter(wxMaService); + router + .rule().handler(logHandler).next() + .rule().async(false).content("订阅消息").handler(subscribeMsgHandler).end() + .rule().async(false).content("文本").handler(textHandler).end() + .rule().async(false).content("图片").handler(picHandler).end() + .rule().async(false).content("二维码").handler(qrcodeHandler).end(); + return router; + } + + private final WxMaMessageHandler subscribeMsgHandler = (wxMessage, context, service, sessionManager) -> { + service.getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder() + .templateId("此处更换为自己的模板id") + .data(Lists.newArrayList( + new WxMaSubscribeMessage.MsgData("keyword1", "339208499"))) + .toUser(wxMessage.getFromUser()) + .build()); + return null; + }; + + private final WxMaMessageHandler logHandler = (wxMessage, context, service, sessionManager) -> { + log.info("收到消息:" + wxMessage.toString()); + service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson()) + .toUser(wxMessage.getFromUser()).build()); + return null; + }; + + private final WxMaMessageHandler textHandler = (wxMessage, context, service, sessionManager) -> { + service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息") + .toUser(wxMessage.getFromUser()).build()); + return null; + }; + + private final WxMaMessageHandler picHandler = (wxMessage, context, service, sessionManager) -> { + try { + WxMediaUploadResult uploadResult = service.getMediaService() + .uploadMedia("image", "png", + ClassLoader.getSystemResourceAsStream("tmp.png")); + service.getMsgService().sendKefuMsg( + WxMaKefuMessage + .newImageBuilder() + .mediaId(uploadResult.getMediaId()) + .toUser(wxMessage.getFromUser()) + .build()); + } catch (WxErrorException e) { + e.printStackTrace(); + } + + return null; + }; + + private final WxMaMessageHandler qrcodeHandler = (wxMessage, context, service, sessionManager) -> { + try { + final File file = service.getQrcodeService().createQrcode("123", 430); + WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file); + service.getMsgService().sendKefuMsg( + WxMaKefuMessage + .newImageBuilder() + .mediaId(uploadResult.getMediaId()) + .toUser(wxMessage.getFromUser()) + .build()); + } catch (WxErrorException e) { + e.printStackTrace(); + } + + return null; + }; + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/config/WxMaProperties.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/config/WxMaProperties.java new file mode 100644 index 0000000..dc55d10 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/config/WxMaProperties.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.admin.module.wx.miniapp.config; + +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import lombok.Data; + +/** + * @author Binary Wang + */ +@Data +@ConfigurationProperties(prefix = "wx.miniapp") +public class WxMaProperties { + + private List configs; + + @Data + public static class Config { + /** + * 设置微信小程序的appid + */ + private String appid; + + /** + * 设置微信小程序的Secret + */ + private String secret; + + /** + * 设置微信小程序消息服务器配置的token + */ + private String token; + + /** + * 设置微信小程序消息服务器配置的EncodingAESKey + */ + private String aesKey; + + /** + * 消息格式,XML或者JSON + */ + private String msgDataFormat; + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxMaMediaController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxMaMediaController.java new file mode 100644 index 0000000..4c6b241 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxMaMediaController.java @@ -0,0 +1,88 @@ +package net.lab1024.sa.admin.module.wx.miniapp.controller; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.constant.WxMaConstants; +import cn.binarywang.wx.miniapp.util.WxMaConfigHolder; +import com.google.common.collect.Lists; +import com.google.common.io.Files; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.error.WxErrorException; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +/** + *
+ *  小程序临时素材接口
+ *  Created by BinaryWang on 2017/6/16.
+ * 
+ * + * @author Binary Wang + */ +@RestController +@AllArgsConstructor +@Slf4j +@RequestMapping("/wx/media/{appid}") +public class WxMaMediaController { + private final WxMaService wxMaService; + + /** + * 上传临时素材 + * + * @return 素材的media_id列表,实际上如果有的话,只会有一个 + */ + @PostMapping("/upload") + public List uploadMedia(@PathVariable String appid, HttpServletRequest request) throws WxErrorException { + if (!wxMaService.switchover(appid)) { + throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); + } + + CommonsMultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext()); + + if (!resolver.isMultipart(request)) { + WxMaConfigHolder.remove();//清理ThreadLocal + return Lists.newArrayList(); + } + + MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; + Iterator it = multiRequest.getFileNames(); + List result = Lists.newArrayList(); + while (it.hasNext()) { + try { + MultipartFile file = multiRequest.getFile(it.next()); + File newFile = new File(Files.createTempDir(), file.getOriginalFilename()); + log.info("filePath is :" + newFile.toString()); + file.transferTo(newFile); + WxMediaUploadResult uploadResult = wxMaService.getMediaService().uploadMedia(WxMaConstants.KefuMsgType.IMAGE, newFile); + log.info("media_id : " + uploadResult.getMediaId()); + result.add(uploadResult.getMediaId()); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + WxMaConfigHolder.remove();//清理ThreadLocal + return result; + } + + /** + * 下载临时素材 + */ + @GetMapping("/download/{mediaId}") + public File getMedia(@PathVariable String appid, @PathVariable String mediaId) throws WxErrorException { + if (!wxMaService.switchover(appid)) { + throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); + } + File media = wxMaService.getMediaService().getMedia(mediaId); + WxMaConfigHolder.remove();//清理ThreadLocal + return media; + } +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxMaUserController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxMaUserController.java new file mode 100644 index 0000000..dcdddc3 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxMaUserController.java @@ -0,0 +1,190 @@ +package net.lab1024.sa.admin.module.wx.miniapp.controller; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; +import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; +import cn.binarywang.wx.miniapp.util.WxMaConfigHolder; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson2.JSON; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import net.lab1024.sa.admin.constant.AdminSwaggerTagConst; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertEntity; +import net.lab1024.sa.admin.module.app.expert.admin.ExpertLoginVO; +import net.lab1024.sa.admin.module.app.expert.service.ExpertService; +import net.lab1024.sa.admin.module.business.captcha.service.CaptchaService; +import net.lab1024.sa.admin.module.wx.miniapp.utils.JsonUtils; +import net.lab1024.sa.common.common.annoation.NoNeedLogin; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.Sha256Util; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.module.support.config.ConfigService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +/** + * 微信小程序用户接口 + * + * @author Binary Wang + */ +@RestController +@Slf4j +@RequestMapping("/wx/user/{appid}") +@Api(tags = {AdminSwaggerTagConst.App.WX_MINI}) +public class WxMaUserController { + + private final WxMaService wxMaService; + + public WxMaUserController(WxMaService wxMaService) { + this.wxMaService = wxMaService; + } + + //短信注册 + private final String MOBILELOGIN_URL = "hcp/mobileLogin"; + + @Value("${igandan.doc.host}") + private String IGANDAN_DOC_HOST; + + @Value("${igandan.wx.host}") + private String IGANDAN_WX_HOST; + + @Value("${igandan.wx.platform}") + private String IGANDAN_WX_PLATFORM; + + @Value("${igandan.wx.token}") + private String IGANDAN_WX_token; + + @Autowired + private ExpertService expertService; + + /** + * 登陆接口 + */ + //@NoNeedLogin + //@GetMapping("/login") + //public String login(@PathVariable String appid, String code) { + // if (StringUtils.isBlank(code)) { + // return "empty jscode"; + // } + // + // if (!wxMaService.switchover(appid)) { + // throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); + // } + // + // try { + // WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code); + // log.info(session.getSessionKey()); + // log.info(session.getOpenid()); + // //TODO 可以增加自己的逻辑,关联业务相关数据 + // return JsonUtils.toJson(session); + // } catch (WxErrorException e) { + // log.error(e.getMessage(), e); + // return e.toString(); + // } finally { + // WxMaConfigHolder.remove();//清理ThreadLocal + // } + //} + + /** + *
+     * 获取用户信息接口
+     * 
+ */ + //@NoNeedLogin + //@GetMapping("/info") + //public String info(@PathVariable String appid, String sessionKey, + // String signature, String rawData, String encryptedData, String iv) { + // if (!wxMaService.switchover(appid)) { + // throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); + // } + // + // // 用户信息校验 + // if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) { + // WxMaConfigHolder.remove();//清理ThreadLocal + // return "user check failed"; + // } + // + // // 解密用户信息 + // WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv); + // WxMaConfigHolder.remove();//清理ThreadLocal + // return JsonUtils.toJson(userInfo); + //} + + /** + *
+     * 获取用户绑定手机号信息
+     * 
+ */ + @NoNeedLogin + @GetMapping("/phone") + @ApiOperation("使用微信手机号授权登录") + public ResponseDTO phone(@PathVariable String appid, String code) { + try { + if (!wxMaService.switchover(appid)) { + throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); + } + // 解密 + WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(code); + String phoneNumber = phoneNoInfo.getPhoneNumber(); + Map params = new HashMap<>(8); + params.put("mobile", phoneNumber); + params.put("platform", IGANDAN_WX_PLATFORM); + params.put("timestamp", System.currentTimeMillis()/1000); + String signature = Sha256Util.getSign(params, IGANDAN_WX_token); + params.put("signature", signature); + + String result = HttpUtil.post(IGANDAN_WX_HOST + MOBILELOGIN_URL, params); + ResponseDTO responseDTO = JSON.parseObject(result, ResponseDTO.class); + if(responseDTO.getCode() == 200){ + Map data = (Map) responseDTO.getData(); + String uuid = (String) data.get("uuid"); + String name = (String) data.get("name"); + String photo = (String) data.get("photo"); + String hospital_uuid = (String) data.get("hospital_uuid"); + String hospital_name = (String) data.get("hospital_name"); + Integer prov_id = (Integer) data.get("prov_id"); + Integer county_id = (Integer) data.get("county_id"); + Integer city_id = (Integer) data.get("city_id"); + ExpertEntity expert = new ExpertEntity(); + expert.setName(name); + if(StrUtil.isBlank(photo)){ + expert.setPhoto(""); + }else{ + expert.setPhoto(IGANDAN_DOC_HOST+photo); + } + expert.setUuid(uuid); + expert.setHospitalName(hospital_name); + expert.setHospitalUuid(hospital_uuid); + expert.setProvId(prov_id); + expert.setCityId(city_id); + expert.setCountyId(county_id); + expert.setMobile(phoneNumber); + ExpertEntity expertVO = expertService.addExpert(expert); + ExpertLoginVO expertLoginVO = SmartBeanUtil.copy(expertVO, ExpertLoginVO.class); + return ResponseDTO.app_ok(expertLoginVO); + }else{ + return responseDTO; + } + }catch (Exception e){ + e.printStackTrace(); + return ResponseDTO.userErrorParam(); + }finally { + WxMaConfigHolder.remove();//清理ThreadLocal + } + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxPortalController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxPortalController.java new file mode 100644 index 0000000..a0b62dd --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/controller/WxPortalController.java @@ -0,0 +1,109 @@ +package net.lab1024.sa.admin.module.wx.miniapp.controller; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.WxMaMessage; +import cn.binarywang.wx.miniapp.constant.WxMaConstants; +import cn.binarywang.wx.miniapp.message.WxMaMessageRouter; +import cn.binarywang.wx.miniapp.util.WxMaConfigHolder; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.*; + +import java.util.Objects; + +/** + * @author Binary Wang + */ +@RestController +@AllArgsConstructor +@RequestMapping("/wx/portal/{appid}") +@Slf4j +public class WxPortalController { + private final WxMaService wxMaService; + private final WxMaMessageRouter wxMaMessageRouter; + + @GetMapping(produces = "text/plain;charset=utf-8") + public String authGet(@PathVariable String appid, + @RequestParam(name = "signature", required = false) String signature, + @RequestParam(name = "timestamp", required = false) String timestamp, + @RequestParam(name = "nonce", required = false) String nonce, + @RequestParam(name = "echostr", required = false) String echostr) { + log.info("\n接收到来自微信服务器的认证消息:signature = [{}], timestamp = [{}], nonce = [{}], echostr = [{}]", + signature, timestamp, nonce, echostr); + + if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) { + throw new IllegalArgumentException("请求参数非法,请核实!"); + } + + if (!wxMaService.switchover(appid)) { + throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); + } + + if (wxMaService.checkSignature(timestamp, nonce, signature)) { + WxMaConfigHolder.remove();//清理ThreadLocal + return echostr; + } + WxMaConfigHolder.remove();//清理ThreadLocal + return "非法请求"; + } + + @PostMapping(produces = "application/xml; charset=UTF-8") + public String post(@PathVariable String appid, + @RequestBody String requestBody, + @RequestParam(name = "msg_signature", required = false) String msgSignature, + @RequestParam(name = "encrypt_type", required = false) String encryptType, + @RequestParam(name = "signature", required = false) String signature, + @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce) { + log.info("\n接收微信请求:[msg_signature=[{}], encrypt_type=[{}], signature=[{}]," + + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", + msgSignature, encryptType, signature, timestamp, nonce, requestBody); + + if (!wxMaService.switchover(appid)) { + throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); + } + + final boolean isJson = Objects.equals(wxMaService.getWxMaConfig().getMsgDataFormat(), + WxMaConstants.MsgDataFormat.JSON); + if (StringUtils.isBlank(encryptType)) { + // 明文传输的消息 + WxMaMessage inMessage; + if (isJson) { + inMessage = WxMaMessage.fromJson(requestBody); + } else {//xml + inMessage = WxMaMessage.fromXml(requestBody); + } + + this.route(inMessage); + WxMaConfigHolder.remove();//清理ThreadLocal + return "success"; + } + + if ("aes".equals(encryptType)) { + // 是aes加密的消息 + WxMaMessage inMessage; + if (isJson) { + inMessage = WxMaMessage.fromEncryptedJson(requestBody, wxMaService.getWxMaConfig()); + } else {//xml + inMessage = WxMaMessage.fromEncryptedXml(requestBody, wxMaService.getWxMaConfig(), + timestamp, nonce, msgSignature); + } + + this.route(inMessage); + WxMaConfigHolder.remove();//清理ThreadLocal + return "success"; + } + WxMaConfigHolder.remove();//清理ThreadLocal + throw new RuntimeException("不可识别的加密类型:" + encryptType); + } + + private void route(WxMaMessage message) { + try { + wxMaMessageRouter.route(message); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/error/ErrorController.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/error/ErrorController.java new file mode 100644 index 0000000..e1e07c7 --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/error/ErrorController.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.admin.module.wx.miniapp.error; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + *
+ * 出错页面控制器
+ * Created by Binary Wang on 2018/8/25.
+ * 
+ * + * @author Binary Wang + */ +@Controller +@RequestMapping("/error") +public class ErrorController { + + @GetMapping(value = "/404") + public String error404() { + return "error"; + } + + @GetMapping(value = "/500") + public String error500() { + return "error"; + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/error/ErrorPageConfiguration.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/error/ErrorPageConfiguration.java new file mode 100644 index 0000000..0b6fdda --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/error/ErrorPageConfiguration.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.admin.module.wx.miniapp.error; + +import org.springframework.boot.web.server.ErrorPage; +import org.springframework.boot.web.server.ErrorPageRegistrar; +import org.springframework.boot.web.server.ErrorPageRegistry; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; + +/** + *
+ * 配置错误状态与对应访问路径
+ * Created by Binary Wang on 2018/8/25.
+ * 
+ * + * @author Binary Wang + */ +@Component +public class ErrorPageConfiguration implements ErrorPageRegistrar { + @Override + public void registerErrorPages(ErrorPageRegistry errorPageRegistry) { + errorPageRegistry.addErrorPages( + new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"), + new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500") + ); + } + +} diff --git a/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/utils/JsonUtils.java b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/utils/JsonUtils.java new file mode 100644 index 0000000..93520fa --- /dev/null +++ b/sa-admin/src/main/java/net/lab1024/sa/admin/module/wx/miniapp/utils/JsonUtils.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.admin.module.wx.miniapp.utils; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +/** + * @author Binary Wang + */ +public class JsonUtils { + private static final ObjectMapper JSON = new ObjectMapper(); + + static { + JSON.setSerializationInclusion(Include.NON_NULL); + JSON.configure(SerializationFeature.INDENT_OUTPUT, Boolean.TRUE); + } + + public static String toJson(Object obj) { + try { + return JSON.writeValueAsString(obj); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + + return null; + } +} diff --git a/sa-admin/src/main/resources/dev/application.yaml b/sa-admin/src/main/resources/dev/application.yaml new file mode 100644 index 0000000..1c323d3 --- /dev/null +++ b/sa-admin/src/main/resources/dev/application.yaml @@ -0,0 +1,43 @@ +server: + servlet: + context-path: '/api' + port: 7001 + # tomcat 配置,主要用于 配置 访问日志(便于将来排查错误) + tomcat: + basedir: ./logs/smart_admin_v2/dev/tomcat-logs + accesslog: + enabled: true + pattern: '%t %{X-Forwarded-For}i %a "%r" %s %D (%D ms)' + +spring: + profiles: + active: '@profiles.active@' + +# 项目配置 +project: + name: sa-admin + module: net.lab1024.sa.admin.module + +# swagger文档 +swagger: + host: localhost:${server.port} + tag-class: net.lab1024.sa.admin.constant.AdminSwaggerTagConst + +wx: + miniapp: + configs: + - appid: wx415cbcf96f4a3b27 + secret: d486dfaac69dac3638d97fe6c723f9cb + #token: #微信小程序消息服务器配置的token + #aesKey: #微信小程序消息服务器配置的EncodingAESKey + msgDataFormat: JSON + +igandan: + wx: + host: https://dev-wx.igandan.com/ +# token: XUUHml5iQ9mlFsa8QqOwyBrLI2nGGGxJ +# host: http://192.168.100.40:8083/ + token: XUUHml5iQ9mlFsa8QqOwyBrLI2nGGGxJ + platform: case + doc: + host: https://dev-doc.igandan.com/app/ \ No newline at end of file diff --git a/sa-admin/src/main/resources/dev/log4j2.xml b/sa-admin/src/main/resources/dev/log4j2.xml new file mode 100644 index 0000000..535219e --- /dev/null +++ b/sa-admin/src/main/resources/dev/log4j2.xml @@ -0,0 +1,99 @@ + + + + + ./logs/smart_admin_v2/dev + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/dev/spy.properties b/sa-admin/src/main/resources/dev/spy.properties new file mode 100644 index 0000000..9877f62 --- /dev/null +++ b/sa-admin/src/main/resources/dev/spy.properties @@ -0,0 +1,18 @@ +#相关的包 +modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory +# 日志格式 +logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger +#日志输出到控制台 +appender=com.p6spy.engine.spy.appender.StdoutLogger +# 设置 p6spy driver 代理 +deregisterdrivers=true +# 取消JDBC URL前缀 +useprefix=true +# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset. +excludecategories=info,debug,result,commit,resultset +# 日期格式 +dateformat=yyyy-MM-dd HH:mm:ss +# 开启慢sql +outagedetection=true +# 慢SQL记录标准(单位秒) +outagedetectioninterval=2 \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/app/expert/ExpertMapper.xml b/sa-admin/src/main/resources/mapper/app/expert/ExpertMapper.xml new file mode 100644 index 0000000..b247ae2 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/app/expert/ExpertMapper.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/app/medicalrecord/MedicalRecordDpmasMapper.xml b/sa-admin/src/main/resources/mapper/app/medicalrecord/MedicalRecordDpmasMapper.xml new file mode 100644 index 0000000..ecc9910 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/app/medicalrecord/MedicalRecordDpmasMapper.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/app/medicalrecord/MedicalRecordMapper.xml b/sa-admin/src/main/resources/mapper/app/medicalrecord/MedicalRecordMapper.xml new file mode 100644 index 0000000..d93e431 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/app/medicalrecord/MedicalRecordMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/area/AreaMapper.xml b/sa-admin/src/main/resources/mapper/business/area/AreaMapper.xml new file mode 100644 index 0000000..68d34f2 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/area/AreaMapper.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/bankcard/CaseplatformBankMapper.xml b/sa-admin/src/main/resources/mapper/business/bankcard/CaseplatformBankMapper.xml new file mode 100644 index 0000000..22bd114 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/bankcard/CaseplatformBankMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/captcha/CaptchaMapper.xml b/sa-admin/src/main/resources/mapper/business/captcha/CaptchaMapper.xml new file mode 100644 index 0000000..34dfb3a --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/captcha/CaptchaMapper.xml @@ -0,0 +1,13 @@ + + + + + + + + delete from t_captcha where captcha_key = #{captchaKey} + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/caseplatformcase/CaseplatformCaseMapper.xml b/sa-admin/src/main/resources/mapper/business/caseplatformcase/CaseplatformCaseMapper.xml new file mode 100644 index 0000000..4a7bd6a --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/caseplatformcase/CaseplatformCaseMapper.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/caseplatformcaseabstrac/CaseplatformCaseAbstracMapper.xml b/sa-admin/src/main/resources/mapper/business/caseplatformcaseabstrac/CaseplatformCaseAbstracMapper.xml new file mode 100644 index 0000000..db168f8 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/caseplatformcaseabstrac/CaseplatformCaseAbstracMapper.xml @@ -0,0 +1,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/caseplatformcasecheckdata/CaseplatformCaseCheckdataMapper.xml b/sa-admin/src/main/resources/mapper/business/caseplatformcasecheckdata/CaseplatformCaseCheckdataMapper.xml new file mode 100644 index 0000000..d06068a --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/caseplatformcasecheckdata/CaseplatformCaseCheckdataMapper.xml @@ -0,0 +1,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/caseplatformcasedpms/CaseplatformCaseDpmsMapper.xml b/sa-admin/src/main/resources/mapper/business/caseplatformcasedpms/CaseplatformCaseDpmsMapper.xml new file mode 100644 index 0000000..313c190 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/caseplatformcasedpms/CaseplatformCaseDpmsMapper.xml @@ -0,0 +1,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/caseplatformuser/CaseplatformUserMapper.xml b/sa-admin/src/main/resources/mapper/business/caseplatformuser/CaseplatformUserMapper.xml new file mode 100644 index 0000000..f505246 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/caseplatformuser/CaseplatformUserMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/category/CategoryMapper.xml b/sa-admin/src/main/resources/mapper/business/category/CategoryMapper.xml new file mode 100644 index 0000000..908509c --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/category/CategoryMapper.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/goods/GoodsMapper.xml b/sa-admin/src/main/resources/mapper/business/goods/GoodsMapper.xml new file mode 100644 index 0000000..7fcadcc --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/goods/GoodsMapper.xml @@ -0,0 +1,41 @@ + + + + + update t_goods + set deleted_flag = #{deletedFlag} + WHERE goods_id IN + + #{item} + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/notice/NoticeMapper.xml b/sa-admin/src/main/resources/mapper/business/notice/NoticeMapper.xml new file mode 100644 index 0000000..580bb9b --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/notice/NoticeMapper.xml @@ -0,0 +1,69 @@ + + + + + UPDATE t_notice + SET watch_amount = watch_amount + 1 + WHERE notice_id = #{noticeId} + + + UPDATE t_notice + SET deleted_flag = #{deletedFlag} + WHERE notice_id IN + + #{item} + + + + UPDATE t_notice + SET notice_type = #{noticeType}, + notice_belong_type = #{noticeBelongType}, + notice_title = #{noticeTitle}, + notice_content = #{noticeContent}, + link_address = #{linkAddress}, + cover_file_key = #{coverFileKey}, + accessory_file_keys = #{accessoryFileKeys}, + top_flag = #{topFlag}, + publish_time = #{publishTime}, + disabled_flag = #{disabledFlag} + WHERE notice_id = #{noticeId} + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/oa/bank/BankMapper.xml b/sa-admin/src/main/resources/mapper/business/oa/bank/BankMapper.xml new file mode 100644 index 0000000..79b505d --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/oa/bank/BankMapper.xml @@ -0,0 +1,58 @@ + + + + + UPDATE t_oa_bank + SET deleted_flag = #{deletedFlag} + WHERE bank_id = #{bankId} + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseEmployeeMapper.xml b/sa-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseEmployeeMapper.xml new file mode 100644 index 0000000..62acf08 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseEmployeeMapper.xml @@ -0,0 +1,94 @@ + + + + + + delete from t_oa_enterprise_employee where enterprise_id = #{enterpriseId} and employee_id in + + #{item} + + + + + delete from t_oa_enterprise_employee where employee_id = #{employeeId} + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseMapper.xml b/sa-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseMapper.xml new file mode 100644 index 0000000..11ed88a --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/oa/enterprise/EnterpriseMapper.xml @@ -0,0 +1,59 @@ + + + + + UPDATE t_oa_enterprise + SET deleted_flag = #{deletedFlag} + WHERE enterprise_id = #{enterpriseId} + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/oa/invoice/InvoiceMapper.xml b/sa-admin/src/main/resources/mapper/business/oa/invoice/InvoiceMapper.xml new file mode 100644 index 0000000..0001d92 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/oa/invoice/InvoiceMapper.xml @@ -0,0 +1,56 @@ + + + + + UPDATE t_oa_invoice + SET deleted_flag = #{deletedFlag} + WHERE invoice_id = #{invoiceId} + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/oa/notice/NoticeDao.xml b/sa-admin/src/main/resources/mapper/business/oa/notice/NoticeDao.xml new file mode 100644 index 0000000..11a97d6 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/oa/notice/NoticeDao.xml @@ -0,0 +1,246 @@ + + + + + + + + insert into t_notice_visible_range + (notice_id, data_type, data_id) + values + + ( #{noticeId} , #{item.dataType}, #{item.dataId} ) + + + + delete + from t_notice_visible_range + where notice_id = #{noticeId} + + + + + + + update t_notice + set deleted_flag = true + where notice_id = #{noticeId} + + + + + + + + + + + + + + insert into t_notice_view_record (notice_id, employee_id, first_ip, first_user_agent, page_view_count) + values (#{noticeId}, #{employeeId}, #{ip}, #{userAgent}, #{pageViewCount}) + + + update t_notice_view_record + set page_view_count = page_view_count + 1, + last_ip = #{ip}, + last_user_agent = #{userAgent} + where notice_id = #{noticeId} + and employee_id = #{employeeId} + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/statistics/StatisticMapper.xml b/sa-admin/src/main/resources/mapper/business/statistics/StatisticMapper.xml new file mode 100644 index 0000000..a4d7123 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/statistics/StatisticMapper.xml @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/business/token/TokenMapper.xml b/sa-admin/src/main/resources/mapper/business/token/TokenMapper.xml new file mode 100644 index 0000000..a4fbab2 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/business/token/TokenMapper.xml @@ -0,0 +1,13 @@ + + + + + + + + delete from t_token where token_key = #{captchaKey} + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/system/department/DepartmentMapper.xml b/sa-admin/src/main/resources/mapper/system/department/DepartmentMapper.xml new file mode 100644 index 0000000..326d94f --- /dev/null +++ b/sa-admin/src/main/resources/mapper/system/department/DepartmentMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/system/employee/EmployeeMapper.xml b/sa-admin/src/main/resources/mapper/system/employee/EmployeeMapper.xml new file mode 100644 index 0000000..24f5eeb --- /dev/null +++ b/sa-admin/src/main/resources/mapper/system/employee/EmployeeMapper.xml @@ -0,0 +1,200 @@ + + + + + + + + + UPDATE t_employee + SET disabled_flag = #{disabledFlag} + WHERE employee_id = #{employeeId} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UPDATE t_employee + SET login_pwd = #{password} + WHERE employee_id = #{employeeId} + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/system/menu/MenuMapper.xml b/sa-admin/src/main/resources/mapper/system/menu/MenuMapper.xml new file mode 100644 index 0000000..68fbede --- /dev/null +++ b/sa-admin/src/main/resources/mapper/system/menu/MenuMapper.xml @@ -0,0 +1,78 @@ + + + + + + + + update t_menu + set deleted_flag = #{deletedFlag}, + update_user_id = #{updateUserId} + where menu_id = #{item} + + + + + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/system/role/RoleDataScopeMapper.xml b/sa-admin/src/main/resources/mapper/system/role/RoleDataScopeMapper.xml new file mode 100644 index 0000000..b9f5bcf --- /dev/null +++ b/sa-admin/src/main/resources/mapper/system/role/RoleDataScopeMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + DELETE FROM t_role_data_scope + WHERE role_id = #{roleId} + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/system/role/RoleEmployeeMapper.xml b/sa-admin/src/main/resources/mapper/system/role/RoleEmployeeMapper.xml new file mode 100644 index 0000000..ae1e7b5 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/system/role/RoleEmployeeMapper.xml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + DELETE + FROM t_role_employee + WHERE employee_id = #{employeeId} + + + + + DELETE + FROM t_role_employee + WHERE role_id = #{roleId} + + + + DELETE + FROM t_role_employee + WHERE role_id = #{roleId} + and employee_id = #{employeeId} + + + + + DELETE FROM t_role_employee + WHERE role_id = #{roleId} and employee_id in + + #{item} + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/system/role/RoleMapper.xml b/sa-admin/src/main/resources/mapper/system/role/RoleMapper.xml new file mode 100644 index 0000000..9538c5e --- /dev/null +++ b/sa-admin/src/main/resources/mapper/system/role/RoleMapper.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + insert into t_role_prov(role_id, prov_id) values + + (#{updateDTO.roleId}, #{item}) + + + + + + delete + from t_role_prov + where role_id = #{roleId} + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/system/role/RoleMenuMapper.xml b/sa-admin/src/main/resources/mapper/system/role/RoleMenuMapper.xml new file mode 100644 index 0000000..12b84f0 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/system/role/RoleMenuMapper.xml @@ -0,0 +1,42 @@ + + + + + delete + from t_role_menu + where role_id = #{roleId} + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/mapper/system/role/RoleProvMapper.xml b/sa-admin/src/main/resources/mapper/system/role/RoleProvMapper.xml new file mode 100644 index 0000000..7247e20 --- /dev/null +++ b/sa-admin/src/main/resources/mapper/system/role/RoleProvMapper.xml @@ -0,0 +1,36 @@ + + + + + + insert into t_role_prov(role_id, prov_id) values + + (#{updateDTO.roleId}, #{item}) + + + + + + delete + from t_role_prov + where role_id = #{roleId} + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/pre/application.yaml b/sa-admin/src/main/resources/pre/application.yaml new file mode 100644 index 0000000..5a05e58 --- /dev/null +++ b/sa-admin/src/main/resources/pre/application.yaml @@ -0,0 +1,41 @@ +server: + servlet: + context-path: '/api' + port: 7001 + # tomcat 配置,主要用于 配置 访问日志(便于将来排查错误) + tomcat: + basedir: ${localPath:/home}/logs/smart_admin_v2/pre/tomcat-logs + accesslog: + enabled: true + pattern: '%t %{X-Forwarded-For}i %a "%r" %s %D (%D ms)' + +spring: + profiles: + active: '@profiles.active@' + +# 项目配置 +project: + name: sa-admin + module: net.lab1024.sa.admin.module + +# swagger文档 +swagger: + host: localhost:${server.port} + tag-class: net.lab1024.sa.admin.constant.AdminSwaggerTagConst + +wx: + miniapp: + configs: + - appid: wx415cbcf96f4a3b27 + secret: d486dfaac69dac3638d97fe6c723f9cb + #token: #微信小程序消息服务器配置的token + #aesKey: #微信小程序消息服务器配置的EncodingAESKey + msgDataFormat: JSON + +igandan: + wx: + host: https://wx.igandan.com/ + token: zd8V2LYD4achjFZrbHgD2PuzKuthDCVx + platform: case + doc: + host: https://doc.igandan.com/app/ \ No newline at end of file diff --git a/sa-admin/src/main/resources/pre/log4j2.xml b/sa-admin/src/main/resources/pre/log4j2.xml new file mode 100644 index 0000000..70c3f92 --- /dev/null +++ b/sa-admin/src/main/resources/pre/log4j2.xml @@ -0,0 +1,99 @@ + + + + + $${env:localPath:-/home}/logs/smart_admin_v2/pre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/prod/application.yaml b/sa-admin/src/main/resources/prod/application.yaml new file mode 100644 index 0000000..338ca5c --- /dev/null +++ b/sa-admin/src/main/resources/prod/application.yaml @@ -0,0 +1,35 @@ +server: + servlet: + context-path: '/api' + port: 7001 + +spring: + profiles: + active: '@profiles.active@' + +# 项目配置 +project: + name: sa-admin + module: net.lab1024.sa.admin.module + +# swagger文档 +swagger: + host: localhost:${server.port} + tag-class: net.lab1024.sa.admin.constant.AdminSwaggerTagConst + +wx: + miniapp: + configs: + - appid: wx415cbcf96f4a3b27 + secret: d486dfaac69dac3638d97fe6c723f9cb + #token: #微信小程序消息服务器配置的token + #aesKey: #微信小程序消息服务器配置的EncodingAESKey + msgDataFormat: JSON + +igandan: + wx: + host: https://wx.igandan.com/ + token: zd8V2LYD4achjFZrbHgD2PuzKuthDCVx + platform: case + doc: + host: https://doc.igandan.com/app/ \ No newline at end of file diff --git a/sa-admin/src/main/resources/prod/log4j2.xml b/sa-admin/src/main/resources/prod/log4j2.xml new file mode 100644 index 0000000..2d87334 --- /dev/null +++ b/sa-admin/src/main/resources/prod/log4j2.xml @@ -0,0 +1,99 @@ + + + + + /web/medical-case/logs/case_admin/prod + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/test/application.yaml b/sa-admin/src/main/resources/test/application.yaml new file mode 100644 index 0000000..ed1599f --- /dev/null +++ b/sa-admin/src/main/resources/test/application.yaml @@ -0,0 +1,41 @@ +server: + servlet: + context-path: '/api' + port: 7001 + # tomcat 配置,主要用于 配置 访问日志(便于将来排查错误) + tomcat: + basedir: ${localPath:/home}/logs/smart_admin_v2/test/tomcat-logs + accesslog: + enabled: true + pattern: '%t %{X-Forwarded-For}i %a "%r" %s %D (%D ms)' + +spring: + profiles: + active: '@profiles.active@' + +# 项目配置 +project: + name: sa-admin + module: net.lab1024.sa.admin.module + +# swagger文档 +swagger: + host: localhost:${server.port} + tag-class: net.lab1024.sa.admin.constant.AdminSwaggerTagConst + +wx: + miniapp: + configs: + - appid: wx415cbcf96f4a3b27 + secret: d486dfaac69dac3638d97fe6c723f9cb + #token: #微信小程序消息服务器配置的token + #aesKey: #微信小程序消息服务器配置的EncodingAESKey + msgDataFormat: JSON + +igandan: + wx: + host: https://dev-wx.igandan.com/ + token: XUUHml5iQ9mlFsa8QqOwyBrLI2nGGGxJ + platform: case + doc: + host: https://dev-doc.igandan.com/app/ \ No newline at end of file diff --git a/sa-admin/src/main/resources/test/log4j2.xml b/sa-admin/src/main/resources/test/log4j2.xml new file mode 100644 index 0000000..104e8cf --- /dev/null +++ b/sa-admin/src/main/resources/test/log4j2.xml @@ -0,0 +1,99 @@ + + + + + ./logs/smart_admin_v2/test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sa-admin/src/main/resources/test/spy.properties b/sa-admin/src/main/resources/test/spy.properties new file mode 100644 index 0000000..9877f62 --- /dev/null +++ b/sa-admin/src/main/resources/test/spy.properties @@ -0,0 +1,18 @@ +#相关的包 +modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory +# 日志格式 +logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger +#日志输出到控制台 +appender=com.p6spy.engine.spy.appender.StdoutLogger +# 设置 p6spy driver 代理 +deregisterdrivers=true +# 取消JDBC URL前缀 +useprefix=true +# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset. +excludecategories=info,debug,result,commit,resultset +# 日期格式 +dateformat=yyyy-MM-dd HH:mm:ss +# 开启慢sql +outagedetection=true +# 慢SQL记录标准(单位秒) +outagedetectioninterval=2 \ No newline at end of file diff --git a/sa-admin/src/test/java/net/lab1024/sa/admin/SmartAdminApplicationTest.java b/sa-admin/src/test/java/net/lab1024/sa/admin/SmartAdminApplicationTest.java new file mode 100644 index 0000000..f337433 --- /dev/null +++ b/sa-admin/src/test/java/net/lab1024/sa/admin/SmartAdminApplicationTest.java @@ -0,0 +1,77 @@ +package net.lab1024.sa.admin; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.util.Base64; +import java.util.Map; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +public class SmartAdminApplicationTest { + + @Value("${token.key}") + private String tokenKey; + + @BeforeEach + public void before() { + System.out.println("----------------------- 测试开始 -----------------------"); + + } + + @AfterEach + public void after() { + System.out.println("----------------------- 测试结束 -----------------------"); + } + + public static String getResultSign(String key, String body) throws Exception { + Mac hmacSha256 = Mac.getInstance("HmacSHA256"); + SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256"); + hmacSha256.init(secret_key); + return Base64.getEncoder().encodeToString(hmacSha256.doFinal(body.getBytes())); + } + + @Test + public void test12() throws Exception { + String key = "123654"; + // 请确保 body 为您收到回调请求的原始包体,不要做任何转化,需要完整保留\n\t转移字符,示例如下: + String body = "{\n" + "\t\"EventGroupId\":\t2,\n" + "\t\"EventType\":\t204,\n" + "\t\"CallbackTs\":\t1664209748188,\n" + "\t\"EventInfo\":\t{\n" + "\t\t\"RoomId\":\t8489,\n" + "\t\t\"EventTs\":\t1664209748,\n" + "\t\t\"EventMsTs\":\t1664209748180,\n" + "\t\t\"UserId\":\t\"user_85034614\",\n" + "\t\t\"Reason\":\t0\n" + "\t}\n" + "}"; + String Sign = "kkoFeO3Oh2ZHnjtg8tEAQhtXK16/KI05W3BQff8IvGA="; + String resultSign = getResultSign(key, body); + + if (resultSign.equals(Sign)) { + System.out.println("{'Status': 'OK', 'Info': '校验通过'}"); + } else { + System.out.println("{'Status': 'FAIL', 'Info': '校验失败'}"); + } + + System.out.println("https://medical-case.oss-cn-beijing.aliyuncs.com//sign/10/076436c3-9096-4b14-bef4-5cd3623fc943.png".length()); + } + @Test + public void test1(){ + String token = "eyJhbGciOiJIUzUxMiJ9.eyJpZCI6NSwibmFtZSI6IkFBVyIsInR5cGUiOjIsImRldmljZSI6NSwic3VwZXJQYXNzd29yZEZsYWciOmZhbHNlLCJpYXQiOjE3MDYyNTQ5NTQsImV4cCI6MTcwNjg1OTc1NH0.eQScNydlCvv8iGwg_j2tSVvrF_vyu4CevFaTyGOfWfTUMr4dxrqRujv0cyxPboLNA_1VBEWMgXacVJkXC_D-Pw"; + String token1 = "eyJhbGciOiJIUzUxMiJ9.eyJpZCI6NSwibmFtZSI6IkFBVyIsInR5cGUiOjIsImRldmljZSI6NSwic3VwZXJQYXNzd29yZEZsYWciOmZhbHNlLCJpYXQiOjE3MDYyNTQ5NTQsImV4cCI6MTcwNjg1OTc1NH0.eQScNydlCvv8iGwg_j2tSVvrF_vyu4CevFaTyGOfWfTUMr4dxrqRujv0cyxPboLNA_1VBEWMgXacVJkXC_D-Pw"; + System.out.println(token1.equals(token)); + try { + Claims body = Jwts.parser() + .setSigningKey("sa-jwt-key") + .parseClaimsJws(token) + .getBody(); + System.out.println(body); + } catch (Exception e) { + e.printStackTrace(); + } + } + + +} + diff --git a/sa-common/pom.xml b/sa-common/pom.xml new file mode 100644 index 0000000..5359c9a --- /dev/null +++ b/sa-common/pom.xml @@ -0,0 +1,267 @@ + + 4.0.0 + + net.1024lab + sa-parent + 1.0.0 + ../pom.xml + + + sa-case-common + 1.0.0 + + sa-case-common + sa-case-common project + + + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-logging + + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-starter + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + org.apache.logging.log4j + log4j-spring-boot + + + + org.apache.logging.log4j + log4j-web + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.springframework.boot + spring-boot-starter-test + + + + mysql + mysql-connector-java + + + + com.github.ben-manes.caffeine + caffeine + + + error_prone_annotations + com.google.errorprone + + + + + + org.projectlombok + lombok + + + + org.apache.commons + commons-pool2 + + + + org.springframework + spring-mock + + + + com.baomidou + mybatis-plus-boot-starter + + + + p6spy + p6spy + + + + io.springfox + springfox-swagger2 + + + + com.squareup.okhttp3 + okhttp + + + + io.springfox + springfox-swagger-ui + + + + com.alibaba + fastjson + + + + com.alibaba + druid + + + + com.google.guava + guava + + + + com.github.penggle + kaptcha + + + + + cn.afterturn + easypoi-spring-boot-starter + + + + cn.afterturn + easypoi-web + + + + + com.googlecode.concurrentlinkedhashmap + concurrentlinkedhashmap-lru + + + + org.reflections + reflections + + + + com.amazonaws + aws-java-sdk-s3 + + + + + + + + + org.apache.poi + poi-scratchpad + + + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-collections4 + + + + commons-io + commons-io + + + + cn.hutool + hutool-all + + + + io.jsonwebtoken + jjwt + + + + com.auth0 + jwks-rsa + + + org.apache.velocity + velocity-engine-core + + + + org.apache.velocity.tools + velocity-tools-generic + + + + com.alibaba + easyexcel + + + + + + net.dreamlu + mica-core + 2.6.0 + + + net.dreamlu + mica-xss + 2.6.0 + + + + + org.apache.httpcomponents + httpclient + + + + commons-io + commons-io + 2.11.0 + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/annoation/NoNeedLogin.java b/sa-common/src/main/java/net/lab1024/sa/common/common/annoation/NoNeedLogin.java new file mode 100644 index 0000000..e810062 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/annoation/NoNeedLogin.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.common.common.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 不需要登录注解 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface NoNeedLogin { +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/annoation/SaAuth.java b/sa-common/src/main/java/net/lab1024/sa/common/common/annoation/SaAuth.java new file mode 100644 index 0000000..4d44a2f --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/annoation/SaAuth.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.common.common.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 校验权限注解 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface SaAuth { + + String saAuth = "saAuth"; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/code/AppErrorCode.java b/sa-common/src/main/java/net/lab1024/sa/common/common/code/AppErrorCode.java new file mode 100644 index 0000000..e46e66f --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/code/AppErrorCode.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.common.common.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum AppErrorCode implements ErrorCode { + + PARAM_ERROR(40001, "参数错误"), + + DATA_NOT_EXIST(40002, "左翻右翻,数据竟然找不到了~"), + + ALREADY_EXIST(40003, "数据已存在了呀~"), + + REPEAT_SUBMIT(40004, "亲~您操作的太快了,请稍等下再操作~"), + + NO_PERMISSION(40005, "对不起,您无法访问此资源哦~"), + + DEVELOPING(40006, "系統正在紧急开发中,敬请期待~"), + + LOGIN_STATE_INVALID(40007, "您还未登录或登录失效,请重新登录!"), + + USER_STATUS_ERROR(40008, "用户状态异常"), + + FORM_REPEAT_SUBMIT(40009, "请勿重复提交"); + + private final int code; + + private final String msg; + + private final String level; + + AppErrorCode(int code, String msg) { + this.code = code; + this.msg = msg; + this.level = LEVEL_USER; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCode.java b/sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCode.java new file mode 100644 index 0000000..f67cc95 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCode.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.common.common.code; + +/** + * 错误码
+ * 一共分为三种: 1)系统错误、2)用户级别错误、3)未预期到的错误 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public interface ErrorCode { + + /** + * 系统等级 + */ + String LEVEL_SYSTEM = "system"; + + /** + * 用户等级 + */ + String LEVEL_USER = "user"; + + /** + * 未预期到的等级 + */ + String LEVEL_UNEXPECTED = "unexpected"; + + /** + * 错误码 + * + * @return + */ + int getCode(); + + /** + * 错误消息 + * + * @return + */ + String getMsg(); + + /** + * 错误等级 + * + * @return + */ + String getLevel(); + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCodeRangeContainer.java b/sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCodeRangeContainer.java new file mode 100644 index 0000000..db8cce8 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCodeRangeContainer.java @@ -0,0 +1,119 @@ +package net.lab1024.sa.common.common.code; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 错误码 注册容器 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/09/27 22:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +class ErrorCodeRangeContainer { + + /** + * 所有的错误码均大于10000 + */ + static final int MIN_START_CODE = 10000; + + static final Map, ImmutablePair> CODE_RANGE_MAP = new ConcurrentHashMap<>(); + + /** + * 用于统计数量 + */ + static int errorCounter = 0; + + /** + * 注册状态码 + * 校验是否重复 是否越界 + * + * @param clazz + * @param start + * @param end + */ + static void register(Class clazz, int start, int end) { + String simpleName = clazz.getSimpleName(); + if (!clazz.isEnum()) { + throw new ExceptionInInitializerError(String.format("<> error: %s not Enum class !", simpleName)); + } + if (start > end) { + throw new ExceptionInInitializerError(String.format("<> error: %s start must be less than the end !", simpleName)); + } + + if (start <= MIN_START_CODE) { + throw new ExceptionInInitializerError(String.format("<> error: %s start must be more than %s !", simpleName, MIN_START_CODE)); + } + + // 校验是否重复注册 + boolean containsKey = CODE_RANGE_MAP.containsKey(clazz); + if (containsKey) { + throw new ExceptionInInitializerError(String.format("<> error: Enum %s already exist !", simpleName)); + } + + // 校验 开始结束值 是否越界 + CODE_RANGE_MAP.forEach((k, v) -> { + if (isExistOtherRange(start, end, v)) { + throw new IllegalArgumentException(String.format("<> error: %s[%d,%d] has intersection with class:%s[%d,%d]", simpleName, start, end, + k.getSimpleName(), v.getLeft(), v.getRight())); + } + }); + + // 循环校验code并存储 + List codeList = Stream.of(clazz.getEnumConstants()).map(codeEnum -> { + Integer code = codeEnum.getCode(); + if (code < start || code > end) { + throw new IllegalArgumentException(String.format("<> error: %s[%d,%d] code %d out of range", simpleName, start, end, code)); + } + return code; + }).collect(Collectors.toList()); + + // 校验code是否重复 + List distinctCodeList = codeList.stream().distinct().collect(Collectors.toList()); + Collection subtract = CollectionUtils.subtract(codeList, distinctCodeList); + if (CollectionUtils.isNotEmpty(subtract)) { + throw new IllegalArgumentException(String.format("<> error: %s code %s is repeat!", simpleName, subtract)); + } + + CODE_RANGE_MAP.put(clazz, ImmutablePair.of(start, end)); + // 统计 + errorCounter = errorCounter + distinctCodeList.size(); + } + + /** + * 是否存在于其他范围 + * + * @param start + * @param end + * @param range + * @return + */ + private static boolean isExistOtherRange(int start, int end, ImmutablePair range) { + if (start >= range.getLeft() && start <= range.getRight()) { + return true; + } + + if (end >= range.getLeft() && end <= range.getRight()) { + return true; + } + + return false; + } + + /** + * 进行初始化 + */ + static int initialize() { + return errorCounter; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCodeRegister.java b/sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCodeRegister.java new file mode 100644 index 0000000..f8a2a75 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/code/ErrorCodeRegister.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.common.common.code; + +import static net.lab1024.sa.common.common.code.ErrorCodeRangeContainer.register; + +/** + * 注册code状态码
+ * ps:为什么要在此处不那么优雅的手动注册? + * 主要是为了能统一、清晰、浏览当前定义的所有状态码 + * 方便后续维护 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/09/27 23:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class ErrorCodeRegister { + + static { + + // 系统 错误码 + register(SystemErrorCode.class, 10001, 20000); + + // 意外 错误码 + register(UnexpectedErrorCode.class, 20001, 30000); + + // 用户 通用错误码 + register(UserErrorCode.class, 30001, 40000); + + // app 通用错误码 + register(AppErrorCode.class, 40001, 50000); + + } + + + public static int initialize() { + return ErrorCodeRangeContainer.initialize(); + } + + public static void main(String[] args) { + ErrorCodeRegister.initialize(); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/code/SystemErrorCode.java b/sa-common/src/main/java/net/lab1024/sa/common/common/code/SystemErrorCode.java new file mode 100644 index 0000000..f3fc67e --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/code/SystemErrorCode.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.common.common.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 系统错误状态码(此类返回码应该高度重视) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/10/24 20:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Getter +@AllArgsConstructor +public enum SystemErrorCode implements ErrorCode { + + SYSTEM_ERROR(10001, "系统似乎出现了点小问题"), + + ; + + private final int code; + + private final String msg; + + private final String level; + + SystemErrorCode(int code, String msg) { + this.code = code; + this.msg = msg; + this.level = LEVEL_SYSTEM; + } + +} + diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/code/UnexpectedErrorCode.java b/sa-common/src/main/java/net/lab1024/sa/common/common/code/UnexpectedErrorCode.java new file mode 100644 index 0000000..2fc735d --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/code/UnexpectedErrorCode.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.common.common.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 未预期的错误码(即发生了不可能发生的事情,此类返回码应该高度重视) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/09/27 22:10:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Getter +@AllArgsConstructor +public enum UnexpectedErrorCode implements ErrorCode { + + BUSINESS_HANDING(20001, "呃~ 业务繁忙,请稍后重试"), + PAY_ORDER_ID_ERROR(20002, "付款单id发生了异常,请联系技术人员排查"), + + ; + + private final int code; + + private final String msg; + + private final String level; + + UnexpectedErrorCode(int code, String msg) { + this.code = code; + this.msg = msg; + this.level = LEVEL_UNEXPECTED; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/code/UserErrorCode.java b/sa-common/src/main/java/net/lab1024/sa/common/common/code/UserErrorCode.java new file mode 100644 index 0000000..39869ea --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/code/UserErrorCode.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.common.common.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 用户级别的错误码(用户引起的错误返回码,可以不用关注) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/09/21 22:12:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Getter +@AllArgsConstructor +public enum UserErrorCode implements ErrorCode { + + PARAM_ERROR(30001, "参数错误"), + + DATA_NOT_EXIST(30002, "左翻右翻,数据竟然找不到了~"), + + ALREADY_EXIST(30003, "数据已存在了呀~"), + + REPEAT_SUBMIT(30004, "亲~您操作的太快了,请稍等下再操作~"), + + NO_PERMISSION(30005, "对不起,您无法访问此资源哦~"), + + DEVELOPING(30006, "系統正在紧急开发中,敬请期待~"), + + LOGIN_STATE_INVALID(30007, "您还未登录或登录失效,请重新登录!"), + + USER_STATUS_ERROR(30008, "用户状态异常"), + + FORM_REPEAT_SUBMIT(30009, "请勿重复提交"), + + NO_PERMISSION_EDIT(30010, "该状态不允许修改"), + NO_MODIFY(30011, "该账号无需补充资料"), + PROJECT_CLOSE(30012, "本年度人工肝病例登记项目已结束,谢谢您的关注!"), + ExpertBankVerifyFail(30013, "银行卡认证失败"); + + private final int code; + + private final String msg; + + private final String level; + + UserErrorCode(int code, String msg) { + this.code = code; + this.msg = msg; + this.level = LEVEL_USER; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/constant/RequestHeaderConst.java b/sa-common/src/main/java/net/lab1024/sa/common/common/constant/RequestHeaderConst.java new file mode 100644 index 0000000..674e4dd --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/constant/RequestHeaderConst.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.common.common.constant; + +/** + * 请求消息头常量 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-15 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class RequestHeaderConst { + + public static final String TOKEN = "x-access-token"; + + public static final String USER_AGENT = "user-agent"; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/constant/StringConst.java b/sa-common/src/main/java/net/lab1024/sa/common/common/constant/StringConst.java new file mode 100644 index 0000000..2a40152 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/constant/StringConst.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.common.common.constant; + +/** + * 字符串常量 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-10-14 23:16:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class StringConst { + + /** + * 全局通用分隔符 + */ + public static final String SEPARATOR = ","; + + /** + * 全局通用分隔符 下划线 + */ + public static final String UNDERLINE = "_"; + + /** + * 全局通用 横杠 + */ + public static final String HORIZONTAL = "-"; + + /** + * 全局通用分隔符 + */ + public static final Character SEPARATOR_CHAR = ','; + + /** + * 全局通用分隔符 斜杠 + */ + public static final String SEPARATOR_SLASH = "/"; + + /** + * 空字符串 + */ + public static final String EMPTY = ""; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/controller/SupportBaseController.java b/sa-common/src/main/java/net/lab1024/sa/common/common/controller/SupportBaseController.java new file mode 100644 index 0000000..5c135de --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/controller/SupportBaseController.java @@ -0,0 +1,16 @@ +package net.lab1024.sa.common.common.controller; + +import net.lab1024.sa.common.constant.UrlPrefixConst; +import org.springframework.web.bind.annotation.RequestMapping; +/** + * 支撑类业务路由基类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-04-24 20:43:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@RequestMapping(UrlPrefixConst.SUPPORT) +public class SupportBaseController { +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/domain/DataScopePlugin.java b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/DataScopePlugin.java new file mode 100644 index 0000000..8963f21 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/DataScopePlugin.java @@ -0,0 +1,15 @@ +package net.lab1024.sa.common.common.domain; + +import org.apache.ibatis.plugin.Interceptor; + +/** + * 数据范围 插件 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-11-15 17:20:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public abstract class DataScopePlugin implements Interceptor { +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/domain/PageParam.java b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/PageParam.java new file mode 100644 index 0000000..8ffb7d7 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/PageParam.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.common.common.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.Valid; +import javax.validation.constraints.Max; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 分页基础参数 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020/04/28 16:19 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class PageParam { + + @ApiModelProperty(value = "页码(不能为空)", required = true, example = "1") + @NotNull(message = "分页参数不能为空") + private Integer pageNum; + + @ApiModelProperty(value = "每页数量(不能为空)", required = true, example = "10") + @NotNull(message = "每页数量不能为空") + @Max(value = 200, message = "每页最大为200") + private Integer pageSize; + + @ApiModelProperty("是否查询总条数") + protected Boolean searchCount; + + @ApiModelProperty("排序字段集合") + @Size(max = 10, message = "排序字段最多10") + @Valid + private List sortItemList; + + /** + * 排序DTO类 + */ + @Data + public static class SortItem { + + @ApiModelProperty("true正序|false倒序") + @NotNull(message = "排序规则不能为空") + private Boolean isAsc; + + @ApiModelProperty(value = "排序字段") + @NotBlank(message = "排序字段不能为空") + @Length(max = 30, message = "排序字段最多30") + private String column; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/domain/PageResult.java b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/PageResult.java new file mode 100644 index 0000000..0f75f99 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/PageResult.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.common.common.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 分页返回对象 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020/04/28 16:19 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class PageResult { + + /** + * 当前页 + */ + @ApiModelProperty(value = "当前页") + private Long pageNum; + + /** + * 每页的数量 + */ + @ApiModelProperty(value = "每页的数量") + private Long pageSize; + + /** + * 总记录数 + */ + @ApiModelProperty(value = "总记录数") + private Long total; + + /** + * 总页数 + */ + @ApiModelProperty(value = "总页数") + private Long pages; + + /** + * 结果集 + */ + @ApiModelProperty(value = "结果集") + private List list; + + @ApiModelProperty("是否为空") + private Boolean emptyFlag; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUrlVO.java b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUrlVO.java new file mode 100644 index 0000000..3b8e0be --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUrlVO.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.common.common.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 请求url返回对象 + * + * @Author 1024创新实验室: 李善逸 + * @Date 2021/9/1 20:15 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class RequestUrlVO { + + @ApiModelProperty("注释说明") + private String comment; + + @ApiModelProperty("controller.method") + private String name; + + @ApiModelProperty("url") + private String url; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUser.java b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUser.java new file mode 100644 index 0000000..afce6da --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/RequestUser.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.common.common.domain; + +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; + +/** + * 请求用户 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-12-21 19:55:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public interface RequestUser { + + /** + * 请求用户id + * + * @return + */ + Long getUserId(); + + /** + * 请求用户名称 + * + * @return + */ + String getUserName(); + + /** + * 获取用户类型 + */ + UserTypeEnum getUserType(); + + /** + * 获取请求的IP + * + * @return + */ + String getIp(); + + /** + * 获取请求 user-agent + * + * @return + */ + String getUserAgent(); + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/domain/ResponseDTO.java b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/ResponseDTO.java new file mode 100644 index 0000000..17c8bba --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/ResponseDTO.java @@ -0,0 +1,114 @@ +package net.lab1024.sa.common.common.domain; + + +import lombok.Data; +import net.lab1024.sa.common.common.code.ErrorCode; +import net.lab1024.sa.common.common.code.UserErrorCode; +import org.apache.commons.lang3.StringUtils; + +/** + * 请求返回对象 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-10-31 21:06:11 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class ResponseDTO { + + public static final int OK_CODE = 0; + public static final int APP_OK_CODE = 200; + + public static final String OK_MSG = "success"; + + private Integer code; + + private String level; + + private String msg; + + private Boolean ok; + + private T data; + + public ResponseDTO(Integer code, String level, boolean ok, String msg, T data) { + this.code = code; + this.level = level; + this.ok = ok; + this.msg = msg; + this.data = data; + } + + public ResponseDTO(ErrorCode errorCode, boolean ok, String msg, T data) { + this.code = errorCode.getCode(); + this.level = errorCode.getLevel(); + this.ok = ok; + if (StringUtils.isNotBlank(msg)) { + this.msg = msg; + } else { + this.msg = errorCode.getMsg(); + } + this.data = data; + } + + public static ResponseDTO ok() { + return new ResponseDTO<>(OK_CODE, null, true, OK_MSG, null); + } + + public static ResponseDTO ok(T data) { + return new ResponseDTO<>(OK_CODE, null, true, OK_MSG, data); + } + + public static ResponseDTO okMsg(String msg) { + return new ResponseDTO<>(OK_CODE, null, true, msg, null); + } + + public static ResponseDTO app_ok() { + return new ResponseDTO<>(APP_OK_CODE, null, true, OK_MSG, null); + } + + public static ResponseDTO app_ok(T data) { + return new ResponseDTO<>(APP_OK_CODE, null, true, OK_MSG, data); + } + + public static ResponseDTO app_okMsg(String msg) { + return new ResponseDTO<>(APP_OK_CODE, null, true, msg, null); + } + + // -------------------------------------------- 最常用的 用户参数 错误码 -------------------------------------------- + + public static ResponseDTO userErrorParam() { + return new ResponseDTO<>(UserErrorCode.PARAM_ERROR, false, null, null); + } + + + public static ResponseDTO userErrorParam(String msg) { + return new ResponseDTO<>(UserErrorCode.PARAM_ERROR, false, msg, null); + } + + // -------------------------------------------- 错误码 -------------------------------------------- + + public static ResponseDTO error(ErrorCode errorCode) { + return new ResponseDTO<>(errorCode, false, null, null); + } + + public static ResponseDTO error(ErrorCode errorCode, boolean ok) { + return new ResponseDTO<>(errorCode, ok, null, null); + } + + public static ResponseDTO error(ResponseDTO responseDTO) { + return new ResponseDTO<>(responseDTO.getCode(), responseDTO.getLevel(), responseDTO.getOk(), responseDTO.getMsg(), responseDTO.getData()); + } + + public static ResponseDTO error(ErrorCode errorCode, String msg) { + return new ResponseDTO<>(errorCode, false, msg, null); + } + + public static ResponseDTO errorData(ErrorCode errorCode, T data) { + return new ResponseDTO<>(errorCode, false, null, data); + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/domain/SystemEnvironment.java b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/SystemEnvironment.java new file mode 100644 index 0000000..8cf4b84 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/SystemEnvironment.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.common.common.domain; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum; + +/** + * 系统环境 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/8/13 21:06:11 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@AllArgsConstructor +@Getter +public class SystemEnvironment { + + /** + * 是否位生产环境 + */ + private boolean isProd; + + /** + * 项目名称 + */ + private String projectName; + + /** + * 当前环境 + */ + private SystemEnvironmentEnum currentEnvironment; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/domain/ValidateData.java b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/ValidateData.java new file mode 100644 index 0000000..a9aff00 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/ValidateData.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.common.common.domain; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 校验数据是否为空的包装类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2020/10/16 21:06:11 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class ValidateData { + + @NotNull(message = "数据不能为空哦") + private T data; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/domain/ValidateList.java b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/ValidateList.java new file mode 100644 index 0000000..c2ccb33 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/domain/ValidateList.java @@ -0,0 +1,153 @@ +package net.lab1024.sa.common.common.domain; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import java.util.*; + +/** + * 校验集合是否为空的包装类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-02-03 17:37 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class ValidateList implements List { + + @Valid + @NotEmpty(message = "数据长度不能为空哦") + private List list; + + public ValidateList() { + this.list = new ArrayList<>(); + } + + public ValidateList(List list) { + this.list = list; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + @Override + public int size() { + return list.size(); + } + + @Override + public boolean isEmpty() { + return list.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return list.contains(o); + } + + @Override + public Iterator iterator() { + return list.iterator(); + } + + @Override + public Object[] toArray() { + return list.toArray(); + } + + @Override + public T[] toArray(T[] a) { + return list.toArray(a); + } + + @Override + public boolean add(E e) { + return list.add(e); + } + + @Override + public boolean remove(Object o) { + return list.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return list.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + return list.addAll(c); + } + + @Override + public boolean addAll(int index, Collection c) { + return list.addAll(index, c); + } + + @Override + public boolean removeAll(Collection c) { + return list.removeAll(c); + } + + @Override + public boolean retainAll(Collection c) { + return list.retainAll(c); + } + + @Override + public void clear() { + list.clear(); + } + + @Override + public E get(int index) { + return list.get(index); + } + + @Override + public E set(int index, E element) { + return list.set(index, element); + } + + @Override + public void add(int index, E element) { + list.add(index, element); + } + + @Override + public E remove(int index) { + return list.remove(index); + } + + @Override + public int indexOf(Object o) { + return list.indexOf(o); + } + + @Override + public int lastIndexOf(Object o) { + return list.lastIndexOf(o); + } + + @Override + public ListIterator listIterator() { + return list.listIterator(); + } + + @Override + public ListIterator listIterator(int index) { + return list.listIterator(index); + } + + @Override + public List subList(int fromIndex, int toIndex) { + return list.subList(fromIndex, toIndex); + } + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/BaseEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/BaseEnum.java new file mode 100644 index 0000000..c7eaf69 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/BaseEnum.java @@ -0,0 +1,99 @@ +package net.lab1024.sa.common.common.enumeration; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONAware; +import com.alibaba.fastjson.JSONObject; +import com.google.common.base.CaseFormat; +import lombok.Data; + +import java.util.LinkedHashMap; +import java.util.Objects; + +/** + * 枚举类接口 + * + * @Author 1024创新实验室: 胡克 + * @Date 2018-07-17 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public interface BaseEnum { + + /** + * 获取枚举类的值 + * + * @return + */ + Object getValue(); + + /** + * 获取枚举类的说明 + * + * @return String + */ + String getDesc(); + + /** + * 比较参数是否与枚举类的value相同 + * + * @param value + * @return boolean + */ + default boolean equalsValue(Object value) { + return Objects.equals(getValue(), value); + } + + /** + * 比较枚举类是否相同 + * + * @param baseEnum + * @return boolean + */ + default boolean equals(BaseEnum baseEnum) { + return Objects.equals(getValue(), baseEnum.getValue()) && Objects.equals(getDesc(), baseEnum.getDesc()); + } + + /** + * 返回枚举类的说明 + * + * @param clazz 枚举类类对象 + * @return + */ + static String getInfo(Class clazz) { + BaseEnum[] enums = clazz.getEnumConstants(); + LinkedHashMap json = new LinkedHashMap<>(enums.length); + for (BaseEnum e : enums) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("value", new DeletedQuotationAware(e.getValue())); + jsonObject.put("desc", new DeletedQuotationAware(e.getDesc())); + json.put(e.toString(), jsonObject); + } + + String enumJson = JSON.toJSONString(json, true); + enumJson = enumJson.replaceAll("\"", ""); + enumJson = enumJson.replaceAll("\t", "  "); + enumJson = enumJson.replaceAll("\n", "
"); + String prefix = "
export const
" + CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, clazz.getSimpleName() + " =
"); + return prefix + "" + enumJson + "
"; + } + + @Data + class DeletedQuotationAware implements JSONAware { + + private String value; + + public DeletedQuotationAware(Object value) { + if (value instanceof String) { + this.value = "'" + value + "'"; + } else { + this.value = value.toString(); + } + } + + @Override + public String toJSONString() { + return value; + } + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/GenderEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/GenderEnum.java new file mode 100644 index 0000000..548d02e --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/GenderEnum.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.common.common.enumeration; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 性别枚举类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2019/09/24 16:50 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@AllArgsConstructor +@Getter +public enum GenderEnum implements BaseEnum { + + /** + * 0 未知 + */ + UNKNOWN(0, "未知"), + + /** + * 男 1 奇数为阳 + */ + MAN(1, "男"), + + /** + * 女 2 偶数为阴 + */ + WOMAN(2, "女"); + + private final Integer value; + + private final String desc; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/SystemEnvironmentEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/SystemEnvironmentEnum.java new file mode 100644 index 0000000..1906838 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/SystemEnvironmentEnum.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.common.common.enumeration; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 系统环境枚举类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-10-15 22:45:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@AllArgsConstructor +@Getter +public enum SystemEnvironmentEnum implements BaseEnum { + /** + * dev + */ + DEV(SystemEnvironmentNameConst.DEV, "开发环境"), + + /** + * test + */ + TEST(SystemEnvironmentNameConst.TEST, "测试环境"), + + /** + * pre + */ + PRE(SystemEnvironmentNameConst.PRE, "预发布环境"), + + /** + * prod + */ + PROD(SystemEnvironmentNameConst.PROD, "生产环境"); + + private final String value; + + private final String desc; + + public static final class SystemEnvironmentNameConst { + public static final String DEV = "dev"; + public static final String TEST = "test"; + public static final String PRE = "pre"; + public static final String PROD = "prod----ttt"; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/UserTypeEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/UserTypeEnum.java new file mode 100644 index 0000000..5c3586a --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/enumeration/UserTypeEnum.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.common.enumeration; + +/** + * 用户类型 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/10/19 21:46:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +public enum UserTypeEnum implements BaseEnum { + + /** + * 管理端 员工用户 + */ + ADMIN_EMPLOYEE(1, "员工"), + EXPERT(2, "专家"); + + private Integer type; + + private String desc; + + UserTypeEnum(Integer type, String desc) { + this.type = type; + this.desc = desc; + } + + @Override + public Integer getValue() { + return type; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/excel/ExcelStyle.java b/sa-common/src/main/java/net/lab1024/sa/common/common/excel/ExcelStyle.java new file mode 100644 index 0000000..eb72349 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/excel/ExcelStyle.java @@ -0,0 +1,185 @@ +package net.lab1024.sa.common.common.excel; + +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; +import cn.afterturn.easypoi.excel.entity.params.ExcelForEachParams; +import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler; +import org.apache.poi.ss.usermodel.*; + +/** + * excel样式 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/9/25 19:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class ExcelStyle implements IExcelExportStyler { + private static final short STRING_FORMAT = (short) BuiltinFormats.getBuiltinFormat("TEXT"); + private static final short FONT_SIZE_TEN = 10; + private static final short FONT_SIZE_ELEVEN = 11; + private static final short FONT_SIZE_TWELVE = 12; + /** + * 大标题样式 + */ + private CellStyle headerStyle; + /** + * 每列标题样式 + */ + private CellStyle titleStyle; + /** + * 数据行样式 + */ + private CellStyle styles; + + public ExcelStyle(Workbook workbook) { + this.init(workbook); + } + + /** + * 初始化样式 + * + * @param workbook + */ + private void init(Workbook workbook) { + this.headerStyle = initHeaderStyle(workbook); + this.titleStyle = initTitleStyle(workbook); + this.styles = initStyles(workbook); + } + + /** + * 大标题样式 + * + * @param color + * @return + */ + @Override + public CellStyle getHeaderStyle(short color) { + return headerStyle; + } + + /** + * 每列标题样式 + * + * @param color + * @return + */ + @Override + public CellStyle getTitleStyle(short color) { + return titleStyle; + } + + /** + * 数据行样式 + * + * @param parity 可以用来表示奇偶行 + * @param entity 数据内容 + * @return 样式 + */ + public CellStyle getStyles(boolean parity, ExcelExportEntity entity) { + return styles; + } + + /** + * 获取样式方法 + * + * @param dataRow 数据行 + * @param obj 对象 + * @param data 数据 + */ + @Override + public CellStyle getStyles(Cell cell, int dataRow, ExcelExportEntity entity, Object obj, Object data) { + return getStyles(true, entity); + } + + /** + * 模板使用的样式设置 + */ + @Override + public CellStyle getTemplateStyles(boolean isSingle, ExcelForEachParams excelForEachParams) { + return null; + } + + /** + * 初始化--大标题样式 + * + * @param workbook + * @return + */ + private CellStyle initHeaderStyle(Workbook workbook) { + CellStyle style = getBaseCellStyle(workbook); + style.setFont(getFont(workbook, FONT_SIZE_TWELVE, true)); + return style; + } + + /** + * 初始化--每列标题样式 + * + * @param workbook + * @return + */ + private CellStyle initTitleStyle(Workbook workbook) { + CellStyle style = getBaseCellStyle(workbook); + style.setFont(getFont(workbook, FONT_SIZE_ELEVEN, false)); + //背景色 + style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + return style; + } + + /** + * 初始化--数据行样式 + * + * @param workbook + * @return + */ + private CellStyle initStyles(Workbook workbook) { + CellStyle style = getBaseCellStyle(workbook); + style.setFont(getFont(workbook, FONT_SIZE_TEN, false)); + style.setDataFormat(STRING_FORMAT); + style.setAlignment(HorizontalAlignment.LEFT); + return style; + } + + /** + * 基础样式 + * + * @return + */ + private CellStyle getBaseCellStyle(Workbook workbook) { + CellStyle style = workbook.createCellStyle(); + //下边框 + style.setBorderBottom(BorderStyle.THIN); + //左边框 + style.setBorderLeft(BorderStyle.THIN); + //上边框 + style.setBorderTop(BorderStyle.THIN); + //右边框 + style.setBorderRight(BorderStyle.THIN); + //水平居中 + style.setAlignment(HorizontalAlignment.CENTER); + //上下居中 + style.setVerticalAlignment(VerticalAlignment.CENTER); + //设置自动换行 + style.setWrapText(true); + return style; + } + + /** + * 字体样式 + * + * @param size 字体大小 + * @param isBold 是否加粗 + * @return + */ + private Font getFont(Workbook workbook, short size, boolean isBold) { + Font font = workbook.createFont(); + //字体样式 + font.setFontName("宋体"); + //是否加粗 + font.setBold(isBold); + //字体大小 + font.setFontHeightInPoints(size); + return font; + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/exception/BusinessException.java b/sa-common/src/main/java/net/lab1024/sa/common/common/exception/BusinessException.java new file mode 100644 index 0000000..19b6b95 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/exception/BusinessException.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.common.exception; + +import net.lab1024.sa.common.common.code.ErrorCode; + +/** + * 业务逻辑异常,全局异常拦截后统一返回ResponseCodeConst.SYSTEM_ERROR + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/8/25 21:57 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class BusinessException extends RuntimeException { + + public BusinessException() { + } + + public BusinessException(ErrorCode errorCode) { + super(errorCode.getMsg()); + } + + public BusinessException(String message) { + super(message); + } + + public BusinessException(String message, Throwable cause) { + super(message, cause); + } + + public BusinessException(Throwable cause) { + super(cause); + } + + public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/interceptor/AbstractInterceptor.java b/sa-common/src/main/java/net/lab1024/sa/common/common/interceptor/AbstractInterceptor.java new file mode 100644 index 0000000..62f2042 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/interceptor/AbstractInterceptor.java @@ -0,0 +1,148 @@ +package net.lab1024.sa.common.common.interceptor; + +import com.alibaba.fastjson.JSONObject; +import net.lab1024.sa.common.common.annoation.NoNeedLogin; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.constant.RequestHeaderConst; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.util.CollectionUtils; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.function.Function; + +/** + * 抽象拦截器 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-10-09 20:56:14 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public abstract class AbstractInterceptor implements HandlerInterceptor { + + @Autowired + private List ignoreUrlList; + + + /** + * Token获取用户信息 + * + * @return + */ + protected abstract Function userFunction(); + + /** + * 拦截路径 + * + * @return + */ + public abstract String[] pathPatterns(); + + /** + * 忽略的url集合 + * + * @return + */ + protected List getIgnoreUrlList() { + return ignoreUrlList; + } + + /** + * 拦截服务器端响应处理ajax请求返回结果 + * + * @param request + * @param response + * @param handler + * @return + * @throws Exception + */ + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + // OPTIONS请求直接return + if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) { + response.setStatus(HttpStatus.NO_CONTENT.value()); + return false; + } + + boolean isHandler = handler instanceof HandlerMethod; + if (!isHandler) { + return true; + } + //放行的Uri前缀 + String uri = request.getRequestURI(); + String contextPath = request.getContextPath(); + String target = uri.replaceFirst(contextPath, ""); + if (this.contain(this.getIgnoreUrlList(), target)) { + return true; + } + //不需要登录 + NoNeedLogin noNeedLogin = ((HandlerMethod) handler).getMethodAnnotation(NoNeedLogin.class); + // 检查是否包含 token + String xRequestToken = request.getParameter(RequestHeaderConst.TOKEN); + String xHeaderToken = request.getHeader(RequestHeaderConst.TOKEN); + String xAccessToken = StringUtils.isNotBlank(xRequestToken) ? xRequestToken : xHeaderToken; + // 包含token 则获取用户信息 并保存 + if (StringUtils.isNotBlank(xAccessToken)) { + RequestUser requestUser = userFunction().apply(xAccessToken); + if (requestUser != null) { + SmartRequestUtil.setRequestUser(requestUser); + } + // 有token 无需登录 + if (null != noNeedLogin) { + return true; + } + } + // 无token 无需登录 + if (null != noNeedLogin) { + return true; + } + if (StringUtils.isBlank(xAccessToken)) { + this.outputResult(response, ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID)); + return false; + } + return true; + } + + public Boolean contain(List ignores, String uri) { + if (CollectionUtils.isEmpty(ignores)) { + return false; + } + for (String ignoreUrl : ignores) { + if (uri.startsWith(ignoreUrl)) { + return true; + } + } + return false; + } + + /** + * 错误输出 + * + * @param response + * @param responseDTO + * @throws IOException + */ + private void outputResult(HttpServletResponse response, ResponseDTO responseDTO) throws IOException { + String msg = JSONObject.toJSONString(responseDTO); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write(msg); + response.flushBuffer(); + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + SmartRequestUtil.remove(); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/DictValueVoDeserializer.java b/sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/DictValueVoDeserializer.java new file mode 100644 index 0000000..e61f113 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/DictValueVoDeserializer.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.common.common.json.deserializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.module.support.dict.domain.vo.DictValueVO; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 字典反序列化 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-08-12 22:17:53 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +public class DictValueVoDeserializer extends JsonDeserializer { + + @Override + public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + List list = new ArrayList<>(); + ObjectCodec objectCodec = jsonParser.getCodec(); + JsonNode listOrObjectNode = objectCodec.readTree(jsonParser); + String deserialize = ""; + try { + if (listOrObjectNode.isArray()) { + for (JsonNode node : listOrObjectNode) { + list.add(objectCodec.treeToValue(node, DictValueVO.class)); + } + } else { + list.add(objectCodec.treeToValue(listOrObjectNode, DictValueVO.class)); + } + deserialize = list.stream().map(DictValueVO::getValueCode).collect(Collectors.joining(",")); + } catch (Exception e) { + log.error(e.getMessage(), e); + deserialize = listOrObjectNode.asText(); + } + return deserialize; + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/FileKeyVoDeserializer.java b/sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/FileKeyVoDeserializer.java new file mode 100644 index 0000000..66d5bdb --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/FileKeyVoDeserializer.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.common.common.json.deserializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.module.support.file.domain.vo.FileVO; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 文件key反序列化
+ * 由于前端接收到的是序列化过的字段, 这边入库需要进行反序列化操作比较方便处理 + * + * @Author 1024创新实验室: 胡克 + * @Date 2022-11-24 17:15:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +public class FileKeyVoDeserializer extends JsonDeserializer { + + @Override + public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + List list = new ArrayList<>(); + ObjectCodec objectCodec = jsonParser.getCodec(); + JsonNode listOrObjectNode = objectCodec.readTree(jsonParser); + String deserialize = ""; + try { + if (listOrObjectNode.isArray()) { + for (JsonNode node : listOrObjectNode) { + list.add(objectCodec.treeToValue(node, FileVO.class)); + } + } else { + list.add(objectCodec.treeToValue(listOrObjectNode, FileVO.class)); + } + deserialize = list.stream().map(FileVO::getFileKey).collect(Collectors.joining(",")); + } catch (Exception e) { + log.error(e.getMessage(), e); + deserialize = listOrObjectNode.asText(); + } + return deserialize; + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/LongJsonDeserializer.java b/sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/LongJsonDeserializer.java new file mode 100644 index 0000000..debb487 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/json/deserializer/LongJsonDeserializer.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.common.common.json.deserializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; + +/** + * Long类型序列化 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-06-02 22:55:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class LongJsonDeserializer extends JsonDeserializer { + + @Override + public Long deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + String value = jsonParser.getText(); + try { + return value == null ? null : Long.parseLong(value); + } catch (NumberFormatException e) { + return null; + } + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/BigDecimalNullZeroSerializer.java b/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/BigDecimalNullZeroSerializer.java new file mode 100644 index 0000000..b0174dd --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/BigDecimalNullZeroSerializer.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.common.common.json.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.math.BigDecimal; + +/** + * 数字序列化 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/8/20 21:04 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class BigDecimalNullZeroSerializer extends JsonSerializer { + + @Override + public void serialize(BigDecimal value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + if (value == null) { + jsonGenerator.writeNumber(BigDecimal.ZERO); + return; + } + jsonGenerator.writeNumber(value); + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/DictValueVoSerializer.java b/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/DictValueVoSerializer.java new file mode 100644 index 0000000..5398bb0 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/DictValueVoSerializer.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.common.common.json.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.google.common.collect.Lists; +import net.lab1024.sa.common.module.support.dict.domain.vo.DictValueVO; +import net.lab1024.sa.common.module.support.dict.service.DictCacheService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +/** + * 字典序列化 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-08-12 22:17:53 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class DictValueVoSerializer extends JsonSerializer { + + @Autowired + private DictCacheService dictCacheService; + + + @Override + public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + if (StringUtils.isEmpty(value)) { + jsonGenerator.writeObject(Lists.newArrayList()); + return; + } + + String[] valueCodeArray = value.split(","); + List valueCodeList = Arrays.asList(valueCodeArray); + List dictValueVOList = Lists.newArrayList(); + valueCodeList.forEach(e->{ + if(StringUtils.isNotBlank(e)){ + DictValueVO dictValueVO = dictCacheService.selectValueByValueCode(value); + if(dictValueVO != null){ + dictValueVOList.add(dictValueVO); + } + } + }); + jsonGenerator.writeObject(dictValueVOList); + + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/FileKeySerializer.java b/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/FileKeySerializer.java new file mode 100644 index 0000000..0f6ae76 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/FileKeySerializer.java @@ -0,0 +1,45 @@ +//package net.lab1024.sa.common.common.json.serializer; +// +//import com.fasterxml.jackson.core.JsonGenerator; +//import com.fasterxml.jackson.databind.JsonSerializer; +//import com.fasterxml.jackson.databind.SerializerProvider; +//import net.lab1024.sa.common.common.domain.ResponseDTO; +//import net.lab1024.sa.common.module.support.file.service.FileService; +//import org.apache.commons.lang3.StringUtils; +//import org.springframework.beans.factory.annotation.Autowired; +// +//import java.io.IOException; +// +///** +// * 文件key进行序列化对象 +// * +// * @Author 1024创新实验室: 罗伊 +// * @Date 2020/8/15 22:06 +// * @Wechat zhuoda1024 +// * @Email lab1024@163.com +// * @Copyright 1024创新实验室 ( https://1024lab.net ) +// */ +//public class FileKeySerializer extends JsonSerializer { +// +// @Autowired +// private FileService fileService; +// +// +// @Override +// public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { +// if (StringUtils.isEmpty(value)) { +// jsonGenerator.writeString(value); +// return; +// } +// if (fileService == null) { +// jsonGenerator.writeString(value); +// return; +// } +// ResponseDTO responseDTO = fileService.getFileUrl(value); +// if (responseDTO.getOk()) { +// jsonGenerator.writeString(responseDTO.getData()); +// return; +// } +// jsonGenerator.writeString(value); +// } +//} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/FileKeyVoSerializer.java b/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/FileKeyVoSerializer.java new file mode 100644 index 0000000..6cd8a76 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/FileKeyVoSerializer.java @@ -0,0 +1,46 @@ +//package net.lab1024.sa.common.common.json.serializer; +// +//import com.fasterxml.jackson.core.JsonGenerator; +//import com.fasterxml.jackson.databind.JsonSerializer; +//import com.fasterxml.jackson.databind.SerializerProvider; +//import com.google.common.collect.Lists; +//import net.lab1024.sa.common.module.support.file.domain.vo.FileVO; +//import net.lab1024.sa.common.module.support.file.service.FileService; +//import org.apache.commons.lang3.StringUtils; +//import org.springframework.beans.factory.annotation.Autowired; +// +//import java.io.IOException; +//import java.util.Arrays; +//import java.util.List; +// +///** +// * 文件key进行序列化对象 +// * +// * @Author 1024创新实验室: 罗伊 +// * @Date 2020/8/15 22:06 +// * @Wechat zhuoda1024 +// * @Email lab1024@163.com +// * @Copyright 1024创新实验室 ( https://1024lab.net ) +// */ +//public class FileKeyVoSerializer extends JsonSerializer { +// +// @Autowired +// private FileService fileService; +// +// +// @Override +// public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { +// if (StringUtils.isEmpty(value)) { +// jsonGenerator.writeObject(Lists.newArrayList()); +// return; +// } +// if(fileService == null){ +// jsonGenerator.writeString(value); +// return; +// } +// String[] fileKeyArray = value.split(","); +// List fileKeyList = Arrays.asList(fileKeyArray); +// List fileKeyVOList = fileService.getFileList(fileKeyList); +// jsonGenerator.writeObject(fileKeyVOList); +// } +//} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/LongJsonSerializer.java b/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/LongJsonSerializer.java new file mode 100644 index 0000000..05a140a --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/json/serializer/LongJsonSerializer.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.common.common.json.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; + +/** + * Long类型序列化 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-06-02 22:55:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class LongJsonSerializer extends JsonSerializer { + + @Override + public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { + String text = (value == null ? null : String.valueOf(value)); + if (text != null) { + jsonGenerator.writeString(text); + } + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/security/AbstractSecurityConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/common/security/AbstractSecurityConfig.java new file mode 100644 index 0000000..ad2f8d8 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/security/AbstractSecurityConfig.java @@ -0,0 +1,95 @@ +package net.lab1024.sa.common.common.security; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.filter.CorsFilter; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * Spring Security + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/8/3 17:50 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public abstract class AbstractSecurityConfig extends WebSecurityConfigurerAdapter { + @Autowired + private CorsFilter corsFilter; + + @Autowired + private List noNeedLoginUrlList; + + @Autowired + private List ignoreUrlList; + + /** + * Token获取用户信息 + * + * @return + */ + protected abstract BiFunction userFunction(); + + /** + * 需要认证的url集合 + * + * @return + */ + protected abstract String[] getAuthenticatedUrlPatterns(); + + /** + * 不需要登录的url集合 + * + * @return + */ + protected String[] getNoNeedLoginUrl() { + return noNeedLoginUrlList.toArray(new String[noNeedLoginUrlList.size()]); + } + + /** + * 忽略的url集合 + * + * @return + */ + protected String[] getIgnoreUrlList() { + return ignoreUrlList.toArray(new String[ignoreUrlList.size()]); + } + + @Override + protected void configure(HttpSecurity httpSecurity) throws Exception { + httpSecurity + // CSRF禁用,因为不使用session + .csrf().disable() + // 认证失败处理类 + .exceptionHandling().authenticationEntryPoint(new SecurityAuthenticationFailHandler()).and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() + // 过滤请求 + .authorizeRequests() + //忽略的url + .antMatchers(this.getIgnoreUrlList()).permitAll() + // 不需要登陆的url + .antMatchers(this.getNoNeedLoginUrl()).permitAll() + //需要校验权限的url + .antMatchers(getAuthenticatedUrlPatterns()).authenticated(); + + //防止xss攻击 + httpSecurity.headers().xssProtection(); + // token filter 进行校验 + httpSecurity.addFilterBefore(new SecurityTokenFilter(this.userFunction()), UsernamePasswordAuthenticationFilter.class); + httpSecurity.addFilterBefore(corsFilter, SecurityTokenFilter.class); + // 禁用spring security 使用 X-Frame-Options防止网页被Frame + httpSecurity.headers().frameOptions().disable(); + + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityAuthenticationFailHandler.java b/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityAuthenticationFailHandler.java new file mode 100644 index 0000000..3e146f1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityAuthenticationFailHandler.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.common.common.security; + +import com.alibaba.fastjson.JSONObject; +import net.lab1024.sa.common.common.code.ErrorCode; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 登录认证失败处理 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-08-26 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class SecurityAuthenticationFailHandler implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException { + this.outputResult(response, UserErrorCode.LOGIN_STATE_INVALID); + } + + /** + * 输出 + * + * @param response + * @param errorCode + * @throws IOException + */ + private void outputResult(HttpServletResponse response, ErrorCode errorCode) throws IOException { + String msg = JSONObject.toJSONString(ResponseDTO.error(errorCode)); + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write(msg); + response.flushBuffer(); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityMethodSource.java b/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityMethodSource.java new file mode 100644 index 0000000..290b3d9 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityMethodSource.java @@ -0,0 +1,66 @@ +package net.lab1024.sa.common.common.security; + +import net.lab1024.sa.common.common.annoation.SaAuth; +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.access.prepost.PreInvocationAttribute; +import org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource; +import org.springframework.security.access.prepost.PrePostInvocationAttributeFactory; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; + +/** + * 此类用于默认给所有接口添加权限 @saAuth.checkPermission('%s') + * %s 为类名.方法名 + * 和使用@PreAuthorize("@saAuth.checkPermission('%s')") 效果一致 + * 避免所有接口都添加一遍 减轻工作量 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-08-30 23:08 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class SecurityMethodSource extends PrePostAnnotationSecurityMetadataSource { + + + private static String EXPRESSION_FORMAT = "@%s.checkPermission('%s')"; + + private final PrePostInvocationAttributeFactory attributeFactory; + + private String beanName; + + + public SecurityMethodSource(PrePostInvocationAttributeFactory attributeFactory, String beanName) { + super(attributeFactory); + this.attributeFactory = attributeFactory; + this.beanName = beanName; + } + + + @Override + public Collection getAttributes(Method method, Class targetClass) { + //如果不存在SaAuth采用security认证模式 + SaAuth saAuth = method.getAnnotation(SaAuth.class); + if (saAuth == null) { + return super.getAttributes(method, targetClass); + } + + //存在添加以URL为权限字符串的校验模式 + ArrayList configAttributes = new ArrayList(1); + String classFullName = targetClass.getName(); + String methodName = method.getName(); + String[] classNameArray = StringUtils.split(classFullName, "\\."); + String controllerName = classNameArray[classNameArray.length - 1]; + String privilegeName = controllerName + "." + methodName; + String preAuthorizeAttribute = String.format(EXPRESSION_FORMAT, beanName, privilegeName); + PreInvocationAttribute pre = this.attributeFactory.createPreInvocationAttribute(null, null, preAuthorizeAttribute); + if (pre != null) { + configAttributes.add(pre); + } + return configAttributes; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityPermissionCheckService.java b/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityPermissionCheckService.java new file mode 100644 index 0000000..29e4655 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityPermissionCheckService.java @@ -0,0 +1,74 @@ +package net.lab1024.sa.common.common.security; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Arrays; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 校验权限 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/12 21:50 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public abstract class SecurityPermissionCheckService { + + + /** + * 校验是否有权限 + * + * @param permission + * @return + */ + public boolean checkPermission(String permission) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null) { + return false; + } + return checkPermission(authentication, permission); + } + + /** + * 校验是否有权限 + * + * @param authentication + * @param permission + * @return + */ + public abstract boolean checkPermission(Authentication authentication, String permission); + + /** + * 判断 + * + * @param userDetails + * @param permissionStr + * @return + */ + protected boolean permissionJudge(UserDetails userDetails, String permissionStr) { + if (CollectionUtils.isEmpty(userDetails.getAuthorities())) { + return false; + } + + if (StringUtils.isBlank(permissionStr)) { + return false; + } + + String[] permissionArray = permissionStr.split(","); + for (String permission : permissionArray) { + if(userDetails.getAuthorities().contains(new SimpleGrantedAuthority(permission))){ + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityTokenFilter.java b/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityTokenFilter.java new file mode 100644 index 0000000..1a2ef97 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/security/SecurityTokenFilter.java @@ -0,0 +1,64 @@ +package net.lab1024.sa.common.common.security; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.constant.RequestHeaderConst; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * 注意此处不能 加入@Component,否则对应ignoreUrl的相关请求 将会进入此Filter,并会覆盖CorsFilter + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/12 21:50 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +public class SecurityTokenFilter extends OncePerRequestFilter { + + private BiFunction userFunction; + + public SecurityTokenFilter(BiFunction userFunction) { + this.userFunction = userFunction; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException { + //需要做token校验, 消息头的token优先于请求query参数的token + String xHeaderToken = request.getHeader(RequestHeaderConst.TOKEN); + String xRequestToken = request.getParameter(RequestHeaderConst.TOKEN); + String xAccessToken = null != xHeaderToken ? xHeaderToken : xRequestToken; + if (StringUtils.isBlank(xAccessToken)) { + chain.doFilter(request, response); + return; + } + //清理spring security + SecurityContextHolder.clearContext(); + + UserDetails loginUserDetail = userFunction.apply(xAccessToken,request); + if (null != loginUserDetail) { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUserDetail, null, loginUserDetail.getAuthorities()); + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + SmartRequestUtil.setRequestUser((RequestUser) loginUserDetail); + } + // 若未给予spring security上下文用户授权 则会授权失败 进入AuthenticationEntryPointImpl + chain.doFilter(request, response); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/swagger/ApiModelPropertyEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/common/swagger/ApiModelPropertyEnum.java new file mode 100644 index 0000000..c306f00 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/swagger/ApiModelPropertyEnum.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.common.common.swagger; + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 枚举类字段属性的 自定义 swagger 注解 + * + * @Author 1024创新实验室: 胡克 + * @Date 2019/05/16 23:18 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ApiModelPropertyEnum { + + /** + * 枚举类对象 + * + * @return + */ + Class value(); + + String example() default ""; + + boolean hidden() default false; + + boolean required() default true; + + String dataType() default ""; + + String desc() default ""; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/swagger/Swagger2MapperImplExtension.java b/sa-common/src/main/java/net/lab1024/sa/common/common/swagger/Swagger2MapperImplExtension.java new file mode 100644 index 0000000..85241e8 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/swagger/Swagger2MapperImplExtension.java @@ -0,0 +1,91 @@ +//package net.lab1024.sa.common.common.swagger; +// +//import com.google.common.collect.LinkedListMultimap; +//import com.google.common.collect.Multimap; +//import io.swagger.models.Operation; +//import io.swagger.models.Path; +//import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +//import org.springframework.context.annotation.Primary; +//import org.springframework.stereotype.Component; +//import springfox.documentation.service.ApiDescription; +//import springfox.documentation.service.ApiListing; +//import springfox.documentation.swagger2.mappers.ModelMapper; +//import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2MapperImpl; +// +//import java.lang.reflect.Field; +//import java.lang.reflect.Modifier; +//import java.util.*; +// +//import static springfox.documentation.builders.BuilderDefaults.nullToEmptyList; +// +///** +// * 修改 api 顺序 +// * +// * @Author 1024创新实验室: 胡克 +// * @Date 2021/8/11 22:05 +// * @Wechat zhuoda1024 +// * @Email lab1024@163.com +// * @Copyright 1024创新实验室 ( https://1024lab.net ) +// */ +//@ConditionalOnBean(ModelMapper.class) +//@Component +//@Primary +//public class Swagger2MapperImplExtension extends ServiceModelToSwagger2MapperImpl { +// +// @Override +// protected Map mapApiListings(Multimap apiListings) { +// Map paths = new LinkedHashMap<>(); +// Multimap apiListingMap = LinkedListMultimap.create(); +// Iterator iter = apiListings.entries().iterator(); +// while (iter.hasNext()) { +// Map.Entry entry = (Map.Entry) iter.next(); +// ApiListing apis = entry.getValue(); +// List apiList = apis.getApis(); +// apiList.sort((left, right) -> { +// int position1 = left.getOperations().get(0).getPosition(); +// int position2 = right.getOperations().get(0).getPosition(); +// if (position1 == position2) { +// return String.CASE_INSENSITIVE_ORDER.compare(left.getPath(), right.getPath()); +// } +// return Integer.compare(position1, position2); +// }); +// try { +// // 因ApiListing的属性都是final故需要通过反射来修改值 +// modify(apis, "apis", apiList); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// apiListingMap.put(entry.getKey(), apis); +// } +// +// for (ApiListing each : apiListingMap.values()) { +// for (ApiDescription api : each.getApis()) { +// paths.put(api.getPath(), mapOperations(api, Optional.ofNullable(paths.get(api.getPath())))); +// } +// } +// return paths; +// } +// +// private Path mapOperations(ApiDescription api, Optional existingPath) { +// Path path = existingPath.orElse(new Path()); +// for (springfox.documentation.service.Operation each : nullToEmptyList(api.getOperations())) { +// Operation operation = mapOperation(each); +// path.set(each.getMethod().toString().toLowerCase(), operation); +// } +// return path; +// } +// +// public static void modify(Object object, String fieldName, Object newFieldValue) throws Exception { +// Field field = object.getClass().getDeclaredField(fieldName); +// +// Field modifiersField = Field.class.getDeclaredField("modifiers"); +// modifiersField.setAccessible(true); +// modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); +// +// if (!field.isAccessible()) { +// field.setAccessible(true); +// } +// +// field.set(object, newFieldValue); +// } +//} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/swagger/SwaggerApiModelPropertyEnumPlugin.java b/sa-common/src/main/java/net/lab1024/sa/common/common/swagger/SwaggerApiModelPropertyEnumPlugin.java new file mode 100644 index 0000000..ce12615 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/swagger/SwaggerApiModelPropertyEnumPlugin.java @@ -0,0 +1,77 @@ +package net.lab1024.sa.common.common.swagger; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import net.lab1024.sa.common.common.enumeration.BaseEnum; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.schema.ModelPropertyBuilderPlugin; +import springfox.documentation.spi.schema.contexts.ModelPropertyContext; +import springfox.documentation.swagger.common.SwaggerPluginSupport; + +import java.lang.reflect.AnnotatedElement; + +import static springfox.documentation.schema.Annotations.findPropertyAnnotation; + +/** + * swagger 用于说明枚举类字段说明 + * * SWAGGER_PLUGIN_ORDER+1 是将此配置放在原来的后面执行 + * + * @Author 1024创新实验室: 胡克 + * @Date 2019/8/11 15:36:56 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Component +@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1) +public class SwaggerApiModelPropertyEnumPlugin implements ModelPropertyBuilderPlugin { + + @Override + public void apply(ModelPropertyContext context) { + Optional annotation = Optional.absent(); + + if (context.getAnnotatedElement().isPresent()) { + annotation = annotation.or(findApiModePropertyAnnotation(context.getAnnotatedElement().get())); + } + if (context.getBeanPropertyDefinition().isPresent()) { + annotation = annotation.or(findPropertyAnnotation(context.getBeanPropertyDefinition().get(), ApiModelPropertyEnum.class)); + } + + if (annotation.isPresent()) { + ApiModelPropertyEnum anEnum = annotation.get(); + String enumInfo = BaseEnum.getInfo(anEnum.value()); + context.getBuilder() + .required(annotation.transform(toIsRequired()).or(false)) + .description(anEnum.desc() + ":" + enumInfo) + .example(annotation.transform(toExample()).orNull()) + .isHidden(anEnum.hidden()); + } + } + + @Override + public boolean supports(DocumentationType delimiter) { + return SwaggerPluginSupport.pluginDoesApply(delimiter); + } + + static Function toIsRequired() { + return annotation -> annotation.required(); + } + + public static Optional findApiModePropertyAnnotation(AnnotatedElement annotated) { + return Optional.fromNullable(AnnotationUtils.getAnnotation(annotated, ApiModelPropertyEnum.class)); + } + + static Function toExample() { + return annotation -> { + String example = annotation.example(); + if (StringUtils.isBlank(example)) { + return ""; + } + return example; + }; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/EncryptionKit.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/EncryptionKit.java new file mode 100644 index 0000000..1edd346 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/EncryptionKit.java @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2011-2015, James Zhan 詹波 (jfinal@126.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.lab1024.sa.common.common.util; + +import java.security.MessageDigest; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +public class EncryptionKit { + + public static String md5Encrypt(String srcStr) { + return encrypt("MD5", srcStr); + } + + public static String sha1Encrypt(String srcStr) { + return encrypt("SHA-1", srcStr); + } + + public static String sha256Encrypt(String srcStr) { + return encrypt("SHA-256", srcStr); + } + + public static String sha384Encrypt(String srcStr) { + return encrypt("SHA-384", srcStr); + } + + public static String sha512Encrypt(String srcStr) { + return encrypt("SHA-512", srcStr); + } + + public static String encrypt(String algorithm, String srcStr) { + try { + StringBuilder result = new StringBuilder(); + MessageDigest md = MessageDigest.getInstance(algorithm); + byte[] bytes = md.digest(srcStr.getBytes("utf-8")); + for (byte b : bytes) { + String hex = Integer.toHexString(b & 0xFF); + if (hex.length() == 1) + result.append("0"); + result.append(hex); + } + return result.toString(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static String HMACSHA256(String data, String key) { + try { + Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); + SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256"); + sha256_HMAC.init(secret_key); + byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8")); + StringBuilder sb = new StringBuilder(); + for (byte item : array) { + sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); + } + return sb.toString().toLowerCase(); + } catch (Exception e) { + return ""; + } + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/HttpUtil.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/HttpUtil.java new file mode 100644 index 0000000..7b9d657 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/HttpUtil.java @@ -0,0 +1,542 @@ +package net.lab1024.sa.common.common.util; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.security.GeneralSecurityException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLContextBuilder; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.conn.ssl.X509HostnameVerifier; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Sean + * @createDate 2022/7/20-22:28 + */ +public class HttpUtil { + + private static final Logger log = LoggerFactory.getLogger(HttpUtil.class); + + private static PoolingHttpClientConnectionManager connMgr; + private static RequestConfig requestConfig; + private static final int MAX_TIMEOUT = 3600000;// 7秒 + private static final String UTF_8 = "UTF-8"; + public static final String JSON = "json"; + public static final String XML = "xml"; + + static { + // 设置连接池 + connMgr = new PoolingHttpClientConnectionManager(); + // 设置连接池大小 + connMgr.setMaxTotal(100); + connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal()); + RequestConfig.Builder configBuilder = RequestConfig.custom(); + // 设置连接超时 + configBuilder.setConnectTimeout(MAX_TIMEOUT); + // 设置读取超时 + configBuilder.setSocketTimeout(MAX_TIMEOUT); + // 设置从连接池获取连接实例的超时 + configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT); + // 在提交请求之前 测试连接是否可用 + configBuilder.setStaleConnectionCheckEnabled(true); + requestConfig = configBuilder.build(); + } + + /** + * 发送 GET 请求(HTTP),不带输入数据 + * + * @param url + * @return + * @throws IOException + */ + public static String doGet(String url) throws IOException { + return doGet(url, null); + } + + /** + * 发送 GET 请求(HTTP),K-V形式 + * + * @param url + * @param params + * @return + * @throws IOException + */ + public static String doGet(String url, Map params) throws IOException { + int i = 0; + if (params != null) { + StringBuffer param = new StringBuffer(); + for (String key : params.keySet()) { + if (i == 0) + param.append("?"); + else + param.append("&"); + param.append(key).append("=").append(params.get(key)); + i++; + } + url += param; + } + String result = null; + CloseableHttpClient httpclient = HttpClients.createDefault(); + CloseableHttpResponse response = null; + HttpEntity entity = null; + try { + HttpGet httpGet = new HttpGet(url); + response = httpclient.execute(httpGet); + // int statusCode = response.getStatusLine().getStatusCode(); + + entity = response.getEntity(); + if (entity != null) { + InputStream instream = entity.getContent(); + result = IOUtils.toString(instream, UTF_8); + } + } finally { + // 最后别忘了关闭应该关闭的资源,适当的释放资源 + try { + // 这个方法也可以把底层的流给关闭了 + EntityUtils.consume(entity); + // if (null != response) { + // response.close(); + // } + } catch (IOException e) { + e.printStackTrace(); + } + } + return result; + } + + /** + * 发送 POST 请求(HTTP),不带输入数据 + * + * @param apiUrl + * @return + * @throws ConnectTimeoutException + */ + public static String doPost(String apiUrl) throws IOException { + return doPost(apiUrl, new HashMap()); + } + + /** + * 发送 POST 请求(HTTP),K-V形式 + * + * @param apiUrl API接口URL + * @param params 参数map + * @return + * @throws ConnectTimeoutException + */ + public static String doPost(String apiUrl, Map params) throws IOException { + CloseableHttpClient httpClient = HttpClients.createDefault(); + String httpStr = null; + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + + try { + httpPost.setConfig(requestConfig); + List pairList = new ArrayList<>(params.size()); + for (Map.Entry entry : params.entrySet()) { + NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue()); + pairList.add(pair); + } + httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8"))); + response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + httpStr = EntityUtils.toString(entity, "UTF-8"); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return httpStr; + } + + /** + * 发送 POST 请求(HTTP),JSON形式 + * + * @param apiUrl + * @param content 内容 + * @return + * @throws IOException + */ + public static String doPost(String apiUrl, String content, String type) throws IOException { + CloseableHttpClient httpClient = HttpClients.createDefault(); + String httpStr = null; + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + + try { + httpPost.setConfig(requestConfig); + StringEntity stringEntity = new StringEntity(content, "UTF-8");// 解决中文乱码问题 + stringEntity.setContentEncoding("UTF-8"); + if (JSON.equals(type) || "application/json;charset=UTF-8".equals(type)) { + stringEntity.setContentType("application/json"); + } else if (XML.equals(type)) { + stringEntity.setContentType("application/xml"); + } else { + stringEntity.setContentType("text/plain"); + } + httpPost.setEntity(stringEntity); + response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + // System.out.println(response.getStatusLine().getStatusCode()); + httpStr = EntityUtils.toString(entity, "UTF-8"); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return httpStr; + } + + /** + * 发送 POST 请求(HTTP),JSON形式 + url k-v参数 + * @param apiUrl + * @param content + * @param params + * @param type + * @return + * @throws IOException + */ + public static String doPost(String apiUrl, String content,Map params, String type) throws IOException { + // url参数拼接 + if (params != null) { + int i = 0; + StringBuffer param = new StringBuffer(); + for (String key : params.keySet()) { + if (i == 0) + param.append("?"); + else + param.append("&"); + param.append(key).append("=").append(params.get(key)); + i++; + } + apiUrl += param; + } + + CloseableHttpClient httpClient = HttpClients.createDefault(); + String httpStr = null; + log.info("本次请求apiUrl:"+apiUrl); + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + + try { + httpPost.setConfig(requestConfig); + StringEntity stringEntity = new StringEntity(content, "UTF-8");// 解决中文乱码问题 + stringEntity.setContentEncoding("UTF-8"); + if (JSON.equals(type)) { + stringEntity.setContentType("application/json"); + } else if (XML.equals(type)) { + stringEntity.setContentType("application/xml"); + } else { + stringEntity.setContentType("text/plain"); + } + httpPost.setEntity(stringEntity); + response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + // System.out.println(response.getStatusLine().getStatusCode()); + httpStr = EntityUtils.toString(entity, "UTF-8"); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return httpStr; + } + public static String doPost(String apiUrl, String content, String type,Map headers) throws IOException { + CloseableHttpClient httpClient = HttpClients.createDefault(); + String httpStr = null; + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + + try { + httpPost.setConfig(requestConfig); + if (headers != null) { + for (String headerName : headers.keySet()) { + httpPost.setHeader(headerName, headers.get(headerName)); + } + } + StringEntity stringEntity = new StringEntity(content, "UTF-8");// 解决中文乱码问题 + stringEntity.setContentEncoding("UTF-8"); + if (JSON.equals(type)) { + stringEntity.setContentType("application/json"); + } else if (XML.equals(type)) { + stringEntity.setContentType("application/xml"); + } else { + stringEntity.setContentType("text/plain"); + } + httpPost.setEntity(stringEntity); + response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + // System.out.println(response.getStatusLine().getStatusCode()); + httpStr = EntityUtils.toString(entity, "UTF-8"); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return httpStr; + } + + /** + * 发送 SSL POST 请求(HTTPS),K-V形式 + * + * @param apiUrl API接口URL + * @param params 参数map + * @return + */ + public static String doPostSSL(String apiUrl, Map params) { + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr) + .setDefaultRequestConfig(requestConfig).build(); + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + String httpStr = null; + + try { + httpPost.setConfig(requestConfig); + List pairList = new ArrayList(params.size()); + for (Map.Entry entry : params.entrySet()) { + NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString()); + pairList.add(pair); + } + httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("utf-8"))); + response = httpClient.execute(httpPost); + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + return null; + } + HttpEntity entity = response.getEntity(); + if (entity == null) { + return null; + } + httpStr = EntityUtils.toString(entity, "utf-8"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return httpStr; + } + + /** + * 发送 SSL POST 请求(HTTPS),JSON形式 + * + * @param apiUrl API接口URL + * @param json JSON对象 + * @return + */ + public static String doPostSSL(String apiUrl, Object json) { + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr) + .setDefaultRequestConfig(requestConfig).build(); + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + String httpStr = null; + + try { + httpPost.setConfig(requestConfig); + StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");// 解决中文乱码问题 + stringEntity.setContentEncoding("UTF-8"); + stringEntity.setContentType("application/json"); + httpPost.setEntity(stringEntity); + response = httpClient.execute(httpPost); + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + return null; + } + HttpEntity entity = response.getEntity(); + if (entity == null) { + return null; + } + httpStr = EntityUtils.toString(entity, "utf-8"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return httpStr; + } + + /** + * 创建SSL安全连接 + * + * @return + */ + private static SSLConnectionSocketFactory createSSLConnSocketFactory() { + SSLConnectionSocketFactory sslsf = null; + try { + SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { + + public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { + return true; + } + }).build(); + sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() { + + @Override + public boolean verify(String arg0, SSLSession arg1) { + return true; + } + + @Override + public void verify(String host, SSLSocket ssl) throws IOException { + } + + @Override + public void verify(String host, X509Certificate cert) throws SSLException { + } + + @Override + public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException { + } + }); + } catch (GeneralSecurityException e) { + e.printStackTrace(); + } + return sslsf; + } + + /** + * 发送 SSL POST 请求(HTTPS),加载证书 + * + * @return + */ + public static String doPostSSL(String url, String content, String type, Map headers, SSLConnectionSocketFactory sslsf) { + CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr) + .setDefaultRequestConfig(requestConfig).build(); + HttpPost httpPost = new HttpPost(url); + CloseableHttpResponse response = null; + String httpStr = null; + + try { + httpPost.setConfig(requestConfig); + if (headers != null) { + for (String headerName : headers.keySet()) { + httpPost.setHeader(headerName, headers.get(headerName)); + } + } + StringEntity stringEntity = new StringEntity(content, "UTF-8");// 解决中文乱码问题 + stringEntity.setContentEncoding("UTF-8"); + if (JSON.equals(type)) { + stringEntity.setContentType("application/json"); + } else if (XML.equals(type)) { + stringEntity.setContentType("application/xml"); + } else { + stringEntity.setContentType("text/plain"); + } + httpPost.setEntity(stringEntity); + response = httpClient.execute(httpPost); + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpStatus.SC_OK) { + return null; + } + HttpEntity entity = response.getEntity(); + if (entity == null) { + return null; + } + httpStr = EntityUtils.toString(entity, "utf-8"); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return httpStr; + } + + /** + * 自定义POST带请求头 + * 请求类型为为:application/json + * + */ + public static String doPostWithHeader(String apiUrl, String content, Map map) throws IOException { + CloseableHttpClient httpClient = HttpClients.createDefault(); + String httpStr = null; + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + + for(Map.Entry entry : map.entrySet()){ + httpPost.setHeader(entry.getKey(),entry.getValue()); + } + + try { + httpPost.setConfig(requestConfig); + StringEntity stringEntity = new StringEntity(content, "UTF-8");// 解决中文乱码问题 + stringEntity.setContentEncoding("UTF-8"); + stringEntity.setContentType("application/json"); + httpPost.setEntity(stringEntity); + response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + // System.out.println(response.getStatusLine().getStatusCode()); + httpStr = EntityUtils.toString(entity, "UTF-8"); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return httpStr; + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/Sha256Util.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/Sha256Util.java new file mode 100644 index 0000000..c1cf89b --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/Sha256Util.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.common.common.util; + +import cn.hutool.core.util.StrUtil; +import org.apache.poi.util.StringUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * 加密 + */ +public class Sha256Util { + + /** + * 加密 + * @param params + * @param accessToken + * @return + */ + public static String getSign(Map params, String accessToken) { + List keys = new ArrayList<>(params.keySet()); + List tmp = new ArrayList<>(); + Collections.sort(keys); + for (String key : keys) { + if (!StrUtil.isEmptyIfStr(params.get(key))) { + tmp.add(key + "=" + params.get(key)); + } + } + String join = String.join("&", tmp); + return EncryptionKit.HMACSHA256(join, accessToken); + } + + public static String getSignString(Map params, String accessToken) { + List keys = new ArrayList<>(params.keySet()); + List tmp = new ArrayList<>(); + Collections.sort(keys); + for (String key : keys) { + if (!StrUtil.isEmptyIfStr(params.get(key))) { + tmp.add(key + "=" + params.get(key)); + } + } + String join = String.join("&", tmp); + return EncryptionKit.HMACSHA256(join, accessToken); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartBeanUtil.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartBeanUtil.java new file mode 100644 index 0000000..ec36b2b --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartBeanUtil.java @@ -0,0 +1,94 @@ +package net.lab1024.sa.common.common.util; + +import org.springframework.beans.BeanUtils; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * bean相关工具类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2018-01-15 10:48:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class SmartBeanUtil { + + /** + * 验证器 + */ + private static final Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator(); + + /** + * 复制bean的属性 + * + * @param source 源 要复制的对象 + * @param target 目标 复制到此对象 + */ + public static void copyProperties(Object source, Object target) { + BeanUtils.copyProperties(source, target); + } + + /** + * 复制对象 + * + * @param source 源 要复制的对象 + * @param target 目标 复制到此对象 + * @param + * @return + */ + public static T copy(Object source, Class target) { + if (source == null || target == null) { + return null; + } + try { + T newInstance = target.newInstance(); + BeanUtils.copyProperties(source, newInstance); + return newInstance; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * 复制list + * + * @param source + * @param target + * @param + * @param + * @return + */ + public static List copyList(List source, Class target) { + if (null == source || source.isEmpty()) { + return Collections.emptyList(); + } + return source.stream().map(e -> copy(e, target)).collect(Collectors.toList()); + } + + /** + * 手动验证对象 Model的属性 + * 需要配合 hibernate-validator 校验注解 + * + * @param t + * @return String 返回null代表验证通过,否则返回错误的信息 + */ + public static String verify(T t) { + // 获取验证结果 + Set> validate = VALIDATOR.validate(t); + if (validate.isEmpty()) { + // 验证通过 + return null; + } + // 返回错误信息 + List messageList = validate.stream().map(ConstraintViolation::getMessage).collect(Collectors.toList()); + return messageList.toString(); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartBigDecimalUtil.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartBigDecimalUtil.java new file mode 100644 index 0000000..a1ff2da --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartBigDecimalUtil.java @@ -0,0 +1,247 @@ +package net.lab1024.sa.common.common.util; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * BigDecimal 工具类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2018/01/17 13:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class SmartBigDecimalUtil { + + /** + * 金额 保留小数点 2 + */ + public static final int AMOUNT_DECIMAL_POINT = 2; + + public static final BigDecimal ONE_HUNDRED = new BigDecimal("100"); + + /** + * 金额相关计算方法:四舍五入 保留2位小数点 + */ + public static class Amount { + + public static BigDecimal add(BigDecimal num1, BigDecimal num2) { + return setScale(num1.add(num2), AMOUNT_DECIMAL_POINT); + } + + public static BigDecimal multiply(BigDecimal num1, BigDecimal num2) { + return setScale(num1.multiply(num2), AMOUNT_DECIMAL_POINT); + } + + public static BigDecimal subtract(BigDecimal num1, BigDecimal num2) { + return setScale(num1.subtract(num2), AMOUNT_DECIMAL_POINT); + } + + public static BigDecimal divide(BigDecimal num1, BigDecimal num2) { + return setScale(num1.divide(num2, RoundingMode.HALF_UP), AMOUNT_DECIMAL_POINT); + } + } + + + /** + * BigDecimal 加法 num1 + num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal add(BigDecimal num1, BigDecimal num2, int point) { + return setScale(num1.add(num2), point); + } + + /** + * 累加 + * + * @param point + * @param array + * @return + */ + public static BigDecimal add(int point, BigDecimal... array) { + BigDecimal res = new BigDecimal(0); + for (BigDecimal item : array) { + if (item == null) { + res = res.add(BigDecimal.ZERO); + } else { + res = res.add(item); + } + } + return setScale(res, point); + } + + /** + * BigDecimal 乘法 num1 x num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal multiply(BigDecimal num1, BigDecimal num2, int point) { + return setScale(num1.multiply(num2), point); + } + + /** + * BigDecimal 减法 num1 - num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal subtract(BigDecimal num1, BigDecimal num2, int point) { + return setScale(num1.subtract(num2), point); + } + + /** + * BigDecimal 除法 num1/num2 + * 未做非空校验 + * + * @param num1 + * @param num2 + * @param point 请使用BigDecimalUtils.PRICE_DECIMAL_POINT | BigDecimalUtils.WEIGHT_DECIMAL_POINT + * @return BigDecimal + */ + public static BigDecimal divide(BigDecimal num1, BigDecimal num2, int point) { + return num1.divide(num2, point, RoundingMode.HALF_UP); + } + + /** + * 设置小数点类型为 四舍五入 + * + * @param num + * @param point + * @return BigDecimal + */ + public static BigDecimal setScale(BigDecimal num, int point) { + return num.setScale(point, RoundingMode.HALF_UP); + } + + /** + * 比较 num1 是否大于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isGreaterThan(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) > 0; + } + + /** + * 比较 num1 是否大于等于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isGreaterOrEqual(BigDecimal num1, BigDecimal num2) { + return isGreaterThan(num1, num2) || equals(num1, num2); + } + + /** + * 比较 num1 是否小于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isLessThan(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) < 0; + } + + /** + * 比较 num1 是否小于等于 num2 + * + * @param num1 + * @param num2 + * @return boolean + */ + public static boolean isLessOrEqual(BigDecimal num1, BigDecimal num2) { + return isLessThan(num1, num2) || equals(num1, num2); + } + + /** + * 比较 num1 是否等于 num2 + * + * @param num1 + * @param num2 + * @return + */ + public static boolean equals(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) == 0; + } + + /** + * 计算 num1 / num2 的百分比 + * + * @param num1 + * @param num2 + * @param point 保留几位小数 + * @return String + */ + public static BigDecimal percent(Integer num1, Integer num2, int point) { + if (num1 == null || num2 == null) { + return BigDecimal.ZERO; + } + if (num2.equals(0)) { + return BigDecimal.ZERO; + } + return percent(new BigDecimal(num1), new BigDecimal(num2), point); + } + + /** + * 计算 num1 / num2 的百分比 + * + * @param num1 + * @param num2 + * @param point 保留几位小数 + * @return String + */ + public static BigDecimal percent(BigDecimal num1, BigDecimal num2, int point) { + if (num1 == null || num2 == null) { + return BigDecimal.ZERO; + } + if (equals(BigDecimal.ZERO, num2)) { + return BigDecimal.ZERO; + } + BigDecimal percent = num1.divide(num2, point + 2, RoundingMode.HALF_UP); + return percent.multiply(ONE_HUNDRED).setScale(point); + } + + /** + * 比较 num1,num2 返回最大的值 + * + * @param num1 + * @param num2 + * @return BigDecimal + */ + public static BigDecimal max(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) > 0 ? num1 : num2; + } + + /** + * 比较 num1,num2 返回最小的值 + * + * @param num1 + * @param num2 + * @return BigDecimal + */ + public static BigDecimal min(BigDecimal num1, BigDecimal num2) { + return num1.compareTo(num2) < 0 ? num1 : num2; + } + + public static void main(String[] args) { + System.out.println(percent(new BigDecimal("3"), new BigDecimal("11"), 2)); + System.out.println(percent(new BigDecimal("8"), new BigDecimal("11"), 2)); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEasyExcelUtil.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEasyExcelUtil.java new file mode 100644 index 0000000..d57d06f --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEasyExcelUtil.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.common.common.util; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.fastjson2.JSON; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.domain.ResponseDTO; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; +import java.util.List; + +import static net.lab1024.sa.common.common.code.SystemErrorCode.SYSTEM_ERROR; + +/** + * Easy Excel 工具类 + */ +@Slf4j +public class SmartEasyExcelUtil { + + public static void exportExcel(List list, String sheetName, Class pojoClass, String fileName, HttpServletResponse response) throws IOException { + try { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 + fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + // 这里需要设置不关闭流 + EasyExcel.write(response.getOutputStream(), pojoClass).autoCloseStream(Boolean.FALSE).sheet(sheetName).doWrite(list); + }catch (Exception e){ + e.printStackTrace(); + // 重置response + response.reset(); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + response.getWriter().println(JSON.toJSONString(ResponseDTO.error(SYSTEM_ERROR))); + } + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEasyPoiExcelUtil.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEasyPoiExcelUtil.java new file mode 100644 index 0000000..4099442 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEasyPoiExcelUtil.java @@ -0,0 +1,114 @@ +package net.lab1024.sa.common.common.util; + +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.ExcelImportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.ImportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Workbook; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +/** + * excel 工具类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2018/01/17 13:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +public class SmartEasyPoiExcelUtil { + public static void exportExcel(List list, String title, String sheetName, Class pojoClass, + String fileName, boolean isCreateHeader, HttpServletResponse response) throws IOException { + ExportParams exportParams = new ExportParams(title, sheetName); + exportParams.setCreateHeadRows(isCreateHeader); + defaultExport(list, pojoClass, fileName, response, exportParams); + } + + public static void exportExcel(List list, String title, String sheetName, Class pojoClass, String fileName, + HttpServletResponse response) throws IOException { + defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName)); + } + + public static void exportExcel(List> list, String fileName, HttpServletResponse response) throws IOException { + defaultExport(list, fileName, response); + } + + private static void defaultExport(List list, Class pojoClass, String fileName, + HttpServletResponse response, ExportParams exportParams) throws IOException { + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list); + downloadExcel(fileName, workbook, response); + } + + + public static void downloadExcel(String fileName, Workbook workbook, HttpServletResponse response) { + try { + fileName = URLEncoder.encode(fileName, "UTF-8"); + } catch (UnsupportedEncodingException e) { + log.error("", e); + } + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-Type", "application/vnd.ms-excel"); + response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls"); + try { + workbook.write(response.getOutputStream()); + workbook.close(); + } catch (IOException e) { + log.error("", e); + } + } + + private static void defaultExport(List> list, String fileName, HttpServletResponse response) throws IOException { + Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF); + downloadExcel(fileName, workbook, response); + } + + public static List importExcel(String filePath, Integer titleRows, Integer headerRows, Class pojoClass) { + if (StringUtils.isBlank(filePath)) { + return null; + } + ImportParams params = new ImportParams(); + params.setTitleRows(titleRows); + params.setHeadRows(headerRows); + List list = null; + try { + list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params); + } catch (NoSuchElementException e) { + //throw new NormalException("模板不能为空"); + } catch (Exception e) { + e.printStackTrace(); + } + return list; + } + + public static List importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class pojoClass) { + if (file == null) { + return null; + } + ImportParams params = new ImportParams(); + params.setTitleRows(titleRows); + params.setHeadRows(headerRows); + List list = null; + try { + list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params); + } catch (NoSuchElementException e) { + // throw new NormalException("excel文件不能为空"); + } catch (Exception e) { + //throw new NormalException(e.getMessage()); + System.out.println(e.getMessage()); + } + return list; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEnumUtil.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEnumUtil.java new file mode 100644 index 0000000..40c34a9 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartEnumUtil.java @@ -0,0 +1,165 @@ +package net.lab1024.sa.common.common.util; + +import net.lab1024.sa.common.common.enumeration.BaseEnum; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 枚举工具类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2017/10/10 18:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class SmartEnumUtil { + + /** + * 校验参数与枚举类比较是否合法 + * + * @param value 参数 + * @param enumClass 枚举类必须实现BaseEnum接口 + * @return boolean + * @Author 胡克 + */ + public static boolean checkEnum(Object value, Class enumClass) { + if (null == value) { + return false; + } + return Stream.of(enumClass.getEnumConstants()).anyMatch(e -> e.equalsValue(value)); + } + + /** + * 创建一个具有唯一array值的数组,每个值不包含在其他给定的数组中。 + * + * @param enumClass + * @param exclude + * @param + * @return + */ + public static List differenceValueList(Class enumClass, T... exclude) { + HashSet valueSet = new HashSet<>(); + if (exclude != null) { + valueSet.addAll(Stream.of(exclude).map(BaseEnum::getValue).collect(Collectors.toSet())); + } + + return Stream.of(enumClass.getEnumConstants()) + .filter(e -> !valueSet.contains(e.getValue())) + .map(BaseEnum::getValue) + .collect(Collectors.toList()); + } + + /** + * 获取枚举类的说明 value : info 的形式 + * + * @param enumClass + * @return String + */ + public static String getEnumDesc(Class enumClass) { + BaseEnum[] enums = enumClass.getEnumConstants(); + // value : info 的形式 + StringBuilder sb = new StringBuilder(); + for (BaseEnum baseEnum : enums) { + sb.append(baseEnum.getValue()).append(":").append(baseEnum.getDesc()).append(","); + } + return sb.toString(); + } + + /** + * 获取与参数相匹配的枚举类实例的 说明 + * + * @param value 参数 + * @param enumClass 枚举类必须实现BaseEnum接口 + * @return String 如无匹配枚举则返回null + */ + public static String getEnumDescByValue(Object value, Class enumClass) { + if (null == value) { + return null; + } + return Stream.of(enumClass.getEnumConstants()) + .filter(e -> e.equalsValue(value)) + .findFirst() + .map(BaseEnum::getDesc) + .orElse(null); + } + + public static String getEnumDescByValueList(Collection values, Class enumClass) { + if (CollectionUtils.isEmpty(values)) { + return ""; + } + return Stream.of(enumClass.getEnumConstants()).filter(e -> values.contains(e.getValue())).map(BaseEnum::getDesc).collect(Collectors.joining(",")); + } + + /** + * 根据参数获取枚举类的实例 + * + * @param value 参数 + * @param enumClass 枚举类必须实现BaseEnum接口 + * @return BaseEnum 无匹配值返回null + * @Author 胡克 + */ + public static T getEnumByValue(Object value, Class enumClass) { + if (null == value) { + return null; + } + return Stream.of(enumClass.getEnumConstants()) + .filter(e -> e.equalsValue(value)) + .findFirst() + .orElse(null); + } + + /** + * 根据实例描述与获取枚举类的实例 + * + * @param desc 参数描述 + * @param enumClass 枚举类必须实现BaseEnum接口 + * @return BaseEnum 无匹配值返回null + * @Author 胡克 + */ + public static T getEnumByDesc(String desc, Class enumClass) { + return Stream.of(enumClass.getEnumConstants()) + .filter(e -> Objects.equals(e.getDesc(), desc)) + .findFirst() + .orElse(null); + } + + + public static T getEnumByName(String name, Class enumClass) { + return Stream.of(enumClass.getEnumConstants()) + .filter(e -> StringUtils.equalsIgnoreCase(e.toString(), name)) + .findFirst() + .orElse(null); + } + + + /** + * 根据lambda getter/setter 注入 + * + * @param list + * @param getter + * @param setter + * @param enumClass + * @param + */ + public static void inject(List list, Function getter, BiConsumer setter, Class enumClass) { + if (list == null || list.isEmpty()) { + return; + } + for (T t : list) { + Integer enumValue = getter.apply(t); + if (enumValue != null) { + setter.accept(t, getEnumDescByValue(enumValue, enumClass)); + } + } + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartPageUtil.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartPageUtil.java new file mode 100644 index 0000000..2447ec3 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartPageUtil.java @@ -0,0 +1,122 @@ +package net.lab1024.sa.common.common.util; + +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Lists; +import net.lab1024.sa.common.common.domain.PageParam; +import net.lab1024.sa.common.common.domain.PageResult; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 分页工具类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-04-23 20:51:40 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class SmartPageUtil { + + /** + * 转换为查询参数 + * + * @param baseDTO + * @return + */ + public static Page convert2PageQuery(PageParam baseDTO) { + Page page = new Page<>(baseDTO.getPageNum(), baseDTO.getPageSize()); + // 设置排序字段 + List sortItemList = baseDTO.getSortItemList(); + if (CollectionUtils.isNotEmpty(sortItemList)) { + List orderItemList = sortItemList.stream().map(e -> new OrderItem(e.getColumn(), e.getIsAsc())).collect(Collectors.toList()); + page.setOrders(orderItemList); + } + return page; + } + + /** + * 转换为 PageResultDTO 对象 + * + * @param page + * @param sourceList 原list + * @param targetClazz 目标类 + * @return + */ + public static PageResult convert2PageResult(Page page, List sourceList, Class targetClazz) { + return convert2PageResult(page, SmartBeanUtil.copyList(sourceList, targetClazz)); + } + + /** + * 转换为 PageResultDTO 对象 + * + * @param page + * @param sourceList list + * @return + */ + public static PageResult convert2PageResult(Page page, List sourceList) { + PageResult pageResult = new PageResult<>(); + pageResult.setPageNum(page.getCurrent()); + pageResult.setPageSize(page.getSize()); + pageResult.setTotal(page.getTotal()); + pageResult.setPages(page.getPages()); + pageResult.setList(sourceList); + pageResult.setEmptyFlag(CollectionUtils.isEmpty(sourceList)); + return pageResult; + } + + public static PageResult emptyResult(Page page) { + PageResult pageResult = new PageResult<>(); + pageResult.setPageNum(page.getCurrent()); + pageResult.setPageSize(page.getSize()); + pageResult.setTotal(page.getTotal()); + pageResult.setPages(page.getPages()); + pageResult.setList(null); + pageResult.setEmptyFlag(true); + return pageResult; + } + + /** + * 转换分页结果对象 + * + * @param pageResult + * @param targetClazz + * @return + */ + public static PageResult convert2PageResult(PageResult pageResult, Class targetClazz) { + PageResult newPageResult = new PageResult<>(); + newPageResult.setPageNum(pageResult.getPageNum()); + newPageResult.setPageSize(pageResult.getPageSize()); + newPageResult.setTotal(pageResult.getTotal()); + newPageResult.setPages(pageResult.getPages()); + newPageResult.setEmptyFlag(pageResult.getEmptyFlag()); + newPageResult.setList(SmartBeanUtil.copyList(pageResult.getList(), targetClazz)); + return newPageResult; + } + + public static PageResult subListPage(Integer pageNum, Integer pageSize, List list) { + PageResult pageRet = new PageResult(); + //总条数 + int count = list.size(); + int pages = count % pageSize == 0 ? count / pageSize : (count / pageSize + 1); + int fromIndex = (pageNum - 1) * pageSize; + int toIndex = pageNum * pageSize > count ? count : pageNum * pageSize; + + if (pageNum > pages) { + pageRet.setList(Lists.newLinkedList()); + pageRet.setPageNum(pageNum.longValue()); + pageRet.setPages(Long.valueOf(pages)); + pageRet.setTotal(Long.valueOf(count)); + return pageRet; + } + List pageList = list.subList(fromIndex, toIndex); + pageRet.setList(pageList); + pageRet.setPageNum(pageNum.longValue()); + pageRet.setPages(Long.valueOf(pages)); + pageRet.setTotal(Long.valueOf(count)); + return pageRet; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java new file mode 100644 index 0000000..40210ba --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartRequestUtil.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.common.util; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.domain.RequestUser; + +/** + * 请求用户 工具类 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +public class SmartRequestUtil { + + private static final ThreadLocal requestThreadLocal = new ThreadLocal<>(); + + public static void setRequestUser(RequestUser requestUser) { + requestThreadLocal.set(requestUser); + } + + public static RequestUser getRequestUser() { + return requestThreadLocal.get(); + } + + public static Long getRequestUserId() { + RequestUser requestUser = getRequestUser(); + return null == requestUser ? null : requestUser.getUserId(); + } + + public static void remove() { + requestThreadLocal.remove(); + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartStringUtil.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartStringUtil.java new file mode 100644 index 0000000..230863a --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartStringUtil.java @@ -0,0 +1,334 @@ +package net.lab1024.sa.common.common.util; + + +import cn.hutool.core.util.StrUtil; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * 独有的字符串工具类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class SmartStringUtil extends StrUtil { + + // ===============split ======================= + + public static Set splitConvertToSet(String str, String split) { + if (isEmpty(str)) { + return new HashSet(); + } + String[] splitArr = str.split(split); + HashSet set = new HashSet(splitArr.length); + for (String string : splitArr) { + set.add(string); + } + return set; + } + + public static List splitConvertToList(String str, String split) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] splitArr = str.split(split); + ArrayList list = new ArrayList(splitArr.length); + for (String string : splitArr) { + list.add(string); + } + return list; + } + + // ===============split Integer======================= + + public static List splitConvertToIntList(String str, String split, int defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + int parseInt = Integer.parseInt(strArr[i]); + list.add(parseInt); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static Set splitConvertToIntSet(String str, String split, int defaultVal) { + if (isEmpty(str)) { + return new HashSet(); + } + String[] strArr = str.split(split); + HashSet set = new HashSet(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + int parseInt = Integer.parseInt(strArr[i]); + set.add(parseInt); + } catch (NumberFormatException e) { + set.add(defaultVal); + continue; + } + } + return set; + } + + public static Set splitConvertToIntSet(String str, String split) { + return splitConvertToIntSet(str, split, 0); + } + + public static List splitConvertToIntList(String str, String split) { + return splitConvertToIntList(str, split, 0); + } + + public static int[] splitConvertToIntArray(String str, String split, int defaultVal) { + if (isEmpty(str)) { + return new int[0]; + } + String[] strArr = str.split(split); + int[] result = new int[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Integer.parseInt(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static int[] splitConvertToIntArray(String str, String split) { + return splitConvertToIntArray(str, split, 0); + } + + // ===============split 2 Long======================= + + public static List splitConvertToLongList(String str, String split, long defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + long parseLong = Long.parseLong(strArr[i]); + list.add(parseLong); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConvertToLongList(String str, String split) { + return splitConvertToLongList(str, split, 0L); + } + + public static long[] splitConvertToLongArray(String str, String split, long defaultVal) { + if (isEmpty(str)) { + return new long[0]; + } + String[] strArr = str.split(split); + long[] result = new long[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Long.parseLong(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static long[] splitConvertToLongArray(String str, String split) { + return splitConvertToLongArray(str, split, 0L); + } + + // ===============split convert byte======================= + + public static List splitConvertToByteList(String str, String split, byte defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + byte parseByte = Byte.parseByte(strArr[i]); + list.add(parseByte); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConvertToByteList(String str, String split) { + return splitConvertToByteList(str, split, (byte) 0); + } + + public static byte[] splitConvertToByteArray(String str, String split, byte defaultVal) { + if (isEmpty(str)) { + return new byte[0]; + } + String[] strArr = str.split(split); + byte[] result = new byte[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Byte.parseByte(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static byte[] splitConvertToByteArray(String str, String split) { + return splitConvertToByteArray(str, split, (byte) 0); + } + + // ===============split convert double======================= + + public static List splitConvertToDoubleList(String str, String split, double defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + double parseByte = Double.parseDouble(strArr[i]); + list.add(parseByte); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConvertToDoubleList(String str, String split) { + return splitConvertToDoubleList(str, split, 0); + } + + public static double[] splitConvertToDoubleArray(String str, String split, double defaultVal) { + if (isEmpty(str)) { + return new double[0]; + } + String[] strArr = str.split(split); + double[] result = new double[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Double.parseDouble(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static double[] splitConvertToDoubleArray(String str, String split) { + return splitConvertToDoubleArray(str, split, 0); + } + + // ===============split convert float======================= + + public static List splitConvertToFloatList(String str, String split, float defaultVal) { + if (isEmpty(str)) { + return new ArrayList(); + } + String[] strArr = str.split(split); + List list = new ArrayList(strArr.length); + for (int i = 0; i < strArr.length; i++) { + try { + float parseByte = Float.parseFloat(strArr[i]); + list.add(parseByte); + } catch (NumberFormatException e) { + list.add(defaultVal); + continue; + } + } + return list; + } + + public static List splitConvertToFloatList(String str, String split) { + return splitConvertToFloatList(str, split, 0f); + } + + public static float[] splitConvertToFloatArray(String str, String split, float defaultVal) { + if (isEmpty(str)) { + return new float[0]; + } + String[] strArr = str.split(split); + float[] result = new float[strArr.length]; + for (int i = 0; i < strArr.length; i++) { + try { + result[i] = Float.parseFloat(strArr[i]); + } catch (NumberFormatException e) { + result[i] = defaultVal; + continue; + } + } + return result; + } + + public static float[] splitConvertToFloatArray(String str, String split) { + return splitConvertToFloatArray(str, split, 0f); + } + + + public static String upperCaseFirstChar(String str) { + if (str != null && !str.isEmpty()) { + char firstChar = str.charAt(0); + if (Character.isUpperCase(firstChar)) { + return str; + } else { + char[] values = str.toCharArray(); + values[0] = Character.toUpperCase(firstChar); + return new String(values); + } + } else { + return str; + } + } + + public static String replace(String content, int begin, int end, String newStr) { + if (begin < content.length() && begin >= 0) { + if (end <= content.length() && end >= 0) { + if (begin > end) { + return content; + } else { + StringBuilder starStr = new StringBuilder(); + + for (int i = begin; i < end; ++i) { + starStr.append(newStr); + } + + return content.substring(0, begin) + starStr + content.substring(end); + } + } else { + return content; + } + } else { + return content; + } + } + + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartVerificationUtil.java b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartVerificationUtil.java new file mode 100644 index 0000000..1012d09 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/util/SmartVerificationUtil.java @@ -0,0 +1,98 @@ +package net.lab1024.sa.common.common.util; + +import java.util.regex.Pattern; + +/** + * 验证工具类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2017/11/06 10:54 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class SmartVerificationUtil { + + /** + * 手机号码验证规则 + */ + public static final String PHONE_REGEXP = "^1[0-9]{10}"; + + /** + * 固定号码验证规则 + */ + public static final String FIXED_PHONE_REGEXP = "^0\\d{2,3}-[1-9]\\d{6,7}$"; + + /** + * 密码正则校验 + */ + public static final String PWD_REGEXP = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{6,32}$"; + + /** + * 车牌号 + */ + public static final String CAR_NUMBER = + "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]{1})))|" + "([A-HJ-Z" + "]{1}[A-D0-9]{1}[0-9]{3}警)))|" + + "([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})|" + "([VKHBSLJNGCE]{1}[A-DJ-PR" + "-TVY]{1}[0-9]{5})"; + + /** + * 日期年月日校验 yyyy-MM-dd HH:mm:ss + */ + public static final String DATE_TIME = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9" + + "]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"; + + /** + * 日期校验 yyyy-MM-dd + */ + public static final String DATE = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))" + + "|(02-(0[1-9]|[1][0-9]|2[0-8])))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)" + "([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9" + + "][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|(" + "(([0-9]{2})(0[48]|[2468][048]|[13579][26])|(" + "(0[48" + "]|[2468][048]|[3579][26])00))-02-29)"; + + public static final String DATE_TIME_HM = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9])$"; + + /** + * 年月校验 例: 2019-10 + */ + public static final String YEAR_MONTH = "^\\d{4}-((0([1-9]))|(1(0|1|2)))$"; + + /** + * 时间区间验证 10:23-19:00 + */ + public static final String TIME_SECTION = "^(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9])-(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9])$"; + + /** + * 时间验证 10:23 + */ + public static final String TIME = "^(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9])$"; + + /** + * 身份证号 + */ + public static final String ID_CARD = "(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)"; + + /** + * URL + */ + public static final String URL = "[a-zA-z]+://[^\\s]*"; + + /** + * 邮箱 + */ + public static final String EMAIL = "[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?"; + + /** + * 整数 + */ + public static final String INTEGER = "^-?[1-9]\\d*$"; + + /** + * 小数 + */ + public static final String DOUBLE = "^-?[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*$"; + + + public static void main(String[] args) { + boolean matches = Pattern.matches(INTEGER, "1"); + System.out.println(matches); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/validator/enumeration/CheckEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/common/validator/enumeration/CheckEnum.java new file mode 100644 index 0000000..dd708b3 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/validator/enumeration/CheckEnum.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.common.common.validator.enumeration; + + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义的属性校验注解,为了方便与校验属性的值是否为合法的枚举值 + * + * @Author 1024创新实验室: 胡克 + * @Date 2017/11/11 15:31 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = EnumValidator.class)// 自定义验证的处理类 +public @interface CheckEnum { + + /** + * 默认的错误提示信息 + * + * @return String + */ + String message(); + + /** + * 枚举类对象 必须实现BaseEnum接口 + * + * @return + */ + Class value(); + + /** + * 是否必须 + * + * @return boolean + */ + boolean required() default false; + + //下面这两个属性必须添加 :不然会报错 + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/validator/enumeration/EnumValidator.java b/sa-common/src/main/java/net/lab1024/sa/common/common/validator/enumeration/EnumValidator.java new file mode 100644 index 0000000..bd7ea12 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/validator/enumeration/EnumValidator.java @@ -0,0 +1,75 @@ +package net.lab1024.sa.common.common.validator.enumeration; + + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 枚举类校验器 + * + * @Author 1024创新实验室: 胡克 + * @Date 2017/11/11 15:34 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class EnumValidator implements ConstraintValidator { + + /** + * 枚举类实例集合 + */ + private List enumValList; + + /** + * 是否必须 + */ + private boolean required; + + @Override + public void initialize(CheckEnum constraintAnnotation) { + // 获取注解传入的枚举类对象 + required = constraintAnnotation.required(); + Class enumClass = constraintAnnotation.value(); + enumValList = Stream.of(enumClass.getEnumConstants()).map(BaseEnum::getValue).collect(Collectors.toList()); + } + + @Override + public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) { + // 判断是否必须 + if (null == value) { + return !required; + } + + if (value instanceof List) { + // 如果为 List 集合数据 + return this.checkList((List) value); + } + + // 校验是否为合法的枚举值 + return enumValList.contains(value); + } + + /** + * 校验集合类型 + * + * @param list + * @return + */ + private boolean checkList(List list) { + if (required && list.isEmpty()) { + // 必须的情况下 list 不能为空 + return false; + } + // 校验是否重复 + long count = list.stream().distinct().count(); + if (count != list.size()) { + return false; + } + return enumValList.containsAll(list); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/enums/PicType.java b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/enums/PicType.java new file mode 100644 index 0000000..b3a4cb8 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/enums/PicType.java @@ -0,0 +1,38 @@ +/* + * @(#) PicType.java 2017年4月19日 + * + * Copyright 2010 NetEase.com, Inc. All rights reserved. + */ +package net.lab1024.sa.common.common.wangyi.yidun.enums; + + + +/** + * + * @author hzdingyong + * @version 2017年4月19日 + */ +public enum PicType { + URL(1), + BASE64(2); + + private int type; + + private PicType(int type) { + this.type = type; + } + + public static boolean isValidType(int type) { + if (type != 1 && type != 2) { + return false; + } + return true; + } + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/enums/SignatureMethodEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/enums/SignatureMethodEnum.java new file mode 100644 index 0000000..ccf32a2 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/enums/SignatureMethodEnum.java @@ -0,0 +1,29 @@ +/* + * @(#) SignatureMethodEnum.java 2021-06-11 + * + * Copyright 2021 NetEase.com, Inc. All rights reserved. + */ + +package net.lab1024.sa.common.common.wangyi.yidun.enums; + +import org.apache.commons.lang3.StringUtils; + +/** + * @author yidun + * @version 2021-06-11 + */ +public enum SignatureMethodEnum { + MD5, + SHA1, + SHA256, + SM3; + + public static boolean isValid(String signatureMethod) { + try { + SignatureMethodEnum signatureMethodEnum = SignatureMethodEnum.valueOf(StringUtils.upperCase(signatureMethod)); + return signatureMethodEnum != null; + } catch (Exception e) { + return false; + } + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/resp/APIResponse.java b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/resp/APIResponse.java new file mode 100644 index 0000000..812929b --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/resp/APIResponse.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.common.common.wangyi.yidun.resp; + +/** + * Auto-generated: 2023-08-21 13:33:47 + * + * @author json.cn (i@json.cn) + * @website http://www.json.cn/java2pojo/ + */ +public class APIResponse { + + private int code; + private String msg; + private APIResult result; + + public void setCode(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public APIResult getResult() { + return result; + } + + public void setResult(APIResult result) { + this.result = result; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("APIResponse [code=").append(code).append(", msg=").append(msg).append(", result=") + .append(result).append("]"); + return builder.toString(); + } + + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/resp/APIResult.java b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/resp/APIResult.java new file mode 100644 index 0000000..0c4f271 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/resp/APIResult.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.common.common.wangyi.yidun.resp; + +/** + * Auto-generated: 2023-08-21 13:33:47 + * + * @author json.cn (i@json.cn) + * @website http://www.json.cn/java2pojo/ + */ +public class APIResult { + + private String taskId; + private int status; + private int reasonType; + private int isPayed; + public void setTaskId(String taskId) { + this.taskId = taskId; + } + public String getTaskId() { + return taskId; + } + + public void setStatus(int status) { + this.status = status; + } + public int getStatus() { + return status; + } + + public void setReasonType(int reasonType) { + this.reasonType = reasonType; + } + public int getReasonType() { + return reasonType; + } + + public void setIsPayed(int isPayed) { + this.isPayed = isPayed; + } + public int getIsPayed() { + return isPayed; + } + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("APIResult [taskId=").append(taskId).append(", status=").append(status).append(", reasonType=") + .append(reasonType).append(", isPayed=").append(isPayed).append("]"); + return builder.toString(); + } + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/sdk/BankCardCheckAPI.java b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/sdk/BankCardCheckAPI.java new file mode 100644 index 0000000..244145b --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/sdk/BankCardCheckAPI.java @@ -0,0 +1,97 @@ +/* + * @(#) ImageCheckAPIDemo.java 2016年3月15日 + * + * Copyright 2010 NetEase.com, Inc. All rights reserved. + */ +package net.lab1024.sa.common.common.wangyi.yidun.sdk; + +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import net.lab1024.sa.common.common.wangyi.yidun.resp.APIResponse; +import net.lab1024.sa.common.common.wangyi.yidun.resp.APIResult; +import net.lab1024.sa.common.common.wangyi.yidun.utils.ConstantUtil; +import net.lab1024.sa.common.common.wangyi.yidun.utils.SignatureUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + + +/** + * 银行卡认证 接口调用示例,该示例依赖以下jar包: + * 1. httpclient,用于发送http请求,详细见HttpClient4Utils.java + * 2. commons-codec,使用md5算法生成签名信息,详细见SignatureUtils.java + * 3. gson,用于做json解析 + * + * @author yidun + */ +public class BankCardCheckAPI { + + //public static void main(String[] args) { + // boolean check = check("刘小平", "36078219840215301X", "6214855100007273"); + // System.out.println("check = " + check); + //} + private final static Logger log = LoggerFactory.getLogger(BankCardCheckAPI.class); + + /** + * 业务ID,易盾根据产品业务特点分配 + */ + private final static String BUSINESS_ID = "3cb726bd85104161b25613153c4fba7c"; + /** + * 接口地址 + */ + private final static String API_URL = "https://verify.dun.163.com/v1/bankcard/check"; + + /** + * 银行卡认证 + * @param name + * @param idCardNo + * @param bankCardNo + * @return + * @throws Exception + */ + public static boolean check(String name, String idCardNo, String bankCardNo) { + Map params = new HashMap<>(10); + // 1.设置公共参数 + params.put("secretId", ConstantUtil.SECRET_ID); + params.put("businessId", BUSINESS_ID); + params.put("version", "v1"); + params.put("timestamp", String.valueOf(System.currentTimeMillis())); + params.put("nonce", String.valueOf(new Random().nextInt())); + // params.put("signatureMethod", "SM3"); // 可选参数,可选值为MD5、SHA1、SHA256、SM3。如果不传该字段,默认采用MD5算法生成签名。 + + // 2.设置私有参数 + params.put("name", name); + params.put("idCardNo", idCardNo.toUpperCase()); + params.put("bankCardNo", bankCardNo); + + // 3.生成签名信息 + String signature = null; + try { + signature = SignatureUtils.genSignature(ConstantUtil.SECRET_KEY, params); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + params.put("signature", signature); + + // 4.发送HTTP请求,这里使用的是HttpClient工具包,产品可自行选择自己熟悉的工具包发送请求 + String response = HttpUtil.post(API_URL, params); + + //5.解析报文返回 + APIResponse jObject = JSON.parseObject(response, APIResponse.class); + log.info("银行卡 认证结果:{}", jObject.toString()); + int code = jObject.getCode(); + boolean result = false; + if (code == 200) { + APIResult resultObject = jObject.getResult(); + int status = resultObject.getStatus(); + if (status == 1) { + result = true; + } + } + return result; + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/sdk/IdCardCheckAPI.java b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/sdk/IdCardCheckAPI.java new file mode 100644 index 0000000..f91e9f5 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/sdk/IdCardCheckAPI.java @@ -0,0 +1,88 @@ +/* + * @(#) ImageCheckAPIDemo.java 2016年3月15日 + * + * Copyright 2010 NetEase.com, Inc. All rights reserved. + */ +package net.lab1024.sa.common.common.wangyi.yidun.sdk; + +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import net.lab1024.sa.common.common.wangyi.yidun.resp.APIResponse; +import net.lab1024.sa.common.common.wangyi.yidun.resp.APIResult; +import net.lab1024.sa.common.common.wangyi.yidun.utils.ConstantUtil; +import net.lab1024.sa.common.common.wangyi.yidun.utils.SignatureUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +/** + * 实证认证-实名校验 接口调用示例,该示例依赖以下jar包: 1. + * httpclient,用于发送http请求,详细见HttpClient4Utils.java 2. + * commons-codec,使用md5算法生成签名信息,详细见SignatureUtils.java 3. gson,用于做json解析 + * + * @author yidun + */ +public class IdCardCheckAPI { + + private final static Logger log = LoggerFactory.getLogger(IdCardCheckAPI.class); + + /** + * 业务ID,易盾根据产品业务特点分配 + */ + private final static String BUSINESS_ID = "45a8fd254b4649e9bd25d773ac7ab666"; + /** + * 易盾身份认证服务身份证实名认证在线检测接口地址 + */ + private final static String API_URL = "https://verify.dun.163.com/v1/idcard/check"; + + /** + * 身份证 认证 + * + * @param name + * @param cardNo + * @return + * @throws Exception + */ + public static boolean check(String name, String cardNo) throws Exception { + Map params = new HashMap<>(8); + // 1.设置公共参数 + params.put("secretId", ConstantUtil.SECRET_ID); + params.put("businessId", BUSINESS_ID); + params.put("version", "v1"); + params.put("timestamp", String.valueOf(System.currentTimeMillis())); + params.put("nonce", String.valueOf(new Random().nextInt())); + // params.put("signatureMethod", "SM3"); // + // 可选参数,可选值为MD5、SHA1、SHA256、SM3。如果不传该字段,默认采用MD5算法生成签名。 + + // 2.设置私有参数 + params.put("name", name); + params.put("cardNo", cardNo); + + // 3.生成签名信息 + String signature = SignatureUtils.genSignature(ConstantUtil.SECRET_KEY, params); + params.put("signature", signature); + + // 4.发送HTTP请求,这里使用的是HttpClient工具包,产品可自行选择自己熟悉的工具包发送请求 + String response = HttpUtil.post(API_URL, params); + + // 5.解析接口返回值 + // JsonObject jObject = new + // JsonParser().parse(response).getAsJsonObject(); + APIResponse jObject = JSON.parseObject(response, APIResponse.class); + log.info("身份证 认证结果:", jObject.toString()); + int code = jObject.getCode(); + boolean result = false; + if (code == 200) { + APIResult resultObject = jObject.getResult(); + int status = resultObject.getStatus(); + if (status == 1) { + result = true; + } + } + return result; + } + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/utils/ConstantUtil.java b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/utils/ConstantUtil.java new file mode 100644 index 0000000..8c0349a --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/utils/ConstantUtil.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.common.common.wangyi.yidun.utils; + +/** + * 网易易盾 常量 + * @author haomingming + * + */ +public class ConstantUtil { + + /** + * 产品密钥ID,产品标识 + */ + public final static String SECRET_ID = "0bcf9a5633eb9ca9d196583e67c3762b"; + /** + * 产品私有密钥,服务端生成签名信息使用,请严格保管,避免泄露 + */ + public final static String SECRET_KEY = "b31e8220d115b6531a22ee71d1e89936"; + +} + diff --git a/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/utils/SignatureUtils.java b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/utils/SignatureUtils.java new file mode 100644 index 0000000..5c3b3c2 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/common/wangyi/yidun/utils/SignatureUtils.java @@ -0,0 +1,71 @@ +/* + * @(#) SignatureUtils.java 2016年2月2日 + * + * Copyright 2010 NetEase.com, Inc. All rights reserved. + */ +package net.lab1024.sa.common.common.wangyi.yidun.utils; + +import java.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.Map; + +import net.lab1024.sa.common.common.wangyi.yidun.enums.SignatureMethodEnum; +import org.apache.commons.codec.digest.DigestUtils; + +import org.apache.commons.lang3.StringUtils; + +/** + * 生成及验证签名信息工具类 + * @author hzgaomin + * @version 2016年2月2日 + */ +public class SignatureUtils { + + /** + * 生成签名信息 + * @param secretKey 产品私钥 + * @param params 接口请求参数名和参数值map,不包括signature参数名 + * @return + * @throws UnsupportedEncodingException + */ + public static String genSignature(String secretKey, Map params) throws UnsupportedEncodingException { + return genSignature(secretKey, params, (String) params.get("signatureMethod")); + } + + /** + * 生成签名信息 + * @param secretKey 产品私钥 + * @param params 接口请求参数名和参数值map,不包括signature参数名 + * @param signatureMethod 加密方法 + * @return + * @throws UnsupportedEncodingException + */ + public static String genSignature(String secretKey, Map params, String signatureMethod) throws UnsupportedEncodingException { + // 1. 参数名按照ASCII码表升序排序 + String[] keys = params.keySet().toArray(new String[0]); + Arrays.sort(keys); + + // 2. 按照排序拼接参数名与参数值 + StringBuffer paramBuffer = new StringBuffer(); + for (String key : keys) { + paramBuffer.append(key).append(params.get(key) == null ? "" : params.get(key)); + } + // 3. 将secretKey拼接到最后 + paramBuffer.append(secretKey); + + if (StringUtils.isEmpty(signatureMethod)) { + // 4. MD5是128位长度的摘要算法,用16进制表示,一个十六进制的字符能表示4个位,所以签名后的字符串长度固定为32个十六进制字符。 + return DigestUtils.md5Hex(paramBuffer.toString().getBytes("UTF-8")); + } else { + switch (SignatureMethodEnum.valueOf(StringUtils.upperCase(signatureMethod))) { + case MD5: + return DigestUtils.md5Hex(paramBuffer.toString().getBytes("UTF-8")); + case SHA256: + return DigestUtils.sha256Hex(paramBuffer.toString().getBytes("UTF-8")); + default: + return ""; + } + } + } + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/AsyncConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/AsyncConfig.java new file mode 100644 index 0000000..9d39c7c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/AsyncConfig.java @@ -0,0 +1,71 @@ +package net.lab1024.sa.common.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.AsyncTaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.lang.reflect.Method; +import java.util.Arrays; + +/** + * 异步调用线程配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Configuration +public class AsyncConfig { + + /** + * 线程池 配置bean名称 + */ + public static final String ASYNC_EXECUTOR_THREAD_NAME = "smart-admin-async-executor"; + + /** + * 配置线程池 + * + * @return + */ + @Bean(name = ASYNC_EXECUTOR_THREAD_NAME) + public AsyncTaskExecutor executor() { + int processors = Runtime.getRuntime().availableProcessors(); + int threadCount = Math.max(1, processors - 1); + ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); + // 核心线程数量 + taskExecutor.setCorePoolSize(threadCount); + // 最大线程数量 + taskExecutor.setMaxPoolSize(threadCount); + taskExecutor.setThreadNamePrefix(ASYNC_EXECUTOR_THREAD_NAME); + taskExecutor.initialize(); + return taskExecutor; + } + + /** + * spring 异步任务 异常配置 + */ + @Configuration + public static class AsyncExceptionConfig implements AsyncConfigurer { + @Override + public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { + return new AsyncExceptionHandler(); + } + } + + /** + * 自定义异常处理 + */ + public static class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler { + @Override + public void handleUncaughtException(Throwable throwable, Method method, Object... objects) { + log.error("异步任务发生异常:{}, 参数:{}, ", method.getDeclaringClass().getSimpleName() + "." + method.getName(), Arrays.toString(objects), throwable); + } + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/CorsFilterConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/CorsFilterConfig.java new file mode 100644 index 0000000..7cea2f0 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/CorsFilterConfig.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.common.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +/** + * 跨域配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021/11/15 20:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class CorsFilterConfig { + + @Value("${access-control-allow-origin}") + private String accessControlAllowOrigin; + + /** + * 跨域配置 + * + * @return + */ + @Bean + public CorsFilter corsFilter () { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + // 设置访问源地址 + config.addAllowedOriginPattern(accessControlAllowOrigin); + // 设置访问源请求头 + config.addAllowedHeader("*"); + // 设置访问源请求方法 + config.addAllowedMethod("*"); + // 对接口配置跨域设置 + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/DataSourceConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/DataSourceConfig.java new file mode 100644 index 0000000..cb937a0 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/DataSourceConfig.java @@ -0,0 +1,197 @@ +package net.lab1024.sa.common.config; + +import com.alibaba.druid.filter.Filter; +import com.alibaba.druid.filter.stat.StatFilter; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.support.http.StatViewServlet; +import com.alibaba.druid.support.http.WebStatFilter; +import com.alibaba.druid.support.spring.stat.DruidStatInterceptor; +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.domain.DataScopePlugin; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.session.SqlSessionFactory; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.aop.support.JdkRegexpMethodPointcut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 数据源配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2017-11-28 15:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Configuration +public class DataSourceConfig { + + @Value("${spring.datasource.driver-class-name}") + String driver; + + @Value("${spring.datasource.url}") + String url; + + @Value("${spring.datasource.username}") + String username; + + @Value("${spring.datasource.password}") + String password; + + @Value("${spring.datasource.initial-size}") + int initialSize; + + @Value("${spring.datasource.min-idle}") + int minIdle; + + @Value("${spring.datasource.max-active}") + int maxActive; + + @Value("${spring.datasource.max-wait}") + long maxWait; + + @Value("${spring.datasource.time-between-eviction-runs-millis}") + long timeBetweenEvictionRunsMillis; + + @Value("${spring.datasource.min-evictable-idle-time-millis}") + long minEvictableIdleTimeMillis; + + @Value("${spring.datasource.filters}") + String filters; + + @Value("${spring.datasource.druid.username}") + String druidUserName; + + @Value("${spring.datasource.druid.password}") + String druidPassword; + + @Value("${spring.datasource.druid.login.enabled}") + boolean druidLoginEnable; + @Value("${spring.datasource.druid.method.pointcut}") + String methodPointcut; + + @Autowired + private MybatisPlusInterceptor paginationInterceptor; + + @Autowired(required = false) + private DataScopePlugin dataScopePlugin; + + @Bean + @Primary + public DataSource druidDataSource() { + DruidDataSource druidDataSource = new DruidDataSource(); + druidDataSource.setDbType(DbType.MYSQL.getDb()); + druidDataSource.setDriverClassName(driver); + druidDataSource.setUrl(url); + druidDataSource.setUsername(username); + druidDataSource.setPassword(password); + druidDataSource.setInitialSize(initialSize); + druidDataSource.setMinIdle(minIdle); + druidDataSource.setMaxActive(maxActive); + druidDataSource.setMaxWait(maxWait); + druidDataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); + druidDataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); + druidDataSource.setValidationQuery("SELECT 1"); + try { + druidDataSource.setFilters(filters); + ArrayList arrayList = new ArrayList<>(); + StatFilter statFilter = new StatFilter(); + statFilter.setMergeSql(true); + statFilter.setSlowSqlMillis(500); + statFilter.setLogSlowSql(true); + arrayList.add(statFilter); + druidDataSource.setProxyFilters(arrayList); + druidDataSource.init(); + } catch (SQLException e) { + log.error("初始化数据源出错", e); + } + + return druidDataSource; + } + + @Bean + public SqlSessionFactory sqlSessionFactory() throws Exception { + MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean(); + factoryBean.setDataSource(druidDataSource()); + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + Resource[] resources = resolver.getResources("classpath*:/mapper/**/*.xml"); + factoryBean.setMapperLocations(resources); + + // 设置 MyBatis-Plus 分页插件 注意此处myBatisPlugin一定要放在后面 + List pluginsList = new ArrayList<>(); + pluginsList.add(paginationInterceptor); + if (dataScopePlugin != null) { + pluginsList.add(dataScopePlugin); + } + factoryBean.setPlugins(pluginsList.toArray(new Interceptor[pluginsList.size()])); + + return factoryBean.getObject(); + } + + /** + * 非正式环境 才加载 + * + * @return + */ + @Conditional(SystemEnvironmentConfig.class) + @Bean + public ServletRegistrationBean druidServlet() { + ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean<>(); + servletRegistrationBean.setServlet(new StatViewServlet()); + servletRegistrationBean.addUrlMappings("/druid/*"); + Map initParameters = new HashMap(); + //不设置用户名密码可以直接通过druid/index.html访问 + if (druidLoginEnable) { + initParameters.put("loginUsername", druidUserName); + initParameters.put("loginPassword", druidPassword); + } + initParameters.put("resetEnable", "false"); + servletRegistrationBean.setInitParameters(initParameters); + return servletRegistrationBean; + } + + @Bean + public FilterRegistrationBean filterRegistrationBean() { + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); + filterRegistrationBean.setFilter(new WebStatFilter()); + filterRegistrationBean.addUrlPatterns("/*"); + filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/*"); + return filterRegistrationBean; + } + + @Bean + public JdkRegexpMethodPointcut jdkRegexpMethodPointcut() { + JdkRegexpMethodPointcut jdkRegexpMethodPointcut = new JdkRegexpMethodPointcut(); + jdkRegexpMethodPointcut.setPatterns(methodPointcut); + return jdkRegexpMethodPointcut; + } + + @Bean + public DefaultPointcutAdvisor defaultPointcutAdvisor() { + DefaultPointcutAdvisor pointcutAdvisor = new DefaultPointcutAdvisor(); + pointcutAdvisor.setPointcut(jdkRegexpMethodPointcut()); + pointcutAdvisor.setAdvice(new DruidStatInterceptor()); + return pointcutAdvisor; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/DateConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/DateConfig.java new file mode 100644 index 0000000..5faee79 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/DateConfig.java @@ -0,0 +1,88 @@ +package net.lab1024.sa.common.config; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.LocalDateTimeUtil; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import org.apache.commons.lang3.StringUtils; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeParseException; + +/** + * java8 localDate 时间类格式化配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2017-11-28 15:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class DateConfig { + + @Bean + public Jackson2ObjectMapperBuilderCustomizer customizer() { + return builder -> { + builder.deserializers(new LocalDateDeserializer(DatePattern.NORM_DATE_FORMAT.getDateTimeFormatter())); + builder.deserializers(new LocalDateTimeDeserializer(DatePattern.NORM_DATETIME_FORMAT.getDateTimeFormatter())); + builder.serializers(new LocalDateSerializer(DatePattern.NORM_DATE_FORMAT.getDateTimeFormatter())); + builder.serializers(new LocalDateTimeSerializer(DatePattern.NORM_DATETIME_FORMAT.getDateTimeFormatter())); + }; + } + + + /** + * string 转为 LocalDateTime 配置类 + * + * @author 卓大 + */ + @Configuration + public static class StringToLocalDateTime implements Converter { + + @Override + public LocalDateTime convert(String str) { + if (StringUtils.isBlank(str)) { + return null; + } + LocalDateTime localDateTime; + try { + localDateTime = LocalDateTimeUtil.parse(str, DatePattern.NORM_DATETIME_FORMAT.getDateTimeFormatter()); + } catch (DateTimeParseException e) { + throw new RuntimeException("请输入正确的日期格式:yyyy-MM-dd HH:mm:ss"); + } + return localDateTime; + } + } + + + /** + * string 转为 LocalDate 配置类 + * + * @author 卓大 + */ + @Configuration + public static class StringToLocalDate implements Converter { + + @Override + public LocalDate convert(String str) { + if (StringUtils.isBlank(str)) { + return null; + } + LocalDate localDate; + try { + localDate = LocalDateTimeUtil.parseDate(str, DatePattern.NORM_DATE_FORMAT.getDateTimeFormatter()); + } catch (DateTimeParseException e) { + throw new RuntimeException("请输入正确的日期格式:yyyy-MM-dd"); + } + return localDate; + } + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/FileCloudConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/FileCloudConfig.java new file mode 100644 index 0000000..c728596 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/FileCloudConfig.java @@ -0,0 +1,85 @@ +package net.lab1024.sa.common.config; + +import com.amazonaws.ClientConfiguration; +import com.amazonaws.Protocol; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.client.builder.AwsClientBuilder; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import lombok.Data; +import net.lab1024.sa.common.module.support.file.service.FileStorageCloudServiceImpl; +import net.lab1024.sa.common.module.support.file.service.FileStorageLocalServiceImpl; +import net.lab1024.sa.common.module.support.file.service.IFileStorageService; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 文件上传 配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019-09-02 23:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@Configuration +public class FileCloudConfig { + + @Value("${file.storage.cloud.region}") + private String region; + + @Value("${file.storage.cloud.endpoint}") + private String endpoint; + + @Value("${file.storage.cloud.bucket-name}") + private String bucketName; + + @Value("${file.storage.cloud.access-key}") + private String accessKey; + + @Value("${file.storage.cloud.secret-key}") + private String secretKey; + + @Value("${file.storage.cloud.url.expire}") + private Long urlExpire; + + @Value("${file.storage.cloud.url.public}") + private String publicUrl; + + /** + * 初始化 云oss client 配置 + * + * @return + */ + @Bean + @ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = "cloud") + public AmazonS3 initAmazonS3() { + ClientConfiguration clientConfig = new ClientConfiguration(); + clientConfig.setProtocol(Protocol.HTTPS); + AmazonS3 s3Client = AmazonS3ClientBuilder.standard() + .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey))) + .withClientConfiguration(clientConfig) + .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpoint, region)) + .withPathStyleAccessEnabled(false) + .build(); + return s3Client; + } + + @Bean + @ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = "cloud") + public IFileStorageService initCloudFileService() { + return new FileStorageCloudServiceImpl(); + } + + @Bean + @ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = "local") + public IFileStorageService initLocalFileService() { + return new FileStorageLocalServiceImpl(); + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/HeartBeatConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/HeartBeatConfig.java new file mode 100644 index 0000000..56e8765 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/HeartBeatConfig.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.common.config; + +import net.lab1024.sa.common.module.support.heartbeat.core.HeartBeatManager; +import net.lab1024.sa.common.module.support.heartbeat.core.IHeartBeatRecordHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 心跳配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2018/10/9 18:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class HeartBeatConfig { + + /** + * 间隔时间 + */ + @Value("${heart-beat.interval-seconds}") + private Long intervalSeconds; + + @Autowired + private IHeartBeatRecordHandler heartBeatRecordHandler; + + @Bean + public HeartBeatManager heartBeatManager() { + return new HeartBeatManager(intervalSeconds * 1000L, heartBeatRecordHandler); + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java new file mode 100644 index 0000000..c08339c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/MvcConfig.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.common.config; + +import net.lab1024.sa.common.common.interceptor.AbstractInterceptor; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +/** + * web相关配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class MvcConfig implements WebMvcConfigurer { + + @Autowired(required = false) + private List interceptorList; + + @Override + public void addInterceptors (InterceptorRegistry registry) { + if (CollectionUtils.isEmpty(interceptorList)) { + return; + } + interceptorList.forEach(e->{ + registry.addInterceptor(e).addPathPatterns("/**"); + }); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/preview/**"); + } + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/druidMonitor").setViewName("redirect:druid/index.html"); + registry.addViewController("/swaggerApi").setViewName("redirect:swagger-ui.html"); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/MybatisPlusConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/MybatisPlusConfig.java new file mode 100644 index 0000000..f946abe --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/MybatisPlusConfig.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.common.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * mp 插件 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@EnableTransactionManagement +@Configuration +public class MybatisPlusConfig { + + /** + * 分页插件 + */ + @Bean + public MybatisPlusInterceptor paginationInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + return interceptor; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/PostProcessorConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/PostProcessorConfig.java new file mode 100644 index 0000000..827b499 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/PostProcessorConfig.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.common.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.env.EnvironmentPostProcessor; +import org.springframework.boot.env.YamlPropertySourceLoader; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import java.io.IOException; +import java.util.List; + +/** + * yaml 读取配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +@Slf4j +public class PostProcessorConfig implements EnvironmentPostProcessor { + + private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader(); + + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { + MutablePropertySources propertySources = environment.getPropertySources(); + this.loadProperty(propertySources); + } + + private void loadProperty(MutablePropertySources propertySources) { + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + try { + Resource[] resources = resolver.getResources("classpath*:sa-*.yaml"); + if (resources.length < 1) { + return; + } + for (Resource resource : resources) { + log.info("初始化系统配置:{}", resource.getFilename()); + List> load = loader.load(resource.getFilename(), resource); + load.forEach(propertySources::addLast); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/RedisConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/RedisConfig.java new file mode 100644 index 0000000..cd072f1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/RedisConfig.java @@ -0,0 +1,72 @@ +package net.lab1024.sa.common.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.*; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * redis配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Configuration +public class RedisConfig { + + @Autowired + private RedisConnectionFactory factory; + + @Bean + public RedisTemplate redisTemplate() { + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper om = new ObjectMapper(); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + RedisTemplate template = new RedisTemplate(); + template.setConnectionFactory(factory); + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(jackson2JsonRedisSerializer); + template.setHashKeySerializer(jackson2JsonRedisSerializer); + template.setHashValueSerializer(jackson2JsonRedisSerializer); + template.setDefaultSerializer(new StringRedisSerializer()); + template.afterPropertiesSet(); + return template; + } + + @Bean + public HashOperations hashOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForHash(); + } + + @Bean + public ValueOperations valueOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForValue(); + } + + @Bean + public ListOperations listOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForList(); + } + + @Bean + public SetOperations setOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForSet(); + } + + @Bean + public ZSetOperations zSetOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForZSet(); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/ReloadConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/ReloadConfig.java new file mode 100644 index 0000000..1c31dce --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/ReloadConfig.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.config; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.module.support.reload.ReloadCommand; +import net.lab1024.sa.common.module.support.reload.core.SmartReloadManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * reload配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/9/1 21:40 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Configuration +public class ReloadConfig { + + /** + * 间隔时间 + */ + @Value("${reload.interval-seconds}") + private Integer intervalSeconds; + + @Autowired + private ReloadCommand reloadCommand; + + @Bean + public SmartReloadManager initSmartReloadManager() { + // 创建 Reload Manager 调度器 + return new SmartReloadManager(reloadCommand,intervalSeconds); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/RepeatSubmitConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/RepeatSubmitConfig.java new file mode 100644 index 0000000..fcfdd5e --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/RepeatSubmitConfig.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.common.config; + +import net.lab1024.sa.common.common.constant.StringConst; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.repeatsubmit.RepeatSubmitAspect; +import net.lab1024.sa.common.module.support.repeatsubmit.ticket.RepeatSubmitCaffeineTicket; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 重复提交配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021/10/9 18:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class RepeatSubmitConfig { + + @Bean + public RepeatSubmitAspect repeatSubmitAspect() { + RepeatSubmitCaffeineTicket caffeineTicket = new RepeatSubmitCaffeineTicket(this::ticket); + return new RepeatSubmitAspect(caffeineTicket); + } + + /** + * 获取指明某个用户的凭证 + * + * @return + */ + private String ticket(String servletPath) { + Long userId = SmartRequestUtil.getRequestUserId(); + if (null == userId) { + return StringConst.EMPTY; + } + return servletPath + "_" + userId; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/RestTemplateConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/RestTemplateConfig.java new file mode 100644 index 0000000..d14004c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/RestTemplateConfig.java @@ -0,0 +1,130 @@ +package net.lab1024.sa.common.config; + +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import okhttp3.ConnectionPool; +import okhttp3.OkHttpClient; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.client.OkHttp3ClientHttpRequestFactory; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * http请求配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class RestTemplateConfig { + + @Value("${http.pool.max-total}") + private Integer maxTotal; + + @Value("${http.pool.connect-timeout}") + private Integer connectTimeout; + + @Value("${http.pool.read-timeout}") + private Integer readTimeout; + + @Value("${http.pool.write-timeout}") + private Integer writeTimeout; + + @Value("${http.pool.keep-alive}") + private Integer keepAlive; + + @Bean + public RestTemplate restTemplate() { + RestTemplate restTemplate = new RestTemplate(); + restTemplate.setRequestFactory(this.clientHttpRequestFactory()); + List> messageConverterList = restTemplate.getMessageConverters(); + messageConverterList.add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8)); + messageConverterList.addAll(this.converters()); + return restTemplate; + } + + public List> converters() { + List> converters = new ArrayList<>(); + HttpMessageConverter converter = new StringHttpMessageConverter(StandardCharsets.UTF_8); + FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); + List fastMediaTypes = new ArrayList<>(); + fastMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED); + fastMediaTypes.add(MediaType.APPLICATION_JSON); + fastConverter.setSupportedMediaTypes(fastMediaTypes); + converters.add(converter); + converters.add(fastConverter); + return converters; + } + + + public OkHttp3ClientHttpRequestFactory clientHttpRequestFactory() { + return new OkHttp3ClientHttpRequestFactory(httpClientBuilder()); + } + + public OkHttpClient httpClientBuilder() { + return new OkHttpClient.Builder() + .retryOnConnectionFailure(true) + .connectionPool(this.pool()) + .connectTimeout(connectTimeout, TimeUnit.MILLISECONDS) + .readTimeout(readTimeout, TimeUnit.MILLISECONDS) + .writeTimeout(writeTimeout, TimeUnit.MILLISECONDS) + .build(); + } + + public ConnectionPool pool() { + return new ConnectionPool(maxTotal, keepAlive, TimeUnit.MILLISECONDS); + } + + + @Bean + public X509TrustManager x509TrustManager() { + return new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + }; + } + + @Bean + public SSLSocketFactory sslSocketFactory() { + try { + //信任任何链接 + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom()); + return sslContext.getSocketFactory(); + } catch (NoSuchAlgorithmException | KeyManagementException e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/ScheduleConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/ScheduleConfig.java new file mode 100644 index 0000000..a156a41 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/ScheduleConfig.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.common.config; + +import lombok.extern.slf4j.Slf4j; +import org.apache.logging.log4j.util.Strings; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.SchedulingConfigurer; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; +import org.springframework.scheduling.config.Task; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 定时任务调度 配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Configuration +public class ScheduleConfig implements SchedulingConfigurer { + + private ScheduledTaskRegistrar taskRegistrar; + + @Override + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + this.taskRegistrar = taskRegistrar; + } + + public String destroy() { + List taskList = new ArrayList<>(); + taskList.addAll(taskRegistrar.getCronTaskList()); + taskList.addAll(taskRegistrar.getTriggerTaskList()); + taskList.addAll(taskRegistrar.getFixedDelayTaskList()); + taskList.addAll(taskRegistrar.getFixedRateTaskList()); + + taskRegistrar.destroy(); + + List taskNameList = taskList.stream().map(Task::toString).collect(Collectors.toList()); + return "已关闭 @Scheduled定时任务:" + taskNameList.size() + "个!"; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java new file mode 100644 index 0000000..d577eb6 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/SwaggerConfig.java @@ -0,0 +1,206 @@ +package net.lab1024.sa.common.config; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Lists; +import io.swagger.annotations.Api; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.constant.RequestHeaderConst; +import net.lab1024.sa.common.common.swagger.SwaggerApiModelPropertyEnumPlugin; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; +import org.springframework.context.EnvironmentAware; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.RequestHandler; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.service.Parameter; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger.common.SwaggerPluginSupport; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 根据SwaggerTagConst内部类动态生成Swagger group + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020-03-25 22:54:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@EnableSwagger2 +@Configuration +@Conditional(SystemEnvironmentConfig.class) +public class SwaggerConfig implements EnvironmentAware, BeanDefinitionRegistryPostProcessor { + + /** + * 文档标题 + */ + private String title; + + /** + * 文档描述 + */ + private String description; + + /** + * api版本 + */ + private String version; + + /** + * service url + */ + private String teamUrl; + + /** + * host + */ + private String host; + + private String tagClass; + + @Bean + @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1) + public SwaggerApiModelPropertyEnumPlugin swaggerEnum() { + return new SwaggerApiModelPropertyEnumPlugin(); + } + + @Override + public void setEnvironment(Environment environment) { + this.title = environment.getProperty("swagger.title"); + this.description = environment.getProperty("swagger.description"); + this.version = environment.getProperty("swagger.version"); + this.host = environment.getProperty("swagger.host"); + this.tagClass = environment.getProperty("swagger.tag-class"); + this.teamUrl = environment.getProperty("swagger.team-url"); + } + + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { + Map> groupMap = this.buildGroup(); + for (Map.Entry> entry : groupMap.entrySet()) { + String group = entry.getKey(); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Docket.class, () -> this.baseDocket(group, entry.getValue())); + BeanDefinition beanDefinition = builder.getRawBeanDefinition(); + registry.registerBeanDefinition(group + "Api", beanDefinition); + } + } + + @SneakyThrows + private Map> buildGroup() { + Class clazz = Class.forName(tagClass); + Class[] innerClazz = clazz.getClasses(); + Map> groupMap = new HashMap<>(16); + for (Class cls : innerClazz) { + String group = cls.getSimpleName(); + List apiTags = Lists.newArrayList(); + Field[] fields = cls.getDeclaredFields(); + for (Field field : fields) { + boolean isFinal = Modifier.isFinal(field.getModifiers()); + if (isFinal) { + apiTags.add(field.get(null).toString()); + } + } + groupMap.put(group, apiTags); + } + return groupMap; + } + + private Docket baseDocket(String groupName, List apiTagList) { + // 配置全局参数 + List parameterList = this.generateParameter(); + + Docket docket = new Docket(DocumentationType.SWAGGER_2).groupName(groupName) + .forCodeGeneration(true) + .select() + // 过滤规则 + .apis(this.getControllerPredicate(apiTagList)) + // 与 过滤规则 controller 包路径 二选一 + // .apis(RequestHandlerSelectors.basePackage(packAge)) + .paths(PathSelectors.any()) + .build().apiInfo(this.apiInfo()) + .globalOperationParameters(parameterList); + if (StringUtils.isNotBlank(host)) { + docket = docket.host(host); + } + return docket; + } + + private Predicate getControllerPredicate(List apiTagList) { + Predicate methodPredicate = (input) -> { + Api api = null; + Optional apiOptional = input.findControllerAnnotation(Api.class); + if (apiOptional.isPresent()) { + api = apiOptional.get(); + } + if (api == null) { + return false; + } + List tags = Arrays.asList(api.tags()); + if (apiTagList.containsAll(tags)) { + return true; + } + return false; + }; + Predicate controllerPredicate = Predicates.or(RequestHandlerSelectors.withClassAnnotation(RestController.class), RequestHandlerSelectors.withClassAnnotation(Controller.class)); + return Predicates.and(controllerPredicate, methodPredicate); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder().title(title) + .description(description) + .version(version) + .termsOfServiceUrl(teamUrl) + .contact(new Contact("", teamUrl, "")) + .build(); + } + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { + + } + + /** + * 生成共用请求参数 + * + * @return + */ + private List generateParameter() { + // 配置全局参数 token + Parameter token = new ParameterBuilder().name(RequestHeaderConst.TOKEN) + .description("token") + .modelRef(new ModelRef("string")) + .parameterType("header").defaultValue("1") + .required(false) + .build(); + return Lists.newArrayList(token); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/SystemEnvironmentConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/SystemEnvironmentConfig.java new file mode 100644 index 0000000..1af9577 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/SystemEnvironmentConfig.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.common.config; + +import net.lab1024.sa.common.common.domain.SystemEnvironment; +import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum; +import net.lab1024.sa.common.common.util.SmartEnumUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.type.AnnotatedTypeMetadata; + +/** + * 系统环境 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/08/13 18:56 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class SystemEnvironmentConfig implements Condition { + + @Value("${spring.profiles.active}") + private String systemEnvironment; + + @Value("${project.name}") + private String projectName; + + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { + String property = conditionContext.getEnvironment().getProperty("spring.profiles.active"); + return StringUtils.isNotBlank(property) && !SystemEnvironmentEnum.PROD.equalsValue(property); + } + + @Bean + public SystemEnvironment initEnvironment() { + SystemEnvironmentEnum currentEnvironment = SmartEnumUtil.getEnumByValue(systemEnvironment, SystemEnvironmentEnum.class); + if (currentEnvironment == null) { + throw new ExceptionInInitializerError("无法获取当前环境!请在 application.yaml 配置参数:spring.profiles.active"); + } + if (StringUtils.isBlank(projectName)) { + throw new ExceptionInInitializerError("无法获取当前项目名称!请在 application.yaml 配置参数:project.name"); + } + return new SystemEnvironment(currentEnvironment == SystemEnvironmentEnum.PROD, projectName, currentEnvironment); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java new file mode 100644 index 0000000..6e8ae11 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/config/UrlConfig.java @@ -0,0 +1,150 @@ +package net.lab1024.sa.common.config; + +import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.annoation.NoNeedLogin; +import net.lab1024.sa.common.common.annoation.SaAuth; +import net.lab1024.sa.common.common.domain.RequestUrlVO; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * url配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +@Slf4j +public class UrlConfig { + @Autowired + private RequestMappingHandlerMapping requestMappingHandlerMapping; + + + /** + * 获取每个方法的请求路径 + * + * @return + */ + @Bean + public Map> methodUrlMap() { + Map> methodUrlMap = Maps.newHashMap(); + //获取url与类和方法的对应信息 + Map map = requestMappingHandlerMapping.getHandlerMethods(); + for (Map.Entry entry : map.entrySet()) { + RequestMappingInfo requestMappingInfo = entry.getKey(); + + Set urls = requestMappingInfo.getPatternsCondition().getPatterns(); + if (CollectionUtils.isEmpty(urls)) { + continue; + } + HandlerMethod handlerMethod = entry.getValue(); + methodUrlMap.put(handlerMethod.getMethod(), urls); + } + return methodUrlMap; + } + + /** + * 需要进行url权限校验的方法 + * + * @param methodUrlMap + * @return + */ + @Bean + public List authUrl(Map> methodUrlMap) { + List authUrlList = Lists.newArrayList(); + for (Map.Entry> entry : methodUrlMap.entrySet()) { + Method method = entry.getKey(); + SaAuth saAuth = method.getAnnotation(SaAuth.class); + if (null == saAuth) { + continue; + } + List requestUrlList = this.buildRequestUrl(method, entry.getValue()); + authUrlList.addAll(requestUrlList); + } + log.info("需要权限校验的URL:{}", authUrlList.stream().map(e -> e.getUrl()).collect(Collectors.toList())); + return authUrlList; + } + + private List buildRequestUrl(Method method, Set urlSet) { + List requestUrlList = Lists.newArrayList(); + if (CollectionUtils.isEmpty(urlSet)) { + return requestUrlList; + } + //url对应的方法名称 + String className = method.getDeclaringClass().getName(); + String methodName = method.getName(); + List list = StrUtil.split(className, "."); + String controllerName = list.get(list.size() - 1); + String name = controllerName + "." + methodName; + //swagger 说明信息 + String methodComment = null; + ApiOperation apiOperation = method.getAnnotation(ApiOperation.class); + if (apiOperation != null) { + methodComment = apiOperation.value(); + } + for (String url : urlSet) { + RequestUrlVO requestUrlVO = new RequestUrlVO(); + requestUrlVO.setUrl(url); + requestUrlVO.setName(name); + requestUrlVO.setComment(methodComment); + requestUrlList.add(requestUrlVO); + } + return requestUrlList; + } + + + /** + * 获取无需登录可以匿名访问的url信息 + * + * @return + */ + @Bean + public List noNeedLoginUrlList(Map> methodUrlMap) { + List noNeedLoginUrlList = Lists.newArrayList(); + for (Map.Entry> entry : methodUrlMap.entrySet()) { + Method method = entry.getKey(); + NoNeedLogin noNeedLogin = method.getAnnotation(NoNeedLogin.class); + if (null == noNeedLogin) { + continue; + } + noNeedLoginUrlList.addAll(entry.getValue()); + } + log.info("不需要登录的URL:{}", noNeedLoginUrlList); + return noNeedLoginUrlList; + } + + /** + * 获取忽略的url信息 + * + * @return + */ + @Bean + public List ignoreUrlList() { + List ignoreUrlList = Lists.newArrayList(); + ignoreUrlList.add("/swagger-ui.html"); + ignoreUrlList.add("/swagger-resources/**"); + ignoreUrlList.add("/webjars/**"); + ignoreUrlList.add("/druid/**"); + ignoreUrlList.add("/*/api-docs"); + return ignoreUrlList; + } + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/constant/CacheKeyConst.java b/sa-common/src/main/java/net/lab1024/sa/common/constant/CacheKeyConst.java new file mode 100644 index 0000000..ef91a80 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/constant/CacheKeyConst.java @@ -0,0 +1,14 @@ +package net.lab1024.sa.common.constant; + +/** + * 缓存key常量 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class CacheKeyConst { + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/constant/RedisKeyConst.java b/sa-common/src/main/java/net/lab1024/sa/common/constant/RedisKeyConst.java new file mode 100644 index 0000000..9abb7af --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/constant/RedisKeyConst.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.common.constant; + +/** + * redis key 常量类 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class RedisKeyConst { + + public static final String SEPARATOR = ":"; + + public static class Support { + + public static final String FILE_URL = "file:"; + + public static final String FILE_VO = "file-vo:"; + + public static final String SERIAL_NUMBER_LAST_INFO = "serial-number:last-info"; + + public static final String SERIAL_NUMBER = "serial-number:"; + + public static final String CAPTCHA = "captcha:"; + + public static final String TOKEN = "token:"; + + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/constant/ReloadConst.java b/sa-common/src/main/java/net/lab1024/sa/common/constant/ReloadConst.java new file mode 100644 index 0000000..635dc38 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/constant/ReloadConst.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.common.constant; + +/** + * reload 项目 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class ReloadConst { + + public static final String CONFIG_RELOAD = "system_config"; + + public static final String CACHE_SERVICE = "cache_service"; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/constant/SwaggerTagConst.java b/sa-common/src/main/java/net/lab1024/sa/common/constant/SwaggerTagConst.java new file mode 100644 index 0000000..ebc7bdb --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/constant/SwaggerTagConst.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.common.constant; + +/** + * swagger + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-05-30 21:22:12 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class SwaggerTagConst { + + public static class Support { + + public static final String CACHE = "业务支撑-缓存"; + + public static final String CAPTCHA = "业务支撑-验证码"; + + public static final String OPERATE_LOG = "业务支撑-用户操作记录"; + + public static final String LOGIN_LOG = "业务支撑-登录日志"; + + public static final String RELOAD = "业务支撑-reload"; + + public static final String SERIAL_NUMBER = "业务支撑-id生成器"; + + public static final String HEART_BEAT = "业务支撑-服务心跳"; + + public static final String FILE = "业务支撑-文件服务"; + + public static final String CONFIG = "业务支撑-系统参数"; + + public static final String DATA_TRACER = "业务支撑-数据变动记录"; + + public static final String DICT = "业务支撑-数据字典"; + + public static final String CODE_GENERATOR = "业务支撑-代码生成"; + + public static final String CHANGE_LOG = "业务支撑-更新日志"; + + public static final String HELP_DOC = "业务支撑-帮助文档"; + + public static final String FEEDBACK = "业务支撑-意见反馈"; + + public static final String TABLE_COLUMN = "业务支撑-列自定义"; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/constant/UrlPrefixConst.java b/sa-common/src/main/java/net/lab1024/sa/common/constant/UrlPrefixConst.java new file mode 100644 index 0000000..12c2893 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/constant/UrlPrefixConst.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.common.constant; + +/** + * url前缀 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/10/03 20:48 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class UrlPrefixConst { + + public static final String SUPPORT = "/support"; + + public static final String THIRD = "/third"; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/handler/GlobalExceptionHandler.java b/sa-common/src/main/java/net/lab1024/sa/common/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..66da1df --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/handler/GlobalExceptionHandler.java @@ -0,0 +1,126 @@ +package net.lab1024.sa.common.handler; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.code.SystemErrorCode; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.domain.SystemEnvironment; +import net.lab1024.sa.common.common.exception.BusinessException; +import org.springframework.beans.TypeMismatchException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.validation.BindException; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 全局异常拦截 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2020/8/25 21:57 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@ControllerAdvice +public class GlobalExceptionHandler { + + @Autowired + private SystemEnvironment systemEnvironment; + + /** + * json 格式错误 缺少请求体 + */ + @ResponseBody + @ExceptionHandler({HttpMessageNotReadableException.class}) + public ResponseDTO jsonFormatExceptionHandler(Exception e) { + if (!systemEnvironment.isProd()) { + log.error("全局JSON格式错误异常,URL:{}", getCurrentRequestUrl(), e); + } + return ResponseDTO.error(UserErrorCode.PARAM_ERROR, "参数JSON格式错误"); + } + + /** + * json 格式错误 缺少请求体 + */ + @ResponseBody + @ExceptionHandler({TypeMismatchException.class, BindException.class}) + public ResponseDTO paramExceptionHandler(Exception e) { + if (!systemEnvironment.isProd()) { + log.error("全局参数异常,URL:{}", getCurrentRequestUrl(), e); + } + + if (e instanceof BindException) { + if (e instanceof MethodArgumentNotValidException) { + List fieldErrors = ((MethodArgumentNotValidException) e).getBindingResult().getFieldErrors(); + List msgList = fieldErrors.stream().map(FieldError::getDefaultMessage).collect(Collectors.toList()); + return ResponseDTO.error(UserErrorCode.PARAM_ERROR, String.join(",", msgList)); + } + + List fieldErrors = ((BindException) e).getFieldErrors(); + List error = fieldErrors.stream().map(field -> field.getField() + ":" + field.getRejectedValue()).collect(Collectors.toList()); + String errorMsg = UserErrorCode.PARAM_ERROR.getMsg() + ":" + error; + return ResponseDTO.error(UserErrorCode.PARAM_ERROR, errorMsg); + } + + return ResponseDTO.error(UserErrorCode.PARAM_ERROR); + } + + /** + * 权限异常 + */ + @ResponseBody + @ExceptionHandler({AccessDeniedException.class}) + public ResponseDTO permissionExceptionHandler(AccessDeniedException e) { + return ResponseDTO.error(UserErrorCode.NO_PERMISSION); + } + + /** + * 业务异常 + */ + @ResponseBody + @ExceptionHandler(BusinessException.class) + public ResponseDTO businessExceptionHandler(BusinessException e) { + if (!systemEnvironment.isProd()) { + log.error("全局业务异常,URL:{}", getCurrentRequestUrl(), e); + } + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, e.getMessage()); + } + + /** + * 其他全部异常 + * + * @param e + * @return + */ + @ResponseBody + @ExceptionHandler(Throwable.class) + public ResponseDTO errorHandler(Throwable e) { + log.error("捕获全局异常,URL:{}", getCurrentRequestUrl(), e); + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, systemEnvironment.isProd() ? null : e.toString()); + } + + /** + * 获取当前请求url + */ + private String getCurrentRequestUrl() { + RequestAttributes request = RequestContextHolder.getRequestAttributes(); + if (null == request) { + return null; + } + ServletRequestAttributes servletRequest = (ServletRequestAttributes) request; + return servletRequest.getRequest().getRequestURI(); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/listener/SmartApplicationListener.java b/sa-common/src/main/java/net/lab1024/sa/common/listener/SmartApplicationListener.java new file mode 100644 index 0000000..21cfb93 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/listener/SmartApplicationListener.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.common.listener; + +import cn.hutool.core.net.NetUtil; +import cn.hutool.core.util.URLUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.web.context.WebServerApplicationContext; +import org.springframework.boot.web.context.WebServerInitializedEvent; +import org.springframework.boot.web.server.WebServer; +import org.springframework.context.ApplicationListener; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +/** + * 启动监听器 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-23 23:45:26 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Component +@Order(value = 1024) +public class SmartApplicationListener implements ApplicationListener { + + @Override + public void onApplicationEvent(WebServerInitializedEvent webServerInitializedEvent) { + WebServer server = webServerInitializedEvent.getWebServer(); + WebServerApplicationContext context = webServerInitializedEvent.getApplicationContext(); + Environment env = context.getEnvironment(); + //获取服务信息 + String ip = NetUtil.getLocalhost().getHostAddress(); + Integer port = server.getPort(); + String contextPath = env.getProperty("server.servlet.context-path"); + if (contextPath == null) { + contextPath = ""; + } + String profile = env.getProperty("spring.profiles.active"); + String projectName = env.getProperty("project.name"); + //拼接服务地址 + String title = String.format("-------------【%s】 service is running!current profile is 【%s】-------------", projectName, profile); + String localhostUrl = URLUtil.normalize(String.format("http://localhost:%d%s", port, contextPath), false, true); + String externalUrl = URLUtil.normalize(String.format("http://%s:%d%s", ip, port, contextPath), false, true); + String swaggerUrl = URLUtil.normalize(String.format("http://localhost:%d%s/swagger-ui.html", port, contextPath), false, true); + log.info("\n{}\n" + + "\tLocal:\t\t{}" + + "\n\tExternal:\t{}" + + "\n\tSwagger:\t{}" + + "\n-------------------------------------------------------------------------------------\n", + title, localhostUrl, externalUrl, swaggerUrl); + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/cache/CacheService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/cache/CacheService.java new file mode 100644 index 0000000..7697929 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/cache/CacheService.java @@ -0,0 +1,78 @@ +package net.lab1024.sa.common.module.support.cache; + +import com.google.common.collect.Lists; +import net.lab1024.sa.common.constant.ReloadConst; +import net.lab1024.sa.common.module.support.reload.core.annoation.SmartReload; +import org.springframework.cache.caffeine.CaffeineCache; +import org.springframework.cache.caffeine.CaffeineCacheManager; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 缓存操作 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021/10/11 20:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class CacheService { + + @Resource + private CaffeineCacheManager caffeineCacheManager; + + /** + * 获取所有缓存名称 + * + * @return + */ + public List cacheNames() { + return Lists.newArrayList(caffeineCacheManager.getCacheNames()); + } + + /** + * 某个缓存下的所有key + * + * @param cacheName + * @return + */ + public List cacheKey(String cacheName) { + CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName); + if (cache == null) { + return Lists.newArrayList(); + } + Set cacheKey = cache.getNativeCache().asMap().keySet(); + return cacheKey.stream().map(e -> e.toString()).collect(Collectors.toList()); + } + + /** + * 移除某个key + * + * @param cacheName + */ + + public void removeCache(String cacheName) { + CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(cacheName); + if (cache != null) { + cache.clear(); + } + } + + @SmartReload(ReloadConst.CACHE_SERVICE) + public void clearAllCache() { + Collection cacheNames = caffeineCacheManager.getCacheNames(); + for (String name : cacheNames) { + CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache(name); + if (cache != null) { + cache.clear(); + } + } + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaController.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaController.java new file mode 100644 index 0000000..71bace4 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaController.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.common.module.support.captcha; + + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.captcha.domain.CaptchaVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 图形验证码业务 + * + * @Author 1024创新实验室: 胡克 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Api(tags = SwaggerTagConst.Support.CAPTCHA) +//@RestController +//public class CaptchaController extends SupportBaseController { +// +// @Autowired +// private CaptchaService captchaService; +// +// @ApiOperation("获取图形验证码 @author 胡克") +// @GetMapping("/captcha") +// public ResponseDTO generateCaptcha() { +// return ResponseDTO.ok(captchaService.generateCaptcha()); +// } +// +//} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaService.java new file mode 100644 index 0000000..9d84ed5 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/CaptchaService.java @@ -0,0 +1,114 @@ +//package net.lab1024.sa.common.module.support.captcha; +// +//import com.google.code.kaptcha.impl.DefaultKaptcha; +//import lombok.extern.slf4j.Slf4j; +//import net.lab1024.sa.common.common.constant.StringConst; +//import net.lab1024.sa.common.common.domain.ResponseDTO; +//import net.lab1024.sa.common.common.domain.SystemEnvironment; +//import net.lab1024.sa.common.common.exception.BusinessException; +//import net.lab1024.sa.common.constant.RedisKeyConst; +//import net.lab1024.sa.common.module.support.captcha.domain.CaptchaForm; +//import net.lab1024.sa.common.module.support.captcha.domain.CaptchaVO; +//import net.lab1024.sa.common.module.support.redis.RedisService; +//import org.apache.commons.lang3.StringUtils; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.stereotype.Service; +//import org.springframework.util.Base64Utils; +// +//import javax.imageio.ImageIO; +//import java.awt.image.BufferedImage; +//import java.io.ByteArrayOutputStream; +//import java.util.Objects; +//import java.util.UUID; +// +///** +// * 图形验证码 服务 +// * +// * @Author 1024创新实验室: 胡克 +// * @Date 2021/8/31 20:52 +// * @Wechat zhuoda1024 +// * @Email lab1024@163.com +// * @Copyright 1024创新实验室 ( https://1024lab.net ) +// */ +//@Slf4j +//@Service +//public class CaptchaService { +// +// /** +// * 过期时间:65秒 +// */ +// private static final long EXPIRE_SECOND = 65L; +// +// @Autowired +// private DefaultKaptcha defaultKaptcha; +// @Autowired +// private SystemEnvironment systemEnvironment; +// @Autowired +// private RedisService redisService; +// +// /** +// * 生成图形验证码 +// * 默认 1 分钟有效期 +// * +// * @return +// */ +// public CaptchaVO generateCaptcha() { +// String captchaText = defaultKaptcha.createText(); +// BufferedImage image = defaultKaptcha.createImage(captchaText); +// +// String base64Code; +// try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { +// ImageIO.write(image, "jpg", os); +// base64Code = Base64Utils.encodeToString(os.toByteArray()); +// } catch (Exception e) { +// log.error("generateCaptcha error:", e); +// throw new BusinessException("生成验证码错误"); +// } +// +// /** +// * 返回验证码对象 +// * 图片 base64格式 +// */ +// // uuid 唯一标识 +// String uuid = UUID.randomUUID().toString().replace("-", StringConst.EMPTY); +// +// CaptchaVO captchaVO = new CaptchaVO(); +// captchaVO.setCaptchaUuid(uuid); +// captchaVO.setCaptchaBase64Image("data:image/png;base64," + base64Code); +// captchaVO.setExpireSeconds(EXPIRE_SECOND); +// if (!systemEnvironment.isProd()) { +// captchaVO.setCaptchaText(captchaText); +// } +// String redisCaptchaKey = redisService.generateRedisKey(RedisKeyConst.Support.CAPTCHA, uuid); +// redisService.set(redisCaptchaKey, captchaText, EXPIRE_SECOND); +// return captchaVO; +// } +// +// /** +// * 校验图形验证码 +// * +// * @param captchaForm +// * @return +// */ +// public ResponseDTO checkCaptcha(CaptchaForm captchaForm) { +// if (StringUtils.isBlank(captchaForm.getCaptchaUuid()) || StringUtils.isBlank(captchaForm.getCaptchaCode())) { +// return ResponseDTO.userErrorParam("请输入正确验证码"); +// } +// /** +// * 1、校验redis里的验证码 +// * 2、校验成功后,删除redis +// */ +// String redisCaptchaKey = redisService.generateRedisKey(RedisKeyConst.Support.CAPTCHA, captchaForm.getCaptchaUuid()); +// String redisCaptchaCode = redisService.get(redisCaptchaKey); +// if (StringUtils.isBlank(redisCaptchaCode)) { +// return ResponseDTO.userErrorParam("验证码已过期,请刷新重试"); +// } +// if (!Objects.equals(redisCaptchaCode, captchaForm.getCaptchaCode())) { +// return ResponseDTO.userErrorParam("验证码错误,请输入正确的验证码"); +// } +// // 删除已使用的验证码 +// redisService.delete(redisCaptchaKey); +// return ResponseDTO.ok(); +// } +// +//} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaColor.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaColor.java new file mode 100644 index 0000000..4dd96c1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaColor.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.module.support.captcha.config; + +import com.google.common.collect.Lists; + +import java.awt.*; +import java.util.List; +import java.util.Random; + +/** + * 验证码颜色 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class CaptchaColor { + + public static Color getColor() { + + List colors = Lists.newArrayList(); + colors.add(new Color(0, 135, 255)); + colors.add(new Color(51, 153, 51)); + colors.add(new Color(255, 102, 102)); + colors.add(new Color(255, 153, 0)); + colors.add(new Color(153, 102, 0)); + colors.add(new Color(153, 102, 153)); + colors.add(new Color(51, 153, 153)); + colors.add(new Color(102, 102, 255)); + colors.add(new Color(0, 102, 204)); + colors.add(new Color(204, 51, 51)); + colors.add(new Color(128, 153, 65)); + Random random = new Random(); + int colorIndex = random.nextInt(10); + return colors.get(colorIndex); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaConfig.java new file mode 100644 index 0000000..ea51ce9 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaConfig.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.common.module.support.captcha.config; + +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Properties; + +/** + * 验证码配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Configuration +public class CaptchaConfig { + + @Bean + public DefaultKaptcha getDefaultKaptcha() { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + properties.setProperty("kaptcha.border", "no"); + properties.setProperty("kaptcha.border.color", "34,114,200"); + properties.setProperty("kaptcha.image.width", "125"); + properties.setProperty("kaptcha.image.height", "45"); + properties.setProperty("kaptcha.textproducer.char.string", "123456789abcdefghkmnpqrstuvwxyabcdefghkmnpqrstuvwxyz"); + properties.setProperty("kaptcha.textproducer.char.length", "4"); + properties.setProperty("kaptcha.textproducer.font.names", "Arial,Arial Narrow,Serif,Helvetica,Tahoma,Times New Roman,Verdana"); + properties.setProperty("kaptcha.textproducer.font.size", "38"); + + properties.setProperty("kaptcha.background.clear.from", "white"); + properties.setProperty("kaptcha.background.clear.to", "white"); + + properties.setProperty("kaptcha.word.impl", CaptchaWordRenderer.class.getName()); + properties.setProperty("kaptcha.noise.impl", CaptchaNoise.class.getName()); + + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaNoise.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaNoise.java new file mode 100644 index 0000000..36f773d --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaNoise.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.common.module.support.captcha.config; + +import com.google.code.kaptcha.NoiseProducer; +import com.google.code.kaptcha.util.Configurable; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.Random; + +/** + * 验证码加噪处理 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class CaptchaNoise extends Configurable implements NoiseProducer { + + public CaptchaNoise() { + } + + @Override + public void makeNoise(BufferedImage image, float factorOne, float factorTwo, float factorThree, float factorFour) { + + int width = image.getWidth(); + int height = image.getHeight(); + Graphics2D graph = (Graphics2D) image.getGraphics(); + graph.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)); + graph.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + Random random = new Random(); + int noiseLineNum = random.nextInt(3); + if (noiseLineNum == 0) { + noiseLineNum = 1; + } + for (int i = 0; i < noiseLineNum; i++) { + graph.setColor(CaptchaColor.getColor()); + graph.drawLine(random.nextInt(width), random.nextInt(height), 10 + random.nextInt(20), 10 + random.nextInt(20)); + } + + graph.dispose(); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaWordRenderer.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaWordRenderer.java new file mode 100644 index 0000000..23b2278 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/config/CaptchaWordRenderer.java @@ -0,0 +1,74 @@ +package net.lab1024.sa.common.module.support.captcha.config; + +import com.google.code.kaptcha.text.WordRenderer; +import com.google.code.kaptcha.util.Configurable; + +import java.awt.*; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.image.BufferedImage; +import java.util.Random; + +/** + * 验证码字体生成 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class CaptchaWordRenderer extends Configurable implements WordRenderer { + + public CaptchaWordRenderer() { + } + + @Override + public BufferedImage renderWord(String word, int width, int height) { + int fontSize = this.getConfig().getTextProducerFontSize(); + Font[] fonts = this.getConfig().getTextProducerFonts(fontSize); + int charSpace = this.getConfig().getTextProducerCharSpace(); + BufferedImage image = new BufferedImage(width, height, 2); + + Graphics2D g2D = image.createGraphics(); + g2D.setColor(Color.WHITE); + RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + hints.add(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY)); + g2D.setRenderingHints(hints); + g2D.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + + FontRenderContext frc = g2D.getFontRenderContext(); + Random random = new Random(); + int startPosY = (height - fontSize) / 5 + fontSize; + char[] wordChars = word.toCharArray(); + Font[] chosenFonts = new Font[wordChars.length]; + int[] charWidths = new int[wordChars.length]; + int widthNeeded = 0; + + int startPosX; + for (startPosX = 0; startPosX < wordChars.length; ++startPosX) { + chosenFonts[startPosX] = fonts[random.nextInt(fonts.length)]; + char[] charToDraw = new char[]{wordChars[startPosX]}; + GlyphVector gv = chosenFonts[startPosX].createGlyphVector(frc, charToDraw); + charWidths[startPosX] = (int) gv.getVisualBounds().getWidth(); + if (startPosX > 0) { + widthNeeded += 2; + } + + widthNeeded += charWidths[startPosX]; + } + + startPosX = (width - widthNeeded) / 2; + + for (int i = 0; i < wordChars.length; ++i) { + g2D.setColor(CaptchaColor.getColor()); + g2D.setFont(chosenFonts[i].deriveFont(Font.PLAIN)); + char[] charToDraw = new char[]{wordChars[i]}; + g2D.drawChars(charToDraw, 0, charToDraw.length, startPosX, startPosY); + startPosX = startPosX + charWidths[i] + charSpace; + } + + return image; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/domain/CaptchaForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/domain/CaptchaForm.java new file mode 100644 index 0000000..5d2d21c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/domain/CaptchaForm.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.common.module.support.captcha.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 图形验证码 表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-09-02 20:21:10 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ + +@Data +public class CaptchaForm { + + @ApiModelProperty(value = "验证码") + @NotBlank(message = "验证码不能为空") + private String captchaCode; + + @ApiModelProperty(value = "验证码uuid标识") + @NotBlank(message = "验证码uuid标识不能为空") + private String captchaUuid; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/domain/CaptchaVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/domain/CaptchaVO.java new file mode 100644 index 0000000..cee66da --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/captcha/domain/CaptchaVO.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.common.module.support.captcha.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 图形验证码 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021/8/31 20:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class CaptchaVO { + + @ApiModelProperty("验证码唯一标识") + private String captchaUuid; + + @ApiModelProperty("验证码图片内容-生产环境无效") + private String captchaText; + + @ApiModelProperty("验证码Base64图片") + private String captchaBase64Image; + + @ApiModelProperty("过期时间(秒)") + private Long expireSeconds; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/constant/ChangeLogTypeEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/constant/ChangeLogTypeEnum.java new file mode 100644 index 0000000..e57ad48 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/constant/ChangeLogTypeEnum.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.common.module.support.changelog.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] + * + * @Author 卓大 + * @Date 2022-09-26T14:53:50 + * @Copyright 1024创新实验室 + */ + +@AllArgsConstructor +@Getter +public enum ChangeLogTypeEnum implements BaseEnum { + + MAJOR_UPDATE(1, "重大更新"), + FUNCTION_UPDATE(2, "功能更新"), + BUG_FIX(3, "Bug修复"), + + ; + + private final Integer value; + + private final String desc; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/controller/ChangeLogController.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/controller/ChangeLogController.java new file mode 100644 index 0000000..f0d9ca9 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/controller/ChangeLogController.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.module.support.changelog.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.changelog.domain.form.ChangeLogQueryForm; +import net.lab1024.sa.common.module.support.changelog.domain.vo.ChangeLogVO; +import net.lab1024.sa.common.module.support.changelog.service.ChangeLogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * 系统更新日志 Controller + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@RestController +//@Api(tags = SwaggerTagConst.Support.CHANGE_LOG) +public class ChangeLogController { + + @Autowired + private ChangeLogService changeLogService; + + @ApiOperation("分页查询 @author 卓大") + @PostMapping("/changeLog/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid ChangeLogQueryForm queryForm) { + return ResponseDTO.ok(changeLogService.queryPage(queryForm)); + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/dao/ChangeLogDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/dao/ChangeLogDao.java new file mode 100644 index 0000000..157eecc --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/dao/ChangeLogDao.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.common.module.support.changelog.dao; + +import java.util.List; + +import net.lab1024.sa.common.module.support.changelog.domain.form.ChangeLogQueryForm; +import net.lab1024.sa.common.module.support.changelog.domain.vo.ChangeLogVO; +import net.lab1024.sa.common.module.support.changelog.domain.entity.ChangeLogEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +/** + * 系统更新日志 Dao + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Mapper +@Component +public interface ChangeLogDao extends BaseMapper { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") ChangeLogQueryForm queryForm); + + /** + * 根据版本查询 ChangeLog + * + * @param version + * @return + */ + ChangeLogEntity selectByVersion(@Param("version") String version); + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/entity/ChangeLogEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/entity/ChangeLogEntity.java new file mode 100644 index 0000000..5773f41 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/entity/ChangeLogEntity.java @@ -0,0 +1,68 @@ +package net.lab1024.sa.common.module.support.changelog.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.time.LocalDate; +import java.time.LocalDateTime; +import lombok.Data; + +/** + * 系统更新日志 + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Data +@TableName("t_change_log") +public class ChangeLogEntity { + + /** + * 更新日志id + */ + @TableId(type = IdType.AUTO) + private Long changeLogId; + + /** + * 版本 + */ + private String version; + + /** + * 更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] + */ + private Integer type; + + /** + * 发布人 + */ + private String publishAuthor; + + /** + * 发布日期 + */ + private LocalDate publicDate; + + /** + * 更新内容 + */ + private String content; + + /** + * 跳转链接 + */ + private String link; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogAddForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogAddForm.java new file mode 100644 index 0000000..ad55233 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogAddForm.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.common.module.support.changelog.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDate; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Data; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.changelog.constant.ChangeLogTypeEnum; + +/** + * 系统更新日志 新建表单 + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Data +public class ChangeLogAddForm { + + @ApiModelProperty(value = "版本", required = true) + @NotBlank(message = "版本 不能为空") + private String version; + + @ApiModelPropertyEnum(value = ChangeLogTypeEnum.class, desc = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]") + @CheckEnum(value = ChangeLogTypeEnum.class, message = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] 错误", required = true) + private Integer type; + + @ApiModelProperty(value = "发布人", required = true) + @NotBlank(message = "发布人 不能为空") + private String publishAuthor; + + @ApiModelProperty(value = "发布日期", required = true) + @NotNull(message = "发布日期 不能为空") + private LocalDate publicDate; + + @ApiModelProperty(value = "更新内容", required = true) + @NotBlank(message = "更新内容 不能为空") + private String content; + + @ApiModelProperty(value = "跳转链接") + private String link; + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogQueryForm.java new file mode 100644 index 0000000..393c4c6 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogQueryForm.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.common.module.support.changelog.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.changelog.constant.ChangeLogTypeEnum; + +import java.time.LocalDate; + +/** + * 系统更新日志 查询 + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Data +public class ChangeLogQueryForm extends PageParam{ + + @ApiModelPropertyEnum(value = ChangeLogTypeEnum.class, desc = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]") + @CheckEnum(value = ChangeLogTypeEnum.class, message = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] 错误") + private Integer type; + + @ApiModelProperty(value = "关键字") + private String keyword; + + @ApiModelProperty(value = "发布日期") + private LocalDate publicDateBegin; + + @ApiModelProperty(value = "发布日期") + private LocalDate publicDateEnd; + + @ApiModelProperty(value = "创建时间") + private LocalDate createTime; + + @ApiModelProperty(value = "跳转链接") + private String link; + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogUpdateForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogUpdateForm.java new file mode 100644 index 0000000..1a3c436 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/form/ChangeLogUpdateForm.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.common.module.support.changelog.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDate; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import lombok.Data; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.changelog.constant.ChangeLogTypeEnum; + +/** + * 系统更新日志 更新表单 + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Data +public class ChangeLogUpdateForm { + + @ApiModelProperty(value = "更新日志id", required = true) + @NotNull(message = "更新日志id 不能为空") + private Long changeLogId; + + @ApiModelProperty(value = "版本", required = true) + @NotBlank(message = "版本 不能为空") + private String version; + + @ApiModelPropertyEnum(value = ChangeLogTypeEnum.class, desc = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]") + @CheckEnum(value = ChangeLogTypeEnum.class, message = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] 错误", required = true) + private Integer type; + + @ApiModelProperty(value = "发布人", required = true) + @NotBlank(message = "发布人 不能为空") + private String publishAuthor; + + @ApiModelProperty(value = "发布日期", required = true) + @NotNull(message = "发布日期 不能为空") + private LocalDate publicDate; + + @ApiModelProperty(value = "更新内容", required = true) + @NotBlank(message = "更新内容 不能为空") + private String content; + + @ApiModelProperty(value = "跳转链接") + private String link; + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/vo/ChangeLogVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/vo/ChangeLogVO.java new file mode 100644 index 0000000..cf147c7 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/domain/vo/ChangeLogVO.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.common.module.support.changelog.domain.vo; + +import io.swagger.annotations.ApiModelProperty; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +import lombok.Data; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.module.support.changelog.constant.ChangeLogTypeEnum; + +/** + * 系统更新日志 列表VO + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Data +public class ChangeLogVO { + + private Long changeLogId; + + @ApiModelProperty(value = "版本") + private String version; + + @ApiModelPropertyEnum(value = ChangeLogTypeEnum.class, desc = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]") + private Integer type; + + @ApiModelProperty(value = "发布人") + private String publishAuthor; + + @ApiModelProperty(value = "发布日期") + private LocalDate publicDate; + + @ApiModelProperty(value = "更新内容") + private String content; + + @ApiModelProperty(value = "跳转链接") + private String link; + + @ApiModelProperty(value = "创建时间") + private LocalDateTime createTime; + + @ApiModelProperty(value = "更新时间") + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/manager/ChangeLogManager.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/manager/ChangeLogManager.java new file mode 100644 index 0000000..ee90a6b --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/manager/ChangeLogManager.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.common.module.support.changelog.manager; + +import net.lab1024.sa.common.module.support.changelog.dao.ChangeLogDao; +import net.lab1024.sa.common.module.support.changelog.domain.entity.ChangeLogEntity; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * 系统更新日志 Manager + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ +@Service +public class ChangeLogManager extends ServiceImpl { + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/service/ChangeLogService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/service/ChangeLogService.java new file mode 100644 index 0000000..a8d95e2 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/changelog/service/ChangeLogService.java @@ -0,0 +1,103 @@ +package net.lab1024.sa.common.module.support.changelog.service; + +import java.util.List; + +import net.lab1024.sa.common.module.support.changelog.dao.ChangeLogDao; +import net.lab1024.sa.common.module.support.changelog.domain.entity.ChangeLogEntity; +import net.lab1024.sa.common.module.support.changelog.domain.form.ChangeLogAddForm; +import net.lab1024.sa.common.module.support.changelog.domain.form.ChangeLogQueryForm; +import net.lab1024.sa.common.module.support.changelog.domain.form.ChangeLogUpdateForm; +import net.lab1024.sa.common.module.support.changelog.domain.vo.ChangeLogVO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.domain.PageResult; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 系统更新日志 Service + * + * @Author 卓大 + * @Date 2022-09-26 14:53:50 + * @Copyright 1024创新实验室 + */ + +@Service +public class ChangeLogService { + + @Autowired + private ChangeLogDao changeLogDao; + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public PageResult queryPage(ChangeLogQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = changeLogDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return pageResult; + } + + /** + * 添加 + */ + public synchronized ResponseDTO add(ChangeLogAddForm addForm) { + ChangeLogEntity existVersion = changeLogDao.selectByVersion(addForm.getVersion()); + if (existVersion != null) { + return ResponseDTO.userErrorParam("此版本已经存在"); + } + + ChangeLogEntity changeLogEntity = SmartBeanUtil.copy(addForm, ChangeLogEntity.class); + changeLogDao.insert(changeLogEntity); + return ResponseDTO.ok(); + } + + /** + * 更新 + * + * @param updateForm + * @return + */ + public synchronized ResponseDTO update(ChangeLogUpdateForm updateForm) { + ChangeLogEntity existVersion = changeLogDao.selectByVersion(updateForm.getVersion()); + if (existVersion != null && !updateForm.getChangeLogId().equals(existVersion.getChangeLogId())) { + return ResponseDTO.userErrorParam("此版本已经存在"); + } + ChangeLogEntity changeLogEntity = SmartBeanUtil.copy(updateForm, ChangeLogEntity.class); + changeLogDao.updateById(changeLogEntity); + return ResponseDTO.ok(); + } + + /** + * 批量删除 + * + * @param idList + * @return + */ + public synchronized ResponseDTO batchDelete(List idList) { + if (CollectionUtils.isEmpty(idList)) { + return ResponseDTO.ok(); + } + + changeLogDao.deleteBatchIds(idList); + return ResponseDTO.ok(); + } + + /** + * 单个删除 + */ + public synchronized ResponseDTO delete(Long changeLogId) { + if (null == changeLogId) { + return ResponseDTO.ok(); + } + + changeLogDao.deleteById(changeLogId); + return ResponseDTO.ok(); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeDeleteEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeDeleteEnum.java new file mode 100644 index 0000000..c530860 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeDeleteEnum.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.module.support.codegenerator.constant; + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 删除类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public enum CodeDeleteEnum implements BaseEnum { + + SINGLE("Single", "单个删除"), + BATCH("Batch", "批量删除"), + SINGLE_AND_BATCH("SingleAndBatch", "单个和批量删除"); + + private String value; + + private String desc; + + CodeDeleteEnum(String value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Object getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeFrontComponentEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeFrontComponentEnum.java new file mode 100644 index 0000000..ee94ab7 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeFrontComponentEnum.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.common.module.support.codegenerator.constant; + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 前端组件类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 20:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public enum CodeFrontComponentEnum implements BaseEnum { + + INPUT("Input", "输入框"), + + INPUT_NUMBER("InputNumber", "数字输入框"), + + TEXTAREA("Textarea", " 文本"), + + BOOLEAN_SELECT("BooleanSelect", "布尔下拉框"), + + ENUM_SELECT("SmartEnumSelect", "枚举下拉"), + + DICT_SELECT("DictSelect", "字典下拉"), + + DATE("Date", "日期选择"), + + DATE_TIME("DateTime", "时间选择"), + + FILE_UPLOAD("FileUpload", "文件上传"); + + private String value; + + private String desc; + + CodeFrontComponentEnum(String value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Object getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeGeneratorConstant.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeGeneratorConstant.java new file mode 100644 index 0000000..dccdf33 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeGeneratorConstant.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.common.module.support.codegenerator.constant; + +/** + * 常量 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class CodeGeneratorConstant { + + /** + * 主键 + */ + public final static String PRIMARY_KEY = "PRI"; + + /** + * 自增 + */ + public final static String AUTO_INCREMENT = "auto_increment"; + + /** + * 默认逻辑删除字段名称 + */ + public static String DELETED_FLAG = "deleted_flag"; + + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeGeneratorPageTypeEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeGeneratorPageTypeEnum.java new file mode 100644 index 0000000..4a33e00 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeGeneratorPageTypeEnum.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.module.support.codegenerator.constant; + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 页面类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-29 19:11:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public enum CodeGeneratorPageTypeEnum implements BaseEnum { + + MODAL("modal", "弹窗"), + DRAWER("drawer", "抽屉"), + PAGE("page", "新页面"); + + private String value; + + private String desc; + + CodeGeneratorPageTypeEnum(String value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Object getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeQueryFieldQueryTypeEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeQueryFieldQueryTypeEnum.java new file mode 100644 index 0000000..e68d811 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/constant/CodeQueryFieldQueryTypeEnum.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.common.module.support.codegenerator.constant; + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 查询条件类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-29 20:23:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public enum CodeQueryFieldQueryTypeEnum implements BaseEnum { + + LIKE("Like", "模糊查询"), + EQUAL("Equal", "等于"), + DATE_RANGE("DateRange", "日期范围"), + DATE("Date", "指定日期"), + ENUM("Enum", "枚举"), + + DICT("Dict", "字典"), + ; + + private String value; + + private String desc; + + CodeQueryFieldQueryTypeEnum(String value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public Object getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/controller/CodeGeneratorController.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/controller/CodeGeneratorController.java new file mode 100644 index 0000000..cb25c10 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/controller/CodeGeneratorController.java @@ -0,0 +1,106 @@ +package net.lab1024.sa.common.module.support.codegenerator.controller; + +import com.alibaba.fastjson.JSON; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorPreviewForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.TableQueryForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.vo.TableColumnVO; +import net.lab1024.sa.common.module.support.codegenerator.domain.vo.TableConfigVO; +import net.lab1024.sa.common.module.support.codegenerator.domain.vo.TableVO; +import net.lab1024.sa.common.module.support.codegenerator.service.CodeGeneratorService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 代码生成 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-29 20:23:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Api(tags = SwaggerTagConst.Support.CODE_GENERATOR) +@Controller +public class CodeGeneratorController extends SupportBaseController { + + @Autowired + private CodeGeneratorService codeGeneratorService; + + // ------------------- 查询 ------------------- + @ApiOperation("获取表的列 @author 卓大") + @GetMapping("/codeGenerator/table/getTableColumns/{table}") + @ResponseBody + public ResponseDTO> getTableColumns(@PathVariable String table) { + return ResponseDTO.ok(codeGeneratorService.getTableColumns(table)); + } + + @ApiOperation("查询数据库的表 @author 卓大") + @PostMapping("/codeGenerator/table/queryTableList") + @ResponseBody + public ResponseDTO> queryTableList(@RequestBody @Valid TableQueryForm tableQueryForm) { + return ResponseDTO.ok(codeGeneratorService.queryTableList(tableQueryForm)); + } + + // ------------------- 配置 ------------------- + + @ApiOperation("获取表的配置信息 @author 卓大") + @GetMapping("/codeGenerator/table/getConfig/{table}") + @ResponseBody + public ResponseDTO getTableConfig(@PathVariable String table) { + return ResponseDTO.ok(codeGeneratorService.getTableConfig(table)); + } + + @ApiOperation("更新配置信息 @author 卓大") + @PostMapping("/codeGenerator/table/updateConfig") + @ResponseBody + public ResponseDTO updateConfig(@RequestBody @Valid CodeGeneratorConfigForm form) { + return codeGeneratorService.updateConfig(form); + } + + // ------------------- 生成 ------------------- + + @ApiOperation("代码预览 @author 卓大") + @PostMapping("/codeGenerator/code/preview") + @ResponseBody + public ResponseDTO preview(@RequestBody @Valid CodeGeneratorPreviewForm form) { + return codeGeneratorService.preview(form); + } + + @ApiOperation("代码下载 @author 卓大") + @GetMapping(value = "/codeGenerator/code/download/{tableName}", produces = "application/octet-stream") + public ResponseEntity download(@PathVariable String tableName) { + + ResponseDTO download = codeGeneratorService.download(tableName); + + if (download.getOk()) { + HttpHeaders heads = new HttpHeaders(); + heads.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream; charset=UTF-8"); + heads.add(HttpHeaders.CONTENT_LENGTH, "" + download.getData().length); + heads.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + tableName + "-code.zip"); + ResponseEntity responseEntity = new ResponseEntity<>(download.getData(), heads, HttpStatus.OK); + return responseEntity; + } else { + byte[] data = JSON.toJSONString(download).getBytes(); + HttpHeaders heads = new HttpHeaders(); + heads.add(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8"); + heads.add(HttpHeaders.CONTENT_LENGTH, "" + data.length); + ResponseEntity responseEntity = new ResponseEntity<>(data, heads, HttpStatus.OK); + return responseEntity; + } + } + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/dao/CodeGeneratorConfigDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/dao/CodeGeneratorConfigDao.java new file mode 100644 index 0000000..cc27319 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/dao/CodeGeneratorConfigDao.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.common.module.support.codegenerator.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.common.module.support.codegenerator.domain.entity.CodeGeneratorConfigEntity; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +/** + * 表的 代码生成配置 Dao + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-09-23 20:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface CodeGeneratorConfigDao extends BaseMapper { + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/dao/CodeGeneratorDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/dao/CodeGeneratorDao.java new file mode 100644 index 0000000..f1407d3 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/dao/CodeGeneratorDao.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.common.module.support.codegenerator.dao; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.TableQueryForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.vo.TableColumnVO; +import net.lab1024.sa.common.module.support.codegenerator.domain.vo.TableVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @Author 1024创新实验室: 罗伊 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface CodeGeneratorDao { + + /** + * 分页查询表 + */ + List queryTableList(Page page, @Param("queryForm") TableQueryForm queryForm); + + /** + * 查询表是否存在 + * + * @param tableName + * @return + */ + long countByTableName(@Param("tableName") String tableName); + + + /** + * 查询表列信息 + * + * @param tableName + * @return + */ + List selectTableColumn(@Param("tableName") String tableName); +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/entity/CodeGeneratorConfigEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/entity/CodeGeneratorConfigEntity.java new file mode 100644 index 0000000..c05bebd --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/entity/CodeGeneratorConfigEntity.java @@ -0,0 +1,74 @@ +package net.lab1024.sa.common.module.support.codegenerator.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 代码生成-配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/6/23 21:59:22 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +@TableName("t_code_generator_config") +public class CodeGeneratorConfigEntity { + + /** + * 表名 + */ + @TableId(type = IdType.NONE) + private String tableName; + + /** + * 基础命名信息 + */ + private String basic; + + /** + * 字段列表 + */ + private String fields; + + /** + * 增加、修改 信息 + */ + private String insertAndUpdate; + + /** + * 删除 信息 + */ + private String deleteInfo; + + /** + * 查询字段 + */ + private String queryFields; + + /** + * 列表字段 + */ + private String tableFields; + + /** + * 详情 + */ + private String detail; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/CodeGeneratorConfigForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/CodeGeneratorConfigForm.java new file mode 100644 index 0000000..4a545f2 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/CodeGeneratorConfigForm.java @@ -0,0 +1,64 @@ +package net.lab1024.sa.common.module.support.codegenerator.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.*; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 代码生成 配置信息表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-29 20:23:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CodeGeneratorConfigForm { + + @NotBlank(message = "表名 不能为空") + @ApiModelProperty("表名") + private String tableName; + + + @Valid + @NotNull(message = "基础信息不能为空") + @ApiModelProperty("基础信息") + private CodeBasic basic; + + @Valid + @NotNull(message = "字段信息不能为空") + @ApiModelProperty("字段信息") + private List fields; + + @Valid + @NotNull(message = "增加、修改 信息 不能为空") + @ApiModelProperty("增加、修改 信息") + private CodeInsertAndUpdate insertAndUpdate; + + @Valid + @NotNull(message = "删除 信息 不能为空") + @ApiModelProperty("删除 信息") + private CodeDelete deleteInfo; + + @Valid + @ApiModelProperty("查询字段") + private List queryFields; + + @Valid + @ApiModelProperty("列表字段") + private List tableFields; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/CodeGeneratorPreviewForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/CodeGeneratorPreviewForm.java new file mode 100644 index 0000000..37d6546 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/CodeGeneratorPreviewForm.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.common.module.support.codegenerator.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 代码生成 预览 表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/6/23 23:20:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +@Data +public class CodeGeneratorPreviewForm { + + @NotBlank(message = "模板文件 不能为空") + @ApiModelProperty("模板文件") + private String templateFile; + + @NotBlank(message = "表名 不能为空") + @ApiModelProperty("表名") + private String tableName; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/TableQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/TableQueryForm.java new file mode 100644 index 0000000..3ffd435 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/form/TableQueryForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.common.module.support.codegenerator.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + + +/** + * 查询表数据 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class TableQueryForm extends PageParam { + + @ApiModelProperty("表名关键字") + private String tableNameKeywords; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeBasic.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeBasic.java new file mode 100644 index 0000000..35f96fd --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeBasic.java @@ -0,0 +1,55 @@ +package net.lab1024.sa.common.module.support.codegenerator.domain.model; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * 代码生成 基础数据 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ + +@Data +public class CodeBasic { + + @ApiModelProperty("业务名称") + @NotBlank(message = "1.基础命名 基础命名 不能为空") + private String moduleName; + + @ApiModelProperty("java包名") + @NotBlank(message = "1.基础命名 java包名 不能为空") + private String javaPackageName; + + @ApiModelProperty("注释") + @NotBlank(message = "1.基础命名 注释 不能为空") + private String description; + + @ApiModelProperty("前端作者") + @NotBlank(message = "1.基础命名 前端作者 不能为空") + private String frontAuthor; + + @ApiModelProperty("前端时间") + @NotNull(message = "1.基础命名 前端时间 不能为空") + private LocalDateTime frontDate; + + @ApiModelProperty("后端作者") + @NotBlank(message = "1.基础命名 后端作者 不能为空") + private String backendAuthor; + + @ApiModelProperty("后端时间") + @NotNull(message = "1.基础命名 后端时间 不能为空") + private LocalDateTime backendDate; + + @ApiModelProperty("版权信息") + @NotNull(message = "1.基础命名 版权信息 不能为空") + private String copyright; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeDelete.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeDelete.java new file mode 100644 index 0000000..d334abf --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeDelete.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.common.module.support.codegenerator.domain.model; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.codegenerator.constant.CodeDeleteEnum; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 代码生成 删除 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ + +@Data +public class CodeDelete { + + @ApiModelProperty("是否支持删除 ") + @NotNull(message = "4.删除 是否支持删除 不能为空") + private Boolean isSupportDelete; + + @ApiModelProperty("是否为物理删除") + @NotNull(message = "4.删除 是否为物理删除 不能为空") + private Boolean isPhysicallyDeleted; + + @ApiModelProperty("删除类型") + @NotBlank(message = "4.删除 删除类型 不能为空") + @ApiModelPropertyEnum(CodeDeleteEnum.class) + @CheckEnum(value = CodeDeleteEnum.class, message = "删除 删除类型 枚举值错误") + private String deleteEnum; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeField.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeField.java new file mode 100644 index 0000000..00cce05 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeField.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.common.module.support.codegenerator.domain.model; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 代码生成 基础字段 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ + +@Data +public class CodeField { + + @ApiModelProperty("列") + @NotBlank(message = " 2.字段列表 列名 不能为空") + private String columnName; + + @ApiModelProperty("列备注") + private String columnComment; + + @ApiModelProperty("字段名词") + @NotBlank(message = "2.字段列表 字段名词 不能为空") + private String label; + + @ApiModelProperty("字段命名") + @NotBlank(message = "2.字段列表 字段命名 不能为空") + private String fieldName; + + @ApiModelProperty("java类型") + @NotBlank(message = "2.字段列表 java类型 不能为空") + private String javaType; + + @ApiModelProperty("js类型") + @NotBlank(message = "2.字段列表 js类型 不能为空") + private String jsType; + + @ApiModelProperty("字典key") + private String dict; + + @ApiModelProperty("枚举名称") + private String enumName; + + @ApiModelProperty("主键") + @NotNull(message = "2.字段列表 主键 不能为空") + private Boolean primaryKeyFlag; + + @ApiModelProperty("自增") + @NotNull(message = "2.字段列表 自增 不能为空") + private Boolean autoIncreaseFlag; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeInsertAndUpdate.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeInsertAndUpdate.java new file mode 100644 index 0000000..54df13b --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeInsertAndUpdate.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.common.module.support.codegenerator.domain.model; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.codegenerator.constant.CodeGeneratorPageTypeEnum; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 代码生成 增加、修改 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ + +@Data +public class CodeInsertAndUpdate { + + @NotNull(message = "3.增加、修改 是否支持增加、修改 不能为空") + private Boolean isSupportInsertAndUpdate; + + @ApiModelPropertyEnum(CodeGeneratorPageTypeEnum.class) + @CheckEnum(value = CodeGeneratorPageTypeEnum.class, message = "3.增加、修改 增加、修改 页面类型 枚举值错误") + private String pageType; + + @ApiModelProperty("宽度") + private String width; + + @NotNull(message = "3.增加、修改 每行字段数量 不能为空") + @ApiModelProperty("每行字段数量") + private Integer countPerLine; + + @ApiModelProperty("字段列表") + private List fieldList; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeInsertAndUpdateField.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeInsertAndUpdateField.java new file mode 100644 index 0000000..43c062c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeInsertAndUpdateField.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.common.module.support.codegenerator.domain.model; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.codegenerator.constant.CodeFrontComponentEnum; +import net.lab1024.sa.common.module.support.codegenerator.constant.CodeGeneratorPageTypeEnum; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 代码生成 增加、修改的字段 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ + +@Data +public class CodeInsertAndUpdateField { + + @NotBlank(message = "3.增加、修改 列名 不能为空") + @ApiModelProperty("列名") + private String columnName; + + @NotNull(message = "3.增加、修改 必须 不能为空") + @ApiModelProperty("必须") + private Boolean requiredFlag; + + @NotNull(message = "3.增加、修改 插入标识 不能为空") + @ApiModelProperty("插入标识") + private Boolean insertFlag; + + @NotNull(message = "3.增加、修改 更新标识 不能为空") + @ApiModelProperty("更新标识") + private Boolean updateFlag; + + @ApiModelPropertyEnum(value = CodeGeneratorPageTypeEnum.class) + @CheckEnum(value = CodeFrontComponentEnum.class, message = "3.增加、修改 增加、修改 组件类型 枚举值错误", required = true) + private String frontComponent; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeQueryField.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeQueryField.java new file mode 100644 index 0000000..614b7fc --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeQueryField.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.common.module.support.codegenerator.domain.model; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.codegenerator.constant.CodeQueryFieldQueryTypeEnum; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * 代码生成 查询条件 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ + +@Data +public class CodeQueryField { + + @NotBlank(message = "5、查询条件 条件名称 不能为空") + @ApiModelProperty("条件名称") + private String label; + + @NotBlank(message = "5、查询条件 字段名 不能为空") + @ApiModelProperty("字段名") + private String fieldName; + + @ApiModelPropertyEnum(CodeQueryFieldQueryTypeEnum.class) + @CheckEnum(value = CodeQueryFieldQueryTypeEnum.class, message = "5、查询条件 查询条件 查询类型 枚举值错误") + private String queryTypeEnum; + + @NotEmpty(message = "5、查询条件 列 不能为空") + @ApiModelProperty("列") + private List columnNameList; + + @NotBlank(message = "5、查询条件 宽度 不能为空") + @ApiModelProperty("宽度") + private String width; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeTableField.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeTableField.java new file mode 100644 index 0000000..ac12695 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/model/CodeTableField.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.common.module.support.codegenerator.domain.model; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 代码生成 列表表格 模型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ + +@Data +public class CodeTableField { + + @NotBlank(message = "6、列表 列名 不能为空") + @ApiModelProperty("列名") + private String columnName; + + @NotBlank(message = "6、列表 字段名词 不能为空") + @ApiModelProperty("字段名词") + private String label; + + @NotBlank(message = "6、列表 字段命名 不能为空") + @ApiModelProperty("字段命名") + private String fieldName; + + @NotNull(message = "6、列表 列表显示 不能为空") + @ApiModelProperty("列表显示") + private Boolean showFlag; + + @ApiModelProperty("宽度") + private Integer width; + + @NotNull(message = "6、列表 自动省略标识 不能为空") + @ApiModelProperty("自动省略标识") + private Boolean ellipsisFlag; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableColumnVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableColumnVO.java new file mode 100644 index 0000000..251bfca --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableColumnVO.java @@ -0,0 +1,44 @@ + +package net.lab1024.sa.common.module.support.codegenerator.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 列 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/21 21:07:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +@Data +public class TableColumnVO { + + @ApiModelProperty("列名") + private String columnName; + + @ApiModelProperty("列描述") + private String columnComment; + + @ApiModelProperty("columnKey") + private String columnKey; + + @ApiModelProperty("extra") + private String extra; + + @ApiModelProperty("是否为空") + private String isNullable; + + @ApiModelProperty("数据类型varchar") + private String dataType; + + @ApiModelProperty("列类型varchar(50)") + private String columnType; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableConfigVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableConfigVO.java new file mode 100644 index 0000000..33df952 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableConfigVO.java @@ -0,0 +1,40 @@ + +package net.lab1024.sa.common.module.support.codegenerator.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.*; + +import java.util.List; + +/** + * 表的配置信息 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/21 21:07:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +@Data +public class TableConfigVO { + + @ApiModelProperty("基础命名信息") + private CodeBasic basic; + + @ApiModelProperty("字段列") + private List fields; + + @ApiModelProperty("增加、修改 信息") + private CodeInsertAndUpdate insertAndUpdate; + + @ApiModelProperty("删除 信息") + private CodeDelete deleteInfo; + + @ApiModelProperty("查询字段") + private List queryFields; + + @ApiModelProperty("列表字段") + private List tableFields; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableVO.java new file mode 100644 index 0000000..286a2a3 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/domain/vo/TableVO.java @@ -0,0 +1,37 @@ + +package net.lab1024.sa.common.module.support.codegenerator.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 表信息 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/21 18:07:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +@Data +public class TableVO { + + @ApiModelProperty("表名") + private String tableName; + + @ApiModelProperty("表备注") + private String tableComment; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; + + @ApiModelProperty("配置时间") + private LocalDateTime configTime; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/CodeGeneratorService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/CodeGeneratorService.java new file mode 100644 index 0000000..c4b8505 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/CodeGeneratorService.java @@ -0,0 +1,228 @@ +package net.lab1024.sa.common.module.support.codegenerator.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.common.util.SmartStringUtil; +import net.lab1024.sa.common.module.support.codegenerator.constant.CodeGeneratorConstant; +import net.lab1024.sa.common.module.support.codegenerator.dao.CodeGeneratorConfigDao; +import net.lab1024.sa.common.module.support.codegenerator.dao.CodeGeneratorDao; +import net.lab1024.sa.common.module.support.codegenerator.domain.entity.CodeGeneratorConfigEntity; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorPreviewForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.TableQueryForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.*; +import net.lab1024.sa.common.module.support.codegenerator.domain.vo.TableColumnVO; +import net.lab1024.sa.common.module.support.codegenerator.domain.vo.TableConfigVO; +import net.lab1024.sa.common.module.support.codegenerator.domain.vo.TableVO; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.ByteArrayOutputStream; +import java.util.List; +import java.util.Optional; + +/** + * 代码生成器 Service + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Service +public class CodeGeneratorService { + + @Autowired + private CodeGeneratorDao codeGeneratorDao; + + @Autowired + private CodeGeneratorConfigDao codeGeneratorConfigDao; + + @Autowired + private CodeGeneratorTemplateService codeGeneratorTemplateService; + + + /** + * 列信息 + * + * @param tableName + * @return + */ + public List getTableColumns(String tableName) { + return codeGeneratorDao.selectTableColumn(tableName); + } + + + /** + * 查询数据库表数据 + * + * @param tableQueryForm + * @return + */ + public PageResult queryTableList(TableQueryForm tableQueryForm) { + Page page = SmartPageUtil.convert2PageQuery(tableQueryForm); + List tableVOList = codeGeneratorDao.queryTableList(page, tableQueryForm); + return SmartPageUtil.convert2PageResult(page, tableVOList); + } + + /** + * 获取 表的 配置信息 + * + * @param table + * @return + */ + public TableConfigVO getTableConfig(String table) { + + TableConfigVO config = new TableConfigVO(); + + CodeGeneratorConfigEntity codeGeneratorConfigEntity = codeGeneratorConfigDao.selectById(table); + if (codeGeneratorConfigEntity == null) { + return config; + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getBasic())) { + CodeBasic basic = JSON.parseObject(codeGeneratorConfigEntity.getBasic(), CodeBasic.class); + config.setBasic(basic); + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getFields())) { + List fields = JSONArray.parseArray(codeGeneratorConfigEntity.getFields(), CodeField.class); + config.setFields(fields); + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getInsertAndUpdate())) { + CodeInsertAndUpdate insertAndUpdate = JSON.parseObject(codeGeneratorConfigEntity.getInsertAndUpdate(), CodeInsertAndUpdate.class); + config.setInsertAndUpdate(insertAndUpdate); + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getDeleteInfo())) { + CodeDelete deleteInfo = JSON.parseObject(codeGeneratorConfigEntity.getDeleteInfo(), CodeDelete.class); + config.setDeleteInfo(deleteInfo); + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getQueryFields())) { + List queryFields = JSONArray.parseArray(codeGeneratorConfigEntity.getQueryFields(), CodeQueryField.class); + config.setQueryFields(queryFields); + } + + if (SmartStringUtil.isNotEmpty(codeGeneratorConfigEntity.getTableFields())) { + List tableFields = JSONArray.parseArray(codeGeneratorConfigEntity.getTableFields(), CodeTableField.class); + config.setTableFields(tableFields); + } + + return config; + } + + /** + * 更新配置 + * + * @param form + * @return + */ + public synchronized ResponseDTO updateConfig(CodeGeneratorConfigForm form) { + long existCount = codeGeneratorDao.countByTableName(form.getTableName()); + if (existCount == 0) { + return ResponseDTO.userErrorParam("表不存在,请联系后端查看下数据库"); + } + + CodeGeneratorConfigEntity codeGeneratorConfigEntity = codeGeneratorConfigDao.selectById(form.getTableName()); + boolean updateFlag = true; + if (codeGeneratorConfigEntity == null) { + codeGeneratorConfigEntity = new CodeGeneratorConfigEntity(); + updateFlag = false; + } + + // 校验假删,必须有 deleted_flag 字段 + List tableColumns = getTableColumns(form.getTableName()); + if (null != form.getDeleteInfo() && form.getDeleteInfo().getIsSupportDelete() && !form.getDeleteInfo().getIsPhysicallyDeleted()) { + Optional any = tableColumns.stream().filter(e -> e.getColumnName().equals(CodeGeneratorConstant.DELETED_FLAG)).findAny(); + if (!any.isPresent()) { + return ResponseDTO.userErrorParam("表结构中没有假删字段:" + CodeGeneratorConstant.DELETED_FLAG + ",请仔细排查"); + } + } + + // 校验表必须有主键 + if(!tableColumns.stream().filter( e -> "PRI".equalsIgnoreCase(e.getColumnKey())).findAny().isPresent()){ + return ResponseDTO.userErrorParam("表必须有主键,请联系后端查看下数据库表结构"); + } + + codeGeneratorConfigEntity.setTableName(form.getTableName()); + codeGeneratorConfigEntity.setBasic(JSON.toJSONString(form.getBasic())); + codeGeneratorConfigEntity.setFields(JSONArray.toJSONString(form.getFields())); + codeGeneratorConfigEntity.setInsertAndUpdate(JSON.toJSONString(form.getInsertAndUpdate())); + codeGeneratorConfigEntity.setDeleteInfo(JSON.toJSONString(form.getDeleteInfo())); + codeGeneratorConfigEntity.setQueryFields(JSONArray.toJSONString(form.getQueryFields())); + codeGeneratorConfigEntity.setTableFields(JSONArray.toJSONString(form.getTableFields())); + + if (updateFlag) { + codeGeneratorConfigDao.updateById(codeGeneratorConfigEntity); + } else { + codeGeneratorConfigDao.insert(codeGeneratorConfigEntity); + } + return ResponseDTO.ok(); + } + + /** + * 预览 + * + * @param form + * @return + */ + public ResponseDTO preview(CodeGeneratorPreviewForm form) { + long existCount = codeGeneratorDao.countByTableName(form.getTableName()); + if (existCount == 0) { + return ResponseDTO.userErrorParam("表不存在,请联系后端查看下数据库"); + } + + CodeGeneratorConfigEntity codeGeneratorConfigEntity = codeGeneratorConfigDao.selectById(form.getTableName()); + if (codeGeneratorConfigEntity == null) { + return ResponseDTO.userErrorParam("配置信息不存在,请先进行配置"); + } + + List columns = getTableColumns(form.getTableName()); + if (CollectionUtils.isEmpty(columns)) { + return ResponseDTO.userErrorParam("表没有列信息无法生成"); + } + + String result = codeGeneratorTemplateService.generate(form.getTableName(), form.getTemplateFile(), codeGeneratorConfigEntity); + return ResponseDTO.ok(result); + + } + + /** + * 下载代码 + * @param tableName + * @return + */ + public ResponseDTO download(String tableName) { + if (SmartStringUtil.isBlank(tableName)) { + return ResponseDTO.userErrorParam("表名不能为空"); + } + + long existCount = codeGeneratorDao.countByTableName(tableName); + if (existCount == 0) { + return ResponseDTO.userErrorParam("表不存在,请联系后端查看下数据库"); + } + + CodeGeneratorConfigEntity codeGeneratorConfigEntity = codeGeneratorConfigDao.selectById(tableName); + if (codeGeneratorConfigEntity == null) { + return ResponseDTO.userErrorParam("配置信息不存在,请先进行配置"); + } + + List columns = getTableColumns(tableName); + if (CollectionUtils.isEmpty(columns)) { + return ResponseDTO.userErrorParam("表没有列信息无法生成"); + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + codeGeneratorTemplateService.zipGeneratedFiles(out, tableName, codeGeneratorConfigEntity); + return ResponseDTO.ok(out.toByteArray()); + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/CodeGeneratorTemplateService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/CodeGeneratorTemplateService.java new file mode 100644 index 0000000..d9808e2 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/CodeGeneratorTemplateService.java @@ -0,0 +1,238 @@ +package net.lab1024.sa.common.module.support.codegenerator.service; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IORuntimeException; +import cn.hutool.core.util.ZipUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.google.common.base.CaseFormat; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.util.SmartStringUtil; +import net.lab1024.sa.common.module.support.codegenerator.domain.entity.CodeGeneratorConfigEntity; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.*; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.ControllerVariableService; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.DaoVariableService; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.ManagerVariableService; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.ServiceVariableService; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.domain.*; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.front.ApiVariableService; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.front.ConstVariableService; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.front.FormVariableService; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.front.ListVariableService; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import net.lab1024.sa.common.module.support.codegenerator.util.CodeGeneratorTool; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.velocity.Template; +import org.apache.velocity.app.Velocity; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.tools.ToolContext; +import org.apache.velocity.tools.ToolManager; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.io.File; +import java.io.OutputStream; +import java.io.StringWriter; +import java.nio.charset.Charset; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 代码生成器 模板 Service + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-06-30 22:15:38 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ + +@Service +@Slf4j +public class CodeGeneratorTemplateService { + + + private Map map = new HashMap<>(); + + @PostConstruct + public void init() { + // 后端 + map.put("java/domain/entity/Entity.java", new EntityVariableService()); + map.put("java/domain/form/AddForm.java", new AddFormVariableService()); + map.put("java/domain/form/UpdateForm.java", new UpdateFormVariableService()); + map.put("java/domain/form/QueryForm.java", new QueryFormVariableService()); + map.put("java/domain/vo/VO.java", new VOVariableService()); + map.put("java/controller/Controller.java", new ControllerVariableService()); + map.put("java/service/Service.java", new ServiceVariableService()); + map.put("java/manager/Manager.java", new ManagerVariableService()); + map.put("java/dao/Dao.java", new DaoVariableService()); + map.put("java/mapper/Mapper.xml", new MapperVariableService()); + // 前端 + map.put("js/api.js", new ApiVariableService()); + map.put("js/const.js", new ConstVariableService()); + map.put("js/list.vue", new ListVariableService()); + map.put("js/form.vue", new FormVariableService()); + } + + public void zipGeneratedFiles(OutputStream outputStream, String tableName, CodeGeneratorConfigEntity codeGeneratorConfigEntity) { + String uuid = UUID.randomUUID().toString(); + File dir = new File(uuid); + + // 1、生产文件 + CodeBasic basic = JSON.parseObject(codeGeneratorConfigEntity.getBasic(), CodeBasic.class); + String moduleName = basic.getModuleName(); + + for (Map.Entry entry : map.entrySet()) { + try { + String templateFile = entry.getKey(); + String upperCamel = new CodeGeneratorTool().lowerCamel2UpperCamel(moduleName); + String lowerHyphen = new CodeGeneratorTool().lowerCamel2LowerHyphen(moduleName); + String[] templateSplit = templateFile.split("/"); + String fileName = templateFile.startsWith("java") ? upperCamel + templateSplit[templateSplit.length - 1] : lowerHyphen + "-" + templateSplit[templateSplit.length - 1]; + String fullPathFileName = templateFile.replaceAll(templateSplit[templateSplit.length - 1], fileName); + fullPathFileName = fullPathFileName.replaceAll("java/", "java/" + basic.getModuleName().toLowerCase() + "/"); + + String fileContent = generate(tableName, templateFile, codeGeneratorConfigEntity); + File file = new File(uuid + "/" + fullPathFileName); + file.getParentFile().mkdirs(); + FileUtil.appendUtf8String(fileContent, file); + } catch (IORuntimeException e) { + log.error(e.getMessage(), e); + } + } + + // 2、后端的枚举文件 + List fields = JSONArray.parseArray(codeGeneratorConfigEntity.getFields(), CodeField.class); + if (CollectionUtils.isNotEmpty(fields)) { + List enumFiledList = fields.stream().filter(e -> SmartStringUtil.isNotBlank(e.getEnumName())).collect(Collectors.toList()); + for (CodeField codeField : enumFiledList) { + Map variablesMap = new HashMap<>(); + + String enumName = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, codeField.getEnumName()); + if (!enumName.endsWith("Enum")) { + enumName = enumName + "Enum"; + } + variablesMap.put("enumName", enumName); + variablesMap.put("enumDesc", codeField.getColumnComment()); + variablesMap.put("enumJavaType", codeField.getJavaType()); + variablesMap.put("basic", basic); + variablesMap.put("packageName", basic.getJavaPackageName() + ".constant"); + + String fileContent = render("code-generator-template/java/constant/enum.java.vm", variablesMap); + File file = new File(uuid + "/java/" + basic.getModuleName().toLowerCase() + "/constant/" + enumName + ".java"); + file.getParentFile().mkdirs(); + FileUtil.appendUtf8String(fileContent, file); + } + } + + + ZipUtil.zip(outputStream, Charset.forName("utf-8"), false, null, dir); + + FileUtil.del(dir); + + } + + + public String generate(String tableName, String file, CodeGeneratorConfigEntity codeGeneratorConfigEntity) { + + // -------------------- 1 校验不支持的代码生成,比如增加、删除等 -------------------- + + String finalFile = file; + Optional optional = map.keySet().stream().filter(e -> e.contains(finalFile)).findFirst(); + if (!optional.isPresent()) { + return "不存在此模板!"; + } + + file = optional.get(); + CodeGenerateBaseVariableService codeGenerateBaseVariableService = map.get(file); + if (codeGenerateBaseVariableService == null) { + return "代码生成Service不存在,请检查相关代码!"; + } + + CodeBasic basic = JSON.parseObject(codeGeneratorConfigEntity.getBasic(), CodeBasic.class); + List fields = JSONArray.parseArray(codeGeneratorConfigEntity.getFields(), CodeField.class); + CodeInsertAndUpdate insertAndUpdate = JSON.parseObject(codeGeneratorConfigEntity.getInsertAndUpdate(), CodeInsertAndUpdate.class); + CodeDelete deleteInfo = JSON.parseObject(codeGeneratorConfigEntity.getDeleteInfo(), CodeDelete.class); + List queryFields = JSONArray.parseArray(codeGeneratorConfigEntity.getQueryFields(), CodeQueryField.class); + List tableFields = JSONArray.parseArray(codeGeneratorConfigEntity.getTableFields(), CodeTableField.class); + tableFields.stream().forEach(e -> e.setWidth(e.getWidth() == null ? 0 : e.getWidth())); + + CodeGeneratorConfigForm form = CodeGeneratorConfigForm.builder().basic(basic).fields(fields).insertAndUpdate(insertAndUpdate).deleteInfo(deleteInfo).queryFields(queryFields).tableFields(tableFields).deleteInfo(deleteInfo).build(); + form.setTableName(tableName); + if (!codeGenerateBaseVariableService.isSupport(form)) { + return "业务不需要此功能,故没有生成代码;"; + } + + // -------------------- 2 通用模板的变量 -------------------- + Map variablesMap = new HashMap<>(); + + + Map basicMap = BeanUtil.beanToMap(basic); + basicMap.put("frontDate", DateUtil.formatLocalDateTime(basic.getFrontDate())); + basicMap.put("backendDate", DateUtil.formatLocalDateTime(basic.getBackendDate())); + + variablesMap.put("basic", basicMap); + variablesMap.put("fields", fields); + variablesMap.put("insertAndUpdate", insertAndUpdate); + variablesMap.put("deleteInfo", deleteInfo); + variablesMap.put("queryFields", queryFields); + variablesMap.put("tableFields", tableFields); + variablesMap.put("tableName", tableName); + + //名词的大写开头和小写开头 + HashMap names = new HashMap<>(); + names.put("lowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, basic.getModuleName())); + names.put("upperCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_CAMEL, basic.getModuleName())); + names.put("lowerHyphenCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, basic.getModuleName())); + variablesMap.put("name", names); + + //主键字段名称和java类型 + CodeField primaryKeycodeField = fields.stream().filter(e -> e.getPrimaryKeyFlag()).findFirst().get(); + if (primaryKeycodeField != null) { + variablesMap.put("primaryKeyJavaType", primaryKeycodeField.getJavaType()); + variablesMap.put("primaryKeyFieldName", primaryKeycodeField.getFieldName()); + variablesMap.put("primaryKeyColumnName", primaryKeycodeField.getColumnName()); + } + + // -------------------- 3、针对此 模板 的特殊变量 -------------------- + + Map specialVariables = codeGenerateBaseVariableService.getInjectVariablesMap(form); + variablesMap.putAll(specialVariables); + + // -------------------- 4、模板 生成代码 -------------------- + + return render("code-generator-template/" + file + ".vm", variablesMap); + } + + /** + * 渲染 + * + * @param templateFile + * @param variablesMap + * @return + */ + private String render(String templateFile, Map variablesMap) { + VelocityEngine engine = new VelocityEngine(); + engine.setProperty(Velocity.FILE_RESOURCE_LOADER_CACHE, true); + engine.setProperty(Velocity.INPUT_ENCODING, "UTF-8"); + engine.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + engine.init(); + Template template = engine.getTemplate(templateFile); + + //加载tools.xml配置文件 + ToolManager toolManager = new ToolManager(); + toolManager.configure("code-generator-template/tools.xml"); + + //注入变量 + ToolContext context = toolManager.createContext(); + context.putAll(variablesMap); + + StringWriter sw = new StringWriter(); + template.merge(context, sw); + return sw.toString(); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/CodeGenerateBaseVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/CodeGenerateBaseVariableService.java new file mode 100644 index 0000000..aff8da1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/CodeGenerateBaseVariableService.java @@ -0,0 +1,162 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable; + +import com.google.common.base.CaseFormat; +import net.lab1024.sa.common.common.util.SmartStringUtil; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdate; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ +public abstract class CodeGenerateBaseVariableService { + + public abstract Map getInjectVariablesMap(CodeGeneratorConfigForm form); + + /** + * 是否支持 : + * 1、增加、修改 + * 2、删除 + * + * @param form + * @return + */ + public abstract boolean isSupport(CodeGeneratorConfigForm form); + + /** + * 获取所有javabean的 import 包名 + * + * @param form + * @return + */ + public List getJavaBeanImportClass(CodeGeneratorConfigForm form) { + String upperCamelName = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_CAMEL, form.getBasic().getModuleName()); + ArrayList list = new ArrayList<>(); + + list.add("import " + form.getBasic().getJavaPackageName() + ".domain.entity." + upperCamelName + "Entity;" ); + + list.add("import " + form.getBasic().getJavaPackageName() + ".domain.form." + upperCamelName + "AddForm;" ); + list.add("import " + form.getBasic().getJavaPackageName() + ".domain.form." + upperCamelName + "UpdateForm;" ); + list.add("import " + form.getBasic().getJavaPackageName() + ".domain.form." + upperCamelName + "QueryForm;" ); + + list.add("import " + form.getBasic().getJavaPackageName() + ".domain.vo." + upperCamelName + "VO;" ); + return list; + } + + + /** + * 根据列名查找 CodeField + */ + public CodeField getCodeFieldByColumnName(String columnName, CodeGeneratorConfigForm form) { + List fields = form.getFields(); + if (CollectionUtils.isEmpty(fields)) { + return null; + } + + return fields.stream().filter(e -> columnName.equals(e.getColumnName())) + .findFirst().get(); + } + + + /** + * 是否为文件上传字段 + */ + protected boolean isFile(String columnName, CodeGeneratorConfigForm form) { + CodeInsertAndUpdate insertAndUpdate = form.getInsertAndUpdate(); + if (insertAndUpdate == null) { + return false; + } + + List fieldList = insertAndUpdate.getFieldList(); + if (CollectionUtils.isEmpty(fieldList)) { + return false; + } + + Optional first = fieldList.stream().filter(e -> columnName.equals(e.getColumnName())).findFirst(); + if (!first.isPresent()) { + return false; + } + + CodeInsertAndUpdateField field = first.get(); + return SmartStringUtil.contains(field.getFrontComponent(), "Upload" ); + } + + /** + * 是否为 枚举 + */ + protected boolean isDict(String columnName, CodeGeneratorConfigForm form) { + List fields = form.getFields(); + if (CollectionUtils.isEmpty(fields)) { + return false; + } + + Optional first = fields.stream().filter(e -> columnName.equals(e.getColumnName())).findFirst(); + if (first.isPresent()) { + return false; + } + + CodeField codeField = first.get(); + return codeField.getDict() != null; + } + + /** + * 是否为 枚举 + */ + protected boolean isEnum(String columnName, CodeGeneratorConfigForm form) { + List fields = form.getFields(); + if (CollectionUtils.isEmpty(fields)) { + return false; + } + + Optional first = fields.stream().filter(e -> columnName.equals(e.getColumnName())).findFirst(); + if (first.isPresent()) { + return false; + } + + CodeField codeField = first.get(); + return codeField.getEnumName() != null; + } + + /** + * 获取字段集合 + * + * @param form + * @return + */ + protected Map getFieldMap(CodeGeneratorConfigForm form) { + List fields = form.getFields(); + if (fields == null) { + return new HashMap<>(); + } + + return fields.stream().collect(Collectors.toMap(CodeField::getColumnName, Function.identity())); + } + + /** + * 获取java类型 + * + * @return + */ + protected String getJavaPackageName(String javaType) { + if ("BigDecimal".equals(javaType)) { + return "import java.math.BigDecimal;"; + } else if ("LocalDate".equals(javaType)) { + return "import java.time.LocalDate;"; + } else if ("LocalDateTime".equals(javaType)) { + return "import java.time.LocalDateTime;"; + } else { + return null; + } + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ControllerVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ControllerVariableService.java new file mode 100644 index 0000000..60543b3 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ControllerVariableService.java @@ -0,0 +1,78 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.backend; + +import com.google.common.base.CaseFormat; +import net.lab1024.sa.common.common.util.SmartEnumUtil; +import net.lab1024.sa.common.module.support.codegenerator.constant.CodeDeleteEnum; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class ControllerVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> Boolean.TRUE.equals(e.getInsertFlag())).collect(Collectors.toList()); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".controller"); + + List packageList = getPackageList(updateFieldList, form); + variablesMap.put("importPackageList", packageList); + + return variablesMap; + } + + + public List getPackageList(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return new ArrayList<>(); + } + + HashSet packageSet = new HashSet<>(); + + //1、javabean相关的包 + packageSet.addAll(getJavaBeanImportClass(form).stream().filter(e -> !e.contains("Entity;")).collect(Collectors.toList())); + + //2、其他包 + if (form.getDeleteInfo().getIsSupportDelete()) { + + CodeDeleteEnum codeDeleteEnum = SmartEnumUtil.getEnumByValue(form.getDeleteInfo().getDeleteEnum(), CodeDeleteEnum.class); + if (codeDeleteEnum == CodeDeleteEnum.BATCH || codeDeleteEnum == CodeDeleteEnum.SINGLE_AND_BATCH) { + //2、批量删除的话,要导入ValidateList + packageSet.add("import net.lab1024.sa.common.common.domain.ValidateList;"); + } + + if (codeDeleteEnum == CodeDeleteEnum.SINGLE || codeDeleteEnum == CodeDeleteEnum.SINGLE_AND_BATCH) { + //3、单个删除的话,要导入 @PathVariable + packageSet.add("import org.springframework.web.bind.annotation.PathVariable;"); + packageSet.add("import org.springframework.web.bind.annotation.GetMapping;"); + } + } + + packageSet.add("import " + form.getBasic().getJavaPackageName() + ".service." + CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, form.getBasic().getModuleName()) + "Service;"); + + // 排序一下 + ArrayList packageList = new ArrayList<>(packageSet); + Collections.sort(packageList); + return packageList; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/DaoVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/DaoVariableService.java new file mode 100644 index 0000000..caf4963 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/DaoVariableService.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.backend; + +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class DaoVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> Boolean.TRUE.equals(e.getInsertFlag())).collect(Collectors.toList()); + List packageList = getPackageList(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".dao" ); + variablesMap.put("importPackageList", packageList); + + return variablesMap; + } + + + public List getPackageList(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return new ArrayList<>(); + } + + HashSet packageSet = new HashSet<>(); + + //1、javabean相关的包 + packageSet.addAll(getJavaBeanImportClass(form).stream().filter( e-> e.contains("QueryForm;") || e.contains("VO;")|| e.contains("Entity;")).collect(Collectors.toList())); + + //2、util + packageSet.add("import java.util.List;"); + + //3、 排序一下 + ArrayList packageList = new ArrayList<>(packageSet); + Collections.sort(packageList); + return packageList; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ManagerVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ManagerVariableService.java new file mode 100644 index 0000000..f4e43e0 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ManagerVariableService.java @@ -0,0 +1,55 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.backend; + +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class ManagerVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> Boolean.TRUE.equals(e.getInsertFlag())).collect(Collectors.toList()); + List packageList = getPackageList(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".manager" ); + variablesMap.put("importPackageList", packageList); + + return variablesMap; + } + + + public List getPackageList(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return new ArrayList<>(); + } + + HashSet packageList = new HashSet<>(); + + //1、javabean相关的包 + packageList.addAll(getJavaBeanImportClass(form).stream().filter(e -> e.contains("Entity;")).collect(Collectors.toList())); + + //2、dao + packageList.add("import " + form.getBasic().getJavaPackageName() + ".dao."+ form.getBasic().getModuleName() + "Dao;" ); + return new ArrayList<>(packageList); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ServiceVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ServiceVariableService.java new file mode 100644 index 0000000..a87473c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/ServiceVariableService.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.backend; + +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class ServiceVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> Boolean.TRUE.equals(e.getInsertFlag())).collect(Collectors.toList()); + List packageList = getPackageList(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".service" ); + variablesMap.put("importPackageList", packageList); + + return variablesMap; + } + + + public List getPackageList(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return new ArrayList<>(); + } + + HashSet packageSet = new HashSet<>(); + + //1、javabean相关的包 + packageSet.addAll(getJavaBeanImportClass(form)); + + //2、dao + packageSet.add("import " + form.getBasic().getJavaPackageName() + ".dao."+ form.getBasic().getModuleName() + "Dao;" ); + + //3、util list + packageSet.add("import java.util.List;"); + + //3、 排序一下 + ArrayList packageList = new ArrayList<>(packageSet); + Collections.sort(packageList); + return packageList; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/AddFormVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/AddFormVariableService.java new file mode 100644 index 0000000..ee9822a --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/AddFormVariableService.java @@ -0,0 +1,131 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.domain; + +import cn.hutool.core.bean.BeanUtil; +import net.lab1024.sa.common.common.util.SmartStringUtil; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdate; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class AddFormVariableService extends CodeGenerateBaseVariableService { + + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + CodeInsertAndUpdate insertAndUpdate = form.getInsertAndUpdate(); + return insertAndUpdate != null && insertAndUpdate.getIsSupportInsertAndUpdate() != null && insertAndUpdate.getIsSupportInsertAndUpdate(); + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> Boolean.TRUE.equals(e.getInsertFlag())).collect(Collectors.toList()); + ImmutablePair, List>> packageListAndFields = getPackageListAndFields(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".domain.form"); + variablesMap.put("importPackageList", packageListAndFields.getLeft()); + variablesMap.put("fields", packageListAndFields.getRight()); + + return variablesMap; + } + + + public ImmutablePair, List>> getPackageListAndFields(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return ImmutablePair.of(new ArrayList<>(), new ArrayList<>()); + } + + Map fieldMap = getFieldMap(form); + HashSet packageList = new HashSet<>(); + + + /** + * 1、LocalDate、LocalDateTime、BigDecimal 类型的包名 + * 2、排序 + */ + + List> finalFieldList = new ArrayList<>(); + + for (CodeInsertAndUpdateField field : fields) { + CodeField codeField = fieldMap.get(field.getColumnName()); + if (codeField == null) { + continue; + } + + // CodeField 和 InsertAndUpdateField 合并 + Map finalFieldMap = BeanUtil.beanToMap(field); + finalFieldMap.putAll(BeanUtil.beanToMap(codeField)); + + // 枚举 + if (SmartStringUtil.isNotEmpty(codeField.getEnumName())) { + packageList.add("import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;"); + packageList.add("import net.lab1024.sa.common.common.validator.enumeration.CheckEnum;"); + packageList.add("import " + form.getBasic().getJavaPackageName() + ".constant." + codeField.getEnumName() + ";"); + + //enum check + String checkEnumPrefix = "@CheckEnum(value = " + codeField.getEnumName() + ".class, message = \"" + codeField.getLabel() + " 错误\""; + String checkEnum = checkEnumPrefix + (field.getRequiredFlag() ? ", required = true)" : ")"); + + finalFieldMap.put("apiModelProperty", "@ApiModelPropertyEnum(value = " + codeField.getEnumName() + ".class, desc = \"" + codeField.getLabel() + "\")"); + finalFieldMap.put("checkEnum", checkEnum); + finalFieldMap.put("isEnum", true); + + } else { + String prefix = "@ApiModelProperty(value = \"" + codeField.getLabel() + "\""; + String apiModelProperty = prefix + (field.getRequiredFlag() ? ", required = true)" : ")"); + finalFieldMap.put("apiModelProperty", apiModelProperty); + + packageList.add("import io.swagger.annotations.ApiModelProperty;"); + + if (Boolean.TRUE.equals(field.getRequiredFlag())) { + String notEmptyPrefix = "String".equals(codeField.getJavaType()) ? "@NotBlank" : "@NotNull"; + finalFieldMap.put("notEmpty", "\n " + notEmptyPrefix + "(message = \"" + codeField.getLabel() + " 不能为空\")"); + packageList.add("String".equals(codeField.getJavaType()) ? "import javax.validation.constraints.NotBlank;" + : "import javax.validation.constraints.NotNull;"); + } + } + + + //字典 + if (SmartStringUtil.isNotEmpty(codeField.getDict())) { + finalFieldMap.put("dict", "\n @JsonDeserialize(using = DictValueVoDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.common.common.json.deserializer.DictValueVoDeserializer;"); + } + + //文件上传 + if (SmartStringUtil.contains(field.getFrontComponent(), "Upload")) { + finalFieldMap.put("file", "\n @JsonDeserialize(using = FileKeyVoDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.common.common.json.deserializer.FileKeyVoDeserializer;"); + } + + packageList.add(getJavaPackageName(codeField.getJavaType())); + finalFieldList.add(finalFieldMap); + } + + + // lombok + packageList.add("import lombok.Data;"); + + List packageNameList = packageList.stream().filter(Objects::nonNull).collect(Collectors.toList()); + Collections.sort(packageNameList); + return ImmutablePair.of(packageNameList, finalFieldList); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/DeleteFormVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/DeleteFormVariableService.java new file mode 100644 index 0000000..52525f5 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/DeleteFormVariableService.java @@ -0,0 +1,130 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.domain; + +import cn.hutool.core.bean.BeanUtil; +import net.lab1024.sa.common.common.util.SmartStringUtil; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeDelete; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class DeleteFormVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + CodeDelete deleteInfo = form.getDeleteInfo(); + return deleteInfo != null && deleteInfo.getIsSupportDelete() != null && deleteInfo.getIsSupportDelete(); + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + + Map variablesMap = new HashMap<>(); + + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> Boolean.TRUE.equals(e.getInsertFlag())).collect(Collectors.toList()); + ImmutablePair, List>> packageListAndFields = getPackageListAndFields(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".domain.form"); + variablesMap.put("importPackageList", packageListAndFields.getLeft()); + variablesMap.put("fields", packageListAndFields.getRight()); + + return variablesMap; + } + + public ImmutablePair, List>> getPackageListAndFields(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return ImmutablePair.of(new ArrayList<>(), new ArrayList<>()); + } + + Map fieldMap = getFieldMap(form); + HashSet packageList = new HashSet<>(); + + + /** + * 1、LocalDate、LocalDateTime、BigDecimal 类型的包名 + * 2、排序 + */ + + List> finalFieldList = new ArrayList<>(); + + for (CodeInsertAndUpdateField field : fields) { + CodeField codeField = fieldMap.get(field.getColumnName()); + if (codeField == null) { + continue; + } + + // CodeField 和 InsertAndUpdateField 合并 + Map finalFieldMap = BeanUtil.beanToMap(field); + finalFieldMap.putAll(BeanUtil.beanToMap(codeField)); + + // 枚举 + if (SmartStringUtil.isNotEmpty(codeField.getEnumName())) { + packageList.add("import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;"); + packageList.add("import net.lab1024.sa.common.common.validator.enumeration.CheckEnum;"); + packageList.add("import " + form.getBasic().getJavaPackageName() + ".constant." + codeField.getEnumName() + ";"); + + //enum check + String checkEnumPrefix = "@CheckEnum(value = " + codeField.getEnumName() + ".class, message = \"" + codeField.getLabel() + " 错误\""; + String checkEnum = checkEnumPrefix + (field.getRequiredFlag() ? ", required = true)" : ")"); + + finalFieldMap.put("apiModelProperty", "@ApiModelPropertyEnum(value = " + codeField.getEnumName() + ".class, desc = \"" + codeField.getLabel() + "\")"); + finalFieldMap.put("checkEnum", checkEnum); + finalFieldMap.put("isEnum", true); + + } else { + String prefix = "@ApiModelProperty(value = \"" + codeField.getLabel() + "\""; + String apiModelProperty = prefix + (field.getRequiredFlag() ? ", required = true)" : ")"); + finalFieldMap.put("apiModelProperty", apiModelProperty); + + packageList.add("import io.swagger.annotations.ApiModelProperty;"); + + if (Boolean.TRUE.equals(field.getRequiredFlag())) { + String notEmptyPrefix = "String".equals(codeField.getJavaType()) ? "@NotBlank" : "@NotNull"; + finalFieldMap.put("notEmpty", "\n " + notEmptyPrefix + "(message = \"" + codeField.getLabel() + " 不能为空\")"); + packageList.add("String".equals(codeField.getJavaType()) ? "import javax.validation.constraints.NotBlank;" + : "import javax.validation.constraints.NotNull;"); + } + } + + + //字典 + if (SmartStringUtil.isNotEmpty(codeField.getDict())) { + finalFieldMap.put("dict", "\n @JsonDeserialize(using = DictValueVoDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.common.common.json.deserializer.DictValueVoDeserializer;"); + } + + //文件上传 + if (SmartStringUtil.contains(field.getFrontComponent(), "Upload")) { + finalFieldMap.put("file", "\n @JsonDeserialize(using = FileKeyVoDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.common.common.json.deserializer.FileKeyVoDeserializer;"); + } + + packageList.add(getJavaPackageName(codeField.getJavaType())); + finalFieldList.add(finalFieldMap); + } + + + // lombok + packageList.add("import lombok.Data;"); + + List packageNameList = packageList.stream().filter(Objects::nonNull).collect(Collectors.toList()); + Collections.sort(packageNameList); + return ImmutablePair.of(packageNameList, finalFieldList); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/EntityVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/EntityVariableService.java new file mode 100644 index 0000000..f194385 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/EntityVariableService.java @@ -0,0 +1,73 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.domain; + +import com.google.common.collect.Lists; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class EntityVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".domain.entity"); + variablesMap.put("importPackageList", getImportPackageList(form.getFields())); + + + return variablesMap; + } + + + public List getImportPackageList(List fields) { + if (CollectionUtils.isEmpty(fields)) { + return Lists.newArrayList(); + } + + /** + * 1、LocalDate、LocalDateTime、BigDecimal 类型的包名 + * 2、排序 + */ + List result = fields.stream().map(e -> getJavaPackageName(e.getJavaType())).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + + // lombok + result.add("import lombok.Data;"); + + // mybatis plus + result.add("import com.baomidou.mybatisplus.annotation.TableName;"); + + //主键 + boolean isExistPrimaryKey = fields.stream().filter(e -> e.getPrimaryKeyFlag() != null && e.getPrimaryKeyFlag()).findFirst().isPresent(); + if (isExistPrimaryKey) { + result.add("import com.baomidou.mybatisplus.annotation.TableId;"); + } + + //自增 + boolean isExistAutoIncrease = fields.stream().filter(e -> e.getAutoIncreaseFlag() != null && e.getAutoIncreaseFlag()).findFirst().isPresent(); + if (isExistAutoIncrease) { + result.add("import com.baomidou.mybatisplus.annotation.IdType;"); + } + + Collections.sort(result); + return result; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/MapperVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/MapperVariableService.java new file mode 100644 index 0000000..7a6bbd2 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/MapperVariableService.java @@ -0,0 +1,93 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.domain; + +import cn.hutool.core.bean.BeanUtil; +import net.lab1024.sa.common.module.support.codegenerator.constant.CodeQueryFieldQueryTypeEnum; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeQueryField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class MapperVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + List> finalQueryFiledList = new ArrayList<>(); + for (CodeQueryField queryField : form.getQueryFields()) { + Map fieldMap = BeanUtil.beanToMap(queryField); + finalQueryFiledList.add(fieldMap); + + //模糊查询 + if (CodeQueryFieldQueryTypeEnum.LIKE.getValue().equals(queryField.getQueryTypeEnum())) { + StringBuilder stringBuilder = new StringBuilder(); + List columnNameList = queryField.getColumnNameList(); + if (columnNameList.size() == 1) { + // AND INSTR(t_notice.title,#{query.keywords}) + stringBuilder.append(" AND INSTR(" )// + .append(form.getTableName()).append("." ).append(queryField.getColumnNameList().get(0)) + .append(",#{queryForm." ) + .append(queryField.getFieldName()) + .append("})" ); + } else { + for (int i = 0; i < columnNameList.size(); i++) { + if (i == 0) { + stringBuilder.append("AND ( INSTR(" )// + .append(form.getTableName()).append("." ).append(queryField.getColumnNameList().get(i)) + .append(",#{queryForm." ) + .append(queryField.getFieldName()) + .append("})" ); + } else { + // OR INSTR(t_notice.author,#{query.keywords}) + stringBuilder.append("\n OR INSTR(" )// + .append(form.getTableName()).append("." ).append(queryField.getColumnNameList().get(i)) + .append(",#{queryForm." ) + .append(queryField.getFieldName()) + .append("})" ); + } + } + stringBuilder.append("\n )" ); + } + fieldMap.put("likeStr", stringBuilder.toString()); + }else{ + fieldMap.put("columnName",queryField.getColumnNameList().get(0)); + } + } + + variablesMap.put("queryFields", finalQueryFiledList); + variablesMap.put("daoClassName", form.getBasic().getJavaPackageName() + ".dao." + form.getBasic().getModuleName() + "Dao" ); + return variablesMap; + } + + + public List getPackageList(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return new ArrayList<>(); + } + + HashSet packageList = new HashSet<>(); + + //1、javabean相关的包 + packageList.addAll(getJavaBeanImportClass(form)); + + //2、dao + packageList.add("import " + form.getBasic().getJavaPackageName() + ".dao." + form.getBasic().getModuleName() + "Dao;" ); + return new ArrayList<>(packageList); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/QueryFormVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/QueryFormVariableService.java new file mode 100644 index 0000000..18bf844 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/QueryFormVariableService.java @@ -0,0 +1,128 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.domain; + +import cn.hutool.core.bean.BeanUtil; +import net.lab1024.sa.common.common.util.SmartEnumUtil; +import net.lab1024.sa.common.module.support.codegenerator.constant.CodeQueryFieldQueryTypeEnum; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeQueryField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class QueryFormVariableService extends CodeGenerateBaseVariableService { + + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + ImmutablePair, List>> packageListAndFields = getPackageListAndFields(form); + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".domain.form"); + variablesMap.put("importPackageList", packageListAndFields.getLeft()); + variablesMap.put("fields", packageListAndFields.getRight()); + return variablesMap; + } + + + public ImmutablePair, List>> getPackageListAndFields(CodeGeneratorConfigForm form) { + List fields = form.getQueryFields(); + if (CollectionUtils.isEmpty(fields)) { + return ImmutablePair.of(new ArrayList<>(), new ArrayList<>()); + } + + HashSet packageList = new HashSet<>(); + + + /** + * 1、LocalDate、LocalDateTime、BigDecimal 类型的包名 + * 2、排序 + */ + + List> finalFieldList = new ArrayList<>(); + + for (CodeQueryField field : fields) { + + // CodeField 和 InsertAndUpdateField 合并 + Map finalFieldMap = BeanUtil.beanToMap(field); + finalFieldMap.putAll(BeanUtil.beanToMap(field)); + + String queryTypeEnumStr = field.getQueryTypeEnum(); + CodeQueryFieldQueryTypeEnum queryTypeEnum = SmartEnumUtil.getEnumByValue(queryTypeEnumStr, CodeQueryFieldQueryTypeEnum.class); + if (queryTypeEnum == null) { + continue; + } + + String apiModelProperty = "@ApiModelProperty(value = \"" + field.getLabel() + "\")"; + finalFieldMap.put("apiModelProperty", apiModelProperty); + packageList.add("import io.swagger.annotations.ApiModelProperty;"); + + CodeField codeField = null; + + switch (queryTypeEnum) { + case LIKE: + finalFieldMap.put("javaType", "String"); + break; + case EQUAL: + codeField = getCodeFieldByColumnName(field.getColumnNameList().get(0), form); + if (codeField == null) { + finalFieldMap.put("javaType", "String"); + } else { + finalFieldMap.put("javaType", codeField.getJavaType()); + } + break; + case DATE_RANGE: + case DATE: + packageList.add("import java.time.LocalDate;"); + finalFieldMap.put("javaType", "LocalDate"); + break; + case ENUM: + codeField = getCodeFieldByColumnName(field.getColumnNameList().get(0), form); + if (codeField == null) { + continue; + } + + packageList.add("import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;"); + packageList.add("import net.lab1024.sa.common.common.validator.enumeration.CheckEnum;"); + packageList.add("import " + form.getBasic().getJavaPackageName() + ".constant." + codeField.getEnumName() + ";"); + + //enum check + String checkEnum = "@CheckEnum(value = " + codeField.getEnumName() + ".class, message = \"" + codeField.getLabel() + " 错误\")"; + finalFieldMap.put("apiModelProperty", "@ApiModelPropertyEnum(value = " + codeField.getEnumName() + ".class, desc = \"" + codeField.getLabel() + "\")"); + finalFieldMap.put("checkEnum", checkEnum); + finalFieldMap.put("isEnum", true); + + finalFieldMap.put("javaType", codeField.getJavaType()); + break; + default: + finalFieldMap.put("javaType", "String"); + } + + finalFieldList.add(finalFieldMap); + } + + + // lombok + packageList.add("import lombok.Data;"); + + List packageNameList = packageList.stream().filter(Objects::nonNull).collect(Collectors.toList()); + Collections.sort(packageNameList); + return ImmutablePair.of(packageNameList, finalFieldList); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/UpdateFormVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/UpdateFormVariableService.java new file mode 100644 index 0000000..b0323ad --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/UpdateFormVariableService.java @@ -0,0 +1,145 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.domain; + +import cn.hutool.core.bean.BeanUtil; +import net.lab1024.sa.common.common.util.SmartStringUtil; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdate; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class UpdateFormVariableService extends CodeGenerateBaseVariableService { + + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + CodeInsertAndUpdate insertAndUpdate = form.getInsertAndUpdate(); + return insertAndUpdate != null && insertAndUpdate.getIsSupportInsertAndUpdate() != null && insertAndUpdate.getIsSupportInsertAndUpdate(); + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + Map fieldMap = getFieldMap(form); + List updateFieldList = form.getInsertAndUpdate().getFieldList().stream().filter(e -> { + boolean isUpdate = Boolean.TRUE.equals(e.getUpdateFlag()); + CodeField codeField = fieldMap.get(e.getColumnName()); + if (codeField == null) { + return false; + } + + if(Boolean.TRUE.equals(codeField.getPrimaryKeyFlag())){ + e.setRequiredFlag(true); + } + + return isUpdate || Boolean.TRUE.equals(codeField.getPrimaryKeyFlag()); + } + + ).collect(Collectors.toList()); + + ImmutablePair, List>> packageListAndFields = getPackageListAndFields(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".domain.form"); + variablesMap.put("importPackageList", packageListAndFields.getLeft()); + variablesMap.put("fields", packageListAndFields.getRight()); + + return variablesMap; + } + + public ImmutablePair, List>> getPackageListAndFields(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return ImmutablePair.of(new ArrayList<>(), new ArrayList<>()); + } + + Map fieldMap = getFieldMap(form); + HashSet packageList = new HashSet<>(); + + + /** + * 1、LocalDate、LocalDateTime、BigDecimal 类型的包名 + * 2、排序 + */ + + List> finalFieldList = new ArrayList<>(); + + for (CodeInsertAndUpdateField field : fields) { + CodeField codeField = fieldMap.get(field.getColumnName()); + if (codeField == null) { + continue; + } + + // CodeField 和 InsertAndUpdateField 合并 + Map finalFieldMap = BeanUtil.beanToMap(field); + finalFieldMap.putAll(BeanUtil.beanToMap(codeField)); + + // 枚举 + if (SmartStringUtil.isNotEmpty(codeField.getEnumName())) { + packageList.add("import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;"); + packageList.add("import net.lab1024.sa.common.common.validator.enumeration.CheckEnum;"); + packageList.add("import " + form.getBasic().getJavaPackageName() + ".constant." + codeField.getEnumName() + ";"); + + //enum check + String checkEnumPrefix = "@CheckEnum(value = " + codeField.getEnumName() + ".class, message = \"" + codeField.getLabel() + " 错误\""; + String checkEnum = checkEnumPrefix + (field.getRequiredFlag() ? ", required = true)" : ")"); + + finalFieldMap.put("apiModelProperty", "@ApiModelPropertyEnum(value = " + codeField.getEnumName() + ".class, desc = \"" + codeField.getLabel() + "\")"); + finalFieldMap.put("checkEnum", checkEnum); + finalFieldMap.put("isEnum", true); + + } else { + String prefix = "@ApiModelProperty(value = \"" + codeField.getLabel() + "\""; + String apiModelProperty = prefix + (field.getRequiredFlag() ? ", required = true)" : ")"); + finalFieldMap.put("apiModelProperty", apiModelProperty); + + packageList.add("import io.swagger.annotations.ApiModelProperty;"); + + if (Boolean.TRUE.equals(field.getRequiredFlag())) { + String notEmptyPrefix = "String".equals(codeField.getJavaType()) ? "@NotBlank" : "@NotNull"; + finalFieldMap.put("notEmpty", "\n " + notEmptyPrefix + "(message = \"" + codeField.getLabel() + " 不能为空\")"); + packageList.add("String".equals(codeField.getJavaType()) ? "import javax.validation.constraints.NotBlank;" : "import javax.validation.constraints.NotNull;"); + } + } + + + //字典 + if (SmartStringUtil.isNotEmpty(codeField.getDict())) { + finalFieldMap.put("dict", "\n @JsonDeserialize(using = DictValueVoDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.common.common.json.deserializer.DictValueVoDeserializer;"); + } + + //文件上传 + if (SmartStringUtil.contains(field.getFrontComponent(), "Upload")) { + finalFieldMap.put("file", "\n @JsonDeserialize(using = FileKeyVoDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.common.common.json.deserializer.FileKeyVoDeserializer;"); + } + + packageList.add(getJavaPackageName(codeField.getJavaType())); + finalFieldList.add(finalFieldMap); + } + + + // lombok + packageList.add("import lombok.Data;"); + + List packageNameList = packageList.stream().filter(Objects::nonNull).collect(Collectors.toList()); + Collections.sort(packageNameList); + return ImmutablePair.of(packageNameList, finalFieldList); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/VOVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/VOVariableService.java new file mode 100644 index 0000000..821629e --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/backend/domain/VOVariableService.java @@ -0,0 +1,115 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.backend.domain; + +import cn.hutool.core.bean.BeanUtil; +import net.lab1024.sa.common.common.util.SmartStringUtil; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeTableField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class VOVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + Map fieldMap = getFieldMap(form); + List updateFieldList = form.getTableFields().stream().filter(e -> Boolean.TRUE.equals(e.getShowFlag())).collect(Collectors.toList()); + + ImmutablePair, List>> packageListAndFields = getPackageListAndFields(updateFieldList, form); + + variablesMap.put("packageName", form.getBasic().getJavaPackageName() + ".domain.vo"); + variablesMap.put("importPackageList", packageListAndFields.getLeft()); + variablesMap.put("fields", packageListAndFields.getRight()); + + return variablesMap; + } + + public ImmutablePair, List>> getPackageListAndFields(List fields, CodeGeneratorConfigForm form) { + if (CollectionUtils.isEmpty(fields)) { + return ImmutablePair.of(new ArrayList<>(), new ArrayList<>()); + } + + Map fieldMap = getFieldMap(form); + HashSet packageList = new HashSet<>(); + + + /** + * 1、LocalDate、LocalDateTime、BigDecimal 类型的包名 + * 2、排序 + */ + + List> finalFieldList = new ArrayList<>(); + + for (CodeTableField field : fields) { + CodeField codeField = fieldMap.get(field.getColumnName()); + if (codeField == null) { + continue; + } + + // CodeField 和 CodeTableField 合并 + Map finalFieldMap = BeanUtil.beanToMap(field); + finalFieldMap.putAll(BeanUtil.beanToMap(codeField)); + + // 枚举 + if (SmartStringUtil.isNotEmpty(codeField.getEnumName())) { + packageList.add("import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;"); + packageList.add("import " + form.getBasic().getJavaPackageName() + ".constant." + codeField.getEnumName() + ";"); + + finalFieldMap.put("apiModelProperty", "@ApiModelPropertyEnum(value = " + codeField.getEnumName() + ".class, desc = \"" + codeField.getLabel() + "\")"); + finalFieldMap.put("isEnum", true); + + } else { + String apiModelProperty = "@ApiModelProperty(value = \"" + codeField.getLabel() + "\")"; + finalFieldMap.put("apiModelProperty", apiModelProperty); + + packageList.add("import io.swagger.annotations.ApiModelProperty;"); + } + + + //字典 + if (isDict(field.getColumnName(), form)) { + finalFieldMap.put("dict", "\n @JsonDeserialize(using = DictValueVoDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.common.common.json.deserializer.DictValueVoDeserializer;"); + } + + //文件上传 + if (isFile(field.getColumnName(), form)) { + finalFieldMap.put("file", "\n @JsonDeserialize(using = FileKeyVoDeserializer.class)"); + packageList.add("import com.fasterxml.jackson.databind.annotation.JsonDeserialize;"); + packageList.add("import net.lab1024.sa.common.common.json.deserializer.FileKeyVoDeserializer;"); + } + + packageList.add(getJavaPackageName(codeField.getJavaType())); + finalFieldList.add(finalFieldMap); + } + + + // lombok + packageList.add("import lombok.Data;"); + + List packageNameList = packageList.stream().filter(Objects::nonNull).collect(Collectors.toList()); + Collections.sort(packageNameList); + return ImmutablePair.of(packageNameList, finalFieldList); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ApiVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ApiVariableService.java new file mode 100644 index 0000000..22af04c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ApiVariableService.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.front; + +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; + +import java.util.*; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class ApiVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + return variablesMap; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ConstVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ConstVariableService.java new file mode 100644 index 0000000..0ce4b95 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ConstVariableService.java @@ -0,0 +1,45 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.front; + +import cn.hutool.core.bean.BeanUtil; +import com.google.common.base.CaseFormat; +import net.lab1024.sa.common.common.util.SmartStringUtil; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class ConstVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + List> enumList = new ArrayList<>(); + List enumFiledList = form.getFields().stream().filter(e -> SmartStringUtil.isNotBlank(e.getEnumName())).collect(Collectors.toList()); + for (CodeField codeField : enumFiledList) { + Map beanToMap = BeanUtil.beanToMap(codeField); + String upperUnderscoreEnum = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, codeField.getEnumName()); + beanToMap.put("upperUnderscoreEnum", upperUnderscoreEnum); + enumList.add(beanToMap); + } + variablesMap.put("enumList", enumList); + return variablesMap; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/FormVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/FormVariableService.java new file mode 100644 index 0000000..544d74f --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/FormVariableService.java @@ -0,0 +1,82 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.front; + +import cn.hutool.core.bean.BeanUtil; +import com.google.common.base.CaseFormat; +import net.lab1024.sa.common.common.util.SmartStringUtil; +import net.lab1024.sa.common.module.support.codegenerator.constant.CodeFrontComponentEnum; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeField; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeInsertAndUpdateField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; + +import java.util.*; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class FormVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + List> fieldsVariableList = new ArrayList<>(); + List fieldList = form.getInsertAndUpdate().getFieldList(); + + HashSet frontImportSet = new HashSet<>(); + + for (CodeInsertAndUpdateField field : fieldList) { + // 不存在 添加 和 更新 + if (!(field.getInsertFlag() || field.getUpdateFlag())) { + continue; + } + + Map objectMap = BeanUtil.beanToMap(field); + + CodeField codeField = getCodeFieldByColumnName(field.getColumnName(), form); + if (codeField == null) { + continue; + } + objectMap.put("label", codeField.getLabel()); + objectMap.put("fieldName", codeField.getFieldName()); + objectMap.put("dict", codeField.getDict()); + + if (SmartStringUtil.isNotBlank(codeField.getEnumName())) { + String upperUnderscoreEnum = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, codeField.getEnumName()); + objectMap.put("upperUnderscoreEnum", upperUnderscoreEnum); + } + + fieldsVariableList.add(objectMap); + + if (CodeFrontComponentEnum.ENUM_SELECT.getValue().equals(field.getFrontComponent())) { + frontImportSet.add("import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';"); + } + + if (CodeFrontComponentEnum.BOOLEAN_SELECT.getValue().equals(field.getFrontComponent())) { + frontImportSet.add("import BooleanSelect from '/@/components/framework/boolean-select/index.vue';"); + } + + if (CodeFrontComponentEnum.DICT_SELECT.getValue().equals(field.getFrontComponent())) { + frontImportSet.add("import DictSelect from '/@/components/support/dict-select/index.vue';"); + } + + if (CodeFrontComponentEnum.FILE_UPLOAD.getValue().equals(field.getFrontComponent())) { + frontImportSet.add("import FileUpload from '/@/components/support/file-upload/index.vue';"); + } + } + + variablesMap.put("formFields", fieldsVariableList); + variablesMap.put("frontImportList", new ArrayList<>(frontImportSet)); + + return variablesMap; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ListVariableService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ListVariableService.java new file mode 100644 index 0000000..df05161 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/service/variable/front/ListVariableService.java @@ -0,0 +1,57 @@ +package net.lab1024.sa.common.module.support.codegenerator.service.variable.front; + +import cn.hutool.core.bean.BeanUtil; +import com.google.common.base.CaseFormat; +import net.lab1024.sa.common.module.support.codegenerator.constant.CodeQueryFieldQueryTypeEnum; +import net.lab1024.sa.common.module.support.codegenerator.domain.form.CodeGeneratorConfigForm; +import net.lab1024.sa.common.module.support.codegenerator.domain.model.CodeQueryField; +import net.lab1024.sa.common.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService; + +import java.util.*; + +/** + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/29 17:20:41 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class ListVariableService extends CodeGenerateBaseVariableService { + + @Override + public boolean isSupport(CodeGeneratorConfigForm form) { + return true; + } + + @Override + public Map getInjectVariablesMap(CodeGeneratorConfigForm form) { + Map variablesMap = new HashMap<>(); + + List> variableList = new ArrayList<>(); + List queryFields = form.getQueryFields(); + HashSet frontImportSet = new HashSet<>(); + frontImportSet.add("import " + CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, form.getBasic().getModuleName()) + "Form from './" + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, form.getBasic().getModuleName()) + "-form.vue';"); + + for (CodeQueryField queryField : queryFields) { + Map objectMap = BeanUtil.beanToMap(queryField); + variableList.add(objectMap); + + if("Enum".equals(queryField.getQueryTypeEnum())){ + frontImportSet.add("import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';"); + } + + if("Dict".equals(queryField.getQueryTypeEnum())){ + frontImportSet.add("import DictSelect from '/@/components/support/dict-select/index.vue';"); + } + + if(CodeQueryFieldQueryTypeEnum.DATE_RANGE.getValue().equals(queryField.getQueryTypeEnum())){ + frontImportSet.add("import { defaultTimeRanges } from '/@/lib/default-time-ranges';"); + } + + } + variablesMap.put("queryFields",variableList); + variablesMap.put("frontImportList",new ArrayList<>(frontImportSet)); + return variablesMap; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/util/CodeGeneratorTool.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/util/CodeGeneratorTool.java new file mode 100644 index 0000000..b4843e6 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/codegenerator/util/CodeGeneratorTool.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.common.module.support.codegenerator.util; + +import com.google.common.base.CaseFormat; +import net.lab1024.sa.common.common.constant.StringConst; + +/** + * 代码生成 velocity 工具类 + * + * @Author 1024创新实验室-主任:卓大 + * @Date 2022/9/30 19:02:17 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022 + */ + +public class CodeGeneratorTool { + + /** + * 小写驼峰,转为大写驼峰 + */ + public String lowerCamel2UpperCamel(String str) { + if (str == null) { + return StringConst.EMPTY; + } + return CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, str); + } + + /** + * 小写驼峰,转为小写中划线 + */ + public String lowerCamel2LowerHyphen(String str) { + if (str == null) { + return StringConst.EMPTY; + } + return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, str); + } + + + /** + * 去掉 注释 枚举类型 + */ + public String removeEnumDesc(String str) { + if (str == null) { + return StringConst.EMPTY; + } + + int index = str.indexOf("["); + if (index == -1) { + index = str.indexOf("【"); + } + + if (index == -1) { + return str; + } + + return str.substring(0, index - 1); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigController.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigController.java new file mode 100644 index 0000000..a64477c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigController.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.common.module.support.config; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.config.domain.ConfigVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * 配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Api(tags = {SwaggerTagConst.Support.CONFIG}) +@RestController +public class ConfigController extends SupportBaseController { + + @Autowired + private ConfigService configService; + + @ApiOperation("查询配置详情 @author 卓大") + @GetMapping("/config/queryByKey") + public ResponseDTO queryByKey(@RequestParam String configKey) { + return ResponseDTO.ok(configService.getConfig(configKey)); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigDao.java new file mode 100644 index 0000000..e2e9cde --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigDao.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.common.module.support.config; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.config.domain.ConfigEntity; +import net.lab1024.sa.common.module.support.config.domain.ConfigQueryForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 系统参数配置 t_config Dao层 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Component +@Mapper +public interface ConfigDao extends BaseMapper { + + /** + * 分页查询系统配置 + * + * @param page + * @return + */ + List queryByPage(Page page, @Param("query") ConfigQueryForm queryDTO); + + /** + * 根据key查询获取数据 + * + * @param key + * @return + */ + ConfigEntity selectByKey(String key); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigKeyEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigKeyEnum.java new file mode 100644 index 0000000..1248cdd --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigKeyEnum.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.common.module.support.config; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 系统配置常量类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Getter +@AllArgsConstructor +public enum ConfigKeyEnum implements BaseEnum { + + /** + * 本地上传路径前缀 + */ + LOCAL_UPLOAD_URL_PREFIX("local_upload_url_prefix", "本地上传路径前缀"), + + /** + * 万能密码 + */ + SUPER_PASSWORD("super_password", "万能密码"), + CaseNum("CaseNum", "项目总病例数"), + CaseSwitch("CaseSwitch", "项目开关"), + RUBRIC("rubric", "投稿说明"), + DEAL("deal", "项目协议"), + PRIVACY("privacy", "隐私协议"), + + ; + + private final String value; + + private final String desc; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigService.java new file mode 100644 index 0000000..0428510 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/ConfigService.java @@ -0,0 +1,205 @@ +package net.lab1024.sa.common.module.support.config; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.constant.ReloadConst; +import net.lab1024.sa.common.module.support.config.domain.*; +import net.lab1024.sa.common.module.support.reload.core.annoation.SmartReload; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 系统配置业务类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Service +public class ConfigService { + + /** + * 一个简单的系统配置缓存 + */ + private final ConcurrentHashMap configCache = new ConcurrentHashMap<>(); + + @Autowired + private ConfigDao configDao; + + @SmartReload(ReloadConst.CONFIG_RELOAD) + public void configReload(String param) { + this.loadConfigCache(); + } + + /** + * 初始化系统设置缓存 + */ + @PostConstruct + private void loadConfigCache() { + configCache.clear(); + List entityList = configDao.selectList(null); + if (CollectionUtils.isEmpty(entityList)) { + return; + } + entityList.forEach(entity -> this.configCache.put(entity.getConfigKey().toLowerCase(), entity)); + log.info("################# 系统配置缓存初始化完毕:{} ###################", configCache.size()); + } + + /** + * 刷新系统设置缓存 + */ + private void refreshConfigCache(Long configId) { + // 重新查询 加入缓存 + ConfigEntity configEntity = configDao.selectById(configId); + if (null == configEntity) { + return; + } + this.configCache.put(configEntity.getConfigKey().toLowerCase(), configEntity); + } + + /** + * 分页查询系统配置 + * + * @param queryDTO + * @return + */ + public ResponseDTO> queryConfigPage(ConfigQueryForm queryDTO) { + Page page = SmartPageUtil.convert2PageQuery(queryDTO); + List entityList = configDao.queryByPage(page, queryDTO); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, entityList, ConfigVO.class); + return ResponseDTO.ok(pageResult); + } + + /** + * 查询配置缓存 + * + * @param configKey + * @return + */ + public ConfigVO getConfig(ConfigKeyEnum configKey) { + return this.getConfig(configKey.getValue()); + } + + /** + * 查询配置缓存 + * + * @param configKey + * @return + */ + public ConfigVO getConfig(String configKey) { + if (StrUtil.isBlank(configKey)) { + return null; + } + ConfigEntity entity = this.configCache.get(configKey.toLowerCase()); + return SmartBeanUtil.copy(entity, ConfigVO.class); + } + + /** + * 查询配置缓存参数 + * + * @param configKey + * @return + */ + public String getConfigValue(ConfigKeyEnum configKey) { + return this.getConfig(configKey).getConfigValue(); + } + + /** + * 根据参数key查询 并转换为对象 + * + * @param configKey + * @param clazz + * @param + * @return + */ + public T getConfigValue2Obj(ConfigKeyEnum configKey, Class clazz) { + String configValue = this.getConfigValue(configKey); + return JSON.parseObject(configValue, clazz); + } + + /** + * 添加系统配置 + * + * @param configAddDTO + * @return + */ + public ResponseDTO add(ConfigAddForm configAddDTO) { + ConfigEntity entity = configDao.selectByKey(configAddDTO.getConfigKey()); + if (null != entity) { + return ResponseDTO.error(UserErrorCode.ALREADY_EXIST); + } + entity = SmartBeanUtil.copy(configAddDTO, ConfigEntity.class); + configDao.insert(entity); + + // 刷新缓存 + this.refreshConfigCache(entity.getConfigId()); + return ResponseDTO.ok(); + } + + /** + * 更新系统配置 + * + * @param updateDTO + * @return + */ + public ResponseDTO updateSystemConfig(ConfigUpdateForm updateDTO) { + Long configId = updateDTO.getConfigId(); + ConfigEntity entity = configDao.selectById(configId); + if (null == entity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + ConfigEntity alreadyEntity = configDao.selectByKey(updateDTO.getConfigKey()); + if (null != alreadyEntity && !Objects.equals(configId, alreadyEntity.getConfigId())) { + return ResponseDTO.error(UserErrorCode.ALREADY_EXIST, "config key 已存在"); + } + + // 更新数据 + entity = SmartBeanUtil.copy(updateDTO, ConfigEntity.class); + configDao.updateById(entity); + + // 刷新缓存 + this.refreshConfigCache(configId); + return ResponseDTO.ok(); + } + + /** + * 更新系统配置 + * + * @param key + * @param value + * @return + */ + public ResponseDTO updateValueByKey(ConfigKeyEnum key, String value) { + ConfigVO config = this.getConfig(key); + if (null == config) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + + // 更新数据 + Long configId = config.getConfigId(); + ConfigEntity entity = new ConfigEntity(); + entity.setConfigId(configId); + entity.setConfigValue(value); + configDao.updateById(entity); + + // 刷新缓存 + this.refreshConfigCache(configId); + return ResponseDTO.ok(); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigAddForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigAddForm.java new file mode 100644 index 0000000..e7b480c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigAddForm.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.common.module.support.config.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +/** + * 添加配置表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class ConfigAddForm { + + @ApiModelProperty("参数key") + @NotBlank(message = "参数key不能为空") + @Length(max = 255, message = "参数key最多255个字符") + private String configKey; + + @ApiModelProperty("参数的值") + @NotBlank(message = "参数的值不能为空") + @Length(max = 60000, message = "参数的值最多60000个字符") + private String configValue; + + @ApiModelProperty("参数名称") + @NotBlank(message = "参数名称不能为空") + @Length(max = 255, message = "参数名称最多255个字符") + private String configName; + + @ApiModelProperty("备注") + @Length(max = 255, message = "备注最多255个字符") + private String remark; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigEntity.java new file mode 100644 index 0000000..13a3abc --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigEntity.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.common.module.support.config.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 系统配置参数 实体类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_config") +public class ConfigEntity { + + @TableId(type = IdType.AUTO) + private Long configId; + + /** + * 参数key + */ + private String configKey; + + /** + * 参数的值 + */ + private String configValue; + + /** + * 参数名称 + */ + private String configName; + + /** + * 备注 + */ + private String remark; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigQueryForm.java new file mode 100644 index 0000000..8e56af1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigQueryForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.common.module.support.config.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +/** + * 分页查询 系统配置 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class ConfigQueryForm extends PageParam { + + @ApiModelProperty("参数KEY") + @Length(max = 50, message = "参数Key最多50字符") + private String configKey; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigUpdateForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigUpdateForm.java new file mode 100644 index 0000000..816ced0 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.common.module.support.config.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 配置更新表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class ConfigUpdateForm extends ConfigAddForm { + + @ApiModelProperty("configId") + @NotNull(message = "configId不能为空") + private Long configId; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigVO.java new file mode 100644 index 0000000..17230d8 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/config/domain/ConfigVO.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.common.module.support.config.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 配置信息 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-14 20:46:27 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class ConfigVO { + @ApiModelProperty("主键") + private Long configId; + + @ApiModelProperty("参数key") + private String configKey; + + @ApiModelProperty("参数的值") + private String configValue; + + @ApiModelProperty("参数名称") + private String configName; + + @ApiModelProperty("备注") + private String remark; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("上次修改时间") + private LocalDateTime updateTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldBigDecimal.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldBigDecimal.java new file mode 100644 index 0000000..adb292c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldBigDecimal.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.common.module.support.datatracer.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 数据变动字段注解 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DataTracerFieldBigDecimal { + int scale() default 2; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldDict.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldDict.java new file mode 100644 index 0000000..898a393 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldDict.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.common.module.support.datatracer.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 字典的字段 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DataTracerFieldDict { + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldEnum.java new file mode 100644 index 0000000..d9841c7 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldEnum.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.common.module.support.datatracer.annoation; + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 字段枚举 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DataTracerFieldEnum { + + Class enumClass() default BaseEnum.class; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldLabel.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldLabel.java new file mode 100644 index 0000000..089325b --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldLabel.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.common.module.support.datatracer.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 字段标签 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DataTracerFieldLabel { + /** + * 本属性的注释信息 + * @return + */ + String value() default ""; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldSql.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldSql.java new file mode 100644 index 0000000..4f76636 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/annoation/DataTracerFieldSql.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.common.module.support.datatracer.annoation; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 支持查询sql + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DataTracerFieldSql { + + /** + * 关联字段名称 + * @return + */ + String relateColumn() default "id"; + + /** + * 关联显示的字段 + * @return + */ + String relateDisplayColumn() default ""; + /** + * 是否关联字段查询Mapper + * @return + */ + Class relateMapper() default BaseMapper.class; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/constant/DataTracerConst.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/constant/DataTracerConst.java new file mode 100644 index 0000000..729a241 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/constant/DataTracerConst.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.common.module.support.datatracer.constant; + +/** + * 常量 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class DataTracerConst { + + public static final String TAB = " "; + + public static final String SPLIT_LINE = "-----------------------------"; + + public static final String BLANK = " "; + public static final String SPLIT = ": "; + public static final String HTML_BR = "
"; + + public static final String INSERT = "新增"; + + public static final String DELETE = "删除"; + + public static final String UPDATE = "修改"; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/constant/DataTracerTypeEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/constant/DataTracerTypeEnum.java new file mode 100644 index 0000000..0bed670 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/constant/DataTracerTypeEnum.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.common.module.support.datatracer.constant; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 数据业务类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52- + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@AllArgsConstructor +@Getter +public enum DataTracerTypeEnum implements BaseEnum { + + GOODS(1, "商品"), + + OA_NOTICE(2, "OA-通知公告"), + + OA_ENTERPRISE(3, "OA-企业信息"), + + ; + + private final Integer value; + + private final String desc; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/controller/DataTracerController.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/controller/DataTracerController.java new file mode 100644 index 0000000..4762b5d --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/controller/DataTracerController.java @@ -0,0 +1,40 @@ +package net.lab1024.sa.common.module.support.datatracer.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.datatracer.domain.form.DataTracerQueryForm; +import net.lab1024.sa.common.module.support.datatracer.domain.vo.DataTracerVO; +import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * 数据变动记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Api(tags = {SwaggerTagConst.Support.DATA_TRACER}) +@RestController +public class DataTracerController extends SupportBaseController { + + @Autowired + private DataTracerService dataTracerService; + + @ApiOperation("分页查询业务操作日志 - @author 卓大") + @PostMapping("/dataTracer/query") + public ResponseDTO> query(@Valid @RequestBody DataTracerQueryForm queryForm) { + return dataTracerService.query(queryForm); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/dao/DataTracerDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/dao/DataTracerDao.java new file mode 100644 index 0000000..989b638 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/dao/DataTracerDao.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.common.module.support.datatracer.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.datatracer.domain.entity.DataTracerEntity; +import net.lab1024.sa.common.module.support.datatracer.domain.form.DataTracerQueryForm; +import net.lab1024.sa.common.module.support.datatracer.domain.vo.DataTracerVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * dao: t_data_tracker + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface DataTracerDao extends BaseMapper { + + /** + * 操作记录查询 + * + * @return + */ + List selectRecord(@Param("dataId") Long dataId, @Param("dataType") Integer dataType); + + /** + * 分页查询 + * + * @param page + * @param queryForm + * @return + */ + List query(Page page, @Param("query") DataTracerQueryForm queryForm); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/bo/DataTracerContentBO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/bo/DataTracerContentBO.java new file mode 100644 index 0000000..5333642 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/bo/DataTracerContentBO.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.common.module.support.datatracer.domain.bo; + +import lombok.Data; + +import java.lang.reflect.Field; + +/** + * 变动内容 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DataTracerContentBO { + + /** + * 变动字段 + */ + private Field field; + + /** + * 变动字段的值 + */ + private Object fieldValue; + + /** + * 变动字段描述 + */ + private String fieldDesc; + + /** + * 变动内容 + */ + private String fieldContent; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/entity/DataTracerEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/entity/DataTracerEntity.java new file mode 100644 index 0000000..5732a8f --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/entity/DataTracerEntity.java @@ -0,0 +1,90 @@ +package net.lab1024.sa.common.module.support.datatracer.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum; + +import java.time.LocalDateTime; + +/** + * 数据记录 实体 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_data_tracer") +public class DataTracerEntity { + + @TableId(type = IdType.AUTO) + private Long dataTracerId; + /** + * 数据id + */ + private Long dataId; + /** + * 业务类型 + * {@link DataTracerTypeEnum} + */ + private Integer type; + + /** + * 内容 + */ + private String content; + + /** + * diff 差异:旧的数据 + */ + private String diffOld; + + /** + * 差异:新的数据 + */ + private String diffNew; + + /** + * 扩展字段 + */ + private String extraData; + + /** + * 用户 + */ + private Long userId; + + /** + * 用户类型 + */ + private Integer userType; + + /** + * 用户名 + */ + private String userName; + + /** + * 请求ip + */ + private String ip; + + /** + * 请求头 + */ + private String userAgent; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/form/DataTracerForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/form/DataTracerForm.java new file mode 100644 index 0000000..607d1e6 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/form/DataTracerForm.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.common.module.support.datatracer.domain.form; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum; + +/** + * 数据变动表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DataTracerForm { + + /** + * 业务id + */ + private Long dataId; + + /** + * 业务类型 + */ + private DataTracerTypeEnum type; + + /** + * 操作内容 + */ + private String content; + + /** + * diff 差异:旧的数据 + */ + private String diffOld; + + /** + * 差异:新的数据 + */ + private String diffNew; + + /** + * 扩展字段 + */ + private String extraData; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/form/DataTracerQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/form/DataTracerQueryForm.java new file mode 100644 index 0000000..4eccbe5 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/form/DataTracerQueryForm.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.common.module.support.datatracer.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum; + +import javax.validation.constraints.NotNull; + +/** + * 查询表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DataTracerQueryForm extends PageParam { + + @ApiModelPropertyEnum(DataTracerTypeEnum.class) + private Integer type; + + @ApiModelProperty("业务id") + @NotNull(message = "业务id不能为空") + private Long dataId; + + @ApiModelProperty("关键字") + private String keywords; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/vo/DataTracerVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/vo/DataTracerVO.java new file mode 100644 index 0000000..e55beb9 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/domain/vo/DataTracerVO.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.common.module.support.datatracer.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum; + +import java.time.LocalDateTime; + +/** + * 变动记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DataTracerVO { + + @ApiModelProperty("日志id") + private Long dataTracerId; + + @ApiModelProperty("单据id") + private Long dataId; + + @ApiModelPropertyEnum(value = DataTracerTypeEnum.class, desc = "业务类型") + private Integer type; + + @ApiModelProperty("操作内容") + private String content; + + @ApiModelProperty("diff 差异:旧的数据") + private String diffOld; + + @ApiModelProperty("差异:新的数据") + private String diffNew; + + @ApiModelProperty("扩展字段") + private String extraData; + + @ApiModelProperty("操作人") + private Long userId; + + @ApiModelPropertyEnum(value = UserTypeEnum.class, desc = "用户类型") + private Integer userType; + + @ApiModelProperty("操作人名称") + private String userName; + + @ApiModelProperty("userAgent") + private String userAgent; + + @ApiModelProperty("ip") + private String ip; + + @ApiModelProperty("操作时间") + private LocalDateTime createTime; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/manager/DataTracerManger.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/manager/DataTracerManger.java new file mode 100644 index 0000000..8586cdf --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/manager/DataTracerManger.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.common.module.support.datatracer.manager; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import net.lab1024.sa.common.module.support.datatracer.dao.DataTracerDao; +import net.lab1024.sa.common.module.support.datatracer.domain.entity.DataTracerEntity; +import org.springframework.stereotype.Service; + +/** + * manager层 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class DataTracerManger extends ServiceImpl { +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerChangeContentService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerChangeContentService.java new file mode 100644 index 0000000..24af9f4 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerChangeContentService.java @@ -0,0 +1,486 @@ +package net.lab1024.sa.common.module.support.datatracer.service; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.google.common.base.CaseFormat; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.util.SmartBigDecimalUtil; +import net.lab1024.sa.common.common.util.SmartEnumUtil; +import net.lab1024.sa.common.common.util.SmartStringUtil; +import net.lab1024.sa.common.module.support.datatracer.annoation.*; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerConst; +import net.lab1024.sa.common.module.support.datatracer.domain.bo.DataTracerContentBO; +import net.lab1024.sa.common.module.support.dict.service.DictCacheService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 数据变更内容 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Service +public class DataTracerChangeContentService { + + @Autowired + private ApplicationContext applicationContext; + @Autowired + private DictCacheService dictCacheService; + /** + * 字段描述缓存 + */ + private ConcurrentHashMap fieldDescCacheMap = new ConcurrentHashMap<>(); + + /** + * 类 加注解字段缓存 + */ + private ConcurrentHashMap> fieldMap = new ConcurrentHashMap<>(); + + /** + * 数据批量对比 + * + * @param oldObjectList + * @param newObjectList + * @param + * @return + */ + public String getChangeContent(List oldObjectList, List newObjectList) { + boolean valid = this.valid(oldObjectList, newObjectList); + if (!valid) { + return ""; + } + String operateType = this.getOperateType(oldObjectList, newObjectList); + String operateContent = ""; + if (DataTracerConst.INSERT.equals(operateType) || DataTracerConst.DELETE.equals(operateType)) { + operateContent = this.getObjectListContent(newObjectList); + if (StringUtils.isEmpty(operateContent)) { + return ""; + } + return operateType + ":" + operateContent; + } + if (DataTracerConst.UPDATE.equals(operateType)) { + return this.getUpdateContentList(oldObjectList, newObjectList); + } + return operateContent; + } + + + /** + * 解析多个对象的变更,删除,新增 + * oldObject 为空 ,newObject 不为空 为新增 + * oldObject 不为空 ,newObject 不空 为删除 + * 都不为空为编辑 + * + * @param oldObject + * @param newObject + * @return + */ + public String getChangeContent(Object oldObject, Object newObject) { + boolean valid = this.valid(oldObject, newObject); + if (!valid) { + return ""; + } + String operateType = this.getOperateType(oldObject, newObject); + String operateContent = ""; + if (DataTracerConst.INSERT.equals(operateType) || DataTracerConst.DELETE.equals(operateType)) { + operateContent = this.getAddDeleteContent(newObject); + } + if (DataTracerConst.UPDATE.equals(operateType)) { + operateContent = this.getUpdateContent(oldObject, newObject); + } + if (StringUtils.isEmpty(operateContent)) { + return ""; + } + return operateContent; + } + + /** + * 解析单个bean的内容 + * + * @param object + * @return + */ + public String getChangeContent(Object object) { + return this.getAddDeleteContent(object); + } + + // ---------------------------- 以下 是 私有private 方法 ---------------------------- + + /** + * 获取新增或删除操作内容 + * + * @param object 新增或删除的对象 + * @return + */ + private String getAddDeleteContent(Object object) { + List fields = this.getField(object); + Map beanParseMap = this.fieldParse(object, fields); + return this.getAddDeleteContent(beanParseMap); + } + + /** + * 单个对象变动内容 + * + * @param oldObjectList + * @param newObjectList + * @param + * @return + */ + private String getUpdateContentList(List oldObjectList, List newObjectList) { + String oldContent = this.getObjectListContent(oldObjectList); + String newContent = this.getObjectListContent(newObjectList); + if (oldContent.equals(newContent)) { + return ""; + } + if (StringUtils.isEmpty(oldContent) && StringUtils.isEmpty(newContent)) { + return ""; + } + return "【原数据】:
" + oldContent + "
" + "【新数据】:
" + newContent; + } + + /** + * 获取一个对象的内容信息 + * + * @param objectList + * @param + * @return + */ + private String getObjectListContent(List objectList) { + if (CollectionUtils.isEmpty(objectList)) { + return ""; + } + List fields = this.getField(objectList.get(0)); + List contentList = Lists.newArrayList(); + for (Object objItem : objectList) { + Map beanParseMap = this.fieldParse(objItem, fields); + contentList.add(this.getAddDeleteContent(beanParseMap)); + } + return StringUtils.join(contentList, "
"); + } + + private String getAddDeleteContent(Map beanParseMap) { + List contentList = new ArrayList<>(); + for (Entry entry : beanParseMap.entrySet()) { + DataTracerContentBO dataTracerContentBO = entry.getValue(); + Boolean jsonFlag = JSONUtil.isTypeJSON(dataTracerContentBO.getFieldContent()); + String filedDesc = dataTracerContentBO.getFieldDesc(); + if (jsonFlag) { + contentList.add(filedDesc + "(请进入详情查看)"); + } else { + contentList.add(dataTracerContentBO.getFieldDesc() + ":" + dataTracerContentBO.getFieldContent()); + } + } + String operateContent = StringUtils.join(contentList, "
"); + if (StringUtils.isEmpty(operateContent)) { + return ""; + } + return operateContent; + } + + + /** + * 获取更新操作内容 + * + * @param oldObject + * @param newObject + * @return + */ + private String getUpdateContent(T oldObject, T newObject) { + List fields = this.getField(oldObject); + List contentList = new ArrayList<>(); + Map oldBeanParseMap = this.fieldParse(oldObject, fields); + Map newBeanParseMap = this.fieldParse(newObject, fields); + //oldBeanParseMap与newBeanParseMap size一定相同 + for (Entry entry : oldBeanParseMap.entrySet()) { + String fieldName = entry.getKey(); + // 新旧对象内容 + DataTracerContentBO oldContentBO = entry.getValue(); + DataTracerContentBO newContentBO = newBeanParseMap.get(fieldName); + // fieldContent + String oldContent = oldContentBO.getFieldContent() == null ? "" : oldContentBO.getFieldContent(); + String newContent = newContentBO.getFieldContent() == null ? "" : newContentBO.getFieldContent(); + + if (oldContent.equals(newContent)) { + continue; + } + String fieldDesc = oldContentBO.getFieldDesc(); + Boolean jsonFlag = JSONUtil.isTypeJSON(oldContent) || JSONUtil.isTypeJSON(newContent); + if (jsonFlag) { + String content = fieldDesc + "【进入详情查看】"; + contentList.add(content); + continue; + } + String content = fieldDesc + ":" + "由【" + oldContent + "】变更为【" + newContent + "】"; + contentList.add(content); + } + if (CollectionUtils.isEmpty(contentList)) { + return ""; + } + String operateContent = StringUtils.join(contentList, "
"); + if (StringUtils.isEmpty(operateContent)) { + return ""; + } + return operateContent; + } + + + /** + * 接bean对象 + * + * @param object + * @param fields + * @return + */ + private Map fieldParse(Object object, List fields) { + if (fields == null || fields.size() == 0) { + return new HashMap<>(); + } + //对象解析结果 + Map objectParse = new HashMap<>(16); + for (Field field : fields) { + field.setAccessible(true); + String desc = this.getFieldDesc(field); + if (StringUtils.isEmpty(desc)) { + continue; + } + DataTracerContentBO dataTracerContentBO = this.getFieldValue(field, object); + if (dataTracerContentBO != null) { + dataTracerContentBO.setFieldDesc(desc); + objectParse.put(field.getName(), dataTracerContentBO); + } + } + return objectParse; + } + + /** + * 获取字段值 + * + * @param field + * @param object + * @return + */ + private DataTracerContentBO getFieldValue(Field field, Object object) { + Object fieldValue = ""; + Class clazz = object.getClass(); + try { + PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz); + Method get = pd.getReadMethod(); + fieldValue = get.invoke(object); + } catch (Exception e) { + log.error("bean operate log: reflect field value error " + field.getName()); + return null; + } + if (fieldValue == null) { + return null; + } + + String fieldContent = ""; + DataTracerFieldEnum dataTracerFieldEnum = field.getAnnotation(DataTracerFieldEnum.class); + DataTracerFieldSql dataTracerFieldSql = field.getAnnotation(DataTracerFieldSql.class); + DataTracerFieldDict dataTracerFieldDict = field.getAnnotation(DataTracerFieldDict.class); + if (dataTracerFieldEnum != null) { + if (fieldValue instanceof Collection) { + fieldContent = SmartEnumUtil.getEnumDescByValueList((Collection) fieldValue, dataTracerFieldEnum.enumClass()); + } else { + fieldContent = SmartEnumUtil.getEnumDescByValue(fieldValue, dataTracerFieldEnum.enumClass()); + } + } else if (dataTracerFieldDict != null) { + fieldContent = dictCacheService.selectValueNameByValueCodeSplit(fieldValue.toString()); + } else if (dataTracerFieldSql != null) { + fieldContent = this.getRelateDisplayValue(fieldValue, dataTracerFieldSql); + } else if (fieldValue instanceof Date) { + fieldContent = DateUtil.formatDateTime((Date) fieldValue); + } else if (fieldValue instanceof LocalDateTime) { + fieldContent = LocalDateTimeUtil.formatNormal((LocalDateTime) fieldValue); + } else if (fieldValue instanceof LocalDate) { + fieldContent = LocalDateTimeUtil.formatNormal((LocalDate) fieldValue); + } else if (fieldValue instanceof BigDecimal) { + DataTracerFieldBigDecimal dataTracerFieldBigDecimal = field.getAnnotation(DataTracerFieldBigDecimal.class); + if (dataTracerFieldBigDecimal != null) { + BigDecimal value = SmartBigDecimalUtil.setScale((BigDecimal) fieldValue, dataTracerFieldBigDecimal.scale()); + fieldContent = value.toString(); + } + } else { + fieldContent = JSON.toJSONString(fieldValue); + } + DataTracerContentBO dataTracerContentBO = new DataTracerContentBO(); + dataTracerContentBO.setField(field); + dataTracerContentBO.setFieldValue(fieldValue); + dataTracerContentBO.setFieldContent(fieldContent); + return dataTracerContentBO; + } + + /** + * 获取关联字段的显示值 + * + * @param fieldValue + * @return + */ + private String getRelateDisplayValue(Object fieldValue, DataTracerFieldSql dataTracerFieldSql) { + Class relateMapper = dataTracerFieldSql.relateMapper(); + BaseMapper mapper = applicationContext.getBean(relateMapper); + if (mapper == null) { + return ""; + } + String relateFieldValue = fieldValue.toString(); + QueryWrapper qw = new QueryWrapper(); + qw.select(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, dataTracerFieldSql.relateDisplayColumn())); + qw.in(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, dataTracerFieldSql.relateColumn()), relateFieldValue); + List displayValue = mapper.selectObjs(qw); + if (CollectionUtils.isEmpty(displayValue)) { + return ""; + } + return SmartStringUtil.join(",", displayValue); + } + + /** + * 获取字段描述信息 优先 OperateField 没得话swagger判断 + * + * @param field + * @return + */ + private String getFieldDesc(Field field) { + // 根据字段名称 从缓存中查询 + String fieldName = field.toGenericString(); + String desc = fieldDescCacheMap.get(fieldName); + if (null != desc) { + return desc; + } + DataTracerFieldLabel operateField = field.getAnnotation(DataTracerFieldLabel.class); + if (operateField != null) { + return operateField.value(); + } + fieldDescCacheMap.put(fieldName, desc); + return desc; + } + + /** + * 获取操作类型 + * + * @param oldObject + * @param newObject + * @return + */ + private String getOperateType(Object oldObject, Object newObject) { + if (oldObject == null && newObject != null) { + return DataTracerConst.INSERT; + } + if (oldObject != null && newObject == null) { + return DataTracerConst.DELETE; + } + return DataTracerConst.UPDATE; + } + + /** + * 校验是否进行比对 + * + * @param oldObject + * @param newObject + * @return + */ + private boolean valid(Object oldObject, Object newObject) { + if (oldObject == null && newObject == null) { + return false; + } + if (oldObject == null && newObject != null) { + return true; + } + if (oldObject != null && newObject == null) { + return true; + } + if (oldObject != null && newObject != null) { + String oldClass = oldObject.getClass().getName(); + String newClass = newObject.getClass().getName(); + return oldClass.equals(newClass); + } + return true; + } + + + /** + * 校验 + * + * @param oldObjectList + * @param newObjectList + * @param + * @return + */ + private boolean valid(List oldObjectList, List newObjectList) { + if (CollectionUtils.isEmpty(oldObjectList) && CollectionUtils.isEmpty(newObjectList)) { + return false; + } + if (CollectionUtils.isEmpty(oldObjectList) && CollectionUtils.isNotEmpty(newObjectList)) { + return true; + } + if (CollectionUtils.isNotEmpty(oldObjectList) && CollectionUtils.isEmpty(newObjectList)) { + return true; + } + if (CollectionUtils.isNotEmpty(oldObjectList) && CollectionUtils.isNotEmpty(newObjectList)) { + T oldObject = oldObjectList.get(0); + T newObject = newObjectList.get(0); + String oldClass = oldObject.getClass().getName(); + String newClass = newObject.getClass().getName(); + return oldClass.equals(newClass); + } + return true; + } + + /** + * 查询 包含 file key 注解的字段 + * 使用缓存 + * + * @param obj + * @return + */ + private List getField(Object obj) { + // 从缓存中查询 + Class tClass = obj.getClass(); + List fieldList = fieldMap.get(tClass); + if (null != fieldList) { + return fieldList; + } + + // 这一段递归代码 是为了 从父类中获取属性 + Class tempClass = tClass; + fieldList = new ArrayList<>(); + while (tempClass != null) { + Field[] declaredFields = tempClass.getDeclaredFields(); + for (Field field : declaredFields) { + // 过虑出有注解字段 + if (!field.isAnnotationPresent(DataTracerFieldLabel.class)) { + continue; + } + field.setAccessible(true); + fieldList.add(field); + } + tempClass = tempClass.getSuperclass(); + } + fieldMap.put(tClass, fieldList); + return fieldList; + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerService.java new file mode 100644 index 0000000..2968ed5 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/datatracer/service/DataTracerService.java @@ -0,0 +1,224 @@ +package net.lab1024.sa.common.module.support.datatracer.service; + + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerConst; +import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum; +import net.lab1024.sa.common.module.support.datatracer.dao.DataTracerDao; +import net.lab1024.sa.common.module.support.datatracer.domain.entity.DataTracerEntity; +import net.lab1024.sa.common.module.support.datatracer.domain.form.DataTracerForm; +import net.lab1024.sa.common.module.support.datatracer.domain.form.DataTracerQueryForm; +import net.lab1024.sa.common.module.support.datatracer.domain.vo.DataTracerVO; +import net.lab1024.sa.common.module.support.datatracer.manager.DataTracerManger; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 数据变动记录 Service + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-07-23 19:38:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Service +public class DataTracerService { + + @Autowired + private DataTracerDao dataTracerDao; + + @Autowired + private DataTracerManger dataTracerManger; + + @Autowired + private DataTracerChangeContentService dataTracerChangeContentService; + + /** + * 获取变更内容 + * + * @param object + * @return + */ + public String getChangeContent(Object object) { + return dataTracerChangeContentService.getChangeContent(object); + } + + /** + * 获取变更内容 + */ + public String getChangeContent(Object oldObject, Object newObject) { + return dataTracerChangeContentService.getChangeContent(oldObject, newObject); + } + + + /** + * 获取变更内容 + */ + public String getChangeContent(List oldObjectList, List newObjectList) { + return dataTracerChangeContentService.getChangeContent(oldObjectList, newObjectList); + } + + + /** + * 保存【修改】数据变动记录 + * + * @param dataId + * @param type + */ + public void update(Long dataId, DataTracerTypeEnum type, Object oldObject, Object newObject) { + DataTracerForm form = DataTracerForm.builder() + .dataId(dataId) + .type(type) + .content(dataTracerChangeContentService.getChangeContent(oldObject, newObject)) + .build(); + this.addTrace(form); + } + + + /** + * 保存【新增】数据变动记录 + * + * @param dataId + * @param type + */ + public void insert(Long dataId, DataTracerTypeEnum type) { + DataTracerForm form = DataTracerForm.builder().dataId(dataId).type(type).content(DataTracerConst.INSERT).build(); + this.addTrace(form); + } + + /** + * 保存【删除】数据变动记录 + * + * @param dataId + * @param type + */ + public void delete(Long dataId, DataTracerTypeEnum type) { + DataTracerForm form = DataTracerForm.builder().dataId(dataId).type(type).content(DataTracerConst.DELETE).build(); + this.addTrace(form); + } + + /** + * 保存【删除】数据变动记录 + * + * @param dataId + * @param type + */ + public void delete(Long dataId, DataTracerTypeEnum type, Object object) { + DataTracerForm form = DataTracerForm.builder().dataId(dataId).type(type).content(DataTracerConst.DELETE).build(); + this.addTrace(form); + } + + /** + * 保存【批量删除】数据变动记录 + * + * @param dataIdList + * @param type + */ + public void batchDelete(List dataIdList, DataTracerTypeEnum type) { + if (CollectionUtils.isEmpty(dataIdList)) { + return; + } + + this.addTraceList(dataIdList.stream().map(e -> DataTracerForm.builder() + .dataId(e) + .type(type) + .content(DataTracerConst.DELETE) + .build()) + .collect(Collectors.toList()) + ); + } + + /** + * 保存数据变动记录 + * + * @param dataId + * @param type + * @param content + */ + public void addTrace(Long dataId, DataTracerTypeEnum type, String content) { + DataTracerForm form = DataTracerForm.builder().dataId(dataId).type(type).content(content).build(); + this.addTrace(form); + } + + /** + * 保存数据变动记录 + */ + public void addTrace(DataTracerForm tracerForm) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + this.addTrace(tracerForm, requestUser); + } + + + /** + * 保存数据变动记录 + */ + public void addTrace(DataTracerForm tracerForm, RequestUser requestUser) { + DataTracerEntity tracerEntity = SmartBeanUtil.copy(tracerForm, DataTracerEntity.class); + tracerEntity.setType(tracerForm.getType().getValue()); + if (requestUser != null) { + tracerEntity.setIp(requestUser.getIp()); + tracerEntity.setUserAgent(requestUser.getUserAgent()); + tracerEntity.setUserId(requestUser.getUserId()); + tracerEntity.setUserType(requestUser.getUserType().getValue()); + tracerEntity.setUserName(requestUser.getUserName()); + } + dataTracerManger.save(tracerEntity); + } + + /** + * 批量保存数据变动记录 + */ + public void addTraceList(List tracerFormList) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + this.addTraceList(tracerFormList, requestUser); + } + + /** + * 批量保存数据变动记录 + */ + public void addTraceList(List tracerFormList, RequestUser requestUser) { + if (CollectionUtils.isEmpty(tracerFormList)) { + return; + } + + List tracerEntityList = tracerFormList.stream().map(e -> { + DataTracerEntity tracerEntity = SmartBeanUtil.copy(e, DataTracerEntity.class); + tracerEntity.setType(e.getType().getValue()); + tracerEntity.setIp(requestUser.getIp()); + tracerEntity.setUserAgent(requestUser.getUserAgent()); + tracerEntity.setUserId(requestUser.getUserId()); + tracerEntity.setUserType(requestUser.getUserType().getValue()); + tracerEntity.setUserName(requestUser.getUserName()); + return tracerEntity; + }).collect(Collectors.toList()); + dataTracerManger.saveBatch(tracerEntityList); + } + + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public ResponseDTO> query(DataTracerQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = dataTracerDao.query(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return ResponseDTO.ok(pageResult); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/controller/DictController.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/controller/DictController.java new file mode 100644 index 0000000..a61b6bb --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/controller/DictController.java @@ -0,0 +1,63 @@ +package net.lab1024.sa.common.module.support.dict.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.dict.service.DictCacheService; +import net.lab1024.sa.common.module.support.dict.service.DictService; +import net.lab1024.sa.common.module.support.dict.domain.form.*; +import net.lab1024.sa.common.module.support.dict.domain.vo.DictKeyVO; +import net.lab1024.sa.common.module.support.dict.domain.vo.DictValueVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Api(tags = {SwaggerTagConst.Support.DICT}) +@RestController +public class DictController extends SupportBaseController { + + @Autowired + private DictService dictService; + @Autowired + private DictCacheService dictCacheService; + + + @ApiOperation("查询全部字典key - @author 卓大") + @GetMapping("/dict/key/queryAll") + public ResponseDTO> queryAll() { + return ResponseDTO.ok(dictService.queryAllKey()); + } + + @ApiOperation("分页查询数据字典value - @author 罗伊") + @PostMapping("/dict/value/query") + public ResponseDTO> valueQuery(@Valid @RequestBody DictValueQueryForm queryForm) { + return dictService.valueQuery(queryForm); + } + + @ApiOperation("数据字典缓存-刷新- @author 罗伊") + @GetMapping("/dict/cache/refresh") + public ResponseDTO cacheRefresh() { + return dictCacheService.cacheRefresh(); + } + + @ApiOperation("数据字典-值列表- @author 罗伊") + @GetMapping("/dict/value/list/{keyCode}") + public ResponseDTO> valueList(@PathVariable String keyCode) { + List dictValueVOList = dictCacheService.selectByKeyCode(keyCode); + return ResponseDTO.ok(dictValueVOList); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/dao/DictKeyDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/dao/DictKeyDao.java new file mode 100644 index 0000000..f4d48a5 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/dao/DictKeyDao.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.common.module.support.dict.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.dict.domain.entity.DictKeyEntity; +import net.lab1024.sa.common.module.support.dict.domain.form.DictKeyQueryForm; +import net.lab1024.sa.common.module.support.dict.domain.vo.DictKeyVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface DictKeyDao extends BaseMapper { + + /** + * 查找所有未删除的自带key + * @param deletedFlag + * @return + */ + List selectByDeletedFlag(@Param("deletedFlag") Boolean deletedFlag); + + /** + * 逻辑删除 + * + * @param dictKeyIdList + * @param deletedFlag + */ + void updateDeletedFlagByIdList(@Param("dictKeyIdList") List dictKeyIdList, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 分页查询 + * + * @param page + * @param queryForm + * @return + */ + List query(Page page, @Param("query") DictKeyQueryForm queryForm); + + /** + * 跟进code查询 + * @param keyCode + * @param deletedFlag + * @return + */ + DictKeyEntity selectByCode(@Param("keyCode")String keyCode, @Param("deletedFlag") Boolean deletedFlag); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/dao/DictValueDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/dao/DictValueDao.java new file mode 100644 index 0000000..4cefc6b --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/dao/DictValueDao.java @@ -0,0 +1,69 @@ +package net.lab1024.sa.common.module.support.dict.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.dict.domain.entity.DictValueEntity; +import net.lab1024.sa.common.module.support.dict.domain.form.DictValueQueryForm; +import net.lab1024.sa.common.module.support.dict.domain.vo.DictValueVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface DictValueDao extends BaseMapper { + + /** + * 查找所有未删除的自带key + * + * @param deletedFlag + * @return + */ + List selectByDeletedFlag(@Param("deletedFlag") Boolean deletedFlag); + + /** + * 查找所有未删除的自带key + * + * @param dictKeyId + * @param deletedFlag + * @return + */ + List selectByDeletedFlagAndKeyId(@Param("dictKeyId") Long dictKeyId, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 逻辑删除 + * + * @param dictValueIdList + * @param deletedFlag + */ + void updateDeletedFlagByIdList(@Param("dictValueIdList") List dictValueIdList, @Param("deletedFlag") Boolean deletedFlag); + + /** + * 分页查询 + * + * @param page + * @param queryForm + * @return + */ + List query(Page page, @Param("query") DictValueQueryForm queryForm); + + /** + * 跟进code查询 + * + * @param valueCode + * @param deletedFlag + * @return + */ + DictValueEntity selectByCode(@Param("valueCode") String valueCode, @Param("deletedFlag") Boolean deletedFlag); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/entity/DictKeyEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/entity/DictKeyEntity.java new file mode 100644 index 0000000..1696440 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/entity/DictKeyEntity.java @@ -0,0 +1,54 @@ +package net.lab1024.sa.common.module.support.dict.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_dict_key") +public class DictKeyEntity { + + @TableId(type = IdType.AUTO) + private Long dictKeyId; + + /** + * 编码 + */ + private String keyCode; + /** + * 名称 + */ + private String keyName; + + /** + * 备注 + */ + private String remark; + + /** + * 删除标识 + */ + private Boolean deletedFlag; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/entity/DictValueEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/entity/DictValueEntity.java new file mode 100644 index 0000000..ff46e34 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/entity/DictValueEntity.java @@ -0,0 +1,58 @@ +package net.lab1024.sa.common.module.support.dict.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_dict_value") +public class DictValueEntity { + + @TableId(type = IdType.AUTO) + private Long dictValueId; + + private Long dictKeyId; + /** + * 编码 + */ + private String valueCode; + /** + * 名称 + */ + private String valueName; + /** + * 备注 + */ + private String remark; + + /** + * 排序 + */ + private Integer sort; + /** + * 删除标识 + */ + private Boolean deletedFlag; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyAddForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyAddForm.java new file mode 100644 index 0000000..d6bc67b --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyAddForm.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.common.module.support.dict.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DictKeyAddForm { + + @ApiModelProperty("编码") + @NotBlank(message = "编码不能为空") + @Length(max = 50,message = "编码太长了,不能超过50字符") + private String keyCode; + + @ApiModelProperty("名称") + @NotBlank(message = "名称不能为空") + @Length(max = 50,message = "名称太长了,不能超过50字符") + private String keyName; + + @ApiModelProperty("备注") + @Length(max = 500,message = "备注太长了") + private String remark; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyQueryForm.java new file mode 100644 index 0000000..8cd26dd --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyQueryForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.common.module.support.dict.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DictKeyQueryForm extends PageParam { + + @ApiModelProperty("搜索词") + private String searchWord; + + @ApiModelProperty(value = "删除标识",hidden = true) + private Boolean deletedFlag; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyUpdateForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyUpdateForm.java new file mode 100644 index 0000000..87bfb20 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictKeyUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.common.module.support.dict.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DictKeyUpdateForm extends DictKeyAddForm { + + @ApiModelProperty("keyId") + @NotNull(message = "keyId不能为空") + private Long dictKeyId; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueAddForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueAddForm.java new file mode 100644 index 0000000..7f5b093 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueAddForm.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.common.module.support.dict.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DictValueAddForm { + + @ApiModelProperty("dictKeyId") + @NotNull(message = "dictKeyId不能为空") + private Long dictKeyId; + + @ApiModelProperty("编码") + @NotBlank(message = "编码不能为空") + @Length(max = 50,message = "编码太长了,不能超过50字符") + private String valueCode; + + @ApiModelProperty("名称") + @NotBlank(message = "名称不能为空") + @Length(max = 50,message = "名称太长了,不能超过50字符") + private String valueName; + + @ApiModelProperty("排序") + @NotNull(message = "排序不能为空") + private Integer sort; + + @ApiModelProperty("备注") + @Length(max = 500,message = "备注太长了") + private String remark; + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueQueryForm.java new file mode 100644 index 0000000..40540ea --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueQueryForm.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.common.module.support.dict.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +import javax.validation.constraints.NotNull; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DictValueQueryForm extends PageParam { + + @ApiModelProperty("dictKeyId") + @NotNull(message = "dictKeyId不能为空") + private Long dictKeyId; + + @ApiModelProperty("搜索词") + private String searchWord; + + @ApiModelProperty(value = "删除标识",hidden = true) + private Boolean deletedFlag; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueUpdateForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueUpdateForm.java new file mode 100644 index 0000000..273100a --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/form/DictValueUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.common.module.support.dict.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DictValueUpdateForm extends DictValueAddForm { + + @ApiModelProperty("valueId") + @NotNull(message = "valueId不能为空") + private Long dictValueId; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/vo/DictKeyVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/vo/DictKeyVO.java new file mode 100644 index 0000000..f986495 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/vo/DictKeyVO.java @@ -0,0 +1,29 @@ +package net.lab1024.sa.common.module.support.dict.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DictKeyVO { + + @ApiModelProperty("dictKeyId") + private Long dictKeyId; + + @ApiModelProperty("编码") + private String keyCode; + + @ApiModelProperty("名称") + private String keyName; + + @ApiModelProperty("备注") + private String remark; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/vo/DictValueVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/vo/DictValueVO.java new file mode 100644 index 0000000..ec7535c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/domain/vo/DictValueVO.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.common.module.support.dict.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 字典 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class DictValueVO { + + @ApiModelProperty("valueId") + private Long dictValueId; + + @ApiModelProperty("dictKeyId") + private Long dictKeyId; + + @ApiModelProperty("编码") + private String valueCode; + + @ApiModelProperty("名称") + private String valueName; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("备注") + private String remark; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/service/DictCacheService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/service/DictCacheService.java new file mode 100644 index 0000000..63c9a66 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/service/DictCacheService.java @@ -0,0 +1,133 @@ +package net.lab1024.sa.common.module.support.dict.service; + +import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.module.support.dict.dao.DictKeyDao; +import net.lab1024.sa.common.module.support.dict.dao.DictValueDao; +import net.lab1024.sa.common.module.support.dict.domain.entity.DictKeyEntity; +import net.lab1024.sa.common.module.support.dict.domain.entity.DictValueEntity; +import net.lab1024.sa.common.module.support.dict.domain.vo.DictValueVO; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * 字典缓存 服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Service +public class DictCacheService { + + @Autowired + private DictKeyDao dictKeyDao; + @Autowired + private DictValueDao dictValueDao; + + private ConcurrentHashMap> DICT_CACHE = new ConcurrentHashMap<>(); + + private ConcurrentHashMap VALUE_CACHE = new ConcurrentHashMap<>(); + + + @PostConstruct + public void dictCache() { + this.cacheInit(); + } + + public void cacheInit() { + List dictKeyEntityList = dictKeyDao.selectByDeletedFlag(false); + if (CollectionUtils.isEmpty(dictKeyEntityList)) { + return; + } + List dictKeyValueList = dictValueDao.selectByDeletedFlag(false); + List dictValueVOList = SmartBeanUtil.copyList(dictKeyValueList, DictValueVO.class); + Map> valueListMap = dictValueVOList.stream().collect(Collectors.groupingBy(DictValueVO::getDictKeyId)); + //字典键值对缓存 + for (DictKeyEntity dictKeyEntity : dictKeyEntityList) { + String keyCode = dictKeyEntity.getKeyCode(); + Long dictKeyId = dictKeyEntity.getDictKeyId(); + DICT_CACHE.put(keyCode, valueListMap.getOrDefault(dictKeyId, Lists.newArrayList())); + } + //字典值缓存 + dictValueVOList.forEach(e -> { + VALUE_CACHE.put(e.getValueCode(), e); + }); + log.info("################# 数据字典缓存初始化完毕 ###################"); + } + + /** + * 刷新缓存 + */ + public ResponseDTO cacheRefresh() { + DICT_CACHE.clear(); + VALUE_CACHE.clear(); + this.cacheInit(); + return ResponseDTO.ok(); + } + + /** + * 查询某个key对应的字典值列表 + * + * @param keyCode + * @return + */ + public List selectByKeyCode(String keyCode) { + return DICT_CACHE.getOrDefault(keyCode, Lists.newArrayList()); + } + + /** + * 查询值code名称 + * + * @param valueCode + * @return + */ + public String selectValueNameByValueCode(String valueCode) { + if (StrUtil.isEmpty(valueCode)) { + return null; + } + + DictValueVO dictValueVO = VALUE_CACHE.get(valueCode); + if (dictValueVO == null) { + return ""; + } + return dictValueVO.getValueName(); + } + + public DictValueVO selectValueByValueCode(String valueCode) { + if (StrUtil.isEmpty(valueCode)) { + return null; + } + return VALUE_CACHE.get(valueCode); + } + + public String selectValueNameByValueCodeSplit(String valueCodes) { + if (StrUtil.isEmpty(valueCodes)) { + return ""; + } + List valueNameList = Lists.newArrayList(); + String[] valueCodeArray = valueCodes.split(","); + for (String valueCode : valueCodeArray) { + DictValueVO dictValueVO = VALUE_CACHE.get(valueCode); + if (dictValueVO != null) { + valueNameList.add(dictValueVO.getValueName()); + } + } + return StringUtils.join(valueNameList, ","); + } + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/service/DictService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/service/DictService.java new file mode 100644 index 0000000..ad62415 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/dict/service/DictService.java @@ -0,0 +1,196 @@ +package net.lab1024.sa.common.module.support.dict.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.collect.Interner; +import com.google.common.collect.Interners; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.dict.dao.DictKeyDao; +import net.lab1024.sa.common.module.support.dict.dao.DictValueDao; +import net.lab1024.sa.common.module.support.dict.domain.entity.DictKeyEntity; +import net.lab1024.sa.common.module.support.dict.domain.entity.DictValueEntity; +import net.lab1024.sa.common.module.support.dict.domain.form.*; +import net.lab1024.sa.common.module.support.dict.domain.vo.DictKeyVO; +import net.lab1024.sa.common.module.support.dict.domain.vo.DictValueVO; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 字典 服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2022/5/26 19:40:55 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class DictService { + + @Autowired + private DictKeyDao dictKeyDao; + @Autowired + private DictValueDao dictValueDao; + @Autowired + private DictCacheService dictCacheService; + /** + * CODE锁 + */ + private static final Interner CODE_POOL = Interners.newWeakInterner(); + + + /** + * key添加 + * + * @param keyAddForm + * @return + */ + public ResponseDTO keyAdd(DictKeyAddForm keyAddForm) { + synchronized (CODE_POOL.intern(keyAddForm.getKeyCode())) { + DictKeyEntity dictKeyEntity = dictKeyDao.selectByCode(keyAddForm.getKeyCode(), false); + if (dictKeyEntity != null) { + return ResponseDTO.error(UserErrorCode.ALREADY_EXIST); + } + dictKeyEntity = SmartBeanUtil.copy(keyAddForm, DictKeyEntity.class); + dictKeyDao.insert(dictKeyEntity); + } + return ResponseDTO.ok(); + } + + /** + * 值添加 + * + * @param valueAddForm + * @return + */ + public ResponseDTO valueAdd(DictValueAddForm valueAddForm) { + synchronized (CODE_POOL.intern(valueAddForm.getValueCode())) { + DictValueEntity dictValueEntity = dictValueDao.selectByCode(valueAddForm.getValueCode(), false); + if (dictValueEntity != null) { + return ResponseDTO.error(UserErrorCode.ALREADY_EXIST); + } + dictValueEntity = SmartBeanUtil.copy(valueAddForm, DictValueEntity.class); + dictValueDao.insert(dictValueEntity); + } + return ResponseDTO.ok(); + } + + /** + * key 编辑 + * + * @param keyUpdateForm + * @return + */ + public ResponseDTO keyEdit(DictKeyUpdateForm keyUpdateForm) { + synchronized (CODE_POOL.intern(keyUpdateForm.getKeyCode())) { + DictKeyEntity dictKeyEntity = dictKeyDao.selectByCode(keyUpdateForm.getKeyCode(), false); + if (dictKeyEntity != null && !dictKeyEntity.getDictKeyId().equals(keyUpdateForm.getDictKeyId())) { + return ResponseDTO.error(UserErrorCode.ALREADY_EXIST); + } + DictKeyEntity dictKeyUpdateEntity = SmartBeanUtil.copy(keyUpdateForm, DictKeyEntity.class); + dictKeyDao.updateById(dictKeyUpdateEntity); + } + return ResponseDTO.ok(); + } + + /** + * 值编辑 + * + * @param valueUpdateForm + * @return + */ + public ResponseDTO valueEdit(DictValueUpdateForm valueUpdateForm) { + DictKeyEntity dictKeyEntity = dictKeyDao.selectById(valueUpdateForm.getDictKeyId()); + if (dictKeyEntity == null || dictKeyEntity.getDeletedFlag()) { + return ResponseDTO.userErrorParam("key不能存在"); + } + synchronized (CODE_POOL.intern(valueUpdateForm.getValueCode())) { + DictValueEntity dictValueEntity = dictValueDao.selectByCode(valueUpdateForm.getValueCode(), false); + if (dictValueEntity != null && !dictValueEntity.getDictValueId().equals(valueUpdateForm.getDictValueId())) { + return ResponseDTO.error(UserErrorCode.ALREADY_EXIST); + } + DictValueEntity dictValueUpdateEntity = SmartBeanUtil.copy(valueUpdateForm, DictValueEntity.class); + dictValueDao.updateById(dictValueUpdateEntity); + } + return ResponseDTO.ok(); + } + + /** + * key删除 + * + * @param keyIdList + * @return + */ + public ResponseDTO keyDelete(List keyIdList) { + if (CollectionUtils.isEmpty(keyIdList)) { + return ResponseDTO.ok(); + } + dictKeyDao.updateDeletedFlagByIdList(keyIdList, true); + return ResponseDTO.ok(); + } + + /** + * 值删除 + * + * @param valueIdList + * @return + */ + public ResponseDTO valueDelete(List valueIdList) { + if (CollectionUtils.isEmpty(valueIdList)) { + return ResponseDTO.ok(); + } + dictValueDao.updateDeletedFlagByIdList(valueIdList, true); + return ResponseDTO.ok(); + } + + /** + * 分页查询key + * + * @param queryForm + * @return + */ + public ResponseDTO> keyQuery(DictKeyQueryForm queryForm) { + queryForm.setDeletedFlag(false); + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = dictKeyDao.query(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + if (pageResult.getEmptyFlag()) { + return ResponseDTO.ok(pageResult); + } + return ResponseDTO.ok(pageResult); + } + + /** + * 所有key + * + * @return + */ + public List queryAllKey() { + return SmartBeanUtil.copyList(dictKeyDao.selectList(null), DictKeyVO.class); + } + + /** + * 分页查询值 + * + * @param queryForm + * @return + */ + public ResponseDTO> valueQuery(DictValueQueryForm queryForm) { + queryForm.setDeletedFlag(false); + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = dictValueDao.query(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + if (pageResult.getEmptyFlag()) { + return ResponseDTO.ok(pageResult); + } + return ResponseDTO.ok(pageResult); + } + + +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/controller/FeedbackController.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/controller/FeedbackController.java new file mode 100644 index 0000000..2a5022c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/controller/FeedbackController.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.common.module.support.feedback.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.feedback.domain.FeedbackAddForm; +import net.lab1024.sa.common.module.support.feedback.domain.FeedbackQueryForm; +import net.lab1024.sa.common.module.support.feedback.domain.FeedbackVO; +import net.lab1024.sa.common.module.support.feedback.service.FeedbackService; +import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * 意见反馈 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +//@Api(tags = SwaggerTagConst.Support.FEEDBACK, hidden = true) +@RestController +public class FeedbackController extends SupportBaseController { + + @Autowired + private FeedbackService feedbackService; + + @ApiOperation("意见反馈-分页查询 @author 开云") + @PostMapping("/feedback/query") + public ResponseDTO> query(@RequestBody @Valid FeedbackQueryForm queryForm) { + return feedbackService.query(queryForm); + } + + @ApiOperation("意见反馈-新增 @author 开云") + @PostMapping("/feedback/add") + public ResponseDTO add(@RequestBody @Valid FeedbackAddForm addForm) { + RequestUser employee = SmartRequestUtil.getRequestUser(); + return feedbackService.add(addForm, employee); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/dao/FeedbackDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/dao/FeedbackDao.java new file mode 100644 index 0000000..e03e2e1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/dao/FeedbackDao.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.common.module.support.feedback.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.feedback.domain.FeedbackEntity; +import net.lab1024.sa.common.module.support.feedback.domain.FeedbackQueryForm; +import net.lab1024.sa.common.module.support.feedback.domain.FeedbackVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 意见反馈 dao + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface FeedbackDao extends BaseMapper { + + /** + * 分页查询 + */ + List queryPage(Page page, @Param("query") FeedbackQueryForm query); +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackAddForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackAddForm.java new file mode 100644 index 0000000..0eafb05 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackAddForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.common.module.support.feedback.domain; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.json.deserializer.FileKeyVoDeserializer; + +import javax.validation.constraints.NotBlank; + +/** + * 意见反馈 添加表单 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class FeedbackAddForm { + + @ApiModelProperty("反馈内容") + @NotBlank(message = "反馈内容不能为空") + private String feedbackContent; + + @ApiModelProperty("反馈图片") + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String feedbackAttachment; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackEntity.java new file mode 100644 index 0000000..1a5a989 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackEntity.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.common.module.support.feedback.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 意见反馈 表 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_feedback") +public class FeedbackEntity { + /** + * 主键 + */ + @TableId(type = IdType.AUTO) + private Long feedbackId; + + /** + * 反馈内容 + */ + private String feedbackContent; + + /** + * 反馈附件 + */ + private String feedbackAttachment; + + /** + * 创建人id + */ + private Long userId; + + /** + * 用户类型 + */ + private Integer userType; + + /** + * 创建人姓名 + */ + private String userName; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackQueryForm.java new file mode 100644 index 0000000..954a2e9 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackQueryForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.common.module.support.feedback.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; + +/** + * 意见反馈 查询 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class FeedbackQueryForm extends PageParam { + + @ApiModelProperty("搜索词") + @Length(max = 25, message = "搜索词最多25字符") + private String searchWord; + + @ApiModelProperty(value = "开始时间", example = "2021-02-14") + private LocalDate startDate; + + @ApiModelProperty(value = "截止时间", example = "2022-10-15") + private LocalDate endDate; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackVO.java new file mode 100644 index 0000000..87767cc --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/domain/FeedbackVO.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.common.module.support.feedback.domain; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.common.json.deserializer.FileKeyVoDeserializer; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +import java.time.LocalDateTime; + +/** + * 意见反馈 返回对象 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class FeedbackVO { + + @ApiModelProperty(value = "主键") + private Long feedbackId; + + @ApiModelProperty(value = "反馈内容") + private String feedbackContent; + + @ApiModelProperty("反馈图片") + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String feedbackAttachment; + + @ApiModelProperty(value = "创建人id") + private Long userId; + + @ApiModelProperty(value = "创建人姓名") + private String userName; + + @ApiModelPropertyEnum(value = UserTypeEnum.class, desc = "创建人类型") + private Integer userType; + + @ApiModelProperty(value = "更新时间") + private LocalDateTime updateTime; + + @ApiModelProperty(value = "创建时间") + private LocalDateTime createTime; +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/service/FeedbackService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/service/FeedbackService.java new file mode 100644 index 0000000..a534cc7 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/feedback/service/FeedbackService.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.common.module.support.feedback.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.feedback.dao.FeedbackDao; +import net.lab1024.sa.common.module.support.feedback.domain.FeedbackAddForm; +import net.lab1024.sa.common.module.support.feedback.domain.FeedbackEntity; +import net.lab1024.sa.common.module.support.feedback.domain.FeedbackQueryForm; +import net.lab1024.sa.common.module.support.feedback.domain.FeedbackVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + + +/** + * 意见反馈 + * + * @Author 1024创新实验室: 开云 + * @Date 2022-08-11 20:48:09 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class FeedbackService { + + @Autowired + private FeedbackDao feedbackDao; + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public ResponseDTO> query(FeedbackQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = feedbackDao.queryPage(page, queryForm); + PageResult pageResultDTO = SmartPageUtil.convert2PageResult(page, list); + if (pageResultDTO.getEmptyFlag()) { + return ResponseDTO.ok(pageResultDTO); + } + return ResponseDTO.ok(pageResultDTO); + } + + /** + * 新建 + */ + public ResponseDTO add(FeedbackAddForm addForm, RequestUser requestUser) { + FeedbackEntity feedback = SmartBeanUtil.copy(addForm, FeedbackEntity.class); + feedback.setUserType(requestUser.getUserType().getValue()); + feedback.setUserId(requestUser.getUserId()); + feedback.setUserName(requestUser.getUserName()); + feedbackDao.insert(feedback); + return ResponseDTO.ok(); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/constant/FileFolderTypeEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/constant/FileFolderTypeEnum.java new file mode 100644 index 0000000..5428c41 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/constant/FileFolderTypeEnum.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.common.module.support.file.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 文件服务 文件夹位置类型枚举类 + * + * @Author 1024创新实验室: 胡克 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@AllArgsConstructor +@Getter +public enum FileFolderTypeEnum implements BaseEnum { + + COMMON(1, FileFolderTypeEnum.FOLDER_PUBLIC + "/common/", "通用"), + + NOTICE(2, FileFolderTypeEnum.FOLDER_PUBLIC + "/notice/", "公告"), + + HELP_DOC(3, FileFolderTypeEnum.FOLDER_PUBLIC + "help-doc", "帮助中心"), + + FEEDBACK(4, FileFolderTypeEnum.FOLDER_PUBLIC + "/feedback/", "意见反馈"), + + ; + + /** + * 公用读取文件夹 public + */ + public static final String FOLDER_PUBLIC = "public"; + + /** + * 私有读取文件夹 private + */ + public static final String FOLDER_PRIVATE = "private"; + + + public static final String INFO = "1:通用"; + + private final Integer value; + + private final String folder; + + private final String desc; +} + diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/controller/FileController.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/controller/FileController.java new file mode 100644 index 0000000..4f17bf2 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/controller/FileController.java @@ -0,0 +1,72 @@ +package net.lab1024.sa.common.module.support.file.controller; + +import cn.hutool.extra.servlet.ServletUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.constant.RequestHeaderConst; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.file.domain.form.FileQueryForm; +import net.lab1024.sa.common.module.support.file.domain.form.FileUrlUploadForm; +import net.lab1024.sa.common.module.support.file.domain.vo.FileUploadVO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileVO; +import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; +import net.lab1024.sa.common.module.support.file.constant.FileFolderTypeEnum; +import net.lab1024.sa.common.module.support.file.service.FileService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +/** + * 文件服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@RestController +//@Api(tags = {SwaggerTagConst.Support.FILE}) +public class FileController extends SupportBaseController { + + @Autowired + private FileService fileService; + + + @ApiOperation(value = "文件上传 @author 胡克", notes = FileFolderTypeEnum.INFO) + @PostMapping("/file/upload") + public ResponseDTO upload(@RequestParam MultipartFile file, + @RequestParam Integer folder) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + return fileService.fileUpload(file, folder, requestUser); + } + + @ApiOperation(value = "文件上传,通过url上传 @author 胡克", notes = FileFolderTypeEnum.INFO) + @PostMapping("/file/upload/url") + public ResponseDTO uploadByUrl(@RequestBody @Valid FileUrlUploadForm uploadForm) { + RequestUser requestUser = SmartRequestUtil.getRequestUser(); + return fileService.fileUpload(uploadForm,requestUser); + } + + //@ApiOperation("获取文件URL:根据fileKey @author 胡克") + //@GetMapping("/file/getFileUrl") + //public ResponseDTO getUrl(@RequestParam String fileKey) { + // return fileService.getFileUrl(fileKey); + //} + + @ApiOperation(value = "下载文件流(根据fileKey) @author 胡克") + @GetMapping("/file/downLoad") + public ResponseEntity downLoad(@RequestParam String fileKey, HttpServletRequest request) { + String userAgent = ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT); + return fileService.downloadByFileKey(fileKey, userAgent); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/dao/FileDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/dao/FileDao.java new file mode 100644 index 0000000..f49b417 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/dao/FileDao.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.common.module.support.file.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.file.domain.vo.FileVO; +import net.lab1024.sa.common.module.support.file.domain.entity.FileEntity; +import net.lab1024.sa.common.module.support.file.domain.form.FileQueryForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 文件服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface FileDao extends BaseMapper { + + /** + * 文件key单个查询 + * + * @param fileKey + * @return + */ + FileVO getByFileKey(@Param("fileKey") String fileKey); + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List queryPage(Page page, @Param("queryForm") FileQueryForm queryForm); + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/entity/FileEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/entity/FileEntity.java new file mode 100644 index 0000000..194a4ec --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/entity/FileEntity.java @@ -0,0 +1,73 @@ +package net.lab1024.sa.common.module.support.file.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 文件服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName(value = "t_file") +public class FileEntity { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long fileId; + + /** + * 文件夹类型 + */ + private Integer folderType; + + /** + * 文件名称 + */ + private String fileName; + + /** + * 文件大小 + */ + private Long fileSize; + + /** + * 文件key,用于文件下载 + */ + private String fileKey; + + /** + * 文件类型 + */ + private String fileType; + + /** + * 创建人,即上传人 + */ + private Long creatorId; + + /** + * 用户类型 + */ + private Integer creatorUserType; + + /** + * 创建人 姓名 + */ + private String creatorName; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} + diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/form/FileQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/form/FileQueryForm.java new file mode 100644 index 0000000..29bc58c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/form/FileQueryForm.java @@ -0,0 +1,47 @@ +package net.lab1024.sa.common.module.support.file.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.file.constant.FileFolderTypeEnum; +import org.hibernate.validator.constraints.Length; + +import java.time.LocalDate; + +/** + * 文件信息查询 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class FileQueryForm extends PageParam { + + @ApiModelPropertyEnum(value = FileFolderTypeEnum.class, desc = "文件夹类型") + @CheckEnum(value = FileFolderTypeEnum.class, message = "文件夹类型 错误") + private Integer folderType; + + @ApiModelProperty(value = "文件名词") + private String fileName; + + @ApiModelProperty(value = "文件Key") + private String fileKey; + + @ApiModelProperty(value = "文件类型") + private String fileType; + + @ApiModelProperty(value = "创建人") + private String creatorName; + + @ApiModelProperty(value = "创建时间") + private LocalDate createTimeBegin; + + @ApiModelProperty(value = "创建时间") + private LocalDate createTimeEnd; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/form/FileUrlUploadForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/form/FileUrlUploadForm.java new file mode 100644 index 0000000..a346885 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/form/FileUrlUploadForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.common.module.support.file.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.common.validator.enumeration.CheckEnum; +import net.lab1024.sa.common.module.support.file.constant.FileFolderTypeEnum; + +import javax.validation.constraints.NotBlank; + +/** + * url上传文件 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class FileUrlUploadForm { + + @ApiModelPropertyEnum(value = FileFolderTypeEnum.class, desc = "业务类型") + @CheckEnum(value = FileFolderTypeEnum.class, required = true, message = "业务类型错误") + private Integer folder; + + @ApiModelProperty("文件url") + @NotBlank(message = "文件url不能为空") + private String fileUrl; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileDownloadVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileDownloadVO.java new file mode 100644 index 0000000..42e76dd --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileDownloadVO.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.common.module.support.file.domain.vo; + +import lombok.Data; + +/** + * 文件下载 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class FileDownloadVO { + + /** + * 文件字节数据 + */ + private byte[] data; + + /** + * 文件元数据 + */ + private FileMetadataVO metadata; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileMetadataVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileMetadataVO.java new file mode 100644 index 0000000..ad26889 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileMetadataVO.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.common.module.support.file.domain.vo; + +import lombok.Data; + +/** + * 文件元数据 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class FileMetadataVO { + + /** + * 文件名称 + */ + private String fileName; + + /** + * 文件大小/字节 + */ + private Long fileSize; + + /** + * 文件格式 + */ + private String fileFormat; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileUploadVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileUploadVO.java new file mode 100644 index 0000000..345c337 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileUploadVO.java @@ -0,0 +1,35 @@ +package net.lab1024.sa.common.module.support.file.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 文件信息 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class FileUploadVO { + + @ApiModelProperty(value = "文件id") + private Long fileId; + + @ApiModelProperty(value = "文件名称") + private String fileName; + + @ApiModelProperty(value = "fileUrl") + private String fileUrl; + + @ApiModelProperty(value = "fileKey") + private String fileKey; + + @ApiModelProperty(value = "文件大小") + private Long fileSize; + + @ApiModelProperty(value = "文件类型") + private String fileType; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileVO.java new file mode 100644 index 0000000..9ab8217 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/domain/vo/FileVO.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.common.module.support.file.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.module.support.file.constant.FileFolderTypeEnum; + +import java.time.LocalDateTime; + +/** + * 文件信息 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class FileVO { + + @ApiModelProperty("主键") + private Long fileId; + + @ApiModelProperty("存储文件夹类型") + @ApiModelPropertyEnum(FileFolderTypeEnum.class) + private Integer folderType; + + @ApiModelProperty("文件名称") + private String fileName; + + @ApiModelProperty("文件大小") + private Integer fileSize; + + @ApiModelProperty("文件类型") + private String fileType; + + @ApiModelProperty("文件路径") + private String fileKey; + + @ApiModelProperty("上传人") + private Long creatorId; + + @ApiModelProperty("上传人") + private String creatorName; + + @ApiModelPropertyEnum(value = UserTypeEnum.class, desc = "创建人类型") + private Integer creatorUserType; + + @ApiModelProperty("文件展示url") + private String fileUrl; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileService.java new file mode 100644 index 0000000..6af3397 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileService.java @@ -0,0 +1,207 @@ +package net.lab1024.sa.common.module.support.file.service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.common.code.SystemErrorCode; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartEnumUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.file.constant.FileFolderTypeEnum; +import net.lab1024.sa.common.module.support.file.dao.FileDao; +import net.lab1024.sa.common.module.support.file.domain.entity.FileEntity; +import net.lab1024.sa.common.module.support.file.domain.form.FileQueryForm; +import net.lab1024.sa.common.module.support.file.domain.form.FileUrlUploadForm; +import net.lab1024.sa.common.module.support.file.domain.vo.FileDownloadVO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileMetadataVO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileUploadVO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileVO; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.util.List; + +/** + * 文件服务 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class FileService { + + /** + * 文件名最大长度 + */ + private static final int FILE_NAME_MAX_LENGTH = 100; + + @Resource + private IFileStorageService fileStorageService; + + @Autowired + private FileDao fileDao; + + @Value("${spring.servlet.multipart.max-file-size}") + private String maxFileSize; + + /** + * 文件上传服务:通过 url 上传 + * + * @param urlUploadForm + * @param requestUser + * @return + */ + public ResponseDTO fileUpload(FileUrlUploadForm urlUploadForm, RequestUser requestUser) { + try { + URL url = new URL(urlUploadForm.getFileUrl()); + URLConnection urlConnection = url.openConnection(); + // 获取文件格式 + String contentType = urlConnection.getContentType(); + String fileType = fileStorageService.getFileTypeByContentType(contentType); + // 生成文件key + String fileKey = fileStorageService.generateFileNameByType(fileType); + MockMultipartFile file = new MockMultipartFile(fileKey, fileKey, contentType, urlConnection.getInputStream()); + return this.fileUpload(file, urlUploadForm.getFolder(), requestUser); + } catch (IOException e) { + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, "上传失败"); + } + } + + /** + * 文件上传服务 + * + * @param file + * @param folderType 文件夹类型 + * @return + */ + public ResponseDTO fileUpload(MultipartFile file, Integer folderType, RequestUser requestUser) { + FileFolderTypeEnum folderTypeEnum = SmartEnumUtil.getEnumByValue(folderType, FileFolderTypeEnum.class); + if (null == folderTypeEnum) { + return ResponseDTO.userErrorParam("文件夹错误"); + } + if (null == file || file.getSize() == 0) { + return ResponseDTO.userErrorParam("上传文件不能为空"); + } + // 校验文件名称 + String originalFilename = file.getOriginalFilename(); + if (StringUtils.isBlank(originalFilename)) { + return ResponseDTO.userErrorParam("上传文件名称不能为空"); + } + if (originalFilename.length() > FILE_NAME_MAX_LENGTH) { + return ResponseDTO.userErrorParam("文件名称最大长度为:" + FILE_NAME_MAX_LENGTH); + } + // 校验文件大小 + String maxSizeStr = maxFileSize.toLowerCase().replace("mb", ""); + long maxSize = Integer.parseInt(maxSizeStr) * 1024 * 1024L; + if (file.getSize() > maxSize) { + return ResponseDTO.userErrorParam("上传文件最大:" + maxSize); + } + // 获取文件服务 + ResponseDTO response = fileStorageService.fileUpload(file, folderTypeEnum.getFolder()); + if (!response.getOk()) { + return response; + } + + // 上传成功 保存记录数据库 + FileUploadVO uploadVO = response.getData(); + + FileEntity fileEntity = new FileEntity(); + fileEntity.setFolderType(folderTypeEnum.getValue()); + fileEntity.setFileName(originalFilename); + fileEntity.setFileSize(file.getSize()); + fileEntity.setFileKey(uploadVO.getFileKey()); + fileEntity.setFileType(uploadVO.getFileType()); + fileEntity.setCreatorId(requestUser == null ? null : requestUser.getUserId()); + fileEntity.setCreatorName(requestUser == null ? null : requestUser.getUserName()); + fileEntity.setCreatorUserType(requestUser == null ? null : requestUser.getUserType().getValue()); + fileDao.insert(fileEntity); + uploadVO.setFileId(fileEntity.getFileId()); + return response; + } + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public PageResult queryPage(FileQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = fileDao.queryPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, list); + return pageResult; + } + + /** + * 根据文件服务类型 和 FileKey 下载文件 + * + * @param fileKey + * @return + * @throws IOException + */ + public ResponseEntity downloadByFileKey(String fileKey, String userAgent) { + FileVO fileVO = fileDao.getByFileKey(fileKey); + if (fileVO == null) { + HttpHeaders heads = new HttpHeaders(); + heads.add(HttpHeaders.CONTENT_TYPE, "text/html;charset=UTF-8"); + return new ResponseEntity<>("文件不存在:" + fileKey, heads, HttpStatus.OK); + } + + // 根据文件服务类 获取对应文件服务 查询 url + ResponseDTO responseDTO = fileStorageService.fileDownload(fileKey); + if (!responseDTO.getOk()) { + HttpHeaders heads = new HttpHeaders(); + heads.add(HttpHeaders.CONTENT_TYPE, "text/html;charset=UTF-8"); + return new ResponseEntity<>(responseDTO.getMsg() + ":" + fileKey, heads, HttpStatus.OK); + } + + FileDownloadVO fileDownloadVO = responseDTO.getData(); + FileMetadataVO metadata = fileDownloadVO.getMetadata(); + + // 设置下载头 + HttpHeaders heads = new HttpHeaders(); + heads.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(metadata.getFileSize())); + heads.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream; charset=utf-8"); + heads.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileStorageService.getDownloadFileNameByUA(fileVO.getFileName(), userAgent)); + + // 返回给前端 + ResponseEntity responseEntity = new ResponseEntity<>(fileDownloadVO.getData(), heads, HttpStatus.OK); + return responseEntity; + } + + /** + * 根据文件key 删除 + * + * @param fileKey + * @return + */ + public ResponseDTO deleteByFileKey(String fileKey) { + if (StringUtils.isBlank(fileKey)) { + return ResponseDTO.error(UserErrorCode.PARAM_ERROR); + } + FileEntity fileEntity = new FileEntity(); + fileEntity.setFileKey(fileKey); + fileEntity = fileDao.selectOne(new QueryWrapper<>(fileEntity)); + if (null == fileEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + // 根据文件服务类 获取对应文件服务 删除文件 + return fileStorageService.delete(fileKey); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileStorageCloudServiceImpl.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileStorageCloudServiceImpl.java new file mode 100644 index 0000000..5b414c5 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileStorageCloudServiceImpl.java @@ -0,0 +1,215 @@ +package net.lab1024.sa.common.module.support.file.service; + +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.CannedAccessControlList; +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.S3Object; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.code.SystemErrorCode; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.config.FileCloudConfig; +import net.lab1024.sa.common.module.support.file.domain.vo.FileDownloadVO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileMetadataVO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileUploadVO; +import net.lab1024.sa.common.module.support.file.constant.FileFolderTypeEnum; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * 云计算 实现 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +public class FileStorageCloudServiceImpl implements IFileStorageService { + + @Autowired + private AmazonS3 amazonS3; + + @Autowired + private FileCloudConfig cloudConfig; + + /** + * 自定义元数据 文件名称 + */ + private static final String USER_METADATA_FILE_NAME = "file-name"; + + /** + * 自定义元数据 文件格式 + */ + private static final String USER_METADATA_FILE_FORMAT = "file-format"; + + /** + * 自定义元数据 文件大小 + */ + private static final String USER_METADATA_FILE_SIZE = "file-size"; + + @Override + public ResponseDTO fileUpload(MultipartFile file, String path) { + // 设置文件 key + String originalFilename = file.getOriginalFilename(); + String fileType = FilenameUtils.getExtension(originalFilename); + String fileKey = path + this.generateFileName(originalFilename); + // 文件名称 URL 编码 + String urlEncoderFilename; + try { + urlEncoderFilename = URLEncoder.encode(originalFilename, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + log.error("阿里云文件上传服务URL ENCODE-发生异常:", e); + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR,"上传失败"); + } + ObjectMetadata meta = new ObjectMetadata(); + meta.setContentEncoding(StandardCharsets.UTF_8.name()); + meta.setContentDisposition("attachment;filename=" + urlEncoderFilename); + Map userMetadata = new HashMap(10); + userMetadata.put(USER_METADATA_FILE_NAME, urlEncoderFilename); + userMetadata.put(USER_METADATA_FILE_FORMAT, fileType); + userMetadata.put(USER_METADATA_FILE_SIZE, String.valueOf(file.getSize())); + meta.setUserMetadata(userMetadata); + meta.setContentLength(file.getSize()); + meta.setContentType(this.getContentType(fileType)); + try { + amazonS3.putObject(cloudConfig.getBucketName(), fileKey, file.getInputStream(), meta); + } catch (IOException e) { + log.error("文件上传-发生异常:", e); + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR,"上传失败"); + } + // 根据文件路径获取并设置访问权限 + CannedAccessControlList acl = this.getACL(path); + amazonS3.setObjectAcl(cloudConfig.getBucketName(), fileKey, acl); + // 返回上传结果 + FileUploadVO uploadVO = new FileUploadVO(); + uploadVO.setFileName(originalFilename); + uploadVO.setFileType(fileType); + // 根据 访问权限 返回不同的 URL + String url = cloudConfig.getPublicUrl() + fileKey; + if (CannedAccessControlList.Private.equals(acl)) { + // 获取临时访问的URL + url = this.getFileUrl(fileKey).getData(); + } + uploadVO.setFileUrl(url); + uploadVO.setFileKey(fileKey); + uploadVO.setFileSize(file.getSize()); + return ResponseDTO.ok(uploadVO); + } + + /** + * 获取文件url + * + * @param fileKey + * @return + */ + @Override + public ResponseDTO getFileUrl(String fileKey) { + if (StringUtils.isBlank(fileKey)) { + return ResponseDTO.userErrorParam(); + } + if (!fileKey.startsWith(FileFolderTypeEnum.FOLDER_PRIVATE)) { + // 不是私有的 都公共读 + return ResponseDTO.ok(cloudConfig.getPublicUrl() + fileKey); + } + Date expiration = new Date(System.currentTimeMillis() + cloudConfig.getUrlExpire()); + URL url = amazonS3.generatePresignedUrl(cloudConfig.getBucketName(), fileKey, expiration); + String urlStr = url.toString().replace("http://", "https://"); + return ResponseDTO.ok(urlStr); + } + + /** + * 流式下载(名称为原文件) + */ + @Override + public ResponseDTO fileDownload(String key) { + //获取oss对象 + S3Object s3Object = amazonS3.getObject(cloudConfig.getBucketName(), key); + // 获取文件 meta + ObjectMetadata metadata = s3Object.getObjectMetadata(); + Map userMetadata = metadata.getUserMetadata(); + FileMetadataVO metadataDTO = null; + if (MapUtils.isNotEmpty(userMetadata)) { + metadataDTO = new FileMetadataVO(); + metadataDTO.setFileFormat(userMetadata.get(USER_METADATA_FILE_FORMAT)); + metadataDTO.setFileName(userMetadata.get(USER_METADATA_FILE_NAME)); + String fileSizeStr = userMetadata.get(USER_METADATA_FILE_SIZE); + Long fileSize = StringUtils.isBlank(fileSizeStr) ? null : Long.valueOf(fileSizeStr); + metadataDTO.setFileSize(fileSize); + } + + // 获得输入流 + InputStream objectContent = s3Object.getObjectContent(); + try { + // 输入流转换为字节流 + byte[] buffer = FileCopyUtils.copyToByteArray(objectContent); + + FileDownloadVO fileDownloadVO = new FileDownloadVO(); + fileDownloadVO.setData(buffer); + fileDownloadVO.setMetadata(metadataDTO); + return ResponseDTO.ok(fileDownloadVO); + } catch (IOException e) { + log.error("文件下载-发生异常:", e); + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR,"下载失败"); + } finally { + try { + // 关闭输入流 + objectContent.close(); + s3Object.close(); + } catch (IOException e) { + log.error("文件下载-发生异常:", e); + } + } + } + + /** + * 根据文件夹路径 返回对应的访问权限 + * + * @param fileKey + * @return + */ + private CannedAccessControlList getACL(String fileKey) { + // 公用读 + if (fileKey.contains(FileFolderTypeEnum.FOLDER_PUBLIC)) { + return CannedAccessControlList.PublicRead; + } + // 其他默认私有读写 + return CannedAccessControlList.Private; + } + + /** + * 单个删除文件 + * 根据 file key 删除文件 + * ps:不能删除fileKey不为空的文件夹 + * + * @param fileKey 文件or文件夹 + * @return + */ + @Override + public ResponseDTO delete(String fileKey) { + amazonS3.deleteObject(cloudConfig.getBucketName(), fileKey); + return ResponseDTO.ok(); + } + + + @Override + public Long cacheExpireSecond(){ + return cloudConfig.getUrlExpire() - 1800; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileStorageLocalServiceImpl.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileStorageLocalServiceImpl.java new file mode 100644 index 0000000..759a3fd --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/FileStorageLocalServiceImpl.java @@ -0,0 +1,157 @@ +package net.lab1024.sa.common.module.support.file.service; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.code.SystemErrorCode; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileDownloadVO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileMetadataVO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileUploadVO; +import net.lab1024.sa.common.module.support.config.ConfigKeyEnum; +import net.lab1024.sa.common.module.support.config.ConfigService; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * 本地存储 实现 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +public class FileStorageLocalServiceImpl implements IFileStorageService { + + @Value("${file.storage.local.path}") + private String localPath; + + @Autowired + private ConfigService configService; + + @Override + public ResponseDTO fileUpload(MultipartFile multipartFile, String path) { + if (null == multipartFile) { + return ResponseDTO.userErrorParam("上传文件不能为空"); + } + String filePath = localPath + path; + File directory = new File(filePath); + if (!directory.exists()) { + // 目录不存在,新建 + directory.mkdirs(); + } + if (!path.endsWith("/")) { + path = path + "/"; + } + FileUploadVO fileUploadVO = new FileUploadVO(); + //原文件名 + String originalFileName = multipartFile.getOriginalFilename(); + //新文件名 + String newFileName = this.generateFileName(originalFileName); + //生成文件key + String fileKey = path + newFileName; + //创建文件 + File fileTemp = new File(new File(filePath + newFileName).getAbsolutePath()); + try { + multipartFile.transferTo(fileTemp); + fileUploadVO.setFileUrl(this.generateFileUrl(fileKey)); + fileUploadVO.setFileName(newFileName); + fileUploadVO.setFileKey(fileKey); + fileUploadVO.setFileSize(multipartFile.getSize()); + fileUploadVO.setFileType(FilenameUtils.getExtension(originalFileName)); + } catch (IOException e) { + if (fileTemp.exists() && fileTemp.isFile()) { + fileTemp.delete(); + } + log.error("", e); + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, "上传失败"); + } + return ResponseDTO.ok(fileUploadVO); + } + + /** + * 生成fileUrl地址 + * + * @param fileKey + * @return + */ + public String generateFileUrl(String fileKey) { + String configValue = configService.getConfigValue(ConfigKeyEnum.LOCAL_UPLOAD_URL_PREFIX); + String fileUrl = configValue + fileKey; + return fileUrl; + } + + /** + * 获取文件Url + * + * @param fileKey + * @return + */ + @Override + public ResponseDTO getFileUrl(String fileKey) { + String fileUrl = this.generateFileUrl(fileKey); + return ResponseDTO.ok(fileUrl); + } + + /** + * 文件下载 + * + * @param fileKey + * @return + */ + @Override + public ResponseDTO fileDownload(String fileKey) { + String filePath = localPath + fileKey; + File localFile = new File(filePath); + InputStream in = null; + try { + in = new FileInputStream(localFile); + // 输入流转换为字节流 + byte[] buffer = FileCopyUtils.copyToByteArray(in); + FileDownloadVO fileDownloadVO = new FileDownloadVO(); + fileDownloadVO.setData(buffer); + + FileMetadataVO fileMetadataDTO = new FileMetadataVO(); + fileMetadataDTO.setFileName(localFile.getName()); + fileMetadataDTO.setFileSize(localFile.length()); + fileMetadataDTO.setFileFormat(FilenameUtils.getExtension(localFile.getName())); + fileDownloadVO.setMetadata(fileMetadataDTO); + + return ResponseDTO.ok(fileDownloadVO); + } catch (IOException e) { + log.error("文件下载-发生异常:", e); + return ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR, "文件下载失败"); + } finally { + try { + // 关闭输入流 + if (in != null) { + in.close(); + } + } catch (IOException e) { + log.error("文件下载-发生异常:", e); + } + } + } + + @Override + public ResponseDTO delete(String fileKey) { + String filePath = localPath + fileKey; + File localFile = new File(filePath); + try { + FileUtils.forceDelete(localFile); + } catch (IOException e) { + log.error("删除本地文件失败:{}", e); + } + return ResponseDTO.ok(); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/IFileStorageService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/IFileStorageService.java new file mode 100644 index 0000000..7fd4690 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/file/service/IFileStorageService.java @@ -0,0 +1,209 @@ +package net.lab1024.sa.common.module.support.file.service; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.LocalDateTimeUtil; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileDownloadVO; +import net.lab1024.sa.common.module.support.file.domain.vo.FileUploadVO; +import org.apache.commons.io.FilenameUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.util.UUID; + +/** + * 接口 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2019年10月11日 15:34:47 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public interface IFileStorageService { + + /** + * 文件上传 + * + * @param file + * @param path + * @return + */ + ResponseDTO fileUpload(MultipartFile file, String path); + + /** + * 获取文件url + * + * @param fileKey + * @return + */ + ResponseDTO getFileUrl(String fileKey); + + /** + * 流式下载(名称为原文件) + * + * @param key + * @return + */ + ResponseDTO fileDownload(String key); + + /** + * 单个删除文件 + * 根据文件key删除 + * + * @param fileKey + * @return + */ + ResponseDTO delete(String fileKey); + + + /** + * 缓存过期秒数 + * + * @return + */ + default Long cacheExpireSecond() { + return 3600L; + } + + /** + * 生成文件名字 + * 当前年月日时分秒 +32位 uuid + 文件格式后缀 + * + * @param originalFileName + * @return String + */ + default String generateFileName(String originalFileName) { + return generateFileNameByType(FilenameUtils.getExtension(originalFileName)); + } + + /** + * 根据文件类型 生成文件名,格式如下: + * [uuid]_[日期时间]_[文件类型] + * + * @param fileType + * @return + */ + default String generateFileNameByType(String fileType) { + String uuid = UUID.randomUUID().toString().replaceAll("-", ""); + String time = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_FORMATTER); + return uuid + "_" + time + "_" + fileType; + } + + /** + * 获取文件类型 + * + * @param fileExt + * @return + */ + default String getContentType(String fileExt) { + // 文件的后缀名 + if ("bmp".equalsIgnoreCase(fileExt)) { + return "image/bmp"; + } + if ("gif".equalsIgnoreCase(fileExt)) { + return "image/gif"; + } + if ("jpeg".equalsIgnoreCase(fileExt) || "jpg".equalsIgnoreCase(fileExt)) { + return "image/jpeg"; + } + if ("png".equalsIgnoreCase(fileExt)) { + return "image/png"; + } + if ("html".equalsIgnoreCase(fileExt)) { + return "text/html"; + } + if ("txt".equalsIgnoreCase(fileExt)) { + return "text/plain"; + } + if ("vsd".equalsIgnoreCase(fileExt)) { + return "application/vnd.visio"; + } + if ("ppt".equalsIgnoreCase(fileExt) || "pptx".equalsIgnoreCase(fileExt)) { + return "application/vnd.ms-powerpoint"; + } + if ("doc".equalsIgnoreCase(fileExt) || "docx".equalsIgnoreCase(fileExt)) { + return "application/msword"; + } + if ("pdf".equalsIgnoreCase(fileExt)) { + return "application/pdf"; + } + if ("xml".equalsIgnoreCase(fileExt)) { + return "text/xml"; + } + return ""; + } + + /** + * 获取文件格式 根据 content-type + * + * @param contentType + * @return + */ + default String getFileTypeByContentType(String contentType) { + // 文件的后缀名 + if ("image/bmp".equalsIgnoreCase(contentType)) { + return "bmp"; + } + if ("image/gif".equalsIgnoreCase(contentType)) { + return "gif"; + } + if ("image/jpeg".equalsIgnoreCase(contentType) || "image/jpg".equalsIgnoreCase(contentType)) { + return "jpg"; + } + if ("image/png".equalsIgnoreCase(contentType)) { + return "png"; + } + if ("text/html".equalsIgnoreCase(contentType)) { + return "html"; + } + if ("text/plain".equalsIgnoreCase(contentType)) { + return "txt"; + } + if ("application/vnd.visio".equalsIgnoreCase(contentType)) { + return "vsd"; + } + if ("application/vnd.ms-powerpoint".equalsIgnoreCase(contentType)) { + return "pptx"; + } + if ("application/msword".equalsIgnoreCase(contentType)) { + return "docx"; + } + if ("application/pdf".equalsIgnoreCase(contentType)) { + return "pdf"; + } + if ("text/xml".equalsIgnoreCase(contentType)) { + return "xml"; + } + return ""; + } + + /** + * 根据不同的浏览器 返回对应编码的文件名称 + * + * @param fileName + * @param userAgent + * @return + */ + default String getDownloadFileNameByUA(String fileName, String userAgent) { + try { + userAgent = userAgent.toUpperCase(); + if (userAgent.indexOf("MSIE") > 0) { + // IE浏览器 + fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()); + } else if (userAgent.indexOf("EDGE") > 0) { + // WIN10浏览器 + fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()); + } else { + // 其他 + fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1); + } + } catch (UnsupportedEncodingException e) { + return null; + } + return fileName; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatRecordDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatRecordDao.java new file mode 100644 index 0000000..9859bb8 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatRecordDao.java @@ -0,0 +1,51 @@ +package net.lab1024.sa.common.module.support.heartbeat; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.heartbeat.domain.HeartBeatRecordEntity; +import net.lab1024.sa.common.module.support.heartbeat.domain.HeartBeatRecordQueryForm; +import net.lab1024.sa.common.module.support.heartbeat.domain.HeartBeatRecordVO; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogQueryForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Component +@Mapper +public interface HeartBeatRecordDao extends BaseMapper { + + /** + * 更新心跳日志 + * + * @param id + * @param heartBeatTime + */ + void updateHeartBeatTimeById(@Param("id") Long id, @Param("heartBeatTime") LocalDateTime heartBeatTime); + + /** + * 查询心跳日志 + * + * @param heartBeatRecordEntity + * @return + */ + HeartBeatRecordEntity query(HeartBeatRecordEntity heartBeatRecordEntity); + + /** + * 分页查询 + * @param heartBeatRecordQueryForm + * @return + */ + List pageQuery(Page page, @Param("query") HeartBeatRecordQueryForm heartBeatRecordQueryForm); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatRecordHandler.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatRecordHandler.java new file mode 100644 index 0000000..c666ece --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatRecordHandler.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.common.module.support.heartbeat; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.module.support.heartbeat.domain.HeartBeatRecordEntity; +import net.lab1024.sa.common.module.support.heartbeat.core.HeartBeatRecord; +import net.lab1024.sa.common.module.support.heartbeat.core.IHeartBeatRecordHandler; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Service +public class HeartBeatRecordHandler implements IHeartBeatRecordHandler { + + @Autowired + private HeartBeatRecordDao heartBeatRecordDao; + + /** + * 心跳日志处理方法 + * @param heartBeatRecord + */ + @Override + public void handler(HeartBeatRecord heartBeatRecord) { + HeartBeatRecordEntity heartBeatRecordEntity = SmartBeanUtil.copy(heartBeatRecord, HeartBeatRecordEntity.class); + HeartBeatRecordEntity heartBeatRecordOld = heartBeatRecordDao.query(heartBeatRecordEntity); + if (heartBeatRecordOld == null) { + heartBeatRecordDao.insert(heartBeatRecordEntity); + } else { + heartBeatRecordDao.updateHeartBeatTimeById(heartBeatRecordOld.getHeartBeatRecordId(), heartBeatRecordEntity.getHeartBeatTime()); + } + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatService.java new file mode 100644 index 0000000..1964b68 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/HeartBeatService.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.module.support.heartbeat; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.domain.PageParam; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.heartbeat.domain.HeartBeatRecordQueryForm; +import net.lab1024.sa.common.module.support.heartbeat.domain.HeartBeatRecordVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Service +public class HeartBeatService { + + @Autowired + private HeartBeatRecordDao heartBeatRecordDao; + + public ResponseDTO> pageQuery(HeartBeatRecordQueryForm pageParam) { + Page pageQueryInfo = SmartPageUtil.convert2PageQuery(pageParam); + List recordVOList = heartBeatRecordDao.pageQuery(pageQueryInfo,pageParam); + PageResult pageResult = SmartPageUtil.convert2PageResult(pageQueryInfo, recordVOList); + return ResponseDTO.ok(pageResult); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatManager.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatManager.java new file mode 100644 index 0000000..72973dd --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatManager.java @@ -0,0 +1,59 @@ +package net.lab1024.sa.common.module.support.heartbeat.core; + +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 心跳核心调度管理器 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class HeartBeatManager { + + private static final String THREAD_NAME_PREFIX = "sa-heart-beat"; + private static final int THREAD_COUNT = 1; + private static final long INITIAL_DELAY = 60 * 1000L; + + private ScheduledThreadPoolExecutor threadPoolExecutor; + + /** + * 服务状态持久化处理类 + */ + private IHeartBeatRecordHandler heartBeatRecordHandler; + + /** + * 调度配置信息 + */ + private long intervalMilliseconds; + + /** + * @param intervalMilliseconds 间隔执行时间(毫秒) + */ + public HeartBeatManager(Long intervalMilliseconds, + IHeartBeatRecordHandler heartBeatRecordHandler) { + this.intervalMilliseconds = intervalMilliseconds; + this.heartBeatRecordHandler = heartBeatRecordHandler; + //使用守护线程去处理 + this.threadPoolExecutor = new ScheduledThreadPoolExecutor(THREAD_COUNT, r -> { + Thread t = new Thread(r, THREAD_NAME_PREFIX); + if (!t.isDaemon()) { + t.setDaemon(true); + } + return t; + }); + // 开始心跳 + this.beginHeartBeat(); + } + + /** + * 开启心跳 + */ + private void beginHeartBeat() { + HeartBeatRunnable heartBeatRunnable = new HeartBeatRunnable(heartBeatRecordHandler); + threadPoolExecutor.scheduleWithFixedDelay(heartBeatRunnable, INITIAL_DELAY, intervalMilliseconds, TimeUnit.MILLISECONDS); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatRecord.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatRecord.java new file mode 100644 index 0000000..42698a1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatRecord.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.common.module.support.heartbeat.core; + +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 心跳记录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HeartBeatRecord { + + /** + * 项目名字 + */ + private String projectPath; + /** + * 服务器ip + */ + private String serverIp; + /** + * 进程号 + */ + private Integer processNo; + /** + * 进程开启时间 + */ + private LocalDateTime processStartTime; + /** + * 心跳当前时间 + */ + private LocalDateTime heartBeatTime; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatRunnable.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatRunnable.java new file mode 100644 index 0000000..475780f --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/HeartBeatRunnable.java @@ -0,0 +1,71 @@ +package net.lab1024.sa.common.module.support.heartbeat.core; + +import cn.hutool.core.net.NetUtil; +import org.apache.commons.lang3.StringUtils; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.List; + +/** + * 心跳线程 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class HeartBeatRunnable implements Runnable { + + /** + * 项目路径 + */ + private String projectPath; + /** + * 服务器ip(多网卡) + */ + private List serverIps; + /** + * 进程号 + */ + private Integer processNo; + /** + * 进程开启时间 + */ + private LocalDateTime processStartTime; + + private IHeartBeatRecordHandler recordHandler; + + public HeartBeatRunnable(IHeartBeatRecordHandler recordHandler) { + this.recordHandler = recordHandler; + this.initServerInfo(); + } + + /** + * 初始化心跳相关信息 + */ + private void initServerInfo(){ + RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); + this.projectPath = System.getProperty("user.dir"); + this.serverIps = new ArrayList<>(NetUtil.localIpv4s()); + this.processNo = Integer.valueOf(runtimeMXBean.getName().split("@")[0]).intValue(); + this.processStartTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(runtimeMXBean.getStartTime()), ZoneId.systemDefault()); + } + + + @Override + public void run() { + HeartBeatRecord heartBeatRecord = new HeartBeatRecord(); + heartBeatRecord.setProjectPath(this.projectPath); + heartBeatRecord.setServerIp(StringUtils.join(this.serverIps, ";")); + heartBeatRecord.setProcessNo(this.processNo); + heartBeatRecord.setProcessStartTime(this.processStartTime); + heartBeatRecord.setHeartBeatTime(LocalDateTime.now()); + recordHandler.handler(heartBeatRecord); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/IHeartBeatRecordHandler.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/IHeartBeatRecordHandler.java new file mode 100644 index 0000000..ac5fa58 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/core/IHeartBeatRecordHandler.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.common.module.support.heartbeat.core; + +/** + * 心跳处理接口 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public interface IHeartBeatRecordHandler { + + /** + * 心跳日志处理方法 + * + * @param heartBeatRecord + */ + void handler(HeartBeatRecord heartBeatRecord); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordEntity.java new file mode 100644 index 0000000..052f3d8 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordEntity.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.common.module.support.heartbeat.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.Date; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName(value = "t_heart_beat_record") +public class HeartBeatRecordEntity implements Serializable { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long heartBeatRecordId; + + /** + * 项目名字 + */ + private String projectPath; + /** + * 服务器ip + */ + private String serverIp; + /** + * 进程号 + */ + private Integer processNo; + /** + * 进程开启时间 + */ + private LocalDateTime processStartTime; + /** + * 心跳当前时间 + */ + private LocalDateTime heartBeatTime; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordQueryForm.java new file mode 100644 index 0000000..c9408bb --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordQueryForm.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.common.module.support.heartbeat.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +import java.time.LocalDate; + +/** + * 心跳记录 查询 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HeartBeatRecordQueryForm extends PageParam { + + @ApiModelProperty("关键字") + private String keywords; + + @ApiModelProperty("开始日期") + private LocalDate startDate; + + @ApiModelProperty("结束日期") + private LocalDate endDate; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordVO.java new file mode 100644 index 0000000..9f94f17 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/heartbeat/domain/HeartBeatRecordVO.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.module.support.heartbeat.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 心跳记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-01-09 20:57:24 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HeartBeatRecordVO { + + private Integer heartBeatRecordId; + + @ApiModelProperty("项目路径") + private String projectPath; + + @ApiModelProperty("服务器ip") + private String serverIp; + + @ApiModelProperty("进程号") + private Integer processNo; + + @ApiModelProperty("进程开启时间") + private Date processStartTime; + + @ApiModelProperty("心跳当前时间") + private Date heartBeatTime; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/controller/HelpDocController.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/controller/HelpDocController.java new file mode 100644 index 0000000..a1d9a62 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/controller/HelpDocController.java @@ -0,0 +1,77 @@ +package net.lab1024.sa.common.module.support.helpdoc.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.HelpDocViewRecordQueryForm; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocCatalogVO; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocDetailVO; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocVO; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocViewRecordVO; +import net.lab1024.sa.common.module.support.helpdoc.service.HelpDocCatalogService; +import net.lab1024.sa.common.module.support.helpdoc.service.HelpDocUserService; +import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.List; + +/** + * 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +//@Api(tags = SwaggerTagConst.Support.HELP_DOC, hidden = true) +@RestController +public class HelpDocController extends SupportBaseController { + + @Autowired + private HelpDocCatalogService helpDocCatalogService; + + @Autowired + private HelpDocUserService helpDocUserService; + + // --------------------- 帮助文档 【目录】 ------------------------- + + @ApiOperation("帮助文档目录-获取全部 @author 卓大") + @GetMapping("/helpDoc/helpDocCatalog/getAll") + public ResponseDTO> getAll() { + return ResponseDTO.ok(helpDocCatalogService.getAll()); + } + + // --------------------- 帮助文档 【用户】------------------------- + + @ApiOperation("【用户】帮助文档-查看详情 @author 卓大") + @GetMapping("/helpDoc/user/view/{helpDocId}") + @RepeatSubmit + public ResponseDTO view(@PathVariable Long helpDocId, HttpServletRequest request) { + return helpDocUserService.view( + SmartRequestUtil.getRequestUser(), + helpDocId); + } + + @ApiOperation("【用户】帮助文档-查询全部 @author 卓大") + @GetMapping("/helpDoc/user/queryAllHelpDocList") + @RepeatSubmit + public ResponseDTO> queryAllHelpDocList() { + return helpDocUserService.queryAllHelpDocList(); + } + + + @ApiOperation("【用户】帮助文档-查询 查看记录 @author 卓大") + @PostMapping("/helpDoc/user/queryViewRecord") + @RepeatSubmit + public ResponseDTO> queryViewRecord(@RequestBody @Valid HelpDocViewRecordQueryForm helpDocViewRecordQueryForm) { + return ResponseDTO.ok(helpDocUserService.queryViewRecord(helpDocViewRecordQueryForm)); + } +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/dao/HelpDocCatalogDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/dao/HelpDocCatalogDao.java new file mode 100644 index 0000000..68dac20 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/dao/HelpDocCatalogDao.java @@ -0,0 +1,21 @@ +package net.lab1024.sa.common.module.support.helpdoc.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.common.module.support.helpdoc.domain.entity.HelpDocCatalogEntity; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +/** + * 帮助文档目录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface HelpDocCatalogDao extends BaseMapper { + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/dao/HelpDocDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/dao/HelpDocDao.java new file mode 100644 index 0000000..cab687c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/dao/HelpDocDao.java @@ -0,0 +1,137 @@ +package net.lab1024.sa.common.module.support.helpdoc.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.helpdoc.domain.entity.HelpDocEntity; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.HelpDocQueryForm; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.HelpDocRelationForm; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.HelpDocViewRecordQueryForm; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocRelationVO; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocVO; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocViewRecordVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 帮助文档 dao + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface HelpDocDao extends BaseMapper { + + // ================================= 帮助文档【主表 t_help_doc 】 ================================= + + + /** + * 查询 全部相关文档 + * + * @return + */ + List queryAllHelpDocList(); + + /** + * 后管分页查询帮助文档 + * + * @param page + * @param queryForm + * @return + */ + List query(Page page, @Param("query") HelpDocQueryForm queryForm); + + + /** + * 更新 阅读量 + * @param helpDocId + * @param userViewCountIncrease + * @param pageViewCountIncrease + */ + void updateViewCount(@Param("helpDocId")Long helpDocId, @Param("userViewCountIncrease")Integer userViewCountIncrease,@Param("pageViewCountIncrease") Integer pageViewCountIncrease); + + + /** + * 根据目录,查询文档 + * + * @param helpDocCatalogId + * @return + */ + List queryHelpDocByCatalogId( @Param("helpDocCatalogId") Long helpDocCatalogId); + + /** + * 根据关联文档id,查询文档 + * + * @param relationId + * @return + */ + List queryHelpDocByRelationId( @Param("relationId") Long relationId); + + // ================================= 关联项目 【子表 t_help_doc_relation 】 ================================= + + /** + * 保存 关联 + * + * @param helpDocId + * @param relationList + */ + void insertRelation(@Param("helpDocId") Long helpDocId, @Param("relationList") List relationList); + + /** + * 删除关联 + * + * @param helpDocId + */ + void deleteRelation(@Param("helpDocId") Long helpDocId); + + /** + * 查询关联 + * + * @param helpDocId + */ + List queryRelationByHelpDoc(@Param("helpDocId") Long helpDocId); + + // ================================= 查看记录【子表 t_help_doc_view_record】 ================================= + + /** + * 查询某个用户的指定文档的阅读量 + * @param helpDocId + * @param userId + * @return + */ + long viewRecordCount(@Param("helpDocId")Long helpDocId, @Param("userId")Long userId); + + /** + * 查询帮助文档的 查看记录 + * @param page + * @param helpDocViewRecordQueryForm + * @return + */ + List queryViewRecordList(Page page, @Param("queryForm") HelpDocViewRecordQueryForm helpDocViewRecordQueryForm); + + /** + * 保存查看记录 + * @param helpDocId + * @param userId + * @param userName + * @param ip + * @param userAgent + */ + void insertViewRecord(@Param("helpDocId") Long helpDocId, @Param("userId") Long userId, @Param("userName") String userName, @Param("ip") String ip, @Param("userAgent") String userAgent,@Param("pageViewCount") Integer pageViewCount); + + /** + * 更新查看记录 + * @param helpDocId + * @param userId + * @param ip + * @param userAgent + */ + void updateViewRecord(@Param("helpDocId")Long helpDocId, @Param("userId")Long userId,@Param("ip") String ip, @Param("userAgent")String userAgent); + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/entity/HelpDocCatalogEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/entity/HelpDocCatalogEntity.java new file mode 100644 index 0000000..04a2afb --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/entity/HelpDocCatalogEntity.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 帮助文档的 类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_help_doc_catalog") +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class HelpDocCatalogEntity { + + @TableId(type = IdType.AUTO) + private Long helpDocCatalogId; + + /** + * 名称 + */ + private String name; + + /** + * 父id + */ + private Long parentId; + + /** + * 排序 + */ + @TableField("`sort`") + private Integer sort; + + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/entity/HelpDocEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/entity/HelpDocEntity.java new file mode 100644 index 0000000..fe3d033 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/entity/HelpDocEntity.java @@ -0,0 +1,77 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_help_doc") +public class HelpDocEntity { + + @TableId(type = IdType.AUTO) + private Long helpDocId; + + /** + * 类型 + */ + private Long helpDocCatalogId; + + /** + * 标题 + */ + private String title; + + /** + * 内容 纯文本 + */ + private String contentText; + + /** + * 内容 html + */ + private String contentHtml; + + /** + * 附件 + * 多个英文逗号分隔 + */ + private String attachment; + + /** + * 排序 + */ + @TableField("`sort`") + private Integer sort; + + /** + * 页面浏览量 + */ + private Integer pageViewCount; + + /** + * 用户浏览量 + */ + private Integer userViewCount; + + /** + * 作者 + */ + private String author; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocAddForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocAddForm.java new file mode 100644 index 0000000..116cd00 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocAddForm.java @@ -0,0 +1,57 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.form; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.json.deserializer.FileKeyVoDeserializer; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocAddForm { + + @ApiModelProperty("标题") + @NotBlank(message = "标题不能为空") + @Length(max = 200, message = "标题最多200字符") + private String title; + + @ApiModelProperty("分类") + @NotNull(message = "分类不能为空") + private Long helpDocCatalogId; + + @ApiModelProperty("纯文本内容") + @NotNull(message = "文本内容不能为空") + private String contentText; + + @ApiModelProperty("html内容") + @NotNull(message = "html内容不能为空") + private String contentHtml; + + @ApiModelProperty("附件,多个英文逗号分隔|可选") + @Length(max = 1000, message = "最多1000字符") + @JsonDeserialize(using = FileKeyVoDeserializer.class) + private String attachment; + + @ApiModelProperty("排序") + @NotNull(message = "排序不能为空") + private Integer sort; + + @ApiModelProperty("关联的集合") + private List relationList; + + @ApiModelProperty("作者") + @NotBlank(message = "作者不能为空") + private String author; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocCatalogAddForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocCatalogAddForm.java new file mode 100644 index 0000000..9e44967 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocCatalogAddForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; + +/** + * 帮助文档 目录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocCatalogAddForm { + + @ApiModelProperty("名称") + @NotBlank(message = "名称不能为空") + @Length(max = 200, message = "名称最多200字符") + private String name; + + @ApiModelProperty("父级") + private Long parentId; + + @ApiModelProperty("排序") + private Integer sort; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocCatalogUpdateForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocCatalogUpdateForm.java new file mode 100644 index 0000000..7e2f136 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocCatalogUpdateForm.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 帮助文档 目录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocCatalogUpdateForm extends HelpDocCatalogAddForm { + + @ApiModelProperty("id") + @NotNull(message = "id") + private Long helpDocCatalogId; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocQueryForm.java new file mode 100644 index 0000000..beac2c1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocQueryForm.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +import java.time.LocalDate; + +/** + * 帮助文档 分页查询 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocQueryForm extends PageParam { + + @ApiModelProperty("分类") + private Long helpDocCatalogId; + + @ApiModelProperty("标题") + private String keywords; + + @ApiModelProperty("创建-开始时间") + private LocalDate createTimeBegin; + + @ApiModelProperty("创建-截止时间") + private LocalDate createTimeEnd; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocRelationForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocRelationForm.java new file mode 100644 index 0000000..374a875 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocRelationForm.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 帮助文档 关联项目 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocRelationForm { + + @ApiModelProperty("关联名称") + @NotBlank(message = "关联名称不能为空") + private String relationName; + + @ApiModelProperty("关联id") + @NotNull(message = "关联id不能为空") + private Long relationId; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocUpdateForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocUpdateForm.java new file mode 100644 index 0000000..37f2e1a --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocUpdateForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 更新 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocUpdateForm extends HelpDocAddForm { + + @ApiModelProperty("id") + @NotNull(message = "通知id不能为空") + private Long helpDocId; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocViewRecordQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocViewRecordQueryForm.java new file mode 100644 index 0000000..fc6bebb --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/form/HelpDocViewRecordQueryForm.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.form; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +import javax.validation.constraints.NotNull; + +/** + * 查阅记录 查询 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocViewRecordQueryForm extends PageParam { + + @ApiModelProperty("帮助文档id") + @NotNull(message = "帮助文档id不能为空") + private Long helpDocId; + + @ApiModelProperty("用户id") + private Long userId; + + @ApiModelProperty("关键字") + private String keywords; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocCatalogVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocCatalogVO.java new file mode 100644 index 0000000..423bc3e --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocCatalogVO.java @@ -0,0 +1,30 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 帮助文档的 目录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocCatalogVO { + + @ApiModelProperty("帮助文档目录id") + private Long helpDocCatalogId; + + @ApiModelProperty("帮助文档目录-名称") + private String name; + + @ApiModelProperty("帮助文档目录-父级id") + private Long parentId; + + @ApiModelProperty("帮助文档目录-排序") + private Integer sort; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocDetailVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocDetailVO.java new file mode 100644 index 0000000..13efbfa --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocDetailVO.java @@ -0,0 +1,62 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 帮助文档 详情 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocDetailVO { + + @ApiModelProperty("id") + private Long helpDocId; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("分类") + private Long helpDocCatalogId; + + @ApiModelProperty("分类名称") + private Long helpDocCatalogName; + + @ApiModelProperty("纯文本内容") + private String contentText; + + @ApiModelProperty("html内容") + private String contentHtml; + + @ApiModelProperty("附件") + private String attachment; + + @ApiModelProperty("作者") + @NotBlank(message = "作者不能为空") + private String author; + + @ApiModelProperty("页面浏览量") + private Integer pageViewCount; + + @ApiModelProperty("用户浏览量") + private Integer userViewCount; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; + + @ApiModelProperty("关联项目") + private List relationList; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocRecordVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocRecordVO.java new file mode 100644 index 0000000..3eabf68 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocRecordVO.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 帮助文档 - 浏览记录 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocRecordVO { + + @ApiModelProperty("员工ID") + private Long employeeId; + + @ApiModelProperty("员工姓名") + private String employeeName; + + @ApiModelProperty("员工部门名称") + private String departmentName; + + @ApiModelProperty("查看次数") + private Integer pageViewCount; + + @ApiModelProperty("首次ip") + private String firstIp; + + @ApiModelProperty("首次用户设备等标识") + private String firstUserAgent; + + @ApiModelProperty("首次查看时间") + private LocalDateTime createTime; + + @ApiModelProperty("最后一次 ip") + private String lastIp; + + @ApiModelProperty("最后一次 用户设备等标识") + private String lastUserAgent; + + @ApiModelProperty("最后一次查看时间") + private LocalDateTime updateTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocRelationVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocRelationVO.java new file mode 100644 index 0000000..753a92e --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocRelationVO.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 帮助文档 关联项目 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocRelationVO { + + @ApiModelProperty("关联名称") + private String relationName; + + @ApiModelProperty("关联id") + private Long relationId; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocVO.java new file mode 100644 index 0000000..c668caa --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocVO.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocVO { + + @ApiModelProperty("id") + private Long helpDocId; + + @ApiModelProperty("标题") + private String title; + + @ApiModelProperty("分类") + private Long helpDocCatalogId; + + @ApiModelProperty("分类名称") + private String helpDocCatalogName; + + @ApiModelProperty("作者") + private String author; + + @ApiModelProperty("排序") + private Integer sort; + + @ApiModelProperty("页面浏览量") + private Integer pageViewCount; + + @ApiModelProperty("用户浏览量") + private Integer userViewCount; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocViewRecordVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocViewRecordVO.java new file mode 100644 index 0000000..c03cb73 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/domain/vo/HelpDocViewRecordVO.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.common.module.support.helpdoc.domain.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 帮助文档 - 浏览记录 VO + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class HelpDocViewRecordVO { + + @ApiModelProperty("ID") + private Long userId; + + @ApiModelProperty("姓名") + private String userName; + + @ApiModelProperty("查看次数") + private Integer pageViewCount; + + @ApiModelProperty("首次ip") + private String firstIp; + + @ApiModelProperty("首次用户设备等标识") + private String firstUserAgent; + + @ApiModelProperty("首次查看时间") + private LocalDateTime createTime; + + @ApiModelProperty("最后一次 ip") + private String lastIp; + + @ApiModelProperty("最后一次 用户设备等标识") + private String lastUserAgent; + + @ApiModelProperty("最后一次查看时间") + private LocalDateTime updateTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/manager/HelpDocManager.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/manager/HelpDocManager.java new file mode 100644 index 0000000..44cd84d --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/manager/HelpDocManager.java @@ -0,0 +1,60 @@ +package net.lab1024.sa.common.module.support.helpdoc.manager; + +import net.lab1024.sa.common.module.support.helpdoc.dao.HelpDocDao; +import net.lab1024.sa.common.module.support.helpdoc.domain.entity.HelpDocEntity; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.HelpDocRelationForm; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 帮助文档 manager + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class HelpDocManager { + + @Autowired + private HelpDocDao helpDocDao; + + /** + * 保存 + * + * @param helpDocEntity + * @param relationList + */ + @Transactional(rollbackFor = Throwable.class) + public void save(HelpDocEntity helpDocEntity, List relationList) { + helpDocDao.insert(helpDocEntity); + Long helpDocId = helpDocEntity.getHelpDocId(); + // 保存关联 + if (CollectionUtils.isNotEmpty(relationList)) { + helpDocDao.insertRelation(helpDocId, relationList); + } + } + + /** + * 更新 + * + * @param helpDocEntity + * @param relationList + */ + @Transactional(rollbackFor = Throwable.class) + public void update(HelpDocEntity helpDocEntity, List relationList) { + helpDocDao.updateById(helpDocEntity); + Long helpDocId = helpDocEntity.getHelpDocId(); + // 保存关联 + if (CollectionUtils.isNotEmpty(relationList)) { + helpDocDao.deleteRelation(helpDocId); + helpDocDao.insertRelation(helpDocId, relationList); + } + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocCatalogService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocCatalogService.java new file mode 100644 index 0000000..9a8ec36 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocCatalogService.java @@ -0,0 +1,115 @@ +package net.lab1024.sa.common.module.support.helpdoc.service; + +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.module.support.helpdoc.dao.HelpDocCatalogDao; +import net.lab1024.sa.common.module.support.helpdoc.dao.HelpDocDao; +import net.lab1024.sa.common.module.support.helpdoc.domain.entity.HelpDocCatalogEntity; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.HelpDocCatalogAddForm; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.HelpDocCatalogUpdateForm; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocCatalogVO; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocVO; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +/** + * 帮助文档 目录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class HelpDocCatalogService { + + @Autowired + private HelpDocCatalogDao helpDocCatalogDao; + + @Autowired + private HelpDocDao helpDocDao; + + /** + * 查询全部目录 + * + * @return + */ + public List getAll() { + return SmartBeanUtil.copyList(helpDocCatalogDao.selectList(null), HelpDocCatalogVO.class); + } + + /** + * 添加目录 + * + * @param helpDocCatalogAddForm + * @return + */ + public synchronized ResponseDTO add(HelpDocCatalogAddForm helpDocCatalogAddForm) { + List helpDocCatalogList = getAll(); + Optional exist = helpDocCatalogList.stream().filter(e -> helpDocCatalogAddForm.getName().equals(e.getName())).findFirst(); + if (exist.isPresent()) { + return ResponseDTO.userErrorParam("存在相同名称的目录了"); + } + + helpDocCatalogDao.insert(SmartBeanUtil.copy(helpDocCatalogAddForm, HelpDocCatalogEntity.class)); + return ResponseDTO.ok(); + } + + /** + * 更新目录 + * + * @param updateForm + * @return + */ + public synchronized ResponseDTO update(HelpDocCatalogUpdateForm updateForm) { + HelpDocCatalogEntity helpDocCatalogEntity = helpDocCatalogDao.selectById(updateForm.getHelpDocCatalogId()); + if (helpDocCatalogEntity == null) { + return ResponseDTO.userErrorParam("目录不存在"); + } + + List helpDocCatalogList = getAll(); + Optional exist = helpDocCatalogList.stream().filter(e -> updateForm.getName().equals(e.getName())).findFirst(); + if (exist.isPresent() && !exist.get().getHelpDocCatalogId().equals(updateForm.getHelpDocCatalogId())) { + return ResponseDTO.userErrorParam("存在相同名称的目录了"); + } + helpDocCatalogDao.updateById(SmartBeanUtil.copy(updateForm, HelpDocCatalogEntity.class)); + return ResponseDTO.ok(); + } + + /** + * 删除目录(如果有子目录、或者有帮助文档,则不能删除) + * + * @param helpDocCatalogId + * @return + */ + public synchronized ResponseDTO delete(Long helpDocCatalogId) { + if (helpDocCatalogId == null) { + return ResponseDTO.ok(); + } + + HelpDocCatalogEntity helpDocCatalogEntity = helpDocCatalogDao.selectById(helpDocCatalogId); + if (helpDocCatalogEntity == null) { + return ResponseDTO.userErrorParam("目录不存在"); + } + + //如果有子目录,则不能删除 + Optional existOptional = getAll().stream().filter(e -> helpDocCatalogId.equals(e.getParentId())).findFirst(); + if (existOptional.isPresent()) { + return ResponseDTO.userErrorParam("存在子目录:" + existOptional.get().getName()); + } + + //查询是否有帮助文档 + List helpDocVOList = helpDocDao.queryHelpDocByCatalogId(helpDocCatalogId); + if (CollectionUtils.isNotEmpty(helpDocVOList)) { + return ResponseDTO.userErrorParam("目录下存在文档,不能删除"); + } + helpDocCatalogDao.deleteById(helpDocCatalogId); + return ResponseDTO.ok(); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocService.java new file mode 100644 index 0000000..9d6ba2d --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocService.java @@ -0,0 +1,117 @@ +package net.lab1024.sa.common.module.support.helpdoc.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.helpdoc.dao.HelpDocDao; +import net.lab1024.sa.common.module.support.helpdoc.domain.entity.HelpDocEntity; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.HelpDocAddForm; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.HelpDocQueryForm; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.HelpDocUpdateForm; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocDetailVO; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocVO; +import net.lab1024.sa.common.module.support.helpdoc.manager.HelpDocManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 后台管理业务 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class HelpDocService { + + @Autowired + private HelpDocDao helpDocDao; + + @Autowired + private HelpDocManager helpDaoManager; + + + /** + * 查询 帮助文档 + * + * @param queryForm + * @return + */ + public PageResult query(HelpDocQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List list = helpDocDao.query(page, queryForm); + return SmartPageUtil.convert2PageResult(page, list); + } + + /** + * 添加 + * + * @param addForm + * @return + */ + public ResponseDTO add(HelpDocAddForm addForm) { + HelpDocEntity helpDaoEntity = SmartBeanUtil.copy(addForm, HelpDocEntity.class); + helpDaoManager.save(helpDaoEntity, addForm.getRelationList()); + return ResponseDTO.ok(); + } + + + /** + * 更新 + * + * @param updateForm + * @return + */ + public ResponseDTO update(HelpDocUpdateForm updateForm) { + // 更新 + HelpDocEntity helpDaoEntity = SmartBeanUtil.copy(updateForm, HelpDocEntity.class); + helpDaoManager.update(helpDaoEntity, updateForm.getRelationList()); + return ResponseDTO.ok(); + } + + + /** + * 删除 + * + * @param helpDocId + * @return + */ + public ResponseDTO delete(Long helpDocId) { + HelpDocEntity helpDaoEntity = helpDocDao.selectById(helpDocId); + if (helpDaoEntity != null) { + helpDocDao.deleteById(helpDocId); + } + return ResponseDTO.ok(); + } + + /** + * 获取详情 + * + * @param helpDocId + * @return + */ + public HelpDocDetailVO getDetail(Long helpDocId) { + HelpDocEntity helpDaoEntity = helpDocDao.selectById(helpDocId); + HelpDocDetailVO detail = SmartBeanUtil.copy(helpDaoEntity, HelpDocDetailVO.class); + if (detail != null) { + detail.setRelationList(helpDocDao.queryRelationByHelpDoc(helpDocId)); + } + return detail; + } + + /** + * 获取详情 + * + * @param relationId + * @return + */ + public List queryHelpDocByRelationId(Long relationId) { + return helpDocDao.queryHelpDocByRelationId(relationId); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocUserService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocUserService.java new file mode 100644 index 0000000..16830b7 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/helpdoc/service/HelpDocUserService.java @@ -0,0 +1,85 @@ +package net.lab1024.sa.common.module.support.helpdoc.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.helpdoc.dao.HelpDocDao; +import net.lab1024.sa.common.module.support.helpdoc.domain.entity.HelpDocEntity; +import net.lab1024.sa.common.module.support.helpdoc.domain.form.HelpDocViewRecordQueryForm; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocDetailVO; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocVO; +import net.lab1024.sa.common.module.support.helpdoc.domain.vo.HelpDocViewRecordVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 用户查看 帮助文档 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-20 23:11:42 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class HelpDocUserService { + + @Autowired + private HelpDocDao helpDocDao; + + + /** + * 查询全部 帮助文档 + * + * @return + */ + public ResponseDTO> queryAllHelpDocList() { + return ResponseDTO.ok(helpDocDao.queryAllHelpDocList()); + } + + + /** + * 查询我的 待查看的 帮助文档清单 + * + * @return + */ + public ResponseDTO view(RequestUser requestUser, Long helpDocId) { + HelpDocEntity helpDocEntity = helpDocDao.selectById(helpDocId); + if (helpDocEntity == null) { + return ResponseDTO.userErrorParam("帮助文档不存在"); + } + + HelpDocDetailVO helpDocDetailVO = SmartBeanUtil.copy(helpDocEntity, HelpDocDetailVO.class); + long viewCount = helpDocDao.viewRecordCount(helpDocId, requestUser.getUserId()); + if (viewCount == 0) { + helpDocDao.insertViewRecord(helpDocId, requestUser.getUserId(), requestUser.getUserName(), requestUser.getIp(), requestUser.getUserAgent(), 1); + helpDocDao.updateViewCount(helpDocId, 1, 1); + helpDocDetailVO.setPageViewCount(helpDocDetailVO.getPageViewCount() + 1); + helpDocDetailVO.setUserViewCount(helpDocDetailVO.getUserViewCount() + 1); + } else { + helpDocDao.updateViewRecord(helpDocId, requestUser.getUserId(), requestUser.getIp(), requestUser.getUserAgent()); + helpDocDao.updateViewCount(helpDocId, 0, 1); + helpDocDetailVO.setPageViewCount(helpDocDetailVO.getPageViewCount() + 1); + } + + return ResponseDTO.ok(helpDocDetailVO); + } + + + /** + * 分页查询 查看记录 + * + * @param helpDocViewRecordQueryForm + * @return + */ + public PageResult queryViewRecord(HelpDocViewRecordQueryForm helpDocViewRecordQueryForm) { + Page page = SmartPageUtil.convert2PageQuery(helpDocViewRecordQueryForm); + List noticeViewRecordVOS = helpDocDao.queryViewRecordList(page, helpDocViewRecordQueryForm); + return SmartPageUtil.convert2PageResult(page, noticeViewRecordVOS); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/DecryptData.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/DecryptData.java new file mode 100644 index 0000000..d23f329 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/DecryptData.java @@ -0,0 +1,18 @@ +package net.lab1024.sa.common.module.support.jwe; + +import lombok.Data; + +/** + * 加密数据 包装类 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021/6/29 20:49:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +class DecryptData { + + private String data; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweAspect.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweAspect.java new file mode 100644 index 0000000..7a2dbc6 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweAspect.java @@ -0,0 +1,128 @@ +package net.lab1024.sa.common.module.support.jwe; + +import cn.hutool.crypto.Mode; +import cn.hutool.crypto.Padding; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.symmetric.AES; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.core.annotation.Order; +import org.springframework.util.Base64Utils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; +import java.util.function.Function; + +/** + * 加密数据切口 + * + * @Author 1024创新实验室: 胡克 + * @Date 2020/11/25 10:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Aspect +@Order(100) +public class JweAspect { + + private static final String MD5_SALT_FORMAT = "sa_%s_salt"; + + private Function userFunction; + + public JweAspect(Function userFunction) { + this.userFunction = userFunction; + } + + @Before("@annotation(net.lab1024.sa.common.module.support.jwe.JweDecrypt)") + public void before(JoinPoint joinPoint) { + Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); + JweDecrypt annotation = method.getAnnotation(JweDecrypt.class); + if (annotation == null) { + return; + } + Object[] params = joinPoint.getArgs(); + if (params == null) { + return; + } + if (params.length == 0) { + return; + } + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + JweUserKey user = this.userFunction.apply(request); + if (user == null) { + return; + } + Boolean decryptParamFlag = params[0] instanceof DecryptData; + if (!decryptParamFlag) { + return; + } + DecryptData decryptData = (DecryptData) params[0]; + String data = decryptData.getData(); + log.info("解密前数据:{}", data); + + String key = SecureUtil.md5(String.format(MD5_SALT_FORMAT, user.getUserId())); + log.info("解密KEY数据:{}", key); + //初始化向量是16位长度 + String iv = key.substring(0, 16); + //解密 + AES aes = new AES(Mode.CTS, Padding.PKCS5Padding, key.getBytes(), iv.getBytes()); + data = aes.decryptStr(data); + log.info("解密后数据:{}", data); + //base64解码 + data = new String(Base64Utils.decodeFromString(data)); + log.info("base64解码后数据:{}", data); + decryptData.setData(data); + } + + + @AfterReturning(returning = "object", pointcut = "@annotation(net.lab1024.sa.common.module.support.jwe.JweEncrypt)") + public void afterReturning(JoinPoint joinPoint, Object object) { + Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); + JweEncrypt annotation = method.getAnnotation(JweEncrypt.class); + if (annotation == null) { + return; + } + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + JweUserKey user = this.userFunction.apply(request); + if (user == null) { + return; + } + try { + ResponseDTO responseDTO = (ResponseDTO) object; + Object data = responseDTO.getData(); + if (data == null) { + return; + } + String jsonData = JSON.toJSONString(data, SerializerFeature.DisableCircularReferenceDetect); + log.info("JSON 原数据:{}", jsonData); + //base64编码 + jsonData = Base64Utils.encodeToString(jsonData.getBytes("utf-8")); + log.info("JSON Base64数据:{}", jsonData); + //加密秘钥 + String key = SecureUtil.md5(String.format(MD5_SALT_FORMAT, user.getUserId())); + log.info("JSON MD5 KEY数据:{}", key); + //初始化向量是16位长度 + String iv = key.substring(0, 16); + //AES 加密 + AES aes = new AES(Mode.CTS, Padding.PKCS5Padding, key.getBytes(), iv.getBytes()); + data = aes.encryptBase64(jsonData); + log.info("JSON ASE 加密数据:{}", jsonData); + responseDTO.setData(jsonData); + } catch (Exception e) { + log.error(e.getMessage(),e); + return; + } + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweDecrypt.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweDecrypt.java new file mode 100644 index 0000000..5900f43 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweDecrypt.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.common.module.support.jwe; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 解密注解 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/25 20:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface JweDecrypt { +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweEncrypt.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweEncrypt.java new file mode 100644 index 0000000..e6e9394 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweEncrypt.java @@ -0,0 +1,20 @@ +package net.lab1024.sa.common.module.support.jwe; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 加密注解 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/25 20:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface JweEncrypt { +} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweUserKey.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweUserKey.java new file mode 100644 index 0000000..ce02066 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/jwe/JweUserKey.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.common.module.support.jwe; + +import lombok.Data; + +/** + * 解密用用户信息作为key + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020/11/25 20:46 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class JweUserKey { + + /** + * 用户id + */ + private Long userId; + + /** + * 用户名 + */ + private String userName; + + /** + * 扩展信息 + */ + private String extData; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogDao.java new file mode 100644 index 0000000..e7fe618 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogDao.java @@ -0,0 +1,46 @@ +package net.lab1024.sa.common.module.support.loginlog; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogEntity; +import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogQueryForm; +import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 登录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface LoginLogDao extends BaseMapper { + + /** + * 分页查询 + * + * @param page + * @param queryForm + * @return LoginLogVO + */ + List queryByPage(Page page, @Param("query") LoginLogQueryForm queryForm); + + /** + * 查询上一个登录记录 + * + * @param userId + * @param userType + * @return LoginLogVO + */ + LoginLogVO queryLastByUserId(@Param("userId") Long userId,@Param("userType") Integer userType); + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogResultEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogResultEnum.java new file mode 100644 index 0000000..2ccb750 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogResultEnum.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.common.module.support.loginlog; + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 登录类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public enum LoginLogResultEnum implements BaseEnum { + + LOGIN_SUCCESS(0, "登录成功"), + LOGIN_FAIL(1, "登录失败"), + LOGIN_OUT(2, "退出登录"); + + private Integer type; + private String desc; + + LoginLogResultEnum(Integer type, String desc) { + this.type = type; + this.desc = desc; + } + + @Override + public Integer getValue() { + return type; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogService.java new file mode 100644 index 0000000..0c6fb03 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/LoginLogService.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.common.module.support.loginlog; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogEntity; +import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogQueryForm; +import net.lab1024.sa.common.module.support.loginlog.domain.LoginLogVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 登录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +@Slf4j +public class LoginLogService { + + @Autowired + private LoginLogDao loginLogDao; + + /** + * @author 卓大 + * @description 分页查询 + */ + public ResponseDTO> queryByPage(LoginLogQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List logList = loginLogDao.queryByPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, logList); + return ResponseDTO.ok(pageResult); + } + + /** + * @author 卓大 + * @description 添加 + */ + public void log(LoginLogEntity loginLogEntity) { + try { + loginLogDao.insert(loginLogEntity); + } catch (Throwable e) { + log.error(e.getMessage(), e); + } + } + + + /** + * 查询上一个登录记录 + * + * @author 卓大 + * @description 查询上一个登录记录 + */ + public LoginLogVO queryLastByUserId(Long userId, UserTypeEnum userTypeEnum) { + return loginLogDao.queryLastByUserId(userId,userTypeEnum.getValue()); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogEntity.java new file mode 100644 index 0000000..50c785b --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogEntity.java @@ -0,0 +1,67 @@ +package net.lab1024.sa.common.module.support.loginlog.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Builder; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 登录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@TableName("t_login_log") +@Data +@Builder +public class LoginLogEntity { + + @TableId(type = IdType.AUTO) + private Long loginLogId; + + /** + * 用户id + */ + private Long userId; + + /** + * 用户类型 + */ + private Integer userType; + + /** + * 用户名 + */ + private String userName; + + /** + * 登录ip + */ + private String loginIp; + + /** + * user-agent + */ + private String userAgent; + + /** + * 备注 + */ + private String remark; + + /** + * 登录类型 + */ + private Integer loginResult; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogQueryForm.java new file mode 100644 index 0000000..92d69c1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogQueryForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.common.module.support.loginlog.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +/** + * 登录查询日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class LoginLogQueryForm extends PageParam { + + @ApiModelProperty("开始日期") + private String startDate; + + @ApiModelProperty("结束日期") + private String endDate; + + @ApiModelProperty("用户名称") + private String userName; + + @ApiModelProperty("ip") + private String ip; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogVO.java new file mode 100644 index 0000000..753dd49 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/loginlog/domain/LoginLogVO.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.common.module.support.loginlog.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; +import net.lab1024.sa.common.module.support.loginlog.LoginLogResultEnum; + +import java.time.LocalDateTime; + +/** + * 登录日志 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022/07/22 19:46:23 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class LoginLogVO { + + private Long loginLogId; + + @ApiModelProperty("用户id") + private Long userId; + + @ApiModelPropertyEnum(value = UserTypeEnum.class, desc = "用户类型") + private Integer userType; + + @ApiModelProperty("用户名") + private String userName; + + @ApiModelProperty("登录ip") + private String loginIp; + + @ApiModelProperty("user-agent") + private String userAgent; + + @ApiModelProperty("remark") + private String remark; + + @ApiModelPropertyEnum(LoginLogResultEnum.class) + private Integer loginResult; + + private LocalDateTime createTime; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/OperateLogDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/OperateLogDao.java new file mode 100644 index 0000000..be5af95 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/OperateLogDao.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.common.module.support.operatelog; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogEntity; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogQueryForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 操作日志 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface OperateLogDao extends BaseMapper { + + /** + * 分页查询 + * @param page + * @param queryForm + * @return UserOperateLogEntity + */ + List queryByPage(Page page, @Param("query") OperateLogQueryForm queryForm); + + /** + * 根据id删除 + * + * @param id + * @return + */ + void deleteById(@Param("id") Long id); + + /** + * 批量删除 + * + * @param idList + * @return + */ + void deleteByIds(@Param("idList") List idList); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/OperateLogService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/OperateLogService.java new file mode 100644 index 0000000..d3ac8bf --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/OperateLogService.java @@ -0,0 +1,57 @@ +package net.lab1024.sa.common.module.support.operatelog; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogEntity; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogQueryForm; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 操作日志 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class OperateLogService { + + @Autowired + private OperateLogDao operateLogDao; + + /** + * @author 罗伊 + * @description 分页查询 + */ + public ResponseDTO> queryByPage(OperateLogQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List logEntityList = operateLogDao.queryByPage(page, queryForm); + PageResult pageResult = SmartPageUtil.convert2PageResult(page, logEntityList, OperateLogVO.class); + return ResponseDTO.ok(pageResult); + } + + + /** + * 查询详情 + * @param operateLogId + * @return + */ + public ResponseDTO detail(Long operateLogId) { + OperateLogEntity operateLogEntity = operateLogDao.selectById(operateLogId); + if(operateLogEntity == null){ + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + OperateLogVO operateLogVO = SmartBeanUtil.copy(operateLogEntity, OperateLogVO.class); + return ResponseDTO.ok(operateLogVO); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/annoation/OperateLog.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/annoation/OperateLog.java new file mode 100644 index 0000000..f8acadf --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/annoation/OperateLog.java @@ -0,0 +1,19 @@ +package net.lab1024.sa.common.module.support.operatelog.annoation; + +import java.lang.annotation.*; + +/** + * 用户操作日志 注解 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +public @interface OperateLog { + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogAspect.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogAspect.java new file mode 100644 index 0000000..3d9da66 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogAspect.java @@ -0,0 +1,274 @@ +package net.lab1024.sa.common.module.support.operatelog.core; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.module.support.operatelog.OperateLogDao; +import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogEntity; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Method; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 操作日志记录处理,对所有OperateLog注解的Controller进行操作日志监控 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +@Aspect +public abstract class OperateLogAspect { + + private static final String pointCut = "@within(net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog)"; + + @Autowired + private ApplicationContext applicationContext; + /** + * 线程池 + */ + private ThreadPoolTaskExecutor taskExecutor; + + public abstract OperateLogConfig getOperateLogConfig(); + + public OperateLogAspect() { + this.initThread(); + } + + @Pointcut(pointCut) + public void logPointCut() { + } + + @AfterReturning(pointcut = "logPointCut()") + public void doAfterReturning(JoinPoint joinPoint) { + handleLog(joinPoint, null); + } + + @AfterThrowing(value = "logPointCut()", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Exception e) { + handleLog(joinPoint, e); + } + + /** + * 初始化线程池 + */ + private void initThread() { + OperateLogConfig config = getOperateLogConfig(); + int corePoolSize = Runtime.getRuntime().availableProcessors(); + if (null != config.getCorePoolSize()) { + corePoolSize = config.getCorePoolSize(); + } + taskExecutor = new ThreadPoolTaskExecutor(); + //线程初始化 + taskExecutor.initialize(); + // 设置核心线程数 + taskExecutor.setCorePoolSize(corePoolSize); + // 设置最大线程数 + taskExecutor.setMaxPoolSize(corePoolSize * 2); + // 设置队列容量 + taskExecutor.setQueueCapacity(1000); + // 设置线程活跃时间(秒) + taskExecutor.setKeepAliveSeconds(60); + // 设置默认线程名称 + taskExecutor.setThreadNamePrefix("smart-logs"); + // 设置拒绝策略 + taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + // 等待所有任务结束后再关闭线程池 + taskExecutor.setWaitForTasksToCompleteOnShutdown(true); + } + + protected void handleLog(final JoinPoint joinPoint, final Exception e) { + try { + OperateLog operateLog = this.getAnnotationLog(joinPoint); + if (operateLog == null) { + return; + } + this.submitLog(joinPoint, e); + } catch (Exception exp) { + log.error("保存操作日志异常:{}", exp.getMessage()); + exp.printStackTrace(); + } + } + + private OperateLog getAnnotationLog(JoinPoint joinPoint) throws Exception { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + OperateLog classAnnotation = AnnotationUtils.findAnnotation(method.getDeclaringClass(), OperateLog.class); + if (method != null) { + return classAnnotation; + } + return null; + } + + /** + * swagger API + * + * @param joinPoint + * @return + * @throws Exception + */ + private Api getApi(JoinPoint joinPoint) { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + Api classAnnotation = AnnotationUtils.findAnnotation(method.getDeclaringClass(), Api.class); + if (method != null) { + return classAnnotation; + } + return null; + } + + /** + * swagger ApiOperation + * + * @param joinPoint + * @return + * @throws Exception + */ + private ApiOperation getApiOperation(JoinPoint joinPoint) { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method method = methodSignature.getMethod(); + + if (method != null) { + return method.getAnnotation(ApiOperation.class); + } + return null; + } + + /** + * 提交存储操作日志 + * + * @param joinPoint + * @param e + * @throws Exception + */ + private void submitLog(final JoinPoint joinPoint, final Throwable e) throws Exception { + Boolean isOpen = this.isOpen(); + if (!isOpen) { + return; + } + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + Boolean filter = this.filterUrl(request.getRequestURI()); + if (filter) { + return; + } + //设置用户信息 + RequestUser user = SmartRequestUtil.getRequestUser(); + if (user == null) { + return; + } + + Object[] args = joinPoint.getArgs(); + String params = JSON.toJSONString(args); + // 设置方法名称 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + String operateMethod = className + "." + methodName; + String failReason = null; + Boolean successFlag = true; + if (e != null) { + successFlag = false; + failReason = getExceptionString(e); + } + + + OperateLogEntity operateLogEntity = + OperateLogEntity.builder() + .operateUserId(user.getUserId()) + .operateUserType(user.getUserType().getValue()) + .operateUserName(user.getUserName()) + .url(request.getRequestURI()) + .method(operateMethod) + .param(params) + .ip(user.getIp()) + .userAgent(user.getUserAgent()) + .failReason(failReason) + .successFlag(successFlag).build(); + ApiOperation apiOperation = this.getApiOperation(joinPoint); + if (apiOperation != null) { + operateLogEntity.setContent(apiOperation.value()); + } + Api api = this.getApi(joinPoint); + if (api != null) { + String[] tags = api.tags(); + operateLogEntity.setModule(StrUtil.join(",", tags)); + } + taskExecutor.execute(() -> { + this.saveLog(operateLogEntity); + }); + } + + + private String getExceptionString(Throwable e) { + StringWriter sw = new StringWriter(); + try (PrintWriter pw = new PrintWriter(sw);) { + e.printStackTrace(pw); + } + return sw.toString(); + } + + /** + * 是否开启操作日志 + * + * @return + */ + private Boolean isOpen() { + return Boolean.TRUE; + } + + /** + * 需要过滤的url + * + * @param url + * @return + */ + private Boolean filterUrl(String url) { + return Boolean.FALSE; + } + + /** + * 保存操作日志 + * + * @param operateLogEntity + * @return + */ + private Boolean saveLog(OperateLogEntity operateLogEntity) { + OperateLogConfig operateLogConfig = getOperateLogConfig(); + if (operateLogConfig.getSaveFunction() == null) { + BaseMapper mapper = applicationContext.getBean(OperateLogDao.class); + if (mapper == null) { + return false; + } + mapper.insert(operateLogEntity); + return true; + } + return operateLogConfig.getSaveFunction().apply(operateLogEntity); + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogConfig.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogConfig.java new file mode 100644 index 0000000..7bc6525 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/core/OperateLogConfig.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.module.support.operatelog.core; + +import lombok.Builder; +import lombok.Data; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogEntity; + +import java.util.function.Function; + +/** + * 配置 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@Builder +public class OperateLogConfig { + + /** + * 操作日志存储方法 + */ + private Function saveFunction; + + /** + * 核心线程数 + */ + private Integer corePoolSize; + + /** + * 队列大小 + */ + private Integer queueCapacity; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogEntity.java new file mode 100644 index 0000000..0a51993 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogEntity.java @@ -0,0 +1,106 @@ +package net.lab1024.sa.common.module.support.operatelog.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 操作记录 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("t_operate_log") +public class OperateLogEntity { + + /** + * 主键id + */ + @TableId(type = IdType.AUTO) + private Long operateLogId; + + /** + * 操作人id + */ + private Long operateUserId; + + /** + * 用户类型 + */ + private Integer operateUserType; + + /** + * 操作人名称 + */ + private String operateUserName; + /** + * 操作模块 + */ + private String module; + + /** + * 操作内容 + */ + private String content; + + /** + * 请求路径 + */ + private String url; + + /** + * 请求方法 + */ + private String method; + + /** + * 请求参数 + */ + private String param; + + /** + * 客户ip + */ + private String ip; + + /** + * user-agent + */ + private String userAgent; + + /** + * 请求结果 0失败 1成功 + */ + private Boolean successFlag; + + /** + * 失败原因 + */ + private String failReason; + + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogQueryForm.java new file mode 100644 index 0000000..2e92f11 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogQueryForm.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.common.module.support.operatelog.domain; + +import net.lab1024.sa.common.common.domain.PageParam; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 操作日志查询 表单 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class OperateLogQueryForm extends PageParam { + + + @ApiModelProperty("开始日期") + private String startDate; + + @ApiModelProperty("结束日期") + private String endDate; + + + @ApiModelProperty("用户名称") + private String userName; + + @ApiModelProperty("请求结果 false失败 true成功") + private Boolean successFlag; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogVO.java new file mode 100644 index 0000000..b71f083 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/operatelog/domain/OperateLogVO.java @@ -0,0 +1,72 @@ +package net.lab1024.sa.common.module.support.operatelog.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum; + +import java.time.LocalDateTime; +import java.util.Date; + +/** + * 操作日志信息 + * + * @Author 1024创新实验室: 罗伊 + * @Date 2021-12-08 20:48:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class OperateLogVO { + + @ApiModelProperty("主键") + private Long operateLogId; + + @ApiModelProperty("用户id") + private Long operateUserId; + + @ApiModelPropertyEnum(value = UserTypeEnum.class, desc = "用户类型") + private Integer operateUserType; + + @ApiModelProperty("用户名称") + private String operateUserName; + + @ApiModelProperty("操作模块") + private String module; + + @ApiModelProperty("操作内容") + private String content; + + @ApiModelProperty("请求路径") + private String url; + + @ApiModelProperty("请求方法") + private String method; + + @ApiModelProperty("请求参数") + private String param; + + @ApiModelProperty("客户ip") + private String ip; + + @ApiModelProperty("user-agent") + private String userAgent; + + @ApiModelProperty("请求结果 0失败 1成功") + private Boolean successFlag; + + @ApiModelProperty("失败原因") + private String failReason; + + @ApiModelProperty("更新时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime updateTime; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime createTime; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/redis/RedisService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/redis/RedisService.java new file mode 100644 index 0000000..f332192 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/redis/RedisService.java @@ -0,0 +1,222 @@ +//package net.lab1024.sa.common.module.support.redis; +// +//import com.alibaba.fastjson.JSON; +//import net.lab1024.sa.common.common.domain.SystemEnvironment; +//import net.lab1024.sa.common.common.enumeration.SystemEnvironmentEnum; +//import net.lab1024.sa.common.common.util.SmartStringUtil; +//import net.lab1024.sa.common.constant.RedisKeyConst; +//import org.slf4j.Logger; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.data.redis.core.*; +//import org.springframework.stereotype.Component; +//import org.springframework.util.CollectionUtils; +// +//import java.time.LocalDate; +//import java.time.LocalDateTime; +//import java.time.LocalTime; +//import java.time.temporal.ChronoUnit; +//import java.util.Collection; +//import java.util.List; +//import java.util.concurrent.TimeUnit; +// +///** +// * redis 一顿操作 +// * +// * @Author 1024创新实验室: 罗伊 +// * @Date 2020/8/25 21:57 +// * @Wechat zhuoda1024 +// * @Email lab1024@163.com +// * @Copyright 1024创新实验室 ( https://1024lab.net ) +// */ +////@Component +//public class RedisService { +// +// private static final Logger log = org.slf4j.LoggerFactory.getLogger(RedisService.class); +// +// @Autowired +// private StringRedisTemplate stringRedisTemplate; +// +// @Autowired +// private RedisTemplate redisTemplate; +// +// @Autowired +// private ValueOperations redisValueOperations; +// +// @Autowired +// private HashOperations redisHashOperations; +// +// @Autowired +// private ListOperations redisListOperations; +// +// @Autowired +// private SetOperations redisSetOperations; +// +// @Autowired +// private SystemEnvironment systemEnvironment; +// +// +// /** +// * 生成redis key +// * @param prefix +// * @param key +// * @return +// */ +// public String generateRedisKey(String prefix, String key) { +// SystemEnvironmentEnum currentEnvironment = systemEnvironment.getCurrentEnvironment(); +// return systemEnvironment.getProjectName() + RedisKeyConst.SEPARATOR + currentEnvironment.getValue() + RedisKeyConst.SEPARATOR + prefix + key; +// } +// +// /** +// * redis key 解析成真实的内容 +// * @param redisKey +// * @return +// */ +// public static String redisKeyParse(String redisKey) { +// if(SmartStringUtil.isBlank(redisKey)){ +// return ""; +// } +// int index = redisKey.lastIndexOf(RedisKeyConst.SEPARATOR); +// if(index < 1){ +// return redisKey; +// } +// return redisKey.substring(index); +// } +// +// public boolean getLock(String key, long expire) { +// return redisValueOperations.setIfAbsent(key, String.valueOf(System.currentTimeMillis()), expire, TimeUnit.MILLISECONDS); +// } +// +// public void unLock(String key) { +// redisValueOperations.getOperations().delete(key); +// } +// +// /** +// * 指定缓存失效时间 +// * +// * @param key 键 +// * @param time 时间(秒) +// * @return +// */ +// public boolean expire(String key, long time) { +// return redisTemplate.expire(key, time, TimeUnit.SECONDS); +// } +// +// /** +// * 获取当天剩余的秒数 +// * +// * @return +// */ +// public static long currentDaySecond() { +// return ChronoUnit.SECONDS.between(LocalDateTime.now(), LocalDateTime.of(LocalDate.now(), LocalTime.MAX)); +// } +// +// /** +// * 根据key 获取过期时间 +// * +// * @param key 键 不能为null +// * @return 时间(秒) 返回0代表为永久有效 +// */ +// public long getExpire(String key) { +// return redisTemplate.getExpire(key, TimeUnit.SECONDS); +// } +// +// /** +// * 判断key是否存在 +// * +// * @param key 键 +// * @return true 存在 false不存在 +// */ +// public boolean hasKey(String key) { +// return redisTemplate.hasKey(key); +// } +// +// /** +// * 删除缓存 +// * +// * @param key 可以传一个值 或多个 +// */ +// @SuppressWarnings("unchecked") +// public void delete(String... key) { +// if (key != null && key.length > 0) { +// if (key.length == 1) { +// redisTemplate.delete(key[0]); +// } else { +// redisTemplate.delete((Collection) CollectionUtils.arrayToList(key)); +// } +// } +// } +// +// /** +// * 删除缓存 +// * +// * @param keyList +// */ +// public void delete(List keyList) { +// if (CollectionUtils.isEmpty(keyList)) { +// return; +// } +// redisTemplate.delete(keyList); +// } +// +// //============================String============================= +// +// /** +// * 普通缓存获取 +// * +// * @param key 键 +// * @return 值 +// */ +// public String get(String key) { +// return key == null ? null : redisValueOperations.get(key); +// } +// +// public T getObject(String key, Class clazz) { +// Object json = this.get(key); +// if (json == null) { +// return null; +// } +// T obj = JSON.parseObject(json.toString(), clazz); +// return obj; +// } +// +// +// /** +// * 普通缓存放入 +// */ +// public void set(String key, String value) { +// redisValueOperations.set(key, value); +// } +// public void set(Object key, Object value) { +// String jsonString = JSON.toJSONString(value); +// redisValueOperations.set(key.toString(), jsonString); +// } +// +// /** +// * 普通缓存放入 +// */ +// public void set(String key, String value, long second) { +// redisValueOperations.set(key, value, second, TimeUnit.SECONDS); +// } +// +// /** +// * 普通缓存放入并设置时间 +// */ +// public void set(Object key, Object value, long time) { +// String jsonString = JSON.toJSONString(value); +// if (time > 0) { +// redisValueOperations.set(key.toString(), jsonString, time, TimeUnit.SECONDS); +// } else { +// set(key.toString(), jsonString); +// } +// } +// +// //============================ map ============================= +// public void mset(String key, String hashKey, Object value) { +// redisHashOperations.put(key, hashKey, value); +// } +// +// public Object mget(String key, String hashKey) { +// return redisHashOperations.get(key, hashKey); +// } +// +//} \ No newline at end of file diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/ReloadCommand.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/ReloadCommand.java new file mode 100644 index 0000000..ad039f3 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/ReloadCommand.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.common.module.support.reload; + +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.module.support.reload.dao.ReloadItemDao; +import net.lab1024.sa.common.module.support.reload.dao.ReloadResultDao; +import net.lab1024.sa.common.module.support.reload.core.AbstractSmartReloadCommand; +import net.lab1024.sa.common.module.support.reload.core.domain.SmartReloadItem; +import net.lab1024.sa.common.module.support.reload.core.domain.SmartReloadResult; +import net.lab1024.sa.common.module.support.reload.domain.ReloadItemEntity; +import net.lab1024.sa.common.module.support.reload.domain.ReloadResultEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * reload 操作 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Component +public class ReloadCommand extends AbstractSmartReloadCommand { + + @Autowired + private ReloadItemDao reloadItemDao; + + @Autowired + private ReloadResultDao reloadResultDao; + + /** + * 读取数据库中SmartReload项 + * + * @return List + */ + @Override + public List readReloadItem() { + List reloadItemEntityList = reloadItemDao.selectList(null); + return SmartBeanUtil.copyList(reloadItemEntityList, SmartReloadItem.class); + } + + + /** + * 保存reload结果 + * + * @param smartReloadResult + */ + @Override + public void handleReloadResult(SmartReloadResult smartReloadResult) { + ReloadResultEntity reloadResultEntity = SmartBeanUtil.copy(smartReloadResult, ReloadResultEntity.class); + reloadResultDao.insert(reloadResultEntity); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/ReloadService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/ReloadService.java new file mode 100644 index 0000000..9737f19 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/ReloadService.java @@ -0,0 +1,68 @@ +package net.lab1024.sa.common.module.support.reload; + +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.reload.dao.ReloadItemDao; +import net.lab1024.sa.common.module.support.reload.dao.ReloadResultDao; +import net.lab1024.sa.common.module.support.reload.domain.ReloadForm; +import net.lab1024.sa.common.module.support.reload.domain.ReloadItemEntity; +import net.lab1024.sa.common.module.support.reload.domain.ReloadItemVO; +import net.lab1024.sa.common.module.support.reload.domain.ReloadResultVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * reload (内存热加载、钩子等) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class ReloadService { + + @Autowired + private ReloadItemDao reloadItemDao; + + @Autowired + private ReloadResultDao reloadResultDao; + + /** + * 查询 + * + * @return + */ + public ResponseDTO> query() { + List list = reloadItemDao.query(); + return ResponseDTO.ok(list); + } + + public ResponseDTO> queryReloadItemResult(String tag) { + List reloadResultList = reloadResultDao.query(tag); + return ResponseDTO.ok(reloadResultList); + } + + + /** + * 通过标签更新标识符 + * + * @param reloadForm + * @return + */ + public ResponseDTO updateByTag(ReloadForm reloadForm) { + ReloadItemEntity reloadItemEntity = reloadItemDao.selectById(reloadForm.getTag()); + if (null == reloadItemEntity) { + return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST); + } + reloadItemEntity.setIdentification(reloadForm.getIdentification()); + reloadItemEntity.setUpdateTime(LocalDateTime.now()); + reloadItemEntity.setArgs(reloadForm.getArgs()); + reloadItemDao.updateById(reloadItemEntity); + return ResponseDTO.ok(); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/AbstractSmartReloadCommand.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/AbstractSmartReloadCommand.java new file mode 100644 index 0000000..8479c60 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/AbstractSmartReloadCommand.java @@ -0,0 +1,96 @@ +package net.lab1024.sa.common.module.support.reload.core; + + +import net.lab1024.sa.common.module.support.reload.core.domain.SmartReloadItem; +import net.lab1024.sa.common.module.support.reload.core.domain.SmartReloadObject; +import net.lab1024.sa.common.module.support.reload.core.domain.SmartReloadResult; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 检测是否 Reload 的类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public abstract class AbstractSmartReloadCommand { + + /** + * 当前ReloadItem的存储器 + */ + private ConcurrentHashMap tagIdentifierMap = new ConcurrentHashMap<>(); + + private SmartReloadManager smartReloadManager; + + /** + * @return + */ + public void setReloadManager(SmartReloadManager smartReloadManager) { + this.smartReloadManager = smartReloadManager; + } + + public void init() { + List smartReloadItems = this.readReloadItem(); + if (smartReloadItems != null) { + for (SmartReloadItem smartReloadItem : smartReloadItems) { + tagIdentifierMap.put(smartReloadItem.getTag(), smartReloadItem.getIdentification()); + } + } + } + + + /** + * 该方法返回一个List:
+ * ReloadItem对象的tagIdentify为:该tag的 状态(状态其实就是个字符串,如果该字符串跟上次有变化则进行reload操作)
+ * ReloadItem对象的args为: reload操作需要的参数

+ * + * @return List + */ + public abstract List readReloadItem(); + + /** + * 处理Reload结果 + * + * @param smartReloadResult + */ + public abstract void handleReloadResult(SmartReloadResult smartReloadResult); + + + /** + * 获取本地缓存tag标识 + * + * @return + */ + public ConcurrentHashMap getTagIdentifierMap() { + return tagIdentifierMap; + } + + /** + * 设置新的缓存标识 + * + * @param tag + * @param identification + */ + public void putIdentifierMap(String tag, String identification) { + tagIdentifierMap.put(tag, identification); + } + + + /** + * 获取重载对象 + * + * @return + */ + public SmartReloadObject reloadObject(String tag) { + if (this.smartReloadManager == null) { + return null; + } + Map reloadObjectMap = smartReloadManager.reloadObjectMap(); + return reloadObjectMap.get(tag); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/SmartReloadManager.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/SmartReloadManager.java new file mode 100644 index 0000000..a3aad41 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/SmartReloadManager.java @@ -0,0 +1,97 @@ +package net.lab1024.sa.common.module.support.reload.core; + + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.module.support.reload.core.annoation.SmartReload; +import net.lab1024.sa.common.module.support.reload.core.domain.SmartReloadObject; +import net.lab1024.sa.common.module.support.reload.core.thread.SmartReloadRunnable; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Method; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * SmartReloadManager 管理器 + *

+ * 可以在此类中添加 检测任务 以及注册 处理程序 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +public class SmartReloadManager implements BeanPostProcessor { + + private static final String THREAD_NAME_PREFIX = "smart-admin-reload"; + private static final int THREAD_COUNT = 1; + + private Map reloadObjectMap = new ConcurrentHashMap<>(); + + private ScheduledThreadPoolExecutor threadPoolExecutor; + + public SmartReloadManager(AbstractSmartReloadCommand reloadCommand, int intervalSeconds) { + this.threadPoolExecutor = new ScheduledThreadPoolExecutor(THREAD_COUNT, r -> { + Thread t = new Thread(r, THREAD_NAME_PREFIX); + if (!t.isDaemon()) { + t.setDaemon(true); + } + return t; + }); + this.threadPoolExecutor.scheduleWithFixedDelay(new SmartReloadRunnable(reloadCommand), 10, intervalSeconds, TimeUnit.SECONDS); + reloadCommand.setReloadManager(this); + } + + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + Method[] methods = ReflectionUtils.getAllDeclaredMethods(bean.getClass()); + if (methods == null) { + return bean; + } + for (Method method : methods) { + SmartReload smartReload = method.getAnnotation(SmartReload.class); + if (smartReload == null) { + continue; + } + int paramCount = method.getParameterCount(); + if (paramCount > 1) { + log.error("<> register tag reload : " + smartReload.value() + " , param count cannot greater than one !"); + continue; + } + String reloadTag = smartReload.value(); + this.register(reloadTag, new SmartReloadObject(bean, method)); + } + return bean; + } + + /** + * 注册reload + * + * @param tag + * @param smartReloadObject + */ + private void register(String tag, SmartReloadObject smartReloadObject) { + if (reloadObjectMap.containsKey(tag)) { + log.error("<> register duplicated tag reload : " + tag + " , and it will be cover!"); + } + reloadObjectMap.put(tag, smartReloadObject); + } + + /** + * 获取重载对象 + * + * @return + */ + public Map reloadObjectMap() { + return this.reloadObjectMap; + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/annoation/SmartReload.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/annoation/SmartReload.java new file mode 100644 index 0000000..d22f119 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/annoation/SmartReload.java @@ -0,0 +1,22 @@ +package net.lab1024.sa.common.module.support.reload.core.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 定义 SmartReload 注解 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface SmartReload { + + String value(); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadItem.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadItem.java new file mode 100644 index 0000000..3820d9d --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadItem.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.common.module.support.reload.core.domain; + +import lombok.Data; + +/** + * reload项目 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class SmartReloadItem { + + /** + * 项名称 + */ + private String tag; + + /** + * 参数 + */ + private String args; + + /** + * 标识 + */ + private String identification; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadObject.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadObject.java new file mode 100644 index 0000000..8242a07 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadObject.java @@ -0,0 +1,32 @@ +package net.lab1024.sa.common.module.support.reload.core.domain; + +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.lang.reflect.Method; + +/** + * Reload 处理程序的实现方法,用于包装以注解 SmartReload 实现的处理类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@AllArgsConstructor +public class SmartReloadObject { + + /** + * 方法对应的实例化对象 + */ + private Object reloadObject; + + /** + * 重新加载执行的方法 + */ + private Method method; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadResult.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadResult.java new file mode 100644 index 0000000..58278a7 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/domain/SmartReloadResult.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.common.module.support.reload.core.domain; + +import lombok.Data; + +/** + * t_reload_result 表 实体类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class SmartReloadResult { + + /** + * 项名称 + */ + private String tag; + + /** + * 参数 + */ + private String args; + + /** + * 标识 + */ + private String identification; + + /** + * 处理结果 + */ + private boolean result; + + /** + * 异常说明 + */ + private String exception; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/thread/SmartReloadRunnable.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/thread/SmartReloadRunnable.java new file mode 100644 index 0000000..be88f8b --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/core/thread/SmartReloadRunnable.java @@ -0,0 +1,120 @@ +package net.lab1024.sa.common.module.support.reload.core.thread; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.module.support.reload.core.AbstractSmartReloadCommand; +import net.lab1024.sa.common.module.support.reload.core.domain.SmartReloadItem; +import net.lab1024.sa.common.module.support.reload.core.domain.SmartReloadObject; +import net.lab1024.sa.common.module.support.reload.core.domain.SmartReloadResult; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Method; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * reload 线程 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +public class SmartReloadRunnable implements Runnable { + + private AbstractSmartReloadCommand abstractSmartReloadCommand; + + private boolean isInit = false; + + public SmartReloadRunnable(AbstractSmartReloadCommand abstractSmartReloadCommand) { + this.abstractSmartReloadCommand = abstractSmartReloadCommand; + } + + @Override + public void run() { + try { + this.doTask(); + } catch (Throwable e) { + log.error("", e); + } + } + + /** + * 检测Identifier变化,执行reload + */ + private void doTask() { + if (!isInit) { + this.abstractSmartReloadCommand.init(); + isInit = true; + return; + } + + List smartReloadItemList = this.abstractSmartReloadCommand.readReloadItem(); + ConcurrentHashMap tagIdentifierMap = this.abstractSmartReloadCommand.getTagIdentifierMap(); + for (SmartReloadItem smartReloadItem : smartReloadItemList) { + String tag = smartReloadItem.getTag(); + String tagIdentifier = smartReloadItem.getIdentification(); + String preTagChangeIdentifier = tagIdentifierMap.get(tag); + // 数据不一致 + if (preTagChangeIdentifier == null || !preTagChangeIdentifier.equals(tagIdentifier)) { + this.abstractSmartReloadCommand.putIdentifierMap(tag, tagIdentifier); + // 执行重新加载此项的动作 + SmartReloadResult smartReloadResult = this.doReload(smartReloadItem); + this.abstractSmartReloadCommand.handleReloadResult(smartReloadResult); + } + } + } + + /** + * 方法调用 + * + * @param smartReloadItem + * @return + */ + private SmartReloadResult doReload(SmartReloadItem smartReloadItem) { + SmartReloadResult result = new SmartReloadResult(); + SmartReloadObject smartReloadObject = this.abstractSmartReloadCommand.reloadObject(smartReloadItem.getTag()); + try { + if (smartReloadObject == null) { + result.setResult(false); + result.setException("不能从系统中找到对应的tag:" + smartReloadItem.getTag()); + return result; + } + + Method method = smartReloadObject.getMethod(); + if (method == null) { + result.setResult(false); + result.setException("reload方法不存在"); + return result; + } + + result.setTag(smartReloadItem.getTag()); + result.setArgs(smartReloadItem.getArgs()); + result.setIdentification(smartReloadItem.getIdentification()); + result.setResult(true); + int paramCount = method.getParameterCount(); + if (paramCount > 1) { + result.setResult(false); + result.setException("reload方法" + method.getName() + "参数太多"); + return result; + } + + if (paramCount == 0) { + method.invoke(smartReloadObject.getReloadObject()); + } else { + method.invoke(smartReloadObject.getReloadObject(), smartReloadItem.getArgs()); + } + } catch (Throwable throwable) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + throwable.printStackTrace(pw); + + result.setResult(false); + result.setException(throwable.toString()); + } + return result; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/dao/ReloadItemDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/dao/ReloadItemDao.java new file mode 100644 index 0000000..d063ba5 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/dao/ReloadItemDao.java @@ -0,0 +1,25 @@ +package net.lab1024.sa.common.module.support.reload.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.common.module.support.reload.domain.ReloadItemEntity; +import net.lab1024.sa.common.module.support.reload.domain.ReloadItemVO; +import org.apache.ibatis.annotations.Mapper; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * t_reload_item 数据表dao + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Component +@Mapper +public interface ReloadItemDao extends BaseMapper { + + List query(); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/dao/ReloadResultDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/dao/ReloadResultDao.java new file mode 100644 index 0000000..298100a --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/dao/ReloadResultDao.java @@ -0,0 +1,26 @@ +package net.lab1024.sa.common.module.support.reload.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.common.module.support.reload.domain.ReloadResultEntity; +import net.lab1024.sa.common.module.support.reload.domain.ReloadResultVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * t_reload_result 数据表dao + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Component +@Mapper +public interface ReloadResultDao extends BaseMapper { + + List query(@Param("tag") String tag); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadForm.java new file mode 100644 index 0000000..4591312 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadForm.java @@ -0,0 +1,31 @@ +package net.lab1024.sa.common.module.support.reload.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * reload (内存热加载、钩子等) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class ReloadForm { + + @ApiModelProperty("标签") + @NotBlank(message = "标签不能为空") + private String tag; + + @ApiModelProperty("状态标识") + @NotBlank(message = "状态标识不能为空") + private String identification; + + @ApiModelProperty("参数") + private String args; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadItemEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadItemEntity.java new file mode 100644 index 0000000..54b0113 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadItemEntity.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.common.module.support.reload.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * t_reload_item 数据表 实体类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_reload_item") +public class ReloadItemEntity { + + /** + * 加载项标签 + */ + @TableId(type = IdType.INPUT) + private String tag; + + /** + * 参数 + */ + private String args; + + /** + * 运行标识 + */ + private String identification; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadItemVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadItemVO.java new file mode 100644 index 0000000..b21b8e6 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadItemVO.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.common.module.support.reload.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * reload (内存热加载、钩子等) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class ReloadItemVO { + + @ApiModelProperty("加载项标签") + private String tag; + + @ApiModelProperty("参数") + private String args; + + @ApiModelProperty("运行标识") + private String identification; + + @ApiModelProperty("更新时间") + private LocalDateTime updateTime; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadResultEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadResultEntity.java new file mode 100644 index 0000000..004156d --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadResultEntity.java @@ -0,0 +1,53 @@ +package net.lab1024.sa.common.module.support.reload.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * reload结果
+ * t_reload_result 数据表 实体类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_reload_result") +public class ReloadResultEntity { + + /** + * 加载项标签 + */ + private String tag; + + /** + * 运行标识 + */ + private String identification; + + /** + * 参数 + */ + private String args; + + /** + * 运行结果 + */ + private Boolean result; + + /** + * 异常 + */ + private String exception; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadResultVO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadResultVO.java new file mode 100644 index 0000000..d7d6883 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/reload/domain/ReloadResultVO.java @@ -0,0 +1,34 @@ +package net.lab1024.sa.common.module.support.reload.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * reload结果 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2015-03-02 19:11:52 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class ReloadResultVO { + + @ApiModelProperty("加载项标签") + private String tag; + + @ApiModelProperty("参数") + private String args; + + @ApiModelProperty("运行结果") + private Boolean result; + + @ApiModelProperty("异常") + private String exception; + + @ApiModelProperty("创建时间") + private LocalDateTime createTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/RepeatSubmitAspect.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/RepeatSubmitAspect.java new file mode 100644 index 0000000..bba00d9 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/RepeatSubmitAspect.java @@ -0,0 +1,90 @@ +package net.lab1024.sa.common.module.support.repeatsubmit; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.code.UserErrorCode; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; +import net.lab1024.sa.common.module.support.repeatsubmit.ticket.AbstractRepeatSubmitTicket; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.lang.reflect.Method; + +/** + * 重复提交 aop切口 + * + * @Author 1024创新实验室: 胡克 + * @Date 2020-11-25 20:56:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Aspect +@Slf4j +public class RepeatSubmitAspect { + + private AbstractRepeatSubmitTicket repeatSubmitTicket; + + /** + * 获取凭证信息 + * rep + * + * @param repeatSubmitTicket + */ + public RepeatSubmitAspect(AbstractRepeatSubmitTicket repeatSubmitTicket) { + this.repeatSubmitTicket = repeatSubmitTicket; + } + + /** + * 定义切入点 + * + * @param point + * @return + * @throws Throwable + */ + @Around("@annotation(net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit)") + public Object around(ProceedingJoinPoint point) throws Throwable { + + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + String ticketToken = attributes.getRequest().getServletPath(); + String ticket = this.repeatSubmitTicket.getTicket(ticketToken); + if (StringUtils.isEmpty(ticket)) { + return point.proceed(); + } + Long timeStamp = this.repeatSubmitTicket.getTicketTimestamp(ticket); + if (timeStamp != null) { + Method method = ((MethodSignature) point.getSignature()).getMethod(); + RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); + + // 说明注解去掉了 + if (annotation != null) { + return point.proceed(); + } + + int interval = Math.min(annotation.value(), RepeatSubmit.MAX_INTERVAL); + if (System.currentTimeMillis() < timeStamp + interval) { + // 提交频繁 + return ResponseDTO.error(UserErrorCode.REPEAT_SUBMIT); + } + + } + Object obj = null; + try { + // 先给 ticket 设置在执行中 + this.repeatSubmitTicket.putTicket(ticket); + obj = point.proceed(); + } catch (Throwable throwable) { + log.error("", throwable); + throw throwable; + } finally { + this.repeatSubmitTicket.removeTicket(ticket); + } + return obj; + } + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/annoation/RepeatSubmit.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/annoation/RepeatSubmit.java new file mode 100644 index 0000000..aed0538 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/annoation/RepeatSubmit.java @@ -0,0 +1,33 @@ +package net.lab1024.sa.common.module.support.repeatsubmit.annoation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 标记 需要防止重复提交 的注解
+ * 单位:毫秒 + * + * @Author 1024创新实验室: 胡克 + * @Date 2020-11-25 20:56:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface RepeatSubmit { + + /** + * 重复提交间隔时间/毫秒 + * + * @return + */ + int value() default 300; + + /** + * 最长间隔30s + */ + int MAX_INTERVAL = 30000; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/AbstractRepeatSubmitTicket.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/AbstractRepeatSubmitTicket.java new file mode 100644 index 0000000..fd6d775 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/AbstractRepeatSubmitTicket.java @@ -0,0 +1,56 @@ +package net.lab1024.sa.common.module.support.repeatsubmit.ticket; + +import java.util.function.Function; + +/** + * 凭证(用于校验重复提交的东西) + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020-11-25 20:56:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public abstract class AbstractRepeatSubmitTicket { + + private Function ticketFunction; + + + public AbstractRepeatSubmitTicket(Function ticketFunction) { + this.ticketFunction = ticketFunction; + } + + + /** + * 获取凭证 + * + * @param ticketToken + * @return + */ + public String getTicket(String ticketToken) { + return this.ticketFunction.apply(ticketToken); + } + + /** + * 获取凭证 时间戳 + * + * @param ticket + * @return + */ + public abstract Long getTicketTimestamp(String ticket); + + + /** + * 设置本次请求时间 + * + * @param ticket + */ + public abstract void putTicket(String ticket); + + /** + * 移除凭证 + * + * @param ticket + */ + public abstract void removeTicket(String ticket); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/RepeatSubmitCaffeineTicket.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/RepeatSubmitCaffeineTicket.java new file mode 100644 index 0000000..43fc6f1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/RepeatSubmitCaffeineTicket.java @@ -0,0 +1,50 @@ +package net.lab1024.sa.common.module.support.repeatsubmit.ticket; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; + +import java.util.concurrent.TimeUnit; +import java.util.function.Function; + +/** + * 凭证(内存实现) + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020-11-25 20:56:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class RepeatSubmitCaffeineTicket extends AbstractRepeatSubmitTicket { + + /** + * 限制缓存最大数量 超过后先放入的会自动移除 + * 默认缓存时间 + * 初始大小为:100万 + */ + private static Cache cache = Caffeine.newBuilder() + .maximumSize(10000) + .expireAfterWrite(RepeatSubmit.MAX_INTERVAL, TimeUnit.MILLISECONDS).build(); + + + public RepeatSubmitCaffeineTicket(Function ticketFunction) { + super(ticketFunction); + } + + @Override + public Long getTicketTimestamp(String ticket) { + return cache.getIfPresent(ticket); + } + + + @Override + public void putTicket(String ticket) { + cache.put(ticket, System.currentTimeMillis()); + } + + @Override + public void removeTicket(String ticket) { + cache.invalidate(ticket); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/RepeatSubmitRedisTicket.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/RepeatSubmitRedisTicket.java new file mode 100644 index 0000000..806b732 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/repeatsubmit/ticket/RepeatSubmitRedisTicket.java @@ -0,0 +1,48 @@ +package net.lab1024.sa.common.module.support.repeatsubmit.ticket; + +import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; +import org.springframework.data.redis.core.ValueOperations; + +import java.util.concurrent.TimeUnit; +import java.util.function.Function; + +/** + * 凭证(redis实现) + * + * @Author 1024创新实验室: 罗伊 + * @Date 2020-11-25 20:56:58 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class RepeatSubmitRedisTicket extends AbstractRepeatSubmitTicket { + + private ValueOperations redisValueOperations; + + public RepeatSubmitRedisTicket(ValueOperations redisValueOperations, + Function ticketFunction) { + super(ticketFunction); + this.redisValueOperations = redisValueOperations; + } + + @Override + public Long getTicketTimestamp(String ticket) { + Long timeStamp = System.currentTimeMillis(); + boolean setFlag = redisValueOperations.setIfAbsent(ticket, String.valueOf(timeStamp), RepeatSubmit.MAX_INTERVAL, TimeUnit.MILLISECONDS); + if (!setFlag) { + timeStamp = Long.valueOf(redisValueOperations.get(ticket)); + } + return timeStamp; + } + + @Override + public void putTicket(String ticket) { + redisValueOperations.getOperations().delete(ticket); + this.getTicketTimestamp(ticket); + } + + @Override + public void removeTicket(String ticket) { + redisValueOperations.getOperations().delete(ticket); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/constant/SerialNumberIdEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/constant/SerialNumberIdEnum.java new file mode 100644 index 0000000..72eb858 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/constant/SerialNumberIdEnum.java @@ -0,0 +1,42 @@ +package net.lab1024.sa.common.module.support.serialnumber.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 单据序列号 枚举 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@AllArgsConstructor +@Getter +public enum SerialNumberIdEnum implements BaseEnum { + + ORDER(1, "订单id"), + + CONTRACT(2, "合同id"), + + ; + + private final Integer serialNumberId; + + private final String desc; + + @Override + public Integer getValue() { + return serialNumberId; + } + + @Override + public String toString() { + return "SerialNumberIdEnum{" + + "serialNumberId=" + serialNumberId + + ", desc='" + desc + '\'' + + '}'; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/constant/SerialNumberRuleTypeEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/constant/SerialNumberRuleTypeEnum.java new file mode 100644 index 0000000..5fc0855 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/constant/SerialNumberRuleTypeEnum.java @@ -0,0 +1,44 @@ +package net.lab1024.sa.common.module.support.serialnumber.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.constant.StringConst; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 单据序列号 周期 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@AllArgsConstructor +@Getter +public enum SerialNumberRuleTypeEnum implements BaseEnum { + /** + * 没有周期 + */ + NONE(StringConst.EMPTY, "", "没有周期"), + /** + * 年周期 + */ + YEAR("[yyyy]", "\\[yyyy\\]", "年"), + /** + * 月周期 + */ + MONTH("[mm]", "\\[mm\\]", "年月"), + /** + * 日周期 + */ + DAY("[dd]", "\\[dd\\]", "年月日"); + + private final String value; + + private final String regex; + + private final String desc; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/dao/SerialNumberDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/dao/SerialNumberDao.java new file mode 100644 index 0000000..50d32b6 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/dao/SerialNumberDao.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.common.module.support.serialnumber.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +/** + * 单据序列号 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface SerialNumberDao extends BaseMapper { + + /** + * 排他锁查询 + * + * @param serialNumberId + * @return + */ + SerialNumberEntity selectForUpdate(@Param("serialNumberId") Integer serialNumberId); + + /** + * 更新上一次的 数值和时间 + * + * @param serialNumberId + * @param lastNumber + * @param lastTime + */ + void updateLastNumberAndTime(@Param("serialNumberId") Integer serialNumberId, @Param("lastNumber") Long lastNumber, @Param("lastTime") LocalDateTime lastTime); + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/dao/SerialNumberRecordDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/dao/SerialNumberRecordDao.java new file mode 100644 index 0000000..7d66a46 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/dao/SerialNumberRecordDao.java @@ -0,0 +1,55 @@ +package net.lab1024.sa.common.module.support.serialnumber.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberRecordEntity; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberRecordQueryForm; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; +import java.util.List; + +/** + * 单据序列号 生成的记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +@Component +public interface SerialNumberRecordDao extends BaseMapper { + + /** + * 根据 id和日期 查询 记录id + * + * @param serialNumberId + * @param recordDate + * @return + */ + Long selectRecordIdBySerialNumberIdAndDate(@Param("serialNumberId") Integer serialNumberId, @Param("recordDate") String recordDate); + + /** + * 更新记录 + * + * @param serialNumberId + * @param recordDate + * @param lastNumber + * @param count + * @return + */ + Long updateRecord(@Param("serialNumberId") Integer serialNumberId, @Param("recordDate") LocalDate recordDate, @Param("lastNumber") Long lastNumber, @Param("count") int count); + + /** + * 分页查询记录 + * + * @param page + * @param queryForm + * @return + */ + List query(Page page, @Param("queryForm") SerialNumberRecordQueryForm queryForm); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberEntity.java new file mode 100644 index 0000000..79b589f --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberEntity.java @@ -0,0 +1,79 @@ +package net.lab1024.sa.common.module.support.serialnumber.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import net.lab1024.sa.common.module.support.serialnumber.constant.SerialNumberIdEnum; +import net.lab1024.sa.common.module.support.serialnumber.constant.SerialNumberRuleTypeEnum; + +import java.time.LocalDateTime; + +/** + * 单据序列号 定义表 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_serial_number") +public class SerialNumberEntity { + + /** + * 主键id + * + * @see SerialNumberIdEnum + */ + @TableId(type = IdType.INPUT) + private Integer serialNumberId; + + /** + * 业务 + */ + private String businessName; + + /** + * 格式 + */ + private String format; + + /** + * 生成规则 + * + * @see SerialNumberRuleTypeEnum + */ + private String ruleType; + + + /** + * 初始值 + */ + private Long initNumber; + + /** + * 步长随机数范围 + */ + private Integer stepRandomRange; + + /** + * 备注 + */ + private String remark; + + /** + * 上次产生的单号, 默认为空 + */ + private Long lastNumber; + + /** + * 上次产生的单号时间 + */ + private LocalDateTime lastTime; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberGenerateForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberGenerateForm.java new file mode 100644 index 0000000..30e0b77 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberGenerateForm.java @@ -0,0 +1,28 @@ +package net.lab1024.sa.common.module.support.serialnumber.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 单据序列号 生成表单 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class SerialNumberGenerateForm { + + @ApiModelProperty("单号id") + @NotNull(message = "单号id不能为空") + private Integer serialNumberId; + + @ApiModelProperty("生成的数量") + @NotNull(message = "生成的数量") + private Integer count; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberGenerateResultBO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberGenerateResultBO.java new file mode 100644 index 0000000..f4dfe3a --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberGenerateResultBO.java @@ -0,0 +1,52 @@ +package net.lab1024.sa.common.module.support.serialnumber.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 单据序列号 生成结果 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class SerialNumberGenerateResultBO { + + /** + * 序号id + */ + private Integer serialNumberId; + + /** + * 是否重置的初始值 + */ + private Boolean isReset; + + /** + * 上次生成的数字 + */ + private Long lastNumber; + + /** + * 上次生成的时间 + */ + private LocalDateTime lastTime; + + /** + * 生成的 number 集合 + */ + private List numberList; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberInfoBO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberInfoBO.java new file mode 100644 index 0000000..89fae4e --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberInfoBO.java @@ -0,0 +1,97 @@ +package net.lab1024.sa.common.module.support.serialnumber.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import net.lab1024.sa.common.module.support.serialnumber.constant.SerialNumberIdEnum; +import net.lab1024.sa.common.module.support.serialnumber.constant.SerialNumberRuleTypeEnum; + +/** + * 单据序列号 信息 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class SerialNumberInfoBO { + + /** + * 主键id + * + * @see SerialNumberIdEnum + */ + private Integer serialNumberId; + + /** + * 业务 + */ + private String businessName; + + /** + * 格式 + */ + private String format; + + /** + * 生成规则 + * + * @see SerialNumberRuleTypeEnum + */ + private String ruleType; + + + /** + * 初始值 + */ + private Long initNumber; + + /** + * 步长随机数范围 + */ + private Integer stepRandomRange; + + /** + * 备注 + */ + private String remark; + + /** + * 规则枚举 + */ + private SerialNumberRuleTypeEnum serialNumberRuleTypeEnum; + + + /** + * 存在[nnnnnn]中 n 的数量 + */ + private Integer numberCount; + + /** + * [nnnnnn] 的格式(主要用于替换) + */ + private String numberFormat; + + /** + * 是否存在年份 + */ + private Boolean haveYearFlag; + + /** + * 是否存在月份 + */ + private Boolean haveMonthFlag; + + /** + * 是否存在 月 + */ + private Boolean haveDayFlag; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberLastGenerateBO.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberLastGenerateBO.java new file mode 100644 index 0000000..5ccf4e7 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberLastGenerateBO.java @@ -0,0 +1,41 @@ +package net.lab1024.sa.common.module.support.serialnumber.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +/** + * 上次生成信息 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class SerialNumberLastGenerateBO { + + /** + * 序号id + */ + private Integer serialNumberId; + + /** + * 上次生成的数字 + */ + private Long lastNumber; + + /** + * 上次生成的时间 + */ + private LocalDateTime lastTime; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberRecordEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberRecordEntity.java new file mode 100644 index 0000000..a32982e --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberRecordEntity.java @@ -0,0 +1,57 @@ +package net.lab1024.sa.common.module.support.serialnumber.domain; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * 单据序列号 表结构 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@TableName("t_serial_number_record") +public class SerialNumberRecordEntity { + + /** + * 单号id + */ + private Integer serialNumberId; + + /** + * 记录日期 + */ + private LocalDate recordDate; + + /** + * 最后更新值 + */ + private Long lastNumber; + + /** + * 上次生成时间 + */ + private LocalDateTime lastTime; + + /** + * 数量 + */ + private Long count; + + private LocalDateTime updateTime; + + private LocalDateTime createTime; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberRecordQueryForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberRecordQueryForm.java new file mode 100644 index 0000000..7fe3682 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/domain/SerialNumberRecordQueryForm.java @@ -0,0 +1,24 @@ +package net.lab1024.sa.common.module.support.serialnumber.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import net.lab1024.sa.common.common.domain.PageParam; + +import javax.validation.constraints.NotNull; + +/** + * 单据序列号 生成记录 查询 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class SerialNumberRecordQueryForm extends PageParam { + + @ApiModelProperty("单号id") + @NotNull(message = "单号id不能为空") + private Integer serialNumberId; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberBaseService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberBaseService.java new file mode 100644 index 0000000..1a85af1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberBaseService.java @@ -0,0 +1,252 @@ +package net.lab1024.sa.common.module.support.serialnumber.service; + +import com.google.common.collect.Lists; +import net.lab1024.sa.common.common.exception.BusinessException; +import net.lab1024.sa.common.common.util.SmartEnumUtil; +import net.lab1024.sa.common.module.support.serialnumber.constant.SerialNumberIdEnum; +import net.lab1024.sa.common.module.support.serialnumber.constant.SerialNumberRuleTypeEnum; +import net.lab1024.sa.common.module.support.serialnumber.dao.SerialNumberDao; +import net.lab1024.sa.common.module.support.serialnumber.dao.SerialNumberRecordDao; +import net.lab1024.sa.common.module.support.serialnumber.domain.*; +import org.apache.commons.lang3.RandomUtils; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.annotation.PostConstruct; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 单据序列号 基类 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public abstract class SerialNumberBaseService implements SerialNumberService { + + @Autowired + protected SerialNumberRecordDao serialNumberRecordDao; + + @Autowired + protected SerialNumberDao serialNumberDao; + + private ConcurrentHashMap serialNumberMap = new ConcurrentHashMap<>(); + + public abstract List generateSerialNumberList(SerialNumberInfoBO serialNumber, int count); + + @PostConstruct + void init() { + List serialNumberEntityList = serialNumberDao.selectList(null); + if (serialNumberEntityList == null) { + return; + } + for (SerialNumberEntity serialNumberEntity : serialNumberEntityList) { + SerialNumberRuleTypeEnum ruleTypeEnum = SmartEnumUtil.getEnumByName(serialNumberEntity.getRuleType().toUpperCase(), SerialNumberRuleTypeEnum.class); + if (ruleTypeEnum == null) { + throw new ExceptionInInitializerError("cannot find rule type , id : " + serialNumberEntity.getSerialNumberId()); + } + + String format = serialNumberEntity.getFormat(); + int startIndex = format.indexOf("[n"); + int endIndex = format.indexOf("n]"); + if (startIndex == -1 || endIndex == -1 || endIndex <= startIndex) { + throw new ExceptionInInitializerError("[nnn] 配置错误,请仔细查看 id : " + serialNumberEntity.getSerialNumberId()); + } + + String numberFormat = format.substring(startIndex + 1, endIndex + 1); + + if (serialNumberEntity.getStepRandomRange() < 1) { + throw new ExceptionInInitializerError("random step range must greater than 1 " + serialNumberEntity.getSerialNumberId()); + } + + SerialNumberInfoBO serialNumberInfoBO = SerialNumberInfoBO.builder() + .serialNumberId(serialNumberEntity.getSerialNumberId()) + .serialNumberRuleTypeEnum(ruleTypeEnum) + .initNumber(serialNumberEntity.getInitNumber()) + .format(serialNumberEntity.getFormat()) + .stepRandomRange(serialNumberEntity.getStepRandomRange()) + .haveDayFlag(format.contains(SerialNumberRuleTypeEnum.DAY.getValue())) + .haveMonthFlag(format.contains(SerialNumberRuleTypeEnum.MONTH.getValue())) + .haveYearFlag(format.contains(SerialNumberRuleTypeEnum.YEAR.getValue())) + .numberCount(endIndex - startIndex) + .numberFormat("\\[" + numberFormat + "\\]") + .build(); + + this.serialNumberMap.put(serialNumberEntity.getSerialNumberId(), serialNumberInfoBO); + } + + //初始化数据 + initLastGenerateData(serialNumberEntityList); + } + + /** + * 初始化上次生成的数据 + * + * @param serialNumberEntityList + */ + public abstract void initLastGenerateData(List serialNumberEntityList); + + @Override + public String generate(SerialNumberIdEnum serialNumberIdEnum) { + List generateList = this.generate(serialNumberIdEnum, 1); + if (generateList == null || generateList.isEmpty()) { + throw new BusinessException("cannot generate : " + serialNumberIdEnum.toString()); + } + return generateList.get(0); + } + + @Override + public List generate(SerialNumberIdEnum serialNumberIdEnum, int count) { + SerialNumberInfoBO serialNumberInfoBO = serialNumberMap.get(serialNumberIdEnum.getSerialNumberId()); + if (serialNumberInfoBO == null) { + throw new BusinessException("cannot found SerialNumberId : " + serialNumberIdEnum.toString()); + } + return this.generateSerialNumberList(serialNumberInfoBO, count); + } + + /** + * 循环生成 number 集合 + * + * @param lastGenerate + * @param serialNumberInfo + * @param count + * @return + */ + protected SerialNumberGenerateResultBO loopNumberList(SerialNumberLastGenerateBO lastGenerate, SerialNumberInfoBO serialNumberInfo, int count) { + Long lastNumber = lastGenerate.getLastNumber(); + boolean isReset = false; + if (isResetInitNumber(lastGenerate, serialNumberInfo)) { + lastNumber = serialNumberInfo.getInitNumber(); + isReset = true; + } + + ArrayList numberList = Lists.newArrayListWithCapacity(count); + for (int i = 0; i < count; i++) { + Integer stepRandomRange = serialNumberInfo.getStepRandomRange(); + if (stepRandomRange > 1) { + lastNumber = lastNumber + RandomUtils.nextInt(1, stepRandomRange + 1); + } else { + lastNumber = lastNumber + 1; + } + + numberList.add(lastNumber); + } + + return SerialNumberGenerateResultBO + .builder() + .serialNumberId(serialNumberInfo.getSerialNumberId()) + .lastNumber(lastNumber) + .lastTime(LocalDateTime.now()) + .numberList(numberList) + .isReset(isReset) + .build(); + } + + protected void saveRecord(SerialNumberGenerateResultBO resultBO) { + Long effectRows = serialNumberRecordDao.updateRecord(resultBO.getSerialNumberId(), + resultBO.getLastTime().toLocalDate(), + resultBO.getLastNumber(), + resultBO.getNumberList().size() + ); + + // 需要插入 + if (effectRows == null || effectRows == 0) { + SerialNumberRecordEntity recordEntity = SerialNumberRecordEntity.builder() + .serialNumberId(resultBO.getSerialNumberId()) + .recordDate(LocalDate.now()) + .lastTime(resultBO.getLastTime()) + .lastNumber(resultBO.getLastNumber()) + .count((long) resultBO.getNumberList().size()) + .build(); + serialNumberRecordDao.insert(recordEntity); + } + + } + + /** + * 若不在规则周期内,重制初始值 + * + * @return + */ + private boolean isResetInitNumber(SerialNumberLastGenerateBO lastGenerate, SerialNumberInfoBO serialNumberInfo) { + LocalDateTime lastTime = lastGenerate.getLastTime(); + if (lastTime == null) { + return true; + } + + SerialNumberRuleTypeEnum serialNumberRuleTypeEnum = serialNumberInfo.getSerialNumberRuleTypeEnum(); + int lastTimeYear = lastTime.getYear(); + int lastTimeMonth = lastTime.getMonthValue(); + int lastTimeDay = lastTime.getDayOfYear(); + + LocalDateTime now = LocalDateTime.now(); + + switch (serialNumberRuleTypeEnum) { + case YEAR: + return lastTimeYear != now.getYear(); + case MONTH: + return lastTimeYear != now.getYear() || lastTimeMonth != now.getMonthValue(); + case DAY: + return lastTimeYear != now.getYear() || lastTimeDay != now.getDayOfYear(); + default: + return false; + } + } + + /** + * 替换特殊rule,即替换[yyyy][mm][dd][nnn]等规则 + */ + protected List formatNumberList(SerialNumberGenerateResultBO generteResult, SerialNumberInfoBO serialNumberInfo) { + + /** + * 第一步:替换年、月、日 + */ + LocalDate lastTime = generteResult.getLastTime().toLocalDate(); + String year = String.valueOf(lastTime.getYear()); + String month = lastTime.getMonthValue() > 9 ? String.valueOf(lastTime.getMonthValue()) : "0" + lastTime.getMonthValue(); + String day = lastTime.getDayOfMonth() > 9 ? String.valueOf(lastTime.getDayOfMonth()) : "0" + lastTime.getDayOfMonth(); + + // 把年月日替换 + String format = serialNumberInfo.getFormat(); + + if (serialNumberInfo.getHaveYearFlag()) { + format = format.replaceAll(SerialNumberRuleTypeEnum.YEAR.getRegex(), year); + } + if (serialNumberInfo.getHaveMonthFlag()) { + format = format.replaceAll(SerialNumberRuleTypeEnum.MONTH.getRegex(), month); + } + if (serialNumberInfo.getHaveDayFlag()) { + format = format.replaceAll(SerialNumberRuleTypeEnum.DAY.getRegex(), day); + } + + + /** + * 第二步:替换数字 + */ + + List numberList = Lists.newArrayListWithCapacity(generteResult.getNumberList().size()); + for (Long number : generteResult.getNumberList()) { + StringBuilder numberStringBuilder = new StringBuilder(); + int currentNumberCount = String.valueOf(number).length(); + //数量不够,前面补0 + if (serialNumberInfo.getNumberCount() > currentNumberCount) { + int remain = serialNumberInfo.getNumberCount() - currentNumberCount; + for (int i = 0; i < remain; i++) { + numberStringBuilder.append(0); + } + } + numberStringBuilder.append(number); + //最终替换 + String finalNumber = format.replaceAll(serialNumberInfo.getNumberFormat(), numberStringBuilder.toString()); + numberList.add(finalNumber); + } + return numberList; + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberRecordService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberRecordService.java new file mode 100644 index 0000000..664e24f --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberRecordService.java @@ -0,0 +1,39 @@ +package net.lab1024.sa.common.module.support.serialnumber.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import net.lab1024.sa.common.common.domain.PageResult; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogEntity; +import net.lab1024.sa.common.module.support.operatelog.domain.OperateLogVO; +import net.lab1024.sa.common.module.support.serialnumber.constant.SerialNumberIdEnum; +import net.lab1024.sa.common.module.support.serialnumber.dao.SerialNumberDao; +import net.lab1024.sa.common.module.support.serialnumber.dao.SerialNumberRecordDao; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberRecordEntity; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberRecordQueryForm; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 单据序列号 记录 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class SerialNumberRecordService { + + @Autowired + private SerialNumberRecordDao serialNumberRecordDao; + + public PageResult query(SerialNumberRecordQueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List recordList = serialNumberRecordDao.query(page, queryForm); + return SmartPageUtil.convert2PageResult(page, recordList); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberService.java new file mode 100644 index 0000000..ce40d7f --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/SerialNumberService.java @@ -0,0 +1,36 @@ +package net.lab1024.sa.common.module.support.serialnumber.service; + +import net.lab1024.sa.common.module.support.serialnumber.constant.SerialNumberIdEnum; + +import java.util.List; + +/** + * 单据序列号 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public interface SerialNumberService { + + /** + * 生成 + * + * @param serialNumberIdEnum + * @return + */ + String generate(SerialNumberIdEnum serialNumberIdEnum); + + + /** + * 生成n个 + * + * @param serialNumberIdEnum + * @param count + * @return + */ + List generate(SerialNumberIdEnum serialNumberIdEnum, int count); + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberInternService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberInternService.java new file mode 100644 index 0000000..db8c04e --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberInternService.java @@ -0,0 +1,78 @@ +package net.lab1024.sa.common.module.support.serialnumber.service.impl; + +import com.google.common.collect.Interner; +import com.google.common.collect.Interners; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberEntity; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberGenerateResultBO; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberInfoBO; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberLastGenerateBO; +import net.lab1024.sa.common.module.support.serialnumber.service.SerialNumberBaseService; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 单据序列号 基于内存锁实现 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class SerialNumberInternService extends SerialNumberBaseService { + + /** + * 按照 serialNumberId 进行锁 + */ + private static final Interner POOL = Interners.newWeakInterner(); + + + private ConcurrentHashMap serialNumberLastGenerateMap = new ConcurrentHashMap<>(); + + @Override + public void initLastGenerateData(List serialNumberEntityList) { + if (serialNumberEntityList == null) { + return; + } + + for (SerialNumberEntity serialNumberEntity : serialNumberEntityList) { + SerialNumberLastGenerateBO lastGenerateBO = SerialNumberLastGenerateBO + .builder() + .serialNumberId(serialNumberEntity.getSerialNumberId()) + .lastNumber(serialNumberEntity.getLastNumber()) + .lastTime(serialNumberEntity.getLastTime()) + .build(); + serialNumberLastGenerateMap.put(serialNumberEntity.getSerialNumberId(), lastGenerateBO); + } + } + + @Override + public List generateSerialNumberList(SerialNumberInfoBO serialNumberInfo, int count) { + SerialNumberGenerateResultBO serialNumberGenerateResult = null; + synchronized (POOL.intern(serialNumberInfo.getSerialNumberId())) { + + // 获取上次的生成结果 + SerialNumberLastGenerateBO lastGenerateBO = serialNumberLastGenerateMap.get(serialNumberInfo.getSerialNumberId()); + + // 生成 + serialNumberGenerateResult = super.loopNumberList(lastGenerateBO, serialNumberInfo, count); + + // 将生成信息保存的内存和数据库 + lastGenerateBO.setLastNumber(serialNumberGenerateResult.getLastNumber()); + lastGenerateBO.setLastTime(serialNumberGenerateResult.getLastTime()); + serialNumberDao.updateLastNumberAndTime(serialNumberInfo.getSerialNumberId(), + serialNumberGenerateResult.getLastNumber(), + serialNumberGenerateResult.getLastTime()); + + // 把生成过程保存到数据库里 + super.saveRecord(serialNumberGenerateResult); + } + + return formatNumberList(serialNumberGenerateResult, serialNumberInfo); + } + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberMysqlService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberMysqlService.java new file mode 100644 index 0000000..8d2413a --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberMysqlService.java @@ -0,0 +1,61 @@ +package net.lab1024.sa.common.module.support.serialnumber.service.impl; + +import lombok.extern.slf4j.Slf4j; +import net.lab1024.sa.common.common.exception.BusinessException; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberEntity; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberGenerateResultBO; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberInfoBO; +import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberLastGenerateBO; +import net.lab1024.sa.common.module.support.serialnumber.service.SerialNumberBaseService; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 单据序列号 基于mysql锁实现 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-03-25 21:46:07 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Slf4j +public class SerialNumberMysqlService extends SerialNumberBaseService { + + @Override + @Transactional(rollbackFor = Throwable.class) + public List generateSerialNumberList(SerialNumberInfoBO serialNumberInfo, int count) { + // // 获取上次的生成结果 + SerialNumberEntity serialNumberEntity = serialNumberDao.selectForUpdate(serialNumberInfo.getSerialNumberId()); + if (serialNumberEntity == null) { + throw new BusinessException("cannot found SerialNumberId 数据库不存在:" + serialNumberInfo.getSerialNumberId()); + } + SerialNumberLastGenerateBO lastGenerateBO = SerialNumberLastGenerateBO + .builder() + .lastNumber(serialNumberEntity.getLastNumber()) + .lastTime(serialNumberEntity.getLastTime()) + .serialNumberId(serialNumberEntity.getSerialNumberId()) + .build(); + + // 生成 + SerialNumberGenerateResultBO serialNumberGenerateResult = super.loopNumberList(lastGenerateBO, serialNumberInfo, count); + + // 将生成信息保存的内存和数据库 + lastGenerateBO.setLastNumber(serialNumberGenerateResult.getLastNumber()); + lastGenerateBO.setLastTime(serialNumberGenerateResult.getLastTime()); + serialNumberDao.updateLastNumberAndTime(serialNumberInfo.getSerialNumberId(), + serialNumberGenerateResult.getLastNumber(), + serialNumberGenerateResult.getLastTime()); + + // 把生成过程保存到数据库里 + super.saveRecord(serialNumberGenerateResult); + + return formatNumberList(serialNumberGenerateResult, serialNumberInfo); + } + + @Override + public void initLastGenerateData(List serialNumberEntityList) { + + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberRedisService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberRedisService.java new file mode 100644 index 0000000..1a8213c --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/serialnumber/service/impl/SerialNumberRedisService.java @@ -0,0 +1,105 @@ +//package net.lab1024.sa.common.module.support.serialnumber.service.impl; +// +//import lombok.extern.slf4j.Slf4j; +//import net.lab1024.sa.common.common.exception.BusinessException; +//import net.lab1024.sa.common.constant.RedisKeyConst; +//import net.lab1024.sa.common.module.support.redis.RedisService; +//import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberEntity; +//import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberGenerateResultBO; +//import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberInfoBO; +//import net.lab1024.sa.common.module.support.serialnumber.domain.SerialNumberLastGenerateBO; +//import net.lab1024.sa.common.module.support.serialnumber.service.SerialNumberBaseService; +//import org.springframework.beans.factory.annotation.Autowired; +// +//import java.util.List; +// +///** +// * 单据序列号 基于redis锁实现 +// * +// * @Author 1024创新实验室-主任: 卓大 +// * @Date 2022-03-25 21:46:07 +// * @Wechat zhuoda1024 +// * @Email lab1024@163.com +// * @Copyright 1024创新实验室 ( https://1024lab.net ) +// */ +//@Slf4j +//public class SerialNumberRedisService extends SerialNumberBaseService { +// +// private static final int MAX_GET_LOCK_COUNT = 5; +// +// private static final long SLEEP_MILLISECONDS = 200L; +// +// @Autowired +// private RedisService redisService; +// +// @Override +// public void initLastGenerateData(List serialNumberEntityList) { +// if (serialNumberEntityList == null) { +// return; +// } +// +// //删除之前的 +// redisService.delete(RedisKeyConst.Support.SERIAL_NUMBER_LAST_INFO); +// +// for (SerialNumberEntity serialNumberEntity : serialNumberEntityList) { +// SerialNumberLastGenerateBO lastGenerateBO = SerialNumberLastGenerateBO +// .builder() +// .serialNumberId(serialNumberEntity.getSerialNumberId()) +// .lastNumber(serialNumberEntity.getLastNumber()) +// .lastTime(serialNumberEntity.getLastTime()) +// .build(); +// +// redisService.mset(RedisKeyConst.Support.SERIAL_NUMBER_LAST_INFO, +// String.valueOf(serialNumberEntity.getSerialNumberId()), +// lastGenerateBO +// ); +// } +// } +// +// @Override +// public List generateSerialNumberList(SerialNumberInfoBO serialNumberInfo, int count) { +// SerialNumberGenerateResultBO serialNumberGenerateResult = null; +// String lockKey = RedisKeyConst.Support.SERIAL_NUMBER + serialNumberInfo.getSerialNumberId(); +// try { +// boolean lock = false; +// for (int i = 0; i < MAX_GET_LOCK_COUNT; i++) { +// try { +// lock = redisService.getLock(lockKey, 60 * 1000L); +// if (lock) { +// break; +// } +// Thread.sleep(SLEEP_MILLISECONDS); +// } catch (Throwable e) { +// log.error(e.getMessage(), e); +// } +// } +// if (!lock) { +// throw new BusinessException("SerialNumber 尝试5次,未能生成单号"); +// } +// // 获取上次的生成结果 +// SerialNumberLastGenerateBO lastGenerateBO = (SerialNumberLastGenerateBO) redisService.mget( +// RedisKeyConst.Support.SERIAL_NUMBER_LAST_INFO, +// String.valueOf(serialNumberInfo.getSerialNumberId())); +// +// // 生成 +// serialNumberGenerateResult = super.loopNumberList(lastGenerateBO, serialNumberInfo, count); +// +// // 将生成信息保存的内存和数据库 +// lastGenerateBO.setLastNumber(serialNumberGenerateResult.getLastNumber()); +// lastGenerateBO.setLastTime(serialNumberGenerateResult.getLastTime()); +// serialNumberDao.updateLastNumberAndTime(serialNumberInfo.getSerialNumberId(), +// serialNumberGenerateResult.getLastNumber(), +// serialNumberGenerateResult.getLastTime()); +// +// // 把生成过程保存到数据库里 +// super.saveRecord(serialNumberGenerateResult); +// } catch (Throwable e) { +// log.error(e.getMessage(), e); +// throw e; +// } finally { +// redisService.unLock(lockKey); +// } +// +// return formatNumberList(serialNumberGenerateResult, serialNumberInfo); +// } +//} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnController.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnController.java new file mode 100644 index 0000000..707c9be --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnController.java @@ -0,0 +1,51 @@ +package net.lab1024.sa.common.module.support.table; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import net.lab1024.sa.common.common.controller.SupportBaseController; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.util.SmartRequestUtil; +import net.lab1024.sa.common.constant.SwaggerTagConst; +import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit; +import net.lab1024.sa.common.module.support.table.domain.TableColumnUpdateForm; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * 表格自定义列(前端用户自定义表格列,并保存到数据库里) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@RestController +//@Api(tags = {SwaggerTagConst.Support.TABLE_COLUMN}) +public class TableColumnController extends SupportBaseController { + + @Autowired + private TableColumnService tableColumnService; + + @ApiOperation("修改表格列 @author 卓大") + @PostMapping("/tableColumn/update") + @RepeatSubmit + public ResponseDTO updateTableColumn(@RequestBody @Valid TableColumnUpdateForm updateForm) { + return tableColumnService.updateTableColumns(SmartRequestUtil.getRequestUser(), updateForm); + } + + @ApiOperation("恢复默认(删除) @author 卓大") + @GetMapping("/tableColumn/delete/{tableId}") + @RepeatSubmit + public ResponseDTO deleteTableColumn(@PathVariable Integer tableId) { + return tableColumnService.deleteTableColumn(SmartRequestUtil.getRequestUser(), tableId); + } + + @ApiOperation("查询表格列 @author 卓大") + @GetMapping("/tableColumn/getColumns/{tableId}") + public ResponseDTO getColumns(@PathVariable Integer tableId) { + return ResponseDTO.ok(tableColumnService.getTableColumns(SmartRequestUtil.getRequestUser(), tableId)); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnDao.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnDao.java new file mode 100644 index 0000000..2a7d6cd --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnDao.java @@ -0,0 +1,23 @@ +package net.lab1024.sa.common.module.support.table; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import net.lab1024.sa.common.module.support.table.domain.TableColumnEntity; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 表格自定义列(前端用户自定义表格列,并保存到数据库里) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Mapper +public interface TableColumnDao extends BaseMapper { + + TableColumnEntity selectByUserIdAndTableId(@Param("userId") Long userId, @Param("userType") Integer userType, @Param("tableId") Integer tableId); + + void delete(@Param("userId") Long userId, @Param("userType") Integer userType, @Param("tableId") Integer tableId); +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnService.java new file mode 100644 index 0000000..5f388c4 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/TableColumnService.java @@ -0,0 +1,72 @@ +package net.lab1024.sa.common.module.support.table; + +import com.alibaba.fastjson.JSONArray; +import net.lab1024.sa.common.common.domain.RequestUser; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.module.support.table.domain.TableColumnEntity; +import net.lab1024.sa.common.module.support.table.domain.TableColumnUpdateForm; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 表格自定义列(前端用户自定义表格列,并保存到数据库里) + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Service +public class TableColumnService { + + @Autowired + private TableColumnDao tableColumnDao; + + /** + * 获取 - 表格列 + * + * @return + */ + public String getTableColumns(RequestUser requestUser, Integer tableId) { + TableColumnEntity tableColumnEntity = tableColumnDao.selectByUserIdAndTableId(requestUser.getUserId(), requestUser.getUserType().getValue(), tableId); + return tableColumnEntity == null ? null : tableColumnEntity.getColumns(); + } + + /** + * 更新表格列 + * + * @return + */ + public ResponseDTO updateTableColumns(RequestUser requestUser, TableColumnUpdateForm updateForm) { + if (CollectionUtils.isEmpty(updateForm.getColumnList())) { + return ResponseDTO.ok(); + } + Integer tableId = updateForm.getTableId(); + TableColumnEntity tableColumnEntity = tableColumnDao.selectByUserIdAndTableId(requestUser.getUserId(), requestUser.getUserType().getValue(), tableId); + if (tableColumnEntity == null) { + tableColumnEntity = new TableColumnEntity(); + tableColumnEntity.setTableId(tableId); + tableColumnEntity.setUserId(requestUser.getUserId()); + tableColumnEntity.setUserType(requestUser.getUserType().getValue()); + + tableColumnEntity.setColumns(JSONArray.toJSONString(updateForm.getColumnList())); + tableColumnDao.insert(tableColumnEntity); + } else { + tableColumnEntity.setColumns(JSONArray.toJSONString(updateForm.getColumnList())); + tableColumnDao.updateById(tableColumnEntity); + } + return ResponseDTO.ok(); + } + + /** + * 删除表格列 + * + * @return + */ + public ResponseDTO deleteTableColumn(RequestUser requestUser, Integer tableId) { + tableColumnDao.delete(requestUser.getUserId(), requestUser.getUserType().getValue(), tableId); + return ResponseDTO.ok(); + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnEntity.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnEntity.java new file mode 100644 index 0000000..c177ed1 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnEntity.java @@ -0,0 +1,49 @@ +package net.lab1024.sa.common.module.support.table.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 自定义表格列 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +@TableName("t_table_column") +public class TableColumnEntity { + + @TableId(type = IdType.AUTO) + private Long tableColumnId; + + /** + * 用户id + */ + private Long userId; + + /** + * 用户类型 + */ + private Integer userType; + + /** + * 表id + */ + private Integer tableId; + + /** + * 表列 + */ + private String columns; + + private LocalDateTime createTime; + + private LocalDateTime updateTime; +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnItemForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnItemForm.java new file mode 100644 index 0000000..0a50f8e --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnItemForm.java @@ -0,0 +1,37 @@ +package net.lab1024.sa.common.module.support.table.domain; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** + * 自定义表格列 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class TableColumnItemForm { + + @NotEmpty(message = "列不能为空") + @ApiModelProperty("字段") + private String columnKey; + + @ApiModelProperty("宽度") + private Integer width; + + @NotNull(message = "显示不能为空") + @ApiModelProperty("是否显示") + private Boolean showFlag; + + @NotNull(message = "排序不能为空") + @ApiModelProperty("排序") + private Integer sort; + + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnUpdateForm.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnUpdateForm.java new file mode 100644 index 0000000..106bf61 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/table/domain/TableColumnUpdateForm.java @@ -0,0 +1,27 @@ +package net.lab1024.sa.common.module.support.table.domain; + +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 自定义表格列 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2022-08-12 22:52:21 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +@Data +public class TableColumnUpdateForm { + + @NotNull(message = "表id不能为空") + private Integer tableId; + + @NotEmpty(message = "请上传列") + private List columnList; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/JwtConst.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/JwtConst.java new file mode 100644 index 0000000..23bd7da --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/JwtConst.java @@ -0,0 +1,38 @@ +package net.lab1024.sa.common.module.support.token; + +/** + * jwt相关常量 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-11-29 19:48:35 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public class JwtConst { + /** + * Id + */ + public static final String CLAIM_ID_KEY = "id"; + + /** + * NAME + */ + public static final String CLAIM_NAME_KEY = "name"; + + /** + * user type + */ + public static final String CLAIM_USER_TYPE_KEY = "type"; + + /** + * 设备 + */ + public static final String CLAIM_DEVICE_KEY = "device"; + + /** + * 万能密码登录的标识 + */ + public static final String CLAIM_SUPER_PASSWORD_FLAG = "superPasswordFlag"; + +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/LoginDeviceEnum.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/LoginDeviceEnum.java new file mode 100644 index 0000000..3fa9419 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/LoginDeviceEnum.java @@ -0,0 +1,43 @@ +package net.lab1024.sa.common.module.support.token; + +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * 登录设备类型 + * + * @Author 1024创新实验室-主任: 卓大 + * @Date 2021-11-29 19:48:35 + * @Wechat zhuoda1024 + * @Email lab1024@163.com + * @Copyright 1024创新实验室 ( https://1024lab.net ) + */ +public enum LoginDeviceEnum implements BaseEnum { + + PC(1, "电脑端"), + + ANDROID(2, "安卓"), + + APPLE(3, "苹果"), + + H5(4, "H5"), + + WEIXIN_MP(5, "微信小程序"); + + LoginDeviceEnum(Integer value, String desc) { + this.value = value; + this.desc = desc; + } + + private Integer value; + private String desc; + + @Override + public Integer getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java b/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java new file mode 100644 index 0000000..ef81d38 --- /dev/null +++ b/sa-common/src/main/java/net/lab1024/sa/common/module/support/token/TokenService.java @@ -0,0 +1,220 @@ +//package net.lab1024.sa.common.module.support.token; +// +//import io.jsonwebtoken.Claims; +//import io.jsonwebtoken.JwtBuilder; +//import io.jsonwebtoken.Jwts; +//import io.jsonwebtoken.SignatureAlgorithm; +//import lombok.extern.slf4j.Slf4j; +//import net.lab1024.sa.common.common.enumeration.UserTypeEnum; +//import net.lab1024.sa.common.constant.RedisKeyConst; +//import net.lab1024.sa.common.module.support.redis.RedisService; +//import org.apache.commons.collections4.MapUtils; +//import org.apache.commons.lang3.math.NumberUtils; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.stereotype.Component; +// +//import java.util.Date; +//import java.util.Map; +// +///** +// * 与用户token的相关的服务 +// * +// * @Author 1024创新实验室-主任: 卓大 +// * @Date 2021-11-29 19:48:35 +// * @Wechat zhuoda1024 +// * @Email lab1024@163.com +// * @Copyright 1024创新实验室 ( https://1024lab.net ) +// */ +//@Component +//@Slf4j +//public class TokenService { +// private static final long HOUR_TIME_MILLI = 60 * 60 * 1000; +// +// @Value("${token.key}") +// private String tokenKey; +// +// @Value("${token.expire-day}") +// private Integer tokenExpire; +// +// @Autowired +// private RedisService redisService; +// +// /** +// * 生成Token,并存入redis +// * +// * @param userId +// * @param userName +// * @param userTypeEnum +// * @param loginDeviceEnum +// * @param superPasswordFlag 特殊万能密码标识 +// * @return +// */ +// public String generateToken(Long userId, String userName, UserTypeEnum userTypeEnum, LoginDeviceEnum loginDeviceEnum, Boolean superPasswordFlag) { +// long nowTimeMilli = System.currentTimeMillis(); +// Claims jwtClaims = Jwts.claims(); +// jwtClaims.put(JwtConst.CLAIM_ID_KEY, userId); +// jwtClaims.put(JwtConst.CLAIM_NAME_KEY, userName); +// jwtClaims.put(JwtConst.CLAIM_USER_TYPE_KEY, userTypeEnum.getValue()); +// jwtClaims.put(JwtConst.CLAIM_DEVICE_KEY, loginDeviceEnum.getValue()); +// jwtClaims.put(JwtConst.CLAIM_SUPER_PASSWORD_FLAG, superPasswordFlag); +// JwtBuilder jwtBuilder = Jwts.builder() +// .setClaims(jwtClaims) +// .setIssuedAt(new Date(nowTimeMilli)) +// .signWith(SignatureAlgorithm.HS512, tokenKey); +// +// // 如果是万能密码,则不需要记录到redis中;万能密码最多半个小时有效期 +// if (superPasswordFlag) { +// jwtBuilder.setExpiration(new Date(nowTimeMilli + (HOUR_TIME_MILLI / 2))); +// return jwtBuilder.compact(); +// } +// +// jwtBuilder.setExpiration(new Date(nowTimeMilli + tokenExpire * 24 * HOUR_TIME_MILLI)); +// String token = jwtBuilder.compact(); +// String redisKey = this.generateTokenRedisKey(userId, userTypeEnum.getValue(), loginDeviceEnum.getValue()); +// redisService.set(redisKey, token, tokenExpire * 24 * 3600); +// return token; +// } +// +// /** +// * 生成登录信息: 含设备信息 +// * +// * @param userId +// * @param device +// * @return +// */ +// private String generateTokenRedisKey(Long userId, Integer userType, Integer device) { +// String userKey = userType + "_" + userId + "_" + device; +// return redisService.generateRedisKey(RedisKeyConst.Support.TOKEN, userKey); +// } +// +// +// /** +// * 强制移除 此用户各端的登录信息 +// * +// * @param token +// */ +// public void removeToken(String token) { +// Map tokenData = this.decryptTokenData(token); +// if (MapUtils.isEmpty(tokenData)) { +// return; +// } +// +// //特殊账号 +// if (tokenData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG) != null) { +// try { +// Boolean superPasswordFlag = Boolean.valueOf(tokenData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG).toString()); +// if (superPasswordFlag) { +// return; +// } +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// return; +// } +// } +// +// boolean isValid = this.checkRedisToken(tokenData, token); +// if (!isValid) { +// return; +// } +// +// Long userId = Long.valueOf(tokenData.get(JwtConst.CLAIM_ID_KEY).toString()); +// Integer userType = Integer.valueOf(tokenData.get(JwtConst.CLAIM_USER_TYPE_KEY).toString()); +// Integer device = Integer.valueOf(tokenData.get(JwtConst.CLAIM_DEVICE_KEY).toString()); +// +// String redisKey = this.generateTokenRedisKey(userId, userType, device); +// redisService.delete(redisKey); +// } +// +// /** +// * 解析并校验token信息 获取 userId +// * +// * @param token +// * @return +// */ +// public Long getUserIdAndValidateToken(String token) { +// Map parseJwtData = this.decryptTokenData(token); +// boolean isValid = this.checkRedisToken(parseJwtData, token); +// if (!isValid) { +// return null; +// } +// Long userId = Long.valueOf(parseJwtData.get(JwtConst.CLAIM_ID_KEY).toString()); +// return userId; +// } +// +// /** +// * 解密和解析token +// * +// * @param token +// * @return +// */ +// private Map decryptTokenData(String token) { +// try { +// return Jwts.parser() +// .setSigningKey(tokenKey) +// .parseClaimsJws(token) +// .getBody(); +// } catch (Exception e) { +// } +// return null; +// } +// +// /** +// * 校验token是否有效 +// * +// * @param token +// * @return +// */ +// private boolean checkRedisToken(Map parseJwtData, String token) { +// if (MapUtils.isEmpty(parseJwtData)) { +// return false; +// } +// //特殊账号 +// if (parseJwtData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG) != null) { +// try { +// Boolean superPasswordFlag = Boolean.valueOf(parseJwtData.get(JwtConst.CLAIM_SUPER_PASSWORD_FLAG).toString()); +// if (superPasswordFlag) { +// return true; +// } +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// return false; +// } +// } +// +// Long userId = null; +// Integer userType = null, device = null; +// +// if (null != parseJwtData.get(JwtConst.CLAIM_ID_KEY)) { +// userId = NumberUtils.toLong(parseJwtData.get(JwtConst.CLAIM_ID_KEY).toString(), -1); +// userId = userId == -1 ? null : userId; +// } +// +// if (null != parseJwtData.get(JwtConst.CLAIM_USER_TYPE_KEY)) { +// userType = NumberUtils.toInt(parseJwtData.get(JwtConst.CLAIM_USER_TYPE_KEY).toString(), -1); +// userType = userType == -1 ? null : userType; +// } +// +// if (null != parseJwtData.get(JwtConst.CLAIM_DEVICE_KEY)) { +// device = NumberUtils.toInt(parseJwtData.get(JwtConst.CLAIM_DEVICE_KEY).toString(), -1); +// device = device == -1 ? null : device; +// } +// +// if (userId == null || userType == null || device == null) { +// return false; +// } +// +// String redisKey = this.generateTokenRedisKey(userId, userType, device); +// String redisToken = redisService.get(redisKey); +// return token.equals(redisToken); +// } +// +// /** +// * 批量移除用户所有设备的token +// */ +// public void batchRemoveRedisToken(Long userId, UserTypeEnum userTypeEnum) { +// for (LoginDeviceEnum device : LoginDeviceEnum.values()) { +// redisService.delete(this.generateTokenRedisKey(userId, userTypeEnum.getValue(), device.getValue())); +// } +// } +//} \ No newline at end of file diff --git a/sa-common/src/main/resources/META-INF/spring.factories b/sa-common/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..99b8129 --- /dev/null +++ b/sa-common/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.env.EnvironmentPostProcessor=\ + net.lab1024.sa.common.config.PostProcessorConfig \ No newline at end of file diff --git a/sa-common/src/main/resources/banner.txt b/sa-common/src/main/resources/banner.txt new file mode 100644 index 0000000..655dbb3 --- /dev/null +++ b/sa-common/src/main/resources/banner.txt @@ -0,0 +1,7 @@ + ${AnsiColor.BRIGHT_GREEN} + +保持谦逊 保持学习 ! +热爱代码 热爱生活 ! +永远年轻 永远前行 ! + +${AnsiColor.DEFAULT} \ No newline at end of file diff --git a/sa-common/src/main/resources/code-generator-template/java/constant/enum.java.vm b/sa-common/src/main/resources/code-generator-template/java/constant/enum.java.vm new file mode 100644 index 0000000..6511a80 --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/java/constant/enum.java.vm @@ -0,0 +1,24 @@ +package ${packageName}; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.lab1024.sa.common.common.enumeration.BaseEnum; + +/** + * ${enumDesc} + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@AllArgsConstructor +@Getter +public enum ${enumName} implements BaseEnum { + + ; + + private final ${enumJavaType} value; + + private final String desc; +} diff --git a/sa-common/src/main/resources/code-generator-template/java/controller/Controller.java.vm b/sa-common/src/main/resources/code-generator-template/java/controller/Controller.java.vm new file mode 100644 index 0000000..42f93dc --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/java/controller/Controller.java.vm @@ -0,0 +1,68 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.domain.PageResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import javax.validation.Valid; + +/** + * ${basic.description} Controller + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@RestController +@Api(tags = "") +public class ${name.upperCamel}Controller { + + @Autowired + private ${name.upperCamel}Service ${name.lowerCamel}Service; + + @ApiOperation("分页查询 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/queryPage") + public ResponseDTO> queryPage(@RequestBody @Valid ${name.upperCamel}QueryForm queryForm) { + return ResponseDTO.ok(${name.lowerCamel}Service.queryPage(queryForm)); + } + +#if($insertAndUpdate.isSupportInsertAndUpdate) + @ApiOperation("添加 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/add") + public ResponseDTO add(@RequestBody @Valid ${name.upperCamel}AddForm addForm) { + return ${name.lowerCamel}Service.add(addForm); + } + + @ApiOperation("更新 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/update") + public ResponseDTO update(@RequestBody @Valid ${name.upperCamel}UpdateForm updateForm) { + return ${name.lowerCamel}Service.update(updateForm); + } +#end + +#if($deleteInfo.isSupportDelete) + #if($deleteInfo.deleteEnum == "Batch" || $deleteInfo.deleteEnum == "SingleAndBatch") + @ApiOperation("批量删除 @author ${basic.backendAuthor}") + @PostMapping("/${name.lowerCamel}/batchDelete") + public ResponseDTO batchDelete(@RequestBody ValidateList<${primaryKeyJavaType}> idList) { + return ${name.lowerCamel}Service.batchDelete(idList); + } + #end + + #if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + @ApiOperation("单个删除 @author ${basic.backendAuthor}") + @GetMapping("/${name.lowerCamel}/delete/{${name.lowerCamel}Id}") + public ResponseDTO batchDelete(@PathVariable ${primaryKeyJavaType} ${primaryKeyFieldName}) { + return ${name.lowerCamel}Service.delete(${name.lowerCamel}Id); + } + #end +#end +} diff --git a/sa-common/src/main/resources/code-generator-template/java/dao/Dao.java.vm b/sa-common/src/main/resources/code-generator-template/java/dao/Dao.java.vm new file mode 100644 index 0000000..a5783df --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/java/dao/Dao.java.vm @@ -0,0 +1,51 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Component; + +/** + * ${basic.description} Dao + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Mapper +@Component +public interface ${name.upperCamel}Dao extends BaseMapper<${name.upperCamel}Entity> { + + /** + * 分页 查询 + * + * @param page + * @param queryForm + * @return + */ + List<${name.upperCamel}VO> queryPage(Page page, @Param("queryForm") ${name.upperCamel}QueryForm queryForm); + +#if($deleteInfo.isSupportDelete) +### 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) +#if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 更新删除状态 + */ + long updateDeleted(@Param("${primaryKeyFieldName}")${primaryKeyJavaType} ${primaryKeyFieldName},@Param("deletedFlag")boolean deletedFlag); +#end +#if($deleteInfo.deleteEnum == "Batch" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 批量更新删除状态 + */ + void batchUpdateDeleted(@Param("idList")List<${primaryKeyJavaType}> idList,@Param("deletedFlag")boolean deletedFlag); +#end +#end +#end + +} diff --git a/sa-common/src/main/resources/code-generator-template/java/domain/entity/Entity.java.vm b/sa-common/src/main/resources/code-generator-template/java/domain/entity/Entity.java.vm new file mode 100644 index 0000000..dd1fe0b --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/java/domain/entity/Entity.java.vm @@ -0,0 +1,32 @@ +package ${basic.javaPackageName}.domain.entity; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 实体类 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +@TableName("${tableName}") +public class ${name.upperCamel}Entity { +#foreach ($field in $fields) + + /** + * $field.label + */ +#if($field.primaryKeyFlag && $field.autoIncreaseFlag) + @TableId(type = IdType.AUTO) +#end +#if($field.primaryKeyFlag && !$field.autoIncreaseFlag) + @TableId +#end + private $field.javaType $field.fieldName; +#end + +} \ No newline at end of file diff --git a/sa-common/src/main/resources/code-generator-template/java/domain/form/AddForm.java.vm b/sa-common/src/main/resources/code-generator-template/java/domain/form/AddForm.java.vm new file mode 100644 index 0000000..d1e8581 --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/java/domain/form/AddForm.java.vm @@ -0,0 +1,30 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 新建表单 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +public class ${name.upperCamel}AddForm { +#foreach ($field in $fields) + +#if($field.isEnum) + ${field.apiModelProperty} + ${field.checkEnum} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum) + ${field.apiModelProperty}$!{field.notEmpty}$!{field.dict}$!{field.file} + private $field.javaType $field.fieldName; +#end +#end + +} \ No newline at end of file diff --git a/sa-common/src/main/resources/code-generator-template/java/domain/form/QueryForm.java.vm b/sa-common/src/main/resources/code-generator-template/java/domain/form/QueryForm.java.vm new file mode 100644 index 0000000..ed672d9 --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/java/domain/form/QueryForm.java.vm @@ -0,0 +1,38 @@ +package ${packageName}; + +import net.lab1024.sa.common.common.domain.PageParam; +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 分页查询表单 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +public class ${name.upperCamel}QueryForm extends PageParam{ +#foreach ($field in $fields) + +#if($field.isEnum) + ${field.apiModelProperty} + ${field.checkEnum} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum && $field.queryTypeEnum != "DateRange") + ${field.apiModelProperty}$!{field.dict} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum && $field.queryTypeEnum == "DateRange") + ${field.apiModelProperty} + private $field.javaType ${field.fieldName}Begin; + + ${field.apiModelProperty} + private $field.javaType ${field.fieldName}End; +#end +#end + +} \ No newline at end of file diff --git a/sa-common/src/main/resources/code-generator-template/java/domain/form/UpdateForm.java.vm b/sa-common/src/main/resources/code-generator-template/java/domain/form/UpdateForm.java.vm new file mode 100644 index 0000000..b97d53d --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/java/domain/form/UpdateForm.java.vm @@ -0,0 +1,30 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 更新表单 + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +public class ${name.upperCamel}UpdateForm extends ${name.upperCamel}AddForm{ +#foreach ($field in $fields) + +#if($field.isEnum) + ${field.apiModelProperty} + ${field.checkEnum} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum) + ${field.apiModelProperty}$!{field.notEmpty}$!{field.dict}$!{field.file} + private $field.javaType $field.fieldName; +#end +#end + +} \ No newline at end of file diff --git a/sa-common/src/main/resources/code-generator-template/java/domain/vo/VO.java.vm b/sa-common/src/main/resources/code-generator-template/java/domain/vo/VO.java.vm new file mode 100644 index 0000000..e2c84f8 --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/java/domain/vo/VO.java.vm @@ -0,0 +1,32 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +/** + * ${basic.description} 列表VO + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Data +public class ${name.upperCamel}VO { + + private $!{primaryKeyJavaType} $!{primaryKeyFieldName}; + +#foreach ($field in $fields) + +#if($field.isEnum) + ${field.apiModelProperty} + private $field.javaType $field.fieldName; +#end +#if(!$field.isEnum) + ${field.apiModelProperty}$!{field.dict}$!{field.file} + private $field.javaType $field.fieldName; +#end +#end + +} \ No newline at end of file diff --git a/sa-common/src/main/resources/code-generator-template/java/manager/Manager.java.vm b/sa-common/src/main/resources/code-generator-template/java/manager/Manager.java.vm new file mode 100644 index 0000000..52811ca --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/java/manager/Manager.java.vm @@ -0,0 +1,21 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * ${basic.description} Manager + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ +@Service +public class ${name.upperCamel}Manager extends ServiceImpl<${name.upperCamel}Dao, ${name.upperCamel}Entity> { + + +} diff --git a/sa-common/src/main/resources/code-generator-template/java/mapper/Mapper.xml.vm b/sa-common/src/main/resources/code-generator-template/java/mapper/Mapper.xml.vm new file mode 100644 index 0000000..d680942 --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/java/mapper/Mapper.xml.vm @@ -0,0 +1,74 @@ + + + + + + + +#if($dao.deletedFieldUpperName != $null) + + update ${mapper.tableName} set ${mapper.deletedColumnName} = #{deletedFlag} + where ${mapper.mainKeyColumnName} in + + #{item} + + +#end + +#if($deleteInfo.isSupportDelete) +### 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) +#if($deleteInfo.deleteEnum == "Batch" || $deleteInfo.deleteEnum == "SingleAndBatch") + + + update ${tableName} set deleted_flag = #{deletedFlag} + where ${primaryKeyColumnName} in + + #{item} + + +#end +#if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + + + update ${tableName} set deleted_flag = #{deletedFlag} + where ${primaryKeyColumnName} = #{${primaryKeyFieldName}} + +#end +#end +#end + \ No newline at end of file diff --git a/sa-common/src/main/resources/code-generator-template/java/service/Service.java.vm b/sa-common/src/main/resources/code-generator-template/java/service/Service.java.vm new file mode 100644 index 0000000..02f43a1 --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/java/service/Service.java.vm @@ -0,0 +1,108 @@ +package ${packageName}; + +#foreach ($importClass in $importPackageList) +$importClass +#end +import net.lab1024.sa.common.common.util.SmartBeanUtil; +import net.lab1024.sa.common.common.util.SmartPageUtil; +import net.lab1024.sa.common.common.domain.ResponseDTO; +import net.lab1024.sa.common.common.domain.PageResult; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * ${basic.description} Service + * + * @Author ${basic.backendAuthor} + * @Date ${basic.backendDate} + * @Copyright ${basic.copyright} + */ + +@Service +public class ${name.upperCamel}Service { + + @Autowired + private ${name.upperCamel}Dao ${name.lowerCamel}Dao; + + /** + * 分页查询 + * + * @param queryForm + * @return + */ + public PageResult<${name.upperCamel}VO> queryPage(${name.upperCamel}QueryForm queryForm) { + Page page = SmartPageUtil.convert2PageQuery(queryForm); + List<${name.upperCamel}VO> list = ${name.lowerCamel}Dao.queryPage(page, queryForm); + PageResult<${name.upperCamel}VO> pageResult = SmartPageUtil.convert2PageResult(page, list); + return pageResult; + } + +#if($insertAndUpdate.isSupportInsertAndUpdate) + /** + * 添加 + */ + public ResponseDTO add(${name.upperCamel}AddForm addForm) { + ${name.upperCamel}Entity ${name.lowerCamel}Entity = SmartBeanUtil.copy(addForm, ${name.upperCamel}Entity.class); + ${name.lowerCamel}Dao.insert(${name.lowerCamel}Entity); + return ResponseDTO.ok(); + } + + /** + * 更新 + * + * @param updateForm + * @return + */ + public ResponseDTO update(${name.upperCamel}UpdateForm updateForm) { + ${name.upperCamel}Entity ${name.lowerCamel}Entity = SmartBeanUtil.copy(updateForm, ${name.upperCamel}Entity.class); + ${name.lowerCamel}Dao.updateById(${name.lowerCamel}Entity); + return ResponseDTO.ok(); + } +#end + +#if($deleteInfo.isSupportDelete) + #if($deleteInfo.deleteEnum == "BATCH" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 批量删除 + * + * @param idList + * @return + */ + public ResponseDTO batchDelete(List<${primaryKeyJavaType}> idList) { + if (CollectionUtils.isEmpty(idList)){ + return ResponseDTO.ok(); + } + +### 真删除 or 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) + ${name.lowerCamel}Dao.batchUpdateDeleted(idList, true); +#else + ${name.lowerCamel}Dao.deleteBatchIds(idList); +#end + return ResponseDTO.ok(); + } + #end + + #if($deleteInfo.deleteEnum == "Single" || $deleteInfo.deleteEnum == "SingleAndBatch") + /** + * 单个删除 + */ + public ResponseDTO delete(${primaryKeyJavaType} ${primaryKeyFieldName}) { + if (null == ${primaryKeyFieldName}){ + return ResponseDTO.ok(); + } + +### 真删除 or 假删除 +#if(!${deleteInfo.isPhysicallyDeleted}) + ${name.lowerCamel}Dao.updateDeleted(${primaryKeyFieldName},true); +#end +#if(${deleteInfo.isPhysicallyDeleted}) + ${name.lowerCamel}Dao.deleteById(${primaryKeyFieldName}); +#end + return ResponseDTO.ok(); + } + #end +#end +} diff --git a/sa-common/src/main/resources/code-generator-template/js/api.js.vm b/sa-common/src/main/resources/code-generator-template/js/api.js.vm new file mode 100644 index 0000000..b249d0c --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/js/api.js.vm @@ -0,0 +1,78 @@ +/** + * ${basic.description} api 封装 + * + * @Author: ${basic.frontAuthor} + * @Date: ${basic.frontDate} + * @Copyright ${basic.copyright} + */ +import { postRequest, getRequest } from '/@/lib/axios'; + +export const ${name.lowerCamel}Api = { + + /** + * 分页查询 @author ${basic.frontAuthor} + */ + queryPage : (param) => { + return postRequest('/${name.lowerCamel}/queryPage', param); + }, + + /** + * 增加 @author ${basic.frontAuthor} + */ + add: (param) => { + return postRequest('/${name.lowerCamel}/add', param); + }, + + /** + * 修改 @author ${basic.frontAuthor} + */ + update: (param) => { + return postRequest('/${name.lowerCamel}/update', param); + }, +## ------------------ 详情 ------------------ + +#if($deleteInfo.isSupportDetail) + /** + * 获取详情 @author ${basic.frontAuthor} + */ + getDetail: (id) => { + return getRequest(`/${name.lowerCamel}/getDetail/\${id}`); + }, +#end + +## ------------------ 删除 ------------------ +#if($deleteInfo.isSupportDelete) + #if($deleteInfo.deleteEnum == 'Single') + /** + * 删除 @author ${basic.frontAuthor} + */ + delete: (id) => { + return getRequest(`/${name.lowerCamel}/delete/${id}`); + }, + #end + #if($deleteInfo.deleteEnum == 'Batch') + /** + * 批量删除 @author ${basic.frontAuthor} + */ + batchDelete: (idList) => { + return postRequest('/${name.lowerCamel}/batchDelete', idList); + }, + #end + #if($deleteInfo.deleteEnum == 'SingleAndBatch') + /** + * 删除 @author ${basic.frontAuthor} + */ + delete: (id) => { + return getRequest(`/${name.lowerCamel}/delete/${id}`); + }, + + /** + * 批量删除 @author ${basic.frontAuthor} + */ + batchDelete: (idList) => { + return postRequest('/${name.lowerCamel}/batchDelete', idList); + }, + #end +#end + +}; diff --git a/sa-common/src/main/resources/code-generator-template/js/const.js.vm b/sa-common/src/main/resources/code-generator-template/js/const.js.vm new file mode 100644 index 0000000..30ca06a --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/js/const.js.vm @@ -0,0 +1,23 @@ +/** + * ${basic.description} 枚举 + * + * @Author: ${basic.frontAuthor} + * @Date: ${basic.frontDate} + * @Copyright ${basic.copyright} + */ + +#foreach ($enum in $enumList) + +/** + * $enum.columnComment + */ +export const $enum.upperUnderscoreEnum = { + +} +#end + +export default { +#foreach ($enum in $enumList) + $enum.upperUnderscoreEnum, +#end +}; \ No newline at end of file diff --git a/sa-common/src/main/resources/code-generator-template/js/form.vue.vm b/sa-common/src/main/resources/code-generator-template/js/form.vue.vm new file mode 100644 index 0000000..fa5da6a --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/js/form.vue.vm @@ -0,0 +1,235 @@ + + + diff --git a/sa-common/src/main/resources/code-generator-template/js/list.vue.vm b/sa-common/src/main/resources/code-generator-template/js/list.vue.vm new file mode 100644 index 0000000..83a7d76 --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/js/list.vue.vm @@ -0,0 +1,314 @@ + + + diff --git a/sa-common/src/main/resources/code-generator-template/tools.xml b/sa-common/src/main/resources/code-generator-template/tools.xml new file mode 100644 index 0000000..7f8f868 --- /dev/null +++ b/sa-common/src/main/resources/code-generator-template/tools.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/sa-common/src/main/resources/dev/sa-common.yaml b/sa-common/src/main/resources/dev/sa-common.yaml new file mode 100644 index 0000000..a220841 --- /dev/null +++ b/sa-common/src/main/resources/dev/sa-common.yaml @@ -0,0 +1,127 @@ +spring: + # 数据库连接信息 + datasource: + url: jdbc:p6spy:mysql://42.193.16.243:30001/case_collection?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai + username: root + password: gdxz123456^%$d + initial-size: 2 + min-idle: 2 + max-active: 10 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + driver-class-name: com.p6spy.engine.spy.P6SpyDriver + filters: stat + druid: + username: druid + password: 1024 + login: + enabled: false + method: + pointcut: net.lab1024.sa..*Service.* + + # mvc swagger bugfix + mvc: + pathmatch: + matching-strategy: ant_path_matcher + + # redis 连接池配置信息 +# redis: +# database: 1 +# host: 127.0.0.1 +# lettuce: +# pool: +# max-active: 5 +# min-idle: 1 +# max-idle: 3 +# max-wait: 30000ms +# port: 6379 +# timeout: 10000ms +# password: + + # 上传文件大小配置 + servlet: + multipart: + max-file-size: 30MB + max-request-size: 30MB + + # json序列化相关配置 + jackson: + serialization: + write-enums-using-to-string: true + write-dates-as-timestamps: false + deserialization: + read-enums-using-to-string: true + fail-on-unknown-properties: false + default-property-inclusion: always + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + + # 缓存实现类型 + cache: + type: caffeine + +#swagger: 提高swagger 方法名称有重复的日志提示 +logging: + level: + springfox: + documentation: + spring: + web: + readers: + operation: + CachingOperationNameGenerator: warn + scanners: + ApiListingReferenceScanner: warn + +# 文件上传 配置 +file: + storage: + mode: cloud + local: + path: ${localPath:/home}/smart_admin_v2/upload/ + cloud: + region: oss-cn-beijing + endpoint: oss-cn-beijing.aliyuncs.com + bucket-name: medical-case + access-key: LTAI5tAkZSLF5xbFGPVqmYeq + secret-key: ETrDjr35Ty2uMSqulOuk2Yky5R1R0Y + url: + expire: 7200000 + public: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/ + +# swagger 配置 +swagger: + title: 病例系统 + description: 病例系统 1.0 + version: 2.0 + host: localhost:${server.port} + package: + tag-class: net.lab1024.sa.common.constant.SwaggerTagConst + team-url: + +# RestTemplate 请求配置 +http: + pool: + max-total: 20 + connect-timeout: 50000 + read-timeout: 50000 + write-timeout: 50000 + keep-alive: 300000 + +# token相关配置 +token: + key: gdxz-jwt-key + admin-expire-minute: 60 + app-expire-minute: 527040 + +# 跨域配置 +access-control-allow-origin: '*' + +# 心跳配置 +heart-beat: + interval-seconds: 300 + +# 热加载配置 +reload: + interval-seconds: 300 diff --git a/sa-common/src/main/resources/mapper/support/ChangeLogMapper.xml b/sa-common/src/main/resources/mapper/support/ChangeLogMapper.xml new file mode 100644 index 0000000..7f5b7db --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/ChangeLogMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/CodeGeneratorMapper.xml b/sa-common/src/main/resources/mapper/support/CodeGeneratorMapper.xml new file mode 100644 index 0000000..4376fac --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/CodeGeneratorMapper.xml @@ -0,0 +1,36 @@ + + + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/ConfigMapper.xml b/sa-common/src/main/resources/mapper/support/ConfigMapper.xml new file mode 100644 index 0000000..1fb8474 --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/ConfigMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/DataTracerMapper.xml b/sa-common/src/main/resources/mapper/support/DataTracerMapper.xml new file mode 100644 index 0000000..546e62a --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/DataTracerMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/DictKeyMapper.xml b/sa-common/src/main/resources/mapper/support/DictKeyMapper.xml new file mode 100644 index 0000000..619269b --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/DictKeyMapper.xml @@ -0,0 +1,37 @@ + + + + + + update t_dict_key set deleted_flag = #{deletedFlag} where dict_key_id in + + #{item} + + + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/DictValueMapper.xml b/sa-common/src/main/resources/mapper/support/DictValueMapper.xml new file mode 100644 index 0000000..6f0fbc1 --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/DictValueMapper.xml @@ -0,0 +1,44 @@ + + + + + + update t_dict_value set deleted_flag = #{deletedFlag} where dict_value_id in + + #{item} + + + + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/FeedbackMapper.xml b/sa-common/src/main/resources/mapper/support/FeedbackMapper.xml new file mode 100644 index 0000000..740037a --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/FeedbackMapper.xml @@ -0,0 +1,26 @@ + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/FileMapper.xml b/sa-common/src/main/resources/mapper/support/FileMapper.xml new file mode 100644 index 0000000..405f79f --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/FileMapper.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/HeartBeatRecordMapper.xml b/sa-common/src/main/resources/mapper/support/HeartBeatRecordMapper.xml new file mode 100644 index 0000000..e37f08a --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/HeartBeatRecordMapper.xml @@ -0,0 +1,37 @@ + + + + + + + update t_heart_beat_record + set heart_beat_time = #{heartBeatTime} + + heart_beat_record_id = #{id} + + + + + + + + diff --git a/sa-common/src/main/resources/mapper/support/HelpDocDao.xml b/sa-common/src/main/resources/mapper/support/HelpDocDao.xml new file mode 100644 index 0000000..6bbbf5e --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/HelpDocDao.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + update t_help_doc + set page_view_count = page_view_count + #{pageViewCountIncrease}, + user_view_count = user_view_count + #{userViewCountIncrease} + where help_doc_id = #{helpDocId} + + + + + + + + + + insert into t_help_doc_relation + (relation_id, relation_name, help_doc_id) + values + + ( #{item.relationId} ,#{item.relationName}, #{helpDocId} ) + + + + + delete + from t_help_doc_relation + where help_doc_id = #{helpDocId} + + + + + + + + insert into t_help_doc_view_record (help_doc_id, user_id,user_name, first_ip, first_user_agent, page_view_count) + values (#{helpDocId}, #{userId},#{userName}, #{ip}, #{userAgent}, #{pageViewCount}) + + + update t_help_doc_view_record + set page_view_count = page_view_count + 1, + last_ip = #{ip}, + last_user_agent = #{userAgent} + where help_doc_id = #{helpDocId} + and user_id = #{userId} + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/LoginLogMapper.xml b/sa-common/src/main/resources/mapper/support/LoginLogMapper.xml new file mode 100644 index 0000000..6126a29 --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/LoginLogMapper.xml @@ -0,0 +1,37 @@ + + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/OperateLogMapper.xml b/sa-common/src/main/resources/mapper/support/OperateLogMapper.xml new file mode 100644 index 0000000..e432a89 --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/OperateLogMapper.xml @@ -0,0 +1,37 @@ + + + + + + + + delete from t_operate_log where id = #{id} + + + + delete from t_operate_log where id in + + #{item} + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/ReloadItemMapper.xml b/sa-common/src/main/resources/mapper/support/ReloadItemMapper.xml new file mode 100644 index 0000000..85b6ffb --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/ReloadItemMapper.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/ReloadResultMapper.xml b/sa-common/src/main/resources/mapper/support/ReloadResultMapper.xml new file mode 100644 index 0000000..a1f96b8 --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/ReloadResultMapper.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/SerialNumberMapper.xml b/sa-common/src/main/resources/mapper/support/SerialNumberMapper.xml new file mode 100644 index 0000000..3afd34a --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/SerialNumberMapper.xml @@ -0,0 +1,21 @@ + + + + + + update t_serial_number + set + last_number = #{lastNumber}, + last_time = #{lastTime} + where + serial_number_id = #{serialNumberId} + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/SerialNumberRecordMapper.xml b/sa-common/src/main/resources/mapper/support/SerialNumberRecordMapper.xml new file mode 100644 index 0000000..f13636a --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/SerialNumberRecordMapper.xml @@ -0,0 +1,32 @@ + + + + + + update t_serial_number_record + set last_number = #{lastNumber}, + count = count + #{count} + where + serial_number_id = #{serialNumberId} + and + record_date = #{recordDate} + + + + + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/mapper/support/TableColumnMapper.xml b/sa-common/src/main/resources/mapper/support/TableColumnMapper.xml new file mode 100644 index 0000000..530888b --- /dev/null +++ b/sa-common/src/main/resources/mapper/support/TableColumnMapper.xml @@ -0,0 +1,18 @@ + + + + + delete + from t_table_column + where user_id = #{userId} + and table_id = #{tableId} + + + + \ No newline at end of file diff --git a/sa-common/src/main/resources/pre/sa-common.yaml b/sa-common/src/main/resources/pre/sa-common.yaml new file mode 100644 index 0000000..c3adfeb --- /dev/null +++ b/sa-common/src/main/resources/pre/sa-common.yaml @@ -0,0 +1,127 @@ +spring: + # 数据库连接信息 + datasource: + url: jdbc:mysql://127.0.0.1:3306/smart_case?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai + username: root + password: Zhuoda123456 + initial-size: 5 + min-idle: 5 + max-active: 50 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + driver-class-name: com.mysql.cj.jdbc.Driver + filters: stat + druid: + username: druid + password: 1024 + login: + enabled: true + method: + pointcut: net.lab1024.sa..*Service.* + + # mvc swagger bugfix + mvc: + pathmatch: + matching-strategy: ant_path_matcher + + # redis 连接池配置信息 +# redis: +# database: 1 +# host: 127.0.0.1 +# lettuce: +# pool: +# max-active: 50 +# min-idle: 5 +# max-idle: 5 +# max-wait: 30000ms +# port: 6379 +# timeout: 10000ms +# password: + + # 上传文件大小配置 + servlet: + multipart: + max-file-size: 30MB + max-request-size: 30MB + + # json序列化相关配置 + jackson: + serialization: + write-enums-using-to-string: true + write-dates-as-timestamps: false + deserialization: + read-enums-using-to-string: true + fail-on-unknown-properties: false + default-property-inclusion: always + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + + # 缓存实现类型 + cache: + type: caffeine + +#swagger: 提高swagger 方法名称有重复的日志提示 +logging: + level: + springfox: + documentation: + spring: + web: + readers: + operation: + CachingOperationNameGenerator: warn + scanners: + ApiListingReferenceScanner: warn + +# 文件上传 配置 +file: + storage: + mode: cloud + local: + path: ${localPath:/home}/smart_admin_v2/upload/ + cloud: + region: oss-cn-beijing + endpoint: oss-cn-beijing.aliyuncs.com + bucket-name: medical-case + access-key: LTAI5tAkZSLF5xbFGPVqmYeq + secret-key: ETrDjr35Ty2uMSqulOuk2Yky5R1R0Y + url: + expire: 7200000 + public: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/ + +# swagger 配置 +swagger: + title: 病例系统 + description: 病例系统 1.0 + version: 2.0 + host: localhost:${server.port} + package: + tag-class: net.lab1024.sa.common.constant.SwaggerTagConst + team-url: + +# RestTemplate 请求配置 +http: + pool: + max-total: 20 + connect-timeout: 50000 + read-timeout: 50000 + write-timeout: 50000 + keep-alive: 300000 + +# token相关配置 +token: + key: gdxz-jwt-key + admin-expire-minute: 60 + app-expire-minute: 527040 + +# 跨域配置 +access-control-allow-origin: '*' + +# 心跳配置 +heart-beat: + interval-seconds: 60 + +# 热加载配置 +reload: + interval-seconds: 60 \ No newline at end of file diff --git a/sa-common/src/main/resources/prod----ttt/sa-common.yaml b/sa-common/src/main/resources/prod----ttt/sa-common.yaml new file mode 100644 index 0000000..41a2926 --- /dev/null +++ b/sa-common/src/main/resources/prod----ttt/sa-common.yaml @@ -0,0 +1,127 @@ +spring: + # 数据库连接信息 + datasource: + url: jdbc:mysql://rm-2zegy6343is77861l9o.mysql.rds.aliyuncs.com:3309/case_admin?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai + username: a6d4dsqej2 + password: Kt#&z3zYbkdOEr$u$x08hT!erXztgpsY + initial-size: 10 + min-idle: 10 + max-active: 100 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + driver-class-name: com.mysql.cj.jdbc.Driver + filters: stat + druid: + username: druid + password: 2&wTJ$3!i@2M#g*YQ7uRMgX7ONWw@iNf + login: + enabled: true + method: + pointcut: net.lab1024.sa..*Service.* + + # mvc swagger bugfix + mvc: + pathmatch: + matching-strategy: ant_path_matcher + + # redis 连接池配置信息 +# redis: +# database: 1 +# host: 127.0.0.1 +# lettuce: +# pool: +# max-active: 100 +# min-idle: 10 +# max-idle: 10 +# max-wait: 30000ms +# port: 6379 +# timeout: 10000ms +# password: + + # 上传文件大小配置 + servlet: + multipart: + max-file-size: 30MB + max-request-size: 30MB + + # json序列化相关配置 + jackson: + serialization: + write-enums-using-to-string: true + write-dates-as-timestamps: false + deserialization: + read-enums-using-to-string: true + fail-on-unknown-properties: false + default-property-inclusion: always + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + + # 缓存实现类型 + cache: + type: caffeine + +#swagger: 提高swagger 方法名称有重复的日志提示 +logging: + level: + springfox: + documentation: + spring: + web: + readers: + operation: + CachingOperationNameGenerator: warn + scanners: + ApiListingReferenceScanner: warn + +# 文件上传 配置 +file: + storage: + mode: cloud + local: + path: ${localPath:/home}/smart_admin_v2/upload/ + cloud: + region: oss-cn-beijing + endpoint: oss-cn-beijing.aliyuncs.com + bucket-name: medical-case + access-key: LTAI5tAkZSLF5xbFGPVqmYeq + secret-key: ETrDjr35Ty2uMSqulOuk2Yky5R1R0Y + url: + expire: 7200000 + public: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/ + +# swagger 配置 +swagger: + title: 病例系统 + description: 病例系统 1.0 + version: 2.0 + host: localhost:${server.port} + package: + tag-class: net.lab1024.sa.common.constant.SwaggerTagConst + team-url: + +# RestTemplate 请求配置 +http: + pool: + max-total: 20 + connect-timeout: 50000 + read-timeout: 50000 + write-timeout: 50000 + keep-alive: 300000 + +# token相关配置 +token: + key: gdxz-jwt-key + admin-expire-minute: 60 + app-expire-minute: 527040 + +# 跨域配置 +access-control-allow-origin: '*' + +# 心跳配置 +heart-beat: + interval-seconds: 60 + +# 热加载配置 +reload: + interval-seconds: 60 \ No newline at end of file diff --git a/sa-common/src/main/resources/test/sa-common.yaml b/sa-common/src/main/resources/test/sa-common.yaml new file mode 100644 index 0000000..2d50ddb --- /dev/null +++ b/sa-common/src/main/resources/test/sa-common.yaml @@ -0,0 +1,128 @@ +spring: + # 数据库连接信息 + datasource: + url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_case?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai + username: gdxz + password: Gdxz$20150501 + initial-size: 2 + min-idle: 5 + max-active: 20 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + driver-class-name: com.p6spy.engine.spy.P6SpyDriver + filters: stat + druid: + username: druid + password: 1024 + login: + enabled: true + method: + pointcut: net.lab1024.sa..*Service.* + + # mvc swagger bugfix + mvc: + pathmatch: + matching-strategy: ant_path_matcher + + # redis 连接池配置信息 +# redis: +# database: 1 +# host: 127.0.0.1 +# lettuce: +# pool: +# max-active: 10 +# min-idle: 1 +# max-idle: 3 +# max-wait: 30000ms +# port: 6379 +# timeout: 10000ms +# password: + + # 上传文件大小配置 + servlet: + multipart: + max-file-size: 30MB + max-request-size: 30MB + + # json序列化相关配置 + jackson: + serialization: + write-enums-using-to-string: true + write-dates-as-timestamps: false + deserialization: + read-enums-using-to-string: true + fail-on-unknown-properties: false + default-property-inclusion: always + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + + # 缓存实现类型 + cache: + type: caffeine + + +#swagger: 提高swagger 方法名称有重复的日志提示 +logging: + level: + springfox: + documentation: + spring: + web: + readers: + operation: + CachingOperationNameGenerator: warn + scanners: + ApiListingReferenceScanner: warn + +# 文件上传 配置 +file: + storage: + mode: cloud + local: + path: ${localPath:/home}/smart_admin_v2/upload/ + cloud: + region: oss-cn-beijing + endpoint: oss-cn-beijing.aliyuncs.com + bucket-name: medical-case + access-key: LTAI5tAkZSLF5xbFGPVqmYeq + secret-key: ETrDjr35Ty2uMSqulOuk2Yky5R1R0Y + url: + expire: 7200000 + public: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/ + +# swagger 配置 +swagger: + title: 病例系统 + description: 病例系统 1.0 + version: 2.0 + host: localhost:${server.port} + package: + tag-class: net.lab1024.sa.common.constant.SwaggerTagConst + team-url: + +# RestTemplate 请求配置 +http: + pool: + max-total: 20 + connect-timeout: 50000 + read-timeout: 50000 + write-timeout: 50000 + keep-alive: 300000 + +# token相关配置 +token: + key: gdxz-jwt-key + admin-expire-minute: 60 + app-expire-minute: 527040 + +# 跨域配置 +access-control-allow-origin: '*' + +# 心跳配置 +heart-beat: + interval-seconds: 60 + +# 热加载配置 +reload: + interval-seconds: 60