From d5984685e7efd46a5e850ade13b22fa727163a47 Mon Sep 17 00:00:00 2001
From: k94314517 <8417338+k94314517@user.noreply.gitee.com>
Date: 星期三, 09 七月 2025 16:33:39 +0800
Subject: [PATCH] 111
---
server/services/src/main/java/com/doumee/dao/system/model/SystemUser.java | 88
server/services/src/main/java/com/doumee/config/shiro/ShiroSessionSerializer.java | 36
server/services/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java | 112
server/services/src/main/java/com/doumee/biz/system/impl/SystemDictBizImpl.java | 40
server/services/src/main/java/com/doumee/config/interfaceencryption/tool/RSAEncrypt.java | 104
server/services/src/main/java/com/doumee/dao/system/SystemDictMapper.java | 21
server/services/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java | 44
server/services/src/main/java/com/doumee/core/constants/Constants.java | 330
server/services/src/main/java/com/doumee/core/utils/FtpUtil.java | 768 +
server/services/src/main/java/com/doumee/service/business/impl/IdentityInfoServiceImpl.java | 188
server/services/src/main/java/com/doumee/config/shiro/ShiroConfig.java | 126
server/services/src/main/java/com/doumee/biz/system/SystemRoleBiz.java | 58
server/admin/src/main/resources/application.yml | 89
server/services/src/main/java/com/doumee/dao/business/model/Category.java | 77
server/services/src/main/java/com/doumee/dao/system/SystemJobLogMapper.java | 7
server/services/src/main/java/com/doumee/service/business/impl/MultifileServiceImpl.java | 125
server/services/src/main/java/com/doumee/api/system/SystemRoleController.java | 106
server/services/src/main/java/com/doumee/service/common/CaptchaService.java | 149
server/services/src/main/java/com/doumee/api/BaseController.java | 56
server/services/src/main/java/com/doumee/dao/system/dto/CreateSystemUserDTO.java | 17
server/services/src/main/java/com/doumee/config/interfaceencryption/EncryptResponseBodyAdvice.java | 105
server/services/src/main/java/com/doumee/service/system/impl/SystemTraceLogServiceImpl.java | 126
server/services/src/main/java/com/doumee/dao/system/model/SystemMenu.java | 73
server/services/src/main/java/com/doumee/config/quartz/JobHandlerWithDisallowConcurrent.java | 39
server/services/src/main/resources/application-pro.yml | 57
server/services/src/main/java/com/doumee/core/annotation/trace/TraceInterceptorConfig.java | 23
server/services/src/main/java/com/doumee/dao/business/model/Orders.java | 245
server/services/src/main/java/com/doumee/config/swagger/SwaggerInterceptorConfig.java | 23
server/admin/pom.xml | 75
server/services/src/main/java/com/doumee/config/exception/GlobalExceptionAdvice.java | 79
server/services/src/main/java/com/doumee/service/common/CacheProxy.java | 165
server/services/src/main/java/com/doumee/api/system/SystemDictController.java | 77
server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemDictDataDTO.java | 19
server/services/src/main/java/com/doumee/dao/system/SystemMenuMapper.java | 34
server/services/src/main/java/com/doumee/biz/system/SystemUserBiz.java | 65
server/services/src/main/java/com/doumee/service/system/impl/SystemUserRoleServiceImpl.java | 113
server/services/src/main/java/com/doumee/service/system/impl/SystemRoleServiceImpl.java | 115
server/services/src/main/java/com/doumee/dao/business/model/WithdrawalOrders.java | 78
server/services/src/main/java/com/doumee/dao/system/model/SystemRoleMenu.java | 46
server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateRequestWrapper.java | 78
server/services/src/main/java/com/doumee/api/business/WebApiController.java | 23
server/services/src/main/resources/mappers/SystemPermissionMapper.xml | 57
server/services/src/main/java/com/doumee/service/business/WithdrawalOrdersService.java | 97
server/services/src/main/java/com/doumee/service/system/SystemJobSnippetService.java | 97
server/services/src/main/java/com/doumee/config/interfaceencryption/DecryptRequestBodyAdvice.java | 101
server/services/src/main/resources/mappers/SystemJobListMapper.xml | 47
server/web/src/main/java/com/doumee/JKWebApplication.java | 31
server/services/src/main/java/com/doumee/service/business/IdentityInfoService.java | 97
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserExtAttrResponse.java | 18
server/services/src/main/java/com/doumee/biz/system/SystemJobBiz.java | 26
server/services/src/main/resources/application-dev.yml | 87
server/services/src/main/java/com/doumee/service/system/impl/SystemMenuServiceImpl.java | 140
server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java | 148
server/services/src/main/java/com/doumee/service/system/impl/SystemJobLogServiceImpl.java | 119
server/services/src/main/java/com/doumee/dao/system/model/SystemRole.java | 58
server/services/src/main/java/com/doumee/dao/system/dto/CreateUserRoleDTO.java | 29
server/services/src/main/java/com/doumee/core/utils/DateHelper.java | 81
server/services/src/main/java/com/doumee/service/system/impl/SystemRoleMenuServiceImpl.java | 113
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxSendMsgResponse.java | 28
server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java | 275
server/services/src/main/java/com/doumee/dao/business/model/Member.java | 147
server/services/src/main/java/com/doumee/biz/system/SystemMenuBiz.java | 67
server/services/src/main/java/com/doumee/api/common/LocalFileAccessController.java | 43
server/services/src/main/java/com/doumee/biz/system/dto/TriggerJobDTO.java | 39
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxSendMsgRequest.java | 32
server/services/src/main/java/com/doumee/dao/system/vo/SystemMenuListVO.java | 30
server/services/src/main/java/com/doumee/core/annotation/trace/Trace.java | 44
server/services/src/main/java/com/doumee/dao/business/model/OrderLog.java | 85
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxBaseResponse.java | 34
server/services/src/main/java/com/doumee/dao/system/vo/SystemJobListVO.java | 69
server/services/src/main/java/com/doumee/core/job/JobParam.java | 73
server/services/src/main/java/com/doumee/core/utils/Http.java | 239
server/services/src/main/java/com/doumee/core/job/SchedulerProxy.java | 69
server/services/src/main/java/com/doumee/dao/system/dto/CreateRolePermissionDTO.java | 29
server/services/src/main/java/com/doumee/core/utils/Location.java | 72
server/services/src/main/java/com/doumee/service/system/impl/SystemRolePermissionServiceImpl.java | 113
server/services/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java | 41
server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemRoleDTO.java | 22
server/services/src/main/java/com/doumee/dao/system/vo/SystemDictDataListVO.java | 22
server/services/src/main/java/com/doumee/config/mybatis/MyBatisPlusConfig.java | 23
server/services/src/main/java/com/doumee/biz/system/impl/SystemMenuBizImpl.java | 226
server/services/src/main/java/com/doumee/dao/business/IdentityInfoMapper.java | 12
server/services/src/main/java/com/doumee/dao/system/SystemRolePermissionMapper.java | 8
server/services/src/main/java/com/doumee/config/annotation/EncryptionResp.java | 14
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserInfoResponse.java | 54
server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemLoginLogDTO.java | 22
server/services/src/main/java/com/doumee/dao/system/dto/ResetSystemUserPwdDTO.java | 29
server/services/src/main/java/com/doumee/biz/system/SystemDictDataBiz.java | 54
server/services/src/main/java/com/doumee/dao/system/vo/SystemDictListVO.java | 22
server/services/src/main/java/com/doumee/biz/system/dto/TriggerJobSnippetDTO.java | 24
server/services/src/main/java/com/doumee/service/system/SystemMenuService.java | 120
server/services/src/main/java/com/doumee/dao/business/MemberMapper.java | 12
server/services/src/main/java/com/doumee/config/mybatis/DmStdOutImpl.java | 62
server/services/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java | 25
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxBaseRequest.java | 20
server/services/src/main/java/com/doumee/dao/system/SystemTraceLogMapper.java | 8
server/services/src/main/java/com/doumee/core/utils/AESUtils.java | 35
server/services/src/main/java/com/doumee/service/system/SystemDictService.java | 93
server/services/src/main/java/com/doumee/biz/system/SystemJobTriggerBiz.java | 18
server/services/src/main/resources/application-test.yml | 77
server/services/src/main/resources/mappers/SystemUserMapper.xml | 41
server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemUserDTO.java | 38
server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java | 20
server/services/src/main/java/com/doumee/dao/system/vo/SystemRoleListVO.java | 32
server/services/src/main/java/com/doumee/api/system/SystemUserController.java | 105
server/services/src/main/java/com/doumee/dao/system/model/SystemTraceLog.java | 94
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserListResponse.java | 54
server/services/pom.xml | 20
server/services/src/main/java/com/doumee/service/system/impl/SystemJobListServiceImpl.java | 33
server/services/src/main/java/com/doumee/dao/business/WithdrawalOrdersMapper.java | 12
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/QywxUtil.java | 253
server/services/src/main/resources/logback-spring.xml | 80
server/services/src/main/java/com/doumee/dao/system/vo/SystemPermissionListVO.java | 36
server/services/src/main/java/com/doumee/api/system/SystemJobController.java | 124
server/services/src/main/java/com/doumee/service/system/SystemRoleMenuService.java | 97
server/services/src/main/java/com/doumee/core/exception/BusinessException.java | 35
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUploadMediaResponse.java | 22
server/services/src/main/java/com/doumee/dao/system/model/SystemJobLog.java | 79
server/services/src/main/java/com/doumee/core/utils/MyBatisPlus.java | 36
server/services/src/main/java/com/doumee/dao/business/model/MemberRevenue.java | 90
server/services/src/main/java/com/doumee/dao/system/model/SystemDictData.java | 66
server/services/src/main/java/com/doumee/biz/system/impl/SystemJobSnippetTriggerBizImpl.java | 231
server/services/src/main/java/com/doumee/service/system/SystemJobLogService.java | 98
server/services/src/main/java/com/doumee/dao/business/OrdersMapper.java | 12
server/web/src/main/resources/application.yml | 89
server/services/src/main/java/com/doumee/core/utils/azure/AzureBlobUtil.java | 82
server/services/src/main/java/com/doumee/dao/system/SystemUserMapper.java | 22
server/services/src/main/java/com/doumee/service/business/CategoryService.java | 97
server/services/src/main/java/com/doumee/core/exception/UnSafeSessionException.java | 13
server/services/src/main/java/com/doumee/job/DistributableTestJobDistributer.java | 27
server/services/src/main/java/com/doumee/config/swagger/SwaggerConfig.java | 118
server/services/src/main/java/com/doumee/config/annotation/UserLoginRequired.java | 12
server/services/src/main/java/com/doumee/dao/system/dto/DeleteSystemPermissionDTO.java | 20
server/services/src/main/java/com/doumee/core/utils/Monitor.java | 163
server/services/src/main/java/com/doumee/dao/system/model/SystemUserRole.java | 46
server/services/src/main/java/com/doumee/service/system/impl/SystemDictServiceImpl.java | 97
server/services/src/main/java/com/doumee/api/system/SystemLoginLogController.java | 44
server/services/src/main/java/com/doumee/core/utils/Server.java | 92
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/QywxConstant.java | 32
server/services/src/main/java/com/doumee/core/utils/monitor/Memory.java | 32
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxTextCardMsgRequest.java | 22
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxBaseSingleResponse.java | 21
server/services/src/main/java/com/doumee/service/business/MultifileService.java | 97
server/services/src/main/java/com/doumee/core/model/PageWrap.java | 105
server/services/src/main/java/com/doumee/config/quartz/JobInitializer.java | 81
server/services/src/main/java/com/doumee/core/utils/ApplicationContextHelper.java | 48
server/services/src/main/java/com/doumee/dao/business/MemberRevenueMapper.java | 12
server/services/src/main/java/com/doumee/job/DistributableTestJob.java | 36
server/services/src/main/java/com/doumee/service/system/SystemUserService.java | 93
server/services/src/main/java/com/doumee/core/annotation/trace/TraceStatus.java | 21
server/services/src/main/java/com/doumee/core/model/ApiResponse.java | 146
server/services/src/main/java/com/doumee/core/job/BaseJob.java | 17
server/services/src/main/java/com/doumee/dao/system/SystemRoleMenuMapper.java | 8
server/services/src/main/java/com/doumee/dao/system/dto/QueryJobDTO.java | 18
server/services/src/main/java/com/doumee/biz/system/SystemDictBiz.java | 27
server/services/src/main/java/com/doumee/api/system/SystemJobSnippetController.java | 75
server/services/src/main/java/com/doumee/api/common/PublicCloudController.java | 190
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserAttrValResponse.java | 16
server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatAdapter.java | 107
server/services/src/main/java/com/doumee/service/business/ReceiveWeightService.java | 97
server/services/src/main/java/com/doumee/core/job/JobContext.java | 21
server/admin/src/main/java/com/doumee/JKAdminApplication.java | 31
server/services/src/main/java/com/doumee/dao/system/SystemUserRoleMapper.java | 8
server/services/src/main/java/com/doumee/dao/system/SystemRoleMapper.java | 30
server/services/src/main/java/com/doumee/dao/system/SystemDictDataMapper.java | 20
server/services/src/main/java/com/doumee/core/utils/DateUtil.java | 3630 ++++++++
server/services/src/main/java/com/doumee/dao/business/CategoryMapper.java | 12
server/services/src/main/java/com/doumee/core/utils/Week.java | 45
server/services/src/main/java/com/doumee/api/system/SystemTraceLogController.java | 43
server/services/src/main/java/com/doumee/core/utils/AES.java | 96
server/services/src/main/java/com/doumee/api/system/SystemController.java | 76
server/services/src/main/java/com/doumee/core/annotation/trace/TraceType.java | 34
server/services/src/main/java/com/doumee/core/model/PageData.java | 82
server/services/src/main/java/com/doumee/config/interfaceencryption/tool/RSAEncryptTest.java | 87
server/services/src/main/java/com/doumee/service/common/EmailService.java | 79
server/services/src/main/java/com/doumee/biz/system/SystemJobSnippetTriggerBiz.java | 18
server/services/src/main/resources/mappers/SystemMenuMapper.xml | 58
server/services/src/main/java/com/doumee/config/mybatis/MyBatisInterceptor.java | 125
server/services/src/main/java/com/doumee/service/system/SystemTraceLogService.java | 91
server/services/src/main/java/com/doumee/config/shiro/ShiroCache.java | 159
server/services/src/main/java/com/doumee/api/system/SystemPermissionController.java | 82
server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatInterceptorConfig.java | 23
server/services/src/main/java/com/doumee/core/servlet/ServletRewriteFilter.java | 45
server/services/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java | 27
server/services/src/main/java/com/doumee/core/utils/ThreadPool.java | 20
server/services/src/main/java/com/doumee/core/model/LoginUserInfo.java | 74
server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemJobLogDTO.java | 39
server/services/src/main/java/com/doumee/service/system/SystemUserRoleService.java | 97
server/services/src/main/java/com/doumee/config/quartz/JobHandler.java | 37
server/services/src/main/java/com/doumee/core/utils/monitor/JVM.java | 50
server/services/src/main/java/com/doumee/core/utils/UserClient.java | 126
server/services/src/main/java/com/doumee/service/business/OrdersService.java | 97
server/services/src/main/java/com/doumee/dao/system/SystemLoginLogMapper.java | 8
server/services/src/main/java/com/doumee/core/annotation/excel/ExcelDataHandlerAdapter.java | 17
server/services/src/main/java/com/doumee/dao/business/model/IdentityInfo.java | 131
server/services/src/main/java/com/doumee/dao/common/dto/UpdateSortDTO.java | 26
server/services/src/main/java/com/doumee/job/CommonTestJob.java | 29
server/services/src/main/java/com/doumee/biz/system/impl/SystemJobBizImpl.java | 49
server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemPermissionDTO.java | 23
server/services/src/main/resources/mappers/SystemDictMapper.xml | 37
server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemTraceLogDTO.java | 24
server/services/src/main/java/com/doumee/core/annotation/excel/ExcelImporter.java | 394
server/services/src/main/java/com/doumee/config/shiro/ShiroRealm.java | 80
server/services/src/main/java/com/doumee/dao/system/model/SystemLoginLog.java | 60
server/services/src/main/java/com/doumee/core/config/ProjectConfig.java | 45
server/services/src/main/java/com/doumee/dao/business/MultifileMapper.java | 12
server/services/src/main/java/com/doumee/service/system/SystemDictDataService.java | 101
server/services/src/main/java/com/doumee/dao/system/model/SystemRolePermission.java | 46
server/services/src/main/java/com/doumee/service/business/OrderLogService.java | 97
server/services/src/main/java/com/doumee/config/annotation/LoginRequired.java | 10
server/services/src/main/java/com/doumee/service/business/impl/MemberRevenueServiceImpl.java | 157
server/services/src/main/java/com/doumee/core/constants/ResponseStatus.java | 37
server/services/src/main/java/com/doumee/biz/system/impl/SystemRoleBizImpl.java | 113
server/services/src/main/resources/mappers/SystemDictDataMapper.xml | 33
server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java | 76
server/services/src/main/java/com/doumee/api/system/SystemMonitorController.java | 31
server/services/src/main/java/com/doumee/service/system/SystemJobService.java | 87
server/services/src/main/java/com/doumee/api/common/CaptchaController.java | 32
server/services/src/main/java/com/doumee/config/cache/RedisValueDefaultSerializer.java | 56
server/services/src/main/java/com/doumee/service/business/impl/OrderLogServiceImpl.java | 154
server/services/src/main/java/com/doumee/ContextFinalizer.java | 33
server/services/src/main/java/com/doumee/core/utils/Utils.java | 84
server/services/src/main/java/com/doumee/core/utils/monitor/CPU.java | 37
server/services/src/main/java/com/doumee/dao/system/model/SystemJobSnippet.java | 74
server/services/src/main/java/com/doumee/core/job/BaseDistributer.java | 58
server/services/src/main/java/com/doumee/dao/system/SystemJobSnippetMapper.java | 7
server/services/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java | 87
server/services/src/main/java/com/doumee/dao/system/SystemPermissionMapper.java | 36
server/services/src/main/java/com/doumee/service/system/impl/SystemDictDataServiceImpl.java | 131
server/services/src/main/java/com/doumee/service/system/impl/SystemPermissionServiceImpl.java | 189
server/services/src/main/java/com/doumee/api/system/SystemJobLogController.java | 35
server/services/src/main/java/com/doumee/biz/system/impl/SystemUserBizImpl.java | 177
server/services/src/main/java/com/doumee/config/quartz/SnippetScanner.java | 60
server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeat.java | 45
server/services/src/main/java/com/doumee/dao/business/model/ReceiveWeight.java | 77
server/services/src/main/java/com/doumee/core/annotation/excel/ExcelExporter.java | 431 +
server/services/src/main/java/com/doumee/service/business/MemberService.java | 97
server/services/src/main/java/com/doumee/service/business/impl/WithdrawalOrdersServiceImpl.java | 149
server/services/src/main/java/com/doumee/config/quartz/SnippetScannerConfig.java | 32
server/services/src/main/java/com/doumee/service/system/SystemLoginLogService.java | 98
server/services/src/main/resources/mappers/SystemRoleMapper.xml | 49
server/services/src/main/java/com/doumee/service/system/SystemRolePermissionService.java | 97
server/services/src/main/java/com/doumee/core/annotation/excel/Reflections.java | 294
server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemJobListDTO.java | 18
server/services/src/main/java/com/doumee/core/utils/HttpsUtil.java | 270
server/services/src/main/java/com/doumee/dao/business/ReceiveWeightMapper.java | 12
server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateInputStream.java | 109
server/services/src/main/java/com/doumee/dao/system/SystemJobListMapper.java | 19
server/services/src/main/java/com/doumee/dao/system/dto/LoginDTO.java | 33
server/services/src/main/resources/banner.txt | 20
server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateResponseWrapper.java | 53
server/services/src/main/java/com/doumee/dao/system/dto/CreateRoleMenuDTO.java | 29
server/services/src/main/java/com/doumee/api/system/SystemMenuController.java | 94
server/services/src/main/java/com/doumee/dao/business/OrderLogMapper.java | 12
server/services/src/main/java/com/doumee/service/system/SystemJobListService.java | 23
server/services/src/main/java/com/doumee/config/swagger/SwaggerInterceptor.java | 45
server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemDictDTO.java | 22
server/services/src/main/java/com/doumee/service/system/SystemLoginService.java | 22
server/services/src/main/java/com/doumee/core/annotation/excel/ExcelColumn.java | 115
server/services/src/main/java/com/doumee/biz/system/impl/SystemPermissionBizImpl.java | 67
server/services/src/main/java/com/doumee/dao/system/model/SystemDict.java | 55
server/services/src/main/java/com/doumee/api/system/SystemDictDataController.java | 93
server/services/src/main/java/com/doumee/service/business/impl/ReceiveWeightServiceImpl.java | 148
server/services/src/main/java/com/doumee/biz/system/impl/SystemDictDataBizImpl.java | 217
server/services/src/main/java/com/doumee/biz/system/impl/SystemJobTriggerBizImpl.java | 288
server/services/src/main/java/com/doumee/dao/system/SystemJobMapper.java | 7
server/services/src/main/java/com/doumee/dao/system/vo/SystemUserListVO.java | 28
server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatInterceptor.java | 79
server/services/src/main/java/com/doumee/core/utils/Secure.java | 42
server/services/src/main/java/com/doumee/service/system/SystemRoleService.java | 101
server/services/src/main/java/com/doumee/dao/system/dto/UpdatePwdDto.java | 29
server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatDefaultHandler.java | 50
server/services/src/main/java/com/doumee/core/exception/LockedException.java | 13
server/services/src/main/java/com/doumee/dao/system/vo/SystemMenuNodeVO.java | 35
server/services/src/main/java/com/doumee/service/system/impl/SystemUserServiceImpl.java | 107
server/services/src/main/java/com/doumee/core/annotation/trace/TraceInterceptor.java | 396
server/services/src/main/java/com/doumee/config/annotation/EncryptionReq.java | 14
server/services/src/main/java/com/doumee/core/utils/monitor/Disk.java | 42
server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java(1) | 20
server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateOutputStream.java | 70
server/services/src/main/java/com/doumee/config/cache/RedisConfig.java | 32
server/services/src/main/java/com/doumee/dao/system/model/SystemPermission.java | 61
server/services/src/main/java/com/doumee/service/business/MemberRevenueService.java | 97
server/services/src/main/java/com/doumee/service/system/SystemPermissionService.java | 120
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxDepartInfoResponse.java | 29
server/services/src/main/java/com/doumee/dao/system/model/SystemJob.java | 96
server/services/src/main/java/com/doumee/service/system/impl/SystemLoginLogServiceImpl.java | 132
server/services/src/main/java/com/doumee/dao/business/model/Multifile.java | 77
server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserAttrInfoResponse.java | 25
server/services/src/main/java/com/doumee/service/system/impl/SystemJobSnippetServiceImpl.java | 112
server/services/src/main/java/com/doumee/service/system/impl/SystemJobServiceImpl.java | 87
server/services/src/main/java/com/doumee/core/utils/PwdCheckUtil.java | 78
server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java | 200
server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java(2) | 20
server/services/src/main/java/com/doumee/biz/system/SystemPermissionBiz.java | 42
295 files changed, 25,816 insertions(+), 0 deletions(-)
diff --git a/server/admin/pom.xml b/server/admin/pom.xml
new file mode 100644
index 0000000..c735fe1
--- /dev/null
+++ b/server/admin/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.doumee</groupId>
+ <artifactId>jinkuai</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>admin</artifactId>
+ <properties>
+ <maven.compiler.source>8</maven.compiler.source>
+ <maven.compiler.target>8</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>com.doumee</groupId>
+ <artifactId>services</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-aop</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-cache</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.zaxxer</groupId>
+ <artifactId>HikariCP</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.github.ben-manes.caffeine</groupId>
+ <artifactId>caffeine</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.doumee</groupId>
+ <artifactId>services</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>jinkuai_admin</finalName>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <configuration>
+ <fork>true</fork>
+ <mainClass>com.doumee.JKAdminApplication</mainClass>
+ <layout>ZIP</layout>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/server/admin/src/main/java/com/doumee/JKAdminApplication.java b/server/admin/src/main/java/com/doumee/JKAdminApplication.java
new file mode 100644
index 0000000..73cbe4e
--- /dev/null
+++ b/server/admin/src/main/java/com/doumee/JKAdminApplication.java
@@ -0,0 +1,31 @@
+package com.doumee;
+
+import lombok.extern.slf4j.Slf4j;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.ApplicationContext;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+/**
+ * 鍚姩绫�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@SpringBootApplication
+@MapperScan("com.doumee.dao")
+@EnableAsync
+public class JKAdminApplication extends SpringBootServletInitializer {
+ public static void main(String[] args) {
+ ApplicationContext context = SpringApplication.run(JKAdminApplication.class);
+ context.getEnvironment();
+ }
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
+ return builder.sources(JKAdminApplication.class) ;
+ }
+}
diff --git a/server/admin/src/main/resources/application.yml b/server/admin/src/main/resources/application.yml
new file mode 100644
index 0000000..fc3b292
--- /dev/null
+++ b/server/admin/src/main/resources/application.yml
@@ -0,0 +1,89 @@
+# 绔彛鍣ㄩ厤缃�
+server:
+ port: 10010
+# 椤圭洰淇℃伅閰嶇疆
+project:
+ name: 杩戝揩
+ version: 1.0.0
+ # 鐜锛岀敓浜х幆澧僷roduction锛屽紑鍙戠幆澧僤evelopment
+ env: development
+ # 妯″紡锛宼esting娴嬭瘯妯″紡
+ mode: testing
+
+spring:
+ profiles:
+ active: pro
+ # JSON杩斿洖閰嶇疆
+ jackson:
+ # 榛樿鏃跺尯
+ time-zone: GMT+8
+ # 榛樿鏃ユ湡鏍煎紡鍖�
+ date-format: yyyy-MM-dd HH:mm:ss
+ # Quartz閰嶇疆
+ quartz:
+ # 鏄惁鑷姩鍚姩
+ auto-startup: true
+ # 璋冨害鍣ㄥ悕绉�
+ scheduler-name: EvaScheduler
+ servlet:
+ multipart:
+ max-file-size: 50MB
+ max-request-size: 50MB
+
+# MyBatis閰嶇疆
+mybatis-plus:
+ mapper-locations: classpath*:/mappers/**/*.xml
+ configuration:
+ map-underscore-to-camel-case: true
+ log-impl: com.doumee.config.mybatis.DmStdOutImpl
+# log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
+# log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
+
+
+# 缂撳瓨鍐呭璁剧疆
+cache:
+ session:
+ # 浼氳瘽杩囨湡鏃堕暱(s)
+ expire: 1800
+ captcha:
+ # 楠岃瘉鐮佽繃鏈熸椂闀�(s)
+ expire: 300
+
+# 璺熻釜鏃ュ織
+trace:
+ # 寮�鍚櫤鑳借窡韪ā寮�
+ smart: true
+ # 鎺掗櫎璺熻釜鐨刄RL姝e垯
+ exclude-patterns: .+/list[a-zA-Z0-9\-\_]*$, .+/tree[a-zA-Z0-9\-\_]*$, .+/page[a-zA-Z0-9\-\_]*$, .+/all[a-zA-Z0-9\-\_]*$, /swagger-resources.*
+
+# 瀹夊叏閰嶇疆
+security:
+ aes:
+ key: qklpNODl6JjmgcT+
+ iv: 7rnE4rm3h/hcfqN2
+
+
+# 鏃ュ織閰嶇疆
+logback:
+ level: ERROR
+ appender: ${project.env}
+# dao灞傜殑鏃ュ織璁剧疆涓篸ebug锛屾柟渚挎煡鐪媠ql
+logging:
+ level:
+ # JOB鐩稿叧
+ com.doumee.dao.system.SystemJobMapper: ERROR
+ com.doumee.dao.system.SystemJobListMapper: ERROR
+ com.doumee.dao.system.SystemJobSnippetMapper: ERROR
+ com.doumee.dao.system.SystemJobLogMapper: ERROR
+ com.doumee.dao.business: ERROR
+auth:
+ jwt:
+ enabled: true #鏄惁寮�鍚疛WT鐧诲綍璁よ瘉鍔熻兘
+ secret: fjkfaf;afa # JWT绉侀挜锛岀敤浜庢牎楠孞WT浠ょ墝鐨勫悎娉曟��
+ expiration: 1800000 #JWT浠ょ墝鐨勬湁鏁堟湡锛岀敤浜庢牎楠孞WT浠ょ墝鐨勫悎娉曟��
+ # expiration: 300000 #JWT浠ょ墝鐨勬湁鏁堟湡锛岀敤浜庢牎楠孞WT浠ょ墝鐨勫悎娉曟��
+ header: JWTHeaderName #HTTP璇锋眰鐨凥eader鍚嶇О锛岃Header浣滀负鍙傛暟浼犻�扟WT浠ょ墝
+ userParamName: username #鐢ㄦ埛鐧诲綍璁よ瘉鐢ㄦ埛鍚嶅弬鏁板悕绉�
+ pwdParamName: password #鐢ㄦ埛鐧诲綍璁よ瘉瀵嗙爜鍙傛暟鍚嶇О
+ useDefaultController: true # 鏄惁浣跨敤榛樿鐨凧wtAuthController
+
diff --git a/server/services/pom.xml b/server/services/pom.xml
new file mode 100644
index 0000000..2519395
--- /dev/null
+++ b/server/services/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>services</artifactId>
+ <parent>
+ <groupId>com.doumee</groupId>
+ <artifactId>jinkuai</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <properties>
+ <maven.compiler.source>8</maven.compiler.source>
+ <maven.compiler.target>8</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+
+</project>
\ No newline at end of file
diff --git a/server/services/src/main/java/com/doumee/ContextFinalizer.java b/server/services/src/main/java/com/doumee/ContextFinalizer.java
new file mode 100644
index 0000000..be7ee32
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/ContextFinalizer.java
@@ -0,0 +1,33 @@
+package com.doumee;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Enumeration;
+import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;
+
+//@WebListener
+public class ContextFinalizer implements ServletContextListener{
+
+ public void contextInitialized(ServletContextEvent sce) {}
+
+ public void contextDestroyed(ServletContextEvent sce) {
+ Enumeration<Driver> drivers = DriverManager.getDrivers();
+ Driver d = null;
+ while (drivers.hasMoreElements()) {
+ try {
+ d = drivers.nextElement();
+ DriverManager.deregisterDriver(d);
+ } catch (SQLException ex) {
+ }
+ }
+ try {
+ // 娉ㄦ剰锛歮ysql8鐗堟湰鐨刯ar濂藉儚shutdown鏂规硶绉佹湁浜嗭紝鍙兘璋冪敤checkedShutdown鎴杣ncheckedShutdown
+ AbandonedConnectionCleanupThread.checkedShutdown();
+ } catch ( Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/BaseController.java b/server/services/src/main/java/com/doumee/api/BaseController.java
new file mode 100644
index 0000000..8d3cfea
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/BaseController.java
@@ -0,0 +1,56 @@
+package com.doumee.api;
+
+import com.doumee.core.model.LoginUserInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Controller鍩虹被
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+public class BaseController {
+
+ /**
+ * 鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛
+ */
+ protected LoginUserInfo getLoginUser () {
+ return (LoginUserInfo)SecurityUtils.getSubject().getPrincipal();
+ }
+
+ /**
+ * 鑾峰彇ID闆嗗悎
+ *
+ * @param ids 浣跨敤","闅斿紑鐨勫涓狪D
+ * @return List<Integer>
+ */
+ protected List<Integer> getIdList (String ids) {
+ String [] idArray = ids.split(",");
+ List<Integer> idList = new ArrayList<>();
+ for (String id : idArray) {
+ idList.add(Integer.valueOf(id));
+ }
+ return idList;
+ }
+
+ /**
+ * 鑾峰彇鏂囦欢瀛楄妭娴�
+ *
+ * @param is 杈撳叆娴�
+ * @return ByteArrayOutputStream
+ */
+ protected ByteArrayOutputStream getOutputStream (InputStream is) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] bs = new byte[is.available()];
+ int len;
+ while ((len = is.read(bs)) != -1) {
+ baos.write(bs, 0, len);
+ }
+ return baos;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/business/WebApiController.java b/server/services/src/main/java/com/doumee/api/business/WebApiController.java
new file mode 100644
index 0000000..f00e3e7
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/business/WebApiController.java
@@ -0,0 +1,23 @@
+package com.doumee.api.business;
+
+import io.swagger.annotations.Api;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @Author : Rk
+ * @create 2025/6/18 11:40
+ */
+@RestController
+@Api(tags ="web鎺ュ彛")
+@RequestMapping("/web/api")
+public class WebApiController {
+
+
+
+
+
+
+}
diff --git a/server/services/src/main/java/com/doumee/api/common/CaptchaController.java b/server/services/src/main/java/com/doumee/api/common/CaptchaController.java
new file mode 100644
index 0000000..db52fe6
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/common/CaptchaController.java
@@ -0,0 +1,32 @@
+package com.doumee.api.common;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.trace.Trace;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.service.common.CaptchaService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "鍥剧墖楠岃瘉鐮佹帴鍙�")
+@Trace(exclude = true)
+@RestController
+@RequestMapping("/common")
+public class CaptchaController extends BaseController {
+
+ @Autowired
+ private CaptchaService captchaService;
+
+ @ApiOperation("鑾峰彇鍥剧墖楠岃瘉鐮�")
+ @GetMapping("/captcha")
+ public ApiResponse<CaptchaService.Captcha> getCaptcha() {
+ return ApiResponse.success(captchaService.genCaptcha());
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/common/LocalFileAccessController.java b/server/services/src/main/java/com/doumee/api/common/LocalFileAccessController.java
new file mode 100644
index 0000000..d767325
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/common/LocalFileAccessController.java
@@ -0,0 +1,43 @@
+package com.doumee.api.common;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.trace.Trace;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import io.swagger.annotations.Api;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
+@Api(tags = "鏈湴鏂囦欢鎺ュ彛")
+@Trace(exclude = true)
+@RestController
+@RequestMapping("/resource/local")
+public class LocalFileAccessController extends BaseController {
+
+ @Value("${resources.import-template:~/files}")
+ private String resourcesPath;
+
+ /**
+ * 涓嬭浇鏈湴鏂囦欢
+ */
+ @GetMapping("/download")
+ public void download (@RequestParam String path, @RequestParam(required = false) String name, HttpServletResponse response) throws IOException {
+ File file = new File(resourcesPath.replace("~", new File("").getCanonicalPath()) + path);
+ if (!file.exists() || !file.isFile()) {
+ throw new BusinessException(ResponseStatus.LOCAL_FILE_NOT_EXISTS);
+ }
+ ByteArrayOutputStream os = this.getOutputStream(new FileInputStream(file));
+ String encodeFileName = URLEncoder.encode(StringUtils.isBlank(name) ? file.getName() : name, StandardCharsets.UTF_8.toString());
+ response.setHeader("Content-Disposition","attachment;filename=" + encodeFileName);
+ response.setContentType("application/octet-stream");
+ response.setHeader("doumee-opera-type", "download");
+ response.setHeader("doumee-download-filename", encodeFileName);
+ response.getOutputStream().write(os.toByteArray());
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/common/PublicCloudController.java b/server/services/src/main/java/com/doumee/api/common/PublicCloudController.java
new file mode 100644
index 0000000..6a8ff19
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/common/PublicCloudController.java
@@ -0,0 +1,190 @@
+package com.doumee.api.common;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.doumee.api.BaseController;
+import com.doumee.biz.system.SystemDictDataBiz;
+import com.doumee.config.annotation.EncryptionReq;
+import com.doumee.config.annotation.EncryptionResp;
+import com.doumee.core.annotation.trace.Trace;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.utils.DateUtil;
+import com.doumee.core.utils.FtpUtil;
+import com.doumee.core.utils.azure.AzureBlobUtil;
+import com.doumee.core.utils.qiyeweixin.QywxUtil;
+import com.doumee.core.utils.qiyeweixin.model.response.QywxUploadMediaResponse;
+import com.doumee.dao.system.model.SystemDictData;
+import com.doumee.service.common.EmailService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+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.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.multipart.MultipartRequest;
+import org.springframework.web.multipart.commons.CommonsMultipartResolver;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.*;
+
+/**
+ * @author Eva.Caesar Liu
+ * @date 2023/02/14 11:14
+ */
+@Api(tags = "鍏叡涓婁紶鎺ュ彛")
+@Trace(exclude = true)
+@RestController
+@RequestMapping("/web/public")
+@Slf4j
+public class PublicCloudController extends BaseController {
+ @Autowired
+ private SystemDictDataBiz systemDictDataBiz;
+
+ @ApiOperation(value = "涓婁紶", notes = "涓婁紶", httpMethod = "POST", position = 6)
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "folder", value = "鏂囦欢澶�", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
+ @ApiImplicitParam(name = "file", value = "鏂囦欢澶�", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
+ })
+ @PostMapping(value = "/uploadLocal", headers = "content-type=multipart/form-data")
+ public void uploadLocal(HttpServletRequest request, HttpServletResponse response) throws Exception {
+ MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+ uploadFileLocal(multipartRequest, response,
+ systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.IMG_DIR).getCode() ,
+ systemDictDataBiz.queryByCode(Constants.SYSTEM,Constants.FILE_DIR).getCode());
+
+ }
+
+ public void uploadFileLocal(HttpServletRequest request, HttpServletResponse response, String rootPath,String dir) throws Exception {
+ response.setCharacterEncoding("UTF-8");
+ response.setContentType("text/html;charset=UTF-8");
+ CommonsMultipartResolver multipartResovler = new CommonsMultipartResolver();
+ Map<String, Object> context = new HashMap<>();
+ if (multipartResovler.isMultipart(request)) {
+ MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+ Iterator<String> it = multipartRequest.getFileNames();
+ while (it.hasNext()) {
+ MultipartFile file = multipartRequest.getFile((String) it.next());
+ if (file != null) {
+ if (file.getSize() > 200 * 1024 * 1024L) {
+ context.put("code", 4000);
+ context.put("message", "涓婁紶鏂囦欢杩囧ぇ");
+ return;
+ }
+ System.out.println(file.getOriginalFilename());
+ if (file.getOriginalFilename() == null) {
+ context.put("code", 4000);
+ context.put("message", "鏂囦欢鍚嶄笉鍙负绌�");
+ return;
+ }
+ String nowDate = DateUtil.getNowShortDate();
+ String folder = nowDate + "/";
+ String strDirPath = rootPath + folder;
+ File dirPath = new File(strDirPath);
+ if (!dirPath.exists()) {
+ dirPath.mkdirs();
+ }
+ String uploadFileName = file.getOriginalFilename();
+ String x = UUID.randomUUID().toString().replace("-", "")
+ + uploadFileName.substring(uploadFileName.lastIndexOf("."));
+ String fileName = folder + x;
+ String fileNames = nowDate + "/" + x;
+ uploadFileName = uploadFileName.replace(" ", "");
+ uploadFileName = uploadFileName.replace("锛�", ",");
+ uploadFileName = uploadFileName.replaceAll(",", "-");
+ String fileAndPath = dir + fileName;
+ // 鍒ゆ柇濡傛灉涓存椂鐩綍涓瓨鍦ㄧ浉鍚屽悕绉扮殑鏂囦欢鍏堝垹闄わ紝鍦ㄤ笂浼�
+ File tempFile = new File(rootPath + fileName);
+ if (tempFile.isFile() && tempFile.exists()) {
+ tempFile.getAbsoluteFile().delete();
+ }
+ // 涓婁紶鍒版湇鍔″櫒涓存椂鏂囦欢澶�
+ file.transferTo(tempFile);
+ // 杞Щ鍒癋TP鏈嶅姟鍣�
+ String nfix = "";
+ if (null != uploadFileName) {
+ nfix = uploadFileName.substring(uploadFileName.lastIndexOf("."));
+ }
+
+ if (StringUtils.equalsIgnoreCase(nfix, ".exe")) {
+ context.put("code", 4000);
+ context.put("message", "瀵逛笉璧凤紝鏂囦欢鏍煎紡\".exe\"涓婁紶鏈夎锛�");
+ return;
+ }
+ if (StringUtils.equalsIgnoreCase(nfix, ".dll")) {
+ context.put("code", 4000);
+ context.put("message", "瀵逛笉璧凤紝鏂囦欢鏍煎紡\".dll\"涓婁紶鏈夎锛�");
+ return;
+ }
+
+ String remoteFileName = fileAndPath;
+
+ if (true) {
+ context.put("success", true);
+ context.put("code", 200);
+ context.put("errno",0);
+ JSONObject fileJSON = new JSONObject();
+ fileJSON.put("url", remoteFileName);
+ fileJSON.put("imgaddr", fileNames);
+ fileJSON.put("imgname", uploadFileName);
+ fileJSON.put("originname", uploadFileName);
+ context.put("data",fileJSON);
+ context.put("message","璇锋眰鎴愬姛");
+ writerJson(response, context);
+ return;
+ } else {
+ // 绉诲姩澶辫触
+ context.put("code", 0);
+ context.put("message", "涓婁紶澶辫触");
+ writerJson(response, context);
+ }
+ }
+ context.put("code", 0);
+ context.put("message", "涓婁紶澶辫触");
+ writerJson(response, context);
+ return;
+ }
+ }
+ context.put("code", 0);
+ context.put("message", "涓婁紶澶辫触");
+ writerJson(response, context);
+ return;
+ }
+
+
+
+ public static void writerJson(HttpServletResponse response, Object object) {
+ response.setContentType("application/json");
+ writer(response, JSONObject.toJSONString(object));
+ }
+
+ private static void writer(HttpServletResponse response, String str) {
+ try {
+ StringBuffer result = new StringBuffer();
+ //璁剧疆椤甸潰涓嶇紦瀛�
+ response.setHeader("Pragma", "No-cache");
+ response.setHeader("Cache-Control", "no-cache");
+ response.setCharacterEncoding("UTF-8");
+ PrintWriter out = null;
+ out = response.getWriter();
+ out.print(str);
+ out.flush();
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemController.java b/server/services/src/main/java/com/doumee/api/system/SystemController.java
new file mode 100644
index 0000000..366e4bf
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemController.java
@@ -0,0 +1,76 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.biz.system.SystemUserBiz;
+import com.doumee.config.annotation.EncryptionReq;
+import com.doumee.config.annotation.EncryptionResp;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.annotation.trace.Trace;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.LoginUserInfo;
+import com.doumee.dao.system.dto.LoginDTO;
+import com.doumee.dao.system.dto.UpdatePwdDto;
+import com.doumee.service.system.SystemLoginService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "绯荤粺鍔熻兘")
+@Trace(exclude = true)
+@Slf4j
+@RestController
+@RequestMapping("/system")
+public class SystemController extends BaseController {
+
+ @Autowired
+ private SystemUserBiz systemUserBiz;
+
+ @Autowired
+ private SystemLoginService systemLoginService;
+
+ @PreventRepeat(limit = 10, lockTime = 10000)
+ @ApiOperation("鐧诲綍")
+// @EncryptionReq
+// @EncryptionResp
+ @PostMapping("/login")
+ public ApiResponse<String> login (@Validated @RequestBody LoginDTO dto, HttpServletRequest request) {
+ return ApiResponse.success(systemLoginService.loginByPassword(dto, request));
+ }
+
+ @ApiOperation("閫�鍑虹櫥褰�")
+ @PostMapping("/logout")
+ public ApiResponse logout () {
+ Subject subject = SecurityUtils.getSubject();
+ subject.logout();
+ return ApiResponse.success(null);
+ }
+
+ @Trace(withRequestParameters = false)
+ @ApiOperation("淇敼褰撳墠鐢ㄦ埛瀵嗙爜")
+// @EncryptionReq
+// @EncryptionResp
+ @PostMapping("/updatePwd")
+ public ApiResponse updatePwd (@Validated @RequestBody UpdatePwdDto dto) {
+ dto.setUserId(this.getLoginUser().getId());
+ systemUserBiz.updatePwd(dto);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鑾峰彇褰撳墠鐧诲綍鐨勭敤鎴蜂俊鎭�")
+ @GetMapping("/getUserInfo")
+ @EncryptionResp
+ public ApiResponse<LoginUserInfo> getUserInfo () {
+ return ApiResponse.success(this.getLoginUser());
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemDictController.java b/server/services/src/main/java/com/doumee/api/system/SystemDictController.java
new file mode 100644
index 0000000..28f93f1
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemDictController.java
@@ -0,0 +1,77 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.biz.system.SystemDictBiz;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.QuerySystemDictDTO;
+import com.doumee.dao.system.model.SystemDict;
+import com.doumee.dao.system.vo.SystemDictListVO;
+import com.doumee.service.system.SystemDictService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "绯荤粺瀛楀吀")
+@RestController
+@RequestMapping("/system/dict")
+public class SystemDictController extends BaseController {
+
+ @Autowired
+ private SystemDictService systemDictService;
+
+ @Autowired
+ private SystemDictBiz systemDictBiz;
+
+ @PreventRepeat
+ @ApiOperation("鏂板缓")
+ @PostMapping("/create")
+ @RequiresPermissions("system:dict:create")
+ public ApiResponse create(@Validated(Constants.OperaType.Create.class) @RequestBody SystemDict systemDict) {
+ return ApiResponse.success(systemDictBiz.create(systemDict));
+ }
+
+ @ApiOperation("鍒犻櫎")
+ @GetMapping("/delete/{id}")
+ @RequiresPermissions("system:dict:delete")
+ public ApiResponse deleteById(@PathVariable Integer id) {
+ systemDictService.deleteById(id);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鎵归噺鍒犻櫎")
+ @GetMapping("/delete/batch")
+ @RequiresPermissions("system:dict:delete")
+ public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+ systemDictService.deleteByIdInBatch(this.getIdList(ids));
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("淇敼")
+ @PostMapping("/updateById")
+ @RequiresPermissions("system:dict:update")
+ public ApiResponse updateById(@Validated(Constants.OperaType.Update.class) @RequestBody SystemDict systemDict) {
+ systemDictBiz.updateById(systemDict);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鍒嗛〉鏌ヨ")
+ @PostMapping("/page")
+ @RequiresPermissions("system:dict:query")
+ public ApiResponse<PageData<SystemDictListVO>> findPage (@RequestBody PageWrap<QuerySystemDictDTO> pageWrap) {
+ return ApiResponse.success(systemDictService.findPage(pageWrap));
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemDictDataController.java b/server/services/src/main/java/com/doumee/api/system/SystemDictDataController.java
new file mode 100644
index 0000000..b9f529a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemDictDataController.java
@@ -0,0 +1,93 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.biz.system.SystemDictDataBiz;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.annotation.trace.Trace;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.common.dto.UpdateSortDTO;
+import com.doumee.dao.system.dto.QuerySystemDictDataDTO;
+import com.doumee.dao.system.model.SystemDictData;
+import com.doumee.dao.system.vo.SystemDictDataListVO;
+import com.doumee.service.system.SystemDictDataService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "瀛楀吀鏁版嵁")
+@RestController
+@RequestMapping("/system/dictData")
+public class SystemDictDataController extends BaseController {
+
+ @Autowired
+ private SystemDictDataService systemDictDataService;
+
+ @Autowired
+ private SystemDictDataBiz systemDictDataBiz;
+
+ @PreventRepeat
+ @ApiOperation("鏂板缓")
+ @PostMapping("/create")
+ @RequiresPermissions("system:dict:update")
+ public ApiResponse create(@Validated(Constants.OperaType.Create.class) @RequestBody SystemDictData systemDictData) {
+ return ApiResponse.success(systemDictDataBiz.create(systemDictData));
+ }
+
+ @ApiOperation("鍒犻櫎")
+ @GetMapping("/delete/{id}")
+ @RequiresPermissions("system:dict:update")
+ public ApiResponse deleteById(@PathVariable Integer id) {
+ systemDictDataService.deleteById(id);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鎵归噺鍒犻櫎")
+ @GetMapping("/delete/batch")
+ @RequiresPermissions("system:dict:delete")
+ public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+ systemDictDataService.deleteByIdInBatch(this.getIdList(ids));
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("淇敼")
+ @PostMapping("/updateById")
+ @RequiresPermissions("system:dict:update")
+ public ApiResponse updateById(@Validated(Constants.OperaType.Update.class) @RequestBody SystemDictData systemDictData) {
+ systemDictDataBiz.updateById(systemDictData);
+ return ApiResponse.success(null);
+ }
+
+ @Trace
+ @ApiOperation("鎺掑簭")
+ @PostMapping("/sort")
+ @RequiresPermissions("system:dict:update")
+ public ApiResponse sort(@Validated @RequestBody UpdateSortDTO dto) {
+ systemDictDataBiz.sort(dto);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鍒嗛〉鏌ヨ")
+ @PostMapping("/page")
+ @RequiresPermissions("system:dict:update")
+ public ApiResponse<PageData<SystemDictDataListVO>> findPage (@RequestBody PageWrap<QuerySystemDictDataDTO> pageWrap) {
+ return ApiResponse.success(systemDictDataService.findPage(pageWrap));
+ }
+
+ @ApiOperation("鏍规嵁瀛楀吀缂栫爜鏌ヨ鏁版嵁")
+ @GetMapping("/findByDictCode")
+ public ApiResponse<List<SystemDictData>> findByCode (@RequestParam String dictCode) {
+ return ApiResponse.success(systemDictDataService.findByDictCode(dictCode));
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemJobController.java b/server/services/src/main/java/com/doumee/api/system/SystemJobController.java
new file mode 100644
index 0000000..dda3e92
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemJobController.java
@@ -0,0 +1,124 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.biz.system.SystemJobBiz;
+import com.doumee.biz.system.SystemJobTriggerBiz;
+import com.doumee.biz.system.dto.TriggerJobDTO;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.annotation.trace.Trace;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.model.PageData;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.model.SystemJob;
+import com.doumee.dao.system.dto.QuerySystemJobListDTO;
+import com.doumee.dao.system.vo.SystemJobListVO;
+import com.doumee.service.system.SystemJobService;
+import com.doumee.service.system.SystemJobListService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 瀹氭椂浠诲姟鍒楄〃鎺ュ彛
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@RestController
+@RequestMapping("/system/job")
+@Api(tags = "瀹氭椂浠诲姟鍒楄〃鎺ュ彛")
+public class SystemJobController extends BaseController {
+
+ @Autowired
+ private SystemJobListService systemJobListService;
+
+ @Autowired
+ private SystemJobService systemJobService;
+
+ @Autowired
+ private SystemJobBiz systemJobBiz;
+
+ @Autowired
+ private SystemJobTriggerBiz systemJobTriggerBiz;
+
+ @Trace
+ @ApiOperation("鎵嬪姩瑙﹀彂")
+ @PostMapping("/trigger")
+ @RequiresPermissions("system:job:trigger")
+ public ApiResponse triggerJob (@Validated @RequestBody TriggerJobDTO dto) {
+ Utils.ThreadPool.start(() -> {
+ dto.setTriggerType(Constants.Job.TriggerType.MANUAL.getCode());
+ dto.setFireTime(new Date());
+ systemJobTriggerBiz.trigger(dto);
+ });
+ return ApiResponse.success(null);
+ }
+
+ @PreventRepeat
+ @ApiOperation("鏂板缓")
+ @PostMapping("/create")
+ @RequiresPermissions("system:job:create")
+ public ApiResponse create(@Validated(Constants.OperaType.Create.class) @RequestBody SystemJob systemJob) {
+ return ApiResponse.success(systemJobBiz.create(systemJob));
+ }
+
+ @ApiOperation("鏍规嵁ID鍒犻櫎")
+ @GetMapping("/delete/{id}")
+ @RequiresPermissions("system:job:delete")
+ public ApiResponse deleteById(@PathVariable Integer id) {
+ systemJobService.deleteById(id);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鎵归噺鍒犻櫎")
+ @GetMapping("/delete/batch")
+ @RequiresPermissions("system:job:delete")
+ public ApiResponse deleteByIds(@RequestParam String ids) {
+ systemJobService.deleteByIdInBatch(this.getIdList(ids));
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鏍规嵁ID淇敼")
+ @PostMapping("/updateById")
+ @RequiresPermissions("system:job:update")
+ public ApiResponse updateById(@Validated(Constants.OperaType.Update.class) @RequestBody SystemJob systemJob) {
+ systemJobBiz.updateById(systemJob);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("淇敼浠诲姟鐘舵��")
+ @PostMapping("/updateStatus")
+ @RequiresPermissions("system:job:update")
+ public ApiResponse updateStatus(@Validated(Constants.OperaType.UpdateStatus.class) @RequestBody SystemJob systemJob) {
+ systemJobBiz.updateById(systemJob);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鍒嗛〉鏌ヨ")
+ @PostMapping("/page")
+ @RequiresPermissions("system:job:query")
+ public ApiResponse<PageData<SystemJobListVO>> findPage (@RequestBody PageWrap<QuerySystemJobListDTO> pageWrap) {
+ return ApiResponse.success(systemJobListService.findPage(pageWrap));
+ }
+
+ @ApiOperation("鏌ヨ鎵�鏈�")
+ @GetMapping("/all")
+ @RequiresPermissions("system:job:query")
+ public ApiResponse<List<SystemJob>> findAll () {
+ return ApiResponse.success(systemJobService.findList(new SystemJob()));
+ }
+
+ @ApiOperation("鏍规嵁ID鏌ヨ")
+ @GetMapping("/{id}")
+ @RequiresPermissions("system:job:query")
+ public ApiResponse findById(@PathVariable Integer id) {
+ return ApiResponse.success(systemJobService.findById(id));
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemJobLogController.java b/server/services/src/main/java/com/doumee/api/system/SystemJobLogController.java
new file mode 100644
index 0000000..794977e
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemJobLogController.java
@@ -0,0 +1,35 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.model.PageData;
+import com.doumee.dao.system.dto.QuerySystemJobLogDTO;
+import com.doumee.dao.system.model.SystemJobLog;
+import com.doumee.service.system.SystemJobLogService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "绯荤粺瀹氭椂浠诲姟鏃ュ織")
+@RestController
+@RequestMapping("/system/job/log")
+public class SystemJobLogController extends BaseController {
+
+ @Autowired
+ private SystemJobLogService systemJobLogService;
+
+ @ApiOperation("鍒嗛〉鏌ヨ")
+ @PostMapping("/page")
+ @RequiresPermissions("system:job:log:query")
+ public ApiResponse<PageData<SystemJobLog>> findPage (@RequestBody PageWrap<QuerySystemJobLogDTO> pageWrap) {
+ return ApiResponse.success(systemJobLogService.findPage(pageWrap));
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemJobSnippetController.java b/server/services/src/main/java/com/doumee/api/system/SystemJobSnippetController.java
new file mode 100644
index 0000000..6ca5b3f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemJobSnippetController.java
@@ -0,0 +1,75 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.biz.system.SystemJobSnippetTriggerBiz;
+import com.doumee.biz.system.dto.TriggerJobDTO;
+import com.doumee.biz.system.dto.TriggerJobSnippetDTO;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.annotation.trace.Trace;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.model.PageData;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.model.SystemJobSnippet;
+import com.doumee.service.system.SystemJobSnippetService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "瀹氭椂浠诲姟鐗囨")
+@RestController
+@RequestMapping("/system/job/snippet")
+public class SystemJobSnippetController extends BaseController {
+
+ @Autowired
+ private SystemJobSnippetService systemJobSnippetService;
+
+ @Autowired
+ private SystemJobSnippetTriggerBiz systemJobSnippetTriggerBiz;
+
+ @Trace
+ @ApiOperation("鎵嬪姩瑙﹀彂")
+ @PostMapping("/trigger")
+ @RequiresPermissions("system:job:trigger")
+ public ApiResponse triggerJob (@RequestBody TriggerJobSnippetDTO dto) {
+ Utils.ThreadPool.start(() -> {
+ dto.setTriggerType(Constants.Job.TriggerType.MANUAL.getCode());
+ systemJobSnippetTriggerBiz.trigger(dto);
+ });
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鏍规嵁ID鍒犻櫎")
+ @GetMapping("/delete/{id}")
+ @RequiresPermissions("system:job:snippet:delete")
+ public ApiResponse deleteById(@PathVariable Integer id) {
+ systemJobSnippetService.deleteById(id);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鎵归噺鍒犻櫎")
+ @GetMapping("/delete/batch")
+ @RequiresPermissions("system:job:snippet:delete")
+ public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+ systemJobSnippetService.deleteByIdInBatch(this.getIdList(ids));
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鍒嗛〉鏌ヨ")
+ @PostMapping("/page")
+ @RequiresPermissions("system:job:snippet:query")
+ public ApiResponse<PageData<SystemJobSnippet>> findPage (@RequestBody PageWrap<SystemJobSnippet> pageWrap) {
+ return ApiResponse.success(systemJobSnippetService.findPage(pageWrap));
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemLoginLogController.java b/server/services/src/main/java/com/doumee/api/system/SystemLoginLogController.java
new file mode 100644
index 0000000..bb09a75
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemLoginLogController.java
@@ -0,0 +1,44 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.excel.ExcelExporter;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.QuerySystemLoginLogDTO;
+import com.doumee.dao.system.model.SystemLoginLog;
+import com.doumee.service.system.SystemLoginLogService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@RestController
+@RequestMapping("/system/loginLog")
+@Api(tags = "鐧诲綍鏃ュ織")
+public class SystemLoginLogController extends BaseController {
+
+ @Autowired
+ private SystemLoginLogService systemLoginLogService;
+
+ @PostMapping("/page")
+ @ApiOperation("鍒嗛〉鏌ヨ")
+ @RequiresPermissions("system:loginLog:query")
+ public ApiResponse<PageData<SystemLoginLog>> findPage (@RequestBody PageWrap<QuerySystemLoginLogDTO> pageWrap) {
+ return ApiResponse.success(systemLoginLogService.findPage(pageWrap));
+ }
+
+ @PostMapping("/exportExcel")
+ @ApiOperation("瀵煎嚭Excel")
+ @RequiresPermissions("system:loginLog:query")
+ public void export (@RequestBody PageWrap<QuerySystemLoginLogDTO> pageWrap, HttpServletResponse response) {
+ ExcelExporter.build(SystemLoginLog.class).export(systemLoginLogService.findPage(pageWrap).getRecords(), "鐧诲綍鏃ュ織", response);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemMenuController.java b/server/services/src/main/java/com/doumee/api/system/SystemMenuController.java
new file mode 100644
index 0000000..5ecbdd5
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemMenuController.java
@@ -0,0 +1,94 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.biz.system.SystemMenuBiz;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.dao.common.dto.UpdateSortDTO;
+import com.doumee.core.constants.Constants;
+import com.doumee.dao.system.model.SystemMenu;
+import com.doumee.dao.system.vo.SystemMenuListVO;
+import com.doumee.dao.system.vo.SystemMenuNodeVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "绯荤粺鑿滃崟")
+@RestController
+@RequestMapping("/system/menu")
+public class SystemMenuController extends BaseController {
+
+ @Autowired
+ private SystemMenuBiz systemMenuBiz;
+
+ @ApiOperation("鑿滃崟鎺掑簭")
+ @PostMapping("/updateSort")
+ @RequiresPermissions("system:menu:sort")
+ public ApiResponse updateSort (@Validated @RequestBody UpdateSortDTO dto) {
+ systemMenuBiz.updateSort(dto);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鏌ヨ鑿滃崟鏍�")
+ @GetMapping("/treeNodes")
+ public ApiResponse<List<SystemMenuNodeVO>> getTreeMenu () {
+ return ApiResponse.success(systemMenuBiz.findTree(this.getLoginUser().getId()));
+ }
+
+ @ApiOperation("鏌ヨ鍒楄〃鏍�")
+ @PostMapping("/treeList")
+ @RequiresPermissions("system:menu:query")
+ public ApiResponse<List<SystemMenuListVO>> findTree () {
+ return ApiResponse.success(systemMenuBiz.findTree());
+ }
+
+ @PreventRepeat
+ @ApiOperation("鏂板缓")
+ @PostMapping("/create")
+ @RequiresPermissions("system:menu:create")
+ public ApiResponse create(@Validated(Constants.OperaType.Create.class) @RequestBody SystemMenu systemMenu) {
+ return ApiResponse.success(systemMenuBiz.create(systemMenu));
+ }
+
+ @ApiOperation("鍒犻櫎")
+ @GetMapping("/delete/{id}")
+ @RequiresPermissions("system:menu:delete")
+ public ApiResponse deleteById(@PathVariable Integer id) {
+ systemMenuBiz.deleteById(id);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鎵归噺鍒犻櫎")
+ @GetMapping("/delete/batch")
+ @RequiresPermissions("system:menu:delete")
+ public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+ systemMenuBiz.deleteByIdInBatch(this.getIdList(ids));
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("淇敼")
+ @PostMapping("/updateById")
+ @RequiresPermissions("system:menu:update")
+ public ApiResponse updateById(@Validated(Constants.OperaType.Update.class) @RequestBody SystemMenu systemMenu) {
+ systemMenuBiz.updateById(systemMenu);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("淇敼鑿滃崟鐘舵��")
+ @PostMapping("/updateStatus")
+ @RequiresPermissions("system:menu:update")
+ public ApiResponse updateStatus(@Validated(Constants.OperaType.UpdateStatus.class) @RequestBody SystemMenu systemMenu) {
+ systemMenuBiz.updateById(systemMenu);
+ return ApiResponse.success(null);
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemMonitorController.java b/server/services/src/main/java/com/doumee/api/system/SystemMonitorController.java
new file mode 100644
index 0000000..47599f6
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemMonitorController.java
@@ -0,0 +1,31 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.trace.Trace;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.utils.Monitor;
+import com.doumee.core.utils.Utils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "绯荤粺鐩戝惉")
+@Trace(exclude = true)
+@RestController
+@RequestMapping("/system/monitor")
+public class SystemMonitorController extends BaseController {
+
+ @ApiOperation("鑾峰彇绯荤粺淇℃伅")
+ @GetMapping("/getSystemInfo")
+ @RequiresPermissions("system:monitor:query")
+ public ApiResponse<Monitor> getSystemInfo () {
+ return ApiResponse.success(Utils.Monitor.current());
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemPermissionController.java b/server/services/src/main/java/com/doumee/api/system/SystemPermissionController.java
new file mode 100644
index 0000000..714e74f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemPermissionController.java
@@ -0,0 +1,82 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.biz.system.SystemPermissionBiz;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.dao.system.dto.DeleteSystemPermissionDTO;
+import com.doumee.core.constants.Constants;
+import com.doumee.dao.system.model.SystemPermission;
+import com.doumee.dao.system.vo.SystemPermissionListVO;
+import com.doumee.service.system.SystemPermissionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "绯荤粺鏉冮檺")
+@RestController
+@RequestMapping("/system/permission")
+public class SystemPermissionController extends BaseController {
+
+ @Autowired
+ private SystemPermissionService systemPermissionService;
+
+ @Autowired
+ private SystemPermissionBiz systemPermissionBiz;
+
+ @PreventRepeat
+ @ApiOperation("鏂板缓")
+ @PostMapping("/create")
+ @RequiresPermissions("system:permission:create")
+ public ApiResponse create(@Validated(Constants.OperaType.Create.class) @RequestBody SystemPermission systemPermission) {
+ return ApiResponse.success(systemPermissionBiz.create(systemPermission));
+ }
+
+ @ApiOperation("鍒犻櫎")
+ @PostMapping("/delete")
+ @RequiresPermissions("system:permission:delete")
+ public ApiResponse deleteById(@RequestBody DeleteSystemPermissionDTO dto) {
+ systemPermissionService.delete(dto);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鎵归噺鍒犻櫎")
+ @PostMapping("/delete/batch")
+ @RequiresPermissions("system:permission:delete")
+ public ApiResponse deleteByIdInBatch(@RequestBody List<DeleteSystemPermissionDTO> dtos) {
+ systemPermissionService.deleteInBatch(dtos);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("淇敼")
+ @PostMapping("/updateById")
+ @RequiresPermissions("system:permission:update")
+ public ApiResponse updateById(@Validated(Constants.OperaType.Update.class) @RequestBody SystemPermission systemPermission) {
+ systemPermissionBiz.updateById(systemPermission);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鎵归噺淇敼")
+ @PostMapping("/updateByIdInBatch")
+ @RequiresPermissions("system:permission:update")
+ public ApiResponse updateById(@RequestBody List<SystemPermission> permissions) {
+ systemPermissionService.updateByIdInBatch(permissions);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鏌ヨ鏉冮檺鏍戝垪琛�")
+ @GetMapping("/tree")
+ @RequiresPermissions("system:permission:query")
+ public ApiResponse<List<SystemPermissionListVO>> findAll () {
+ return ApiResponse.success(systemPermissionService.findTree());
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemRoleController.java b/server/services/src/main/java/com/doumee/api/system/SystemRoleController.java
new file mode 100644
index 0000000..a97571a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemRoleController.java
@@ -0,0 +1,106 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.biz.system.SystemRoleBiz;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.CreateRoleMenuDTO;
+import com.doumee.dao.system.dto.CreateRolePermissionDTO;
+import com.doumee.dao.system.dto.QuerySystemRoleDTO;
+import com.doumee.dao.system.model.SystemRole;
+import com.doumee.dao.system.vo.SystemRoleListVO;
+import com.doumee.service.system.SystemRoleService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "绯荤粺瑙掕壊")
+@RestController
+@RequestMapping("/system/role")
+public class SystemRoleController extends BaseController {
+
+ @Autowired
+ private SystemRoleService systemRoleService;
+
+ @Autowired
+ private SystemRoleBiz systemRoleBiz;
+
+ @PreventRepeat
+ @ApiOperation("閰嶇疆瑙掕壊鑿滃崟")
+ @PostMapping("/createRoleMenu")
+ @RequiresPermissions("system:role:createRoleMenu")
+ public ApiResponse createRoleMenu (@Validated @RequestBody CreateRoleMenuDTO dto) {
+ systemRoleBiz.createRoleMenu(dto);
+ return ApiResponse.success(null);
+ }
+
+ @PreventRepeat
+ @ApiOperation("閰嶇疆瑙掕壊鏉冮檺")
+ @PostMapping("/createRolePermission")
+ @RequiresPermissions("system:role:createRolePermission")
+ public ApiResponse createRolePermission (@Validated @RequestBody CreateRolePermissionDTO dto) {
+ systemRoleBiz.createRolePermission(dto);
+ return ApiResponse.success(null);
+ }
+
+ @PreventRepeat
+ @ApiOperation("鏂板缓")
+ @PostMapping("/create")
+ @RequiresPermissions("system:role:create")
+ public ApiResponse create(@Validated(Constants.OperaType.Create.class) @RequestBody SystemRole systemRole) {
+ return ApiResponse.success(systemRoleBiz.create(systemRole));
+ }
+
+ @ApiOperation("鍒犻櫎")
+ @GetMapping("/delete/{id}")
+ @RequiresPermissions("system:role:delete")
+ public ApiResponse deleteById(@PathVariable Integer id) {
+ systemRoleBiz.deleteById(id);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鎵归噺鍒犻櫎")
+ @GetMapping("/delete/batch")
+ @RequiresPermissions("system:role:delete")
+ public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+ systemRoleBiz.deleteByIdInBatch(this.getIdList(ids));
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("淇敼")
+ @PostMapping("/updateById")
+ @RequiresPermissions("system:role:update")
+ public ApiResponse updateById(@Validated(Constants.OperaType.Update.class) @RequestBody SystemRole systemRole) {
+ systemRoleBiz.updateById(systemRole);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鍒嗛〉鏌ヨ")
+ @PostMapping("/page")
+ @RequiresPermissions("system:role:query")
+ public ApiResponse<PageData<SystemRoleListVO>> findPage (@RequestBody PageWrap<QuerySystemRoleDTO> pageWrap) {
+ return ApiResponse.success(systemRoleService.findPage(pageWrap));
+ }
+
+ @ApiOperation("鏌ヨ鎵�鏈�")
+ @GetMapping("/all")
+ @RequiresPermissions("system:role:query")
+ public ApiResponse<List<SystemRole>> findAll () {
+ SystemRole systemRole = new SystemRole();
+ systemRole.setDeleted(Boolean.FALSE);
+ return ApiResponse.success(systemRoleService.findList(systemRole));
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemTraceLogController.java b/server/services/src/main/java/com/doumee/api/system/SystemTraceLogController.java
new file mode 100644
index 0000000..5998295
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemTraceLogController.java
@@ -0,0 +1,43 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.annotation.excel.ExcelExporter;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.QuerySystemTraceLogDTO;
+import com.doumee.dao.system.model.SystemTraceLog;
+import com.doumee.service.system.SystemTraceLogService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "璺熻釜鏃ュ織")
+@RestController
+@RequestMapping("/system/traceLog")
+public class SystemTraceLogController extends BaseController {
+
+ @Autowired
+ private SystemTraceLogService systemTraceLogService;
+
+ @ApiOperation("鍒嗛〉鏌ヨ")
+ @PostMapping("/page")
+ @RequiresPermissions("system:traceLog:query")
+ public ApiResponse findPage (@RequestBody PageWrap<QuerySystemTraceLogDTO> pageWrap) {
+ return ApiResponse.success(systemTraceLogService.findPage(pageWrap));
+ }
+
+ @ApiOperation("瀵煎嚭Excel")
+ @PostMapping("/exportExcel")
+ @RequiresPermissions("system:traceLog:query")
+ public void exportExcel (@RequestBody PageWrap<QuerySystemTraceLogDTO> pageWrap, HttpServletResponse response) {
+ ExcelExporter.build(SystemTraceLog.class).export(systemTraceLogService.findPage(pageWrap).getRecords(), "鎿嶄綔鏃ュ織", response);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/api/system/SystemUserController.java b/server/services/src/main/java/com/doumee/api/system/SystemUserController.java
new file mode 100644
index 0000000..10d6929
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/api/system/SystemUserController.java
@@ -0,0 +1,105 @@
+package com.doumee.api.system;
+
+import com.doumee.api.BaseController;
+import com.doumee.biz.system.SystemUserBiz;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.annotation.trace.Trace;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.CreateSystemUserDTO;
+import com.doumee.dao.system.dto.CreateUserRoleDTO;
+import com.doumee.dao.system.dto.QuerySystemUserDTO;
+import com.doumee.dao.system.dto.ResetSystemUserPwdDTO;
+import com.doumee.dao.system.vo.SystemUserListVO;
+import com.doumee.service.system.SystemUserService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Api(tags = "鐢ㄦ埛")
+@RestController
+@RequestMapping("/system/user")
+public class SystemUserController extends BaseController {
+
+ @Autowired
+ private SystemUserService systemUserService;
+
+ @Autowired
+ private SystemUserBiz systemUserBiz;
+
+ @PreventRepeat
+ @ApiOperation("閰嶇疆鐢ㄦ埛瑙掕壊")
+ @PostMapping("/createUserRole")
+ @RequiresPermissions("system:user:createUserRole")
+ public ApiResponse createUserRole (@Validated @RequestBody CreateUserRoleDTO dto) {
+ systemUserBiz.createUserRole(dto);
+ return ApiResponse.success(null);
+ }
+
+ @Trace(withRequestParameters = false)
+ @PreventRepeat
+ @ApiOperation("閲嶇疆鐢ㄦ埛瀵嗙爜")
+ @PostMapping("/resetPwd")
+ @RequiresPermissions("system:user:resetPwd")
+ public ApiResponse resetPwd (@Validated @RequestBody ResetSystemUserPwdDTO dto) {
+ dto.setOperaUserId(this.getLoginUser().getId());
+ systemUserBiz.resetPwd(dto);
+ return ApiResponse.success(null);
+ }
+
+ @Trace(withRequestParameters = false)
+ @PreventRepeat
+ @ApiOperation("鏂板缓")
+ @PostMapping("/create")
+ @RequiresPermissions("system:user:create")
+ public ApiResponse create(@Validated(Constants.OperaType.Create.class) @RequestBody CreateSystemUserDTO systemUser) {
+ systemUser.setCreateUser(this.getLoginUser().getId());
+ systemUserBiz.create(systemUser);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鍒犻櫎")
+ @GetMapping("/delete/{id}")
+ @RequiresPermissions("system:user:delete")
+ public ApiResponse deleteById(@PathVariable Integer id) {
+ systemUserBiz.deleteById(id);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鎵归噺鍒犻櫎")
+ @GetMapping("/delete/batch")
+ @RequiresPermissions("system:user:delete")
+ public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+ systemUserBiz.deleteByIdInBatch(this.getIdList(ids));
+ return ApiResponse.success(null);
+ }
+
+ @Trace(withRequestParameters = false)
+ @ApiOperation("淇敼")
+ @PostMapping("/updateById")
+ @RequiresPermissions("system:user:update")
+ public ApiResponse updateById(@Validated(Constants.OperaType.Update.class) @RequestBody CreateSystemUserDTO systemUser) {
+ systemUser.setUpdateUser(this.getLoginUser().getId());
+ systemUserBiz.updateById(systemUser);
+ return ApiResponse.success(null);
+ }
+
+ @ApiOperation("鍒嗛〉鏌ヨ")
+ @PostMapping("/page")
+ @RequiresPermissions("system:user:query")
+ public ApiResponse<PageData<SystemUserListVO>> findPage (@RequestBody PageWrap<QuerySystemUserDTO> pageWrap) {
+ return ApiResponse.success(systemUserService.findPage(pageWrap));
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/SystemDictBiz.java b/server/services/src/main/java/com/doumee/biz/system/SystemDictBiz.java
new file mode 100644
index 0000000..e4eafd7
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/SystemDictBiz.java
@@ -0,0 +1,27 @@
+package com.doumee.biz.system;
+
+import com.doumee.dao.system.model.SystemDict;
+
+/**
+ * 瀛楀吀涓氬姟澶勭悊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemDictBiz {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemDict 瀛楀吀
+ * @return Integer
+ */
+ Integer create(SystemDict systemDict);
+
+ /**
+ * 缂栬緫
+ *
+ * @param systemDict 瀛楀吀
+ */
+ void updateById(SystemDict systemDict);
+
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/SystemDictDataBiz.java b/server/services/src/main/java/com/doumee/biz/system/SystemDictDataBiz.java
new file mode 100644
index 0000000..f6039cc
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/SystemDictDataBiz.java
@@ -0,0 +1,54 @@
+package com.doumee.biz.system;
+
+import com.doumee.dao.common.dto.UpdateSortDTO;
+import com.doumee.dao.system.model.SystemDictData;
+
+import java.util.List;
+
+/**
+ * 瀛楀吀鏁版嵁涓氬姟澶勭悊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemDictDataBiz {
+
+ /**
+ * 鏂板缓
+ *
+ * @param systemDictData 瀛楀吀鏁版嵁
+ * @return 瀛楀吀鏁版嵁ID
+ */
+ Integer create(SystemDictData systemDictData);
+
+ /**
+ * 缂栬緫
+ *
+ * @param systemDictData 瀛楀吀鏁版嵁
+ */
+ void updateById(SystemDictData systemDictData);
+
+ /**
+ * 鎺掑簭
+ *
+ * @param dto 璇﹁UpdateSortDTO
+ */
+ void sort(UpdateSortDTO dto);
+
+ String updateQywxToken();
+
+ void updateByIdNew(SystemDictData systemDictData);
+ SystemDictData queryByCode(String dicCode, String label);
+ String queryCodeById(Integer id);
+
+ List<SystemDictData> queryListByCode(String dicCode, String label);
+ List<SystemDictData> queryDataByCode(String dicCode, String code);
+
+ /**
+ * 鑾峰彇璺緞鍓嶇紑
+ * @param resourceCode
+ * @param targetCode
+ * @return
+ */
+ String getPreFixPath(String resourceCode, String targetCode);
+ void updateByDicId(List<SystemDictData> list);
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/SystemJobBiz.java b/server/services/src/main/java/com/doumee/biz/system/SystemJobBiz.java
new file mode 100644
index 0000000..38a1772
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/SystemJobBiz.java
@@ -0,0 +1,26 @@
+package com.doumee.biz.system;
+
+import com.doumee.dao.system.model.SystemJob;
+
+/**
+ * 瀹氭椂浠诲姟涓氬姟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemJobBiz {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param job 瀹炰綋
+ * @return Integer
+ */
+ Integer create (SystemJob job);
+
+ /**
+ * 淇敼
+ *
+ * @param job 瀹炰綋
+ */
+ void updateById(SystemJob job);
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/SystemJobSnippetTriggerBiz.java b/server/services/src/main/java/com/doumee/biz/system/SystemJobSnippetTriggerBiz.java
new file mode 100644
index 0000000..576d4c8
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/SystemJobSnippetTriggerBiz.java
@@ -0,0 +1,18 @@
+package com.doumee.biz.system;
+
+import com.doumee.biz.system.dto.TriggerJobSnippetDTO;
+
+/**
+ * 鍒嗙墖浠诲姟涓氬姟澶勭悊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemJobSnippetTriggerBiz {
+
+ /**
+ * 瑙﹀彂鍒嗙墖浠诲姟
+ *
+ * @param dto 璇﹁TriggerJobSnippetDTO
+ */
+ void trigger (TriggerJobSnippetDTO dto);
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/SystemJobTriggerBiz.java b/server/services/src/main/java/com/doumee/biz/system/SystemJobTriggerBiz.java
new file mode 100644
index 0000000..de26329
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/SystemJobTriggerBiz.java
@@ -0,0 +1,18 @@
+package com.doumee.biz.system;
+
+import com.doumee.biz.system.dto.TriggerJobDTO;
+
+/**
+ * 瀹氭椂浠诲姟涓氬姟澶勭悊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemJobTriggerBiz {
+
+ /**
+ * 瑙﹀彂浠诲姟
+ *
+ * @param dto 璇﹁TriggerJobDTO
+ */
+ void trigger(TriggerJobDTO dto);
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/SystemMenuBiz.java b/server/services/src/main/java/com/doumee/biz/system/SystemMenuBiz.java
new file mode 100644
index 0000000..cde59e8
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/SystemMenuBiz.java
@@ -0,0 +1,67 @@
+package com.doumee.biz.system;
+
+import com.doumee.dao.common.dto.UpdateSortDTO;
+import com.doumee.dao.system.model.SystemMenu;
+import com.doumee.dao.system.vo.SystemMenuListVO;
+import com.doumee.dao.system.vo.SystemMenuNodeVO;
+
+import java.util.List;
+
+/**
+ * 绯荤粺鑿滃崟涓氬姟澶勭悊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemMenuBiz {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemMenu 鑿滃崟
+ * @return Integer
+ */
+ Integer create(SystemMenu systemMenu);
+
+ /**
+ * 缂栬緫
+ *
+ * @param systemMenu 鑿滃崟
+ */
+ void updateById(SystemMenu systemMenu);
+
+ /**
+ * 鑿滃崟鎺掑簭
+ *
+ * @param dto 璇﹁UpdateSortDTO
+ */
+ void updateSort(UpdateSortDTO dto);
+
+ /**
+ * 鏍规嵁鐢ㄦ埛ID鏌ヨ鑿滃崟鏍�
+ *
+ * @param userId 鐢ㄦ埛ID
+ * @return List<SystemMenuNodeVO>
+ */
+ List<SystemMenuNodeVO> findTree(Integer userId);
+
+ /**
+ * 鏌ヨ鑿滃崟鏍�
+ *
+ * @return List<SystemMenuListVO>
+ */
+ List<SystemMenuListVO> findTree();
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param id 鑿滃崟ID
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鎵归噺鍒犻櫎
+ *
+ * @param ids 鑿滃崟ID鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/SystemPermissionBiz.java b/server/services/src/main/java/com/doumee/biz/system/SystemPermissionBiz.java
new file mode 100644
index 0000000..b0a4553
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/SystemPermissionBiz.java
@@ -0,0 +1,42 @@
+package com.doumee.biz.system;
+
+import com.doumee.dao.system.model.SystemPermission;
+
+import java.util.List;
+
+/**
+ * 绯荤粺鏉冮檺涓氬姟澶勭悊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemPermissionBiz {
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param id 鏉冮檺ID
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鎵归噺鍒犻櫎
+ *
+ * @param ids 鏉冮檺ID鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemPermission 鏉冮檺
+ * @return Integer
+ */
+ Integer create(SystemPermission systemPermission);
+
+ /**
+ * 淇敼
+ *
+ * @param systemPermission 鏉冮檺
+ */
+ void updateById(SystemPermission systemPermission);
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/SystemRoleBiz.java b/server/services/src/main/java/com/doumee/biz/system/SystemRoleBiz.java
new file mode 100644
index 0000000..b22ccfb
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/SystemRoleBiz.java
@@ -0,0 +1,58 @@
+package com.doumee.biz.system;
+
+import com.doumee.dao.system.dto.CreateRoleMenuDTO;
+import com.doumee.dao.system.dto.CreateRolePermissionDTO;
+import com.doumee.dao.system.model.SystemRole;
+
+import java.util.List;
+
+/**
+ * 瑙掕壊鏉冮檺涓氬姟澶勭悊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemRoleBiz {
+
+ /**
+ * 鏂板缓
+ *
+ * @param systemRole 瑙掕壊
+ * @return Integer
+ */
+ Integer create (SystemRole systemRole);
+
+ /**
+ * 淇敼
+ *
+ * @param systemRole 瑙掕壊
+ */
+ void updateById(SystemRole systemRole);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param id 瑙掕壊ID
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鎵归噺鍒犻櫎
+ *
+ * @param ids 瑙掕壊ID鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 鍒涘缓瑙掕壊鏉冮檺
+ *
+ * @param dto 璇﹁CreateRolePermissionDTO
+ */
+ void createRolePermission(CreateRolePermissionDTO dto);
+
+ /**
+ * 鍒涘缓瑙掕壊鑿滃崟
+ *
+ * @param dto 璇﹁CreateRoleMenuDTO
+ */
+ void createRoleMenu(CreateRoleMenuDTO dto);
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/SystemUserBiz.java b/server/services/src/main/java/com/doumee/biz/system/SystemUserBiz.java
new file mode 100644
index 0000000..10c44ac
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/SystemUserBiz.java
@@ -0,0 +1,65 @@
+package com.doumee.biz.system;
+
+import com.doumee.dao.system.dto.CreateSystemUserDTO;
+import com.doumee.dao.system.dto.CreateUserRoleDTO;
+import com.doumee.dao.system.dto.ResetSystemUserPwdDTO;
+import com.doumee.dao.system.dto.UpdatePwdDto;
+
+import java.util.List;
+
+/**
+ * 绯荤粺鐢ㄦ埛涓氬姟澶勭悊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemUserBiz {
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param id 鐢ㄦ埛ID
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鎵归噺鍒犻櫎
+ *
+ * @param ids 鐢ㄦ埛ID鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 淇敼瀵嗙爜
+ *
+ * @param dto 璇﹁UpdatePwdDto
+ */
+ void updatePwd(UpdatePwdDto dto);
+
+ /**
+ * 閲嶇疆瀵嗙爜
+ *
+ * @param dto 璇﹁ResetSystemUserPwdDTO
+ */
+ void resetPwd(ResetSystemUserPwdDTO dto);
+
+ /**
+ * 鍒涘缓鐢ㄦ埛
+ *
+ * @param systemUser 璇﹁CreateSystemUserDTO
+ */
+ void create(CreateSystemUserDTO systemUser);
+
+ /**
+ * 淇敼鐢ㄦ埛淇℃伅
+ *
+ * @param systemUser 璇﹁CreateSystemUserDTO
+ */
+ void updateById(CreateSystemUserDTO systemUser);
+
+ /**
+ * 鍒涘缓鐢ㄦ埛瑙掕壊
+ *
+ * @param dto 璇﹁CreateUserRoleDTO
+ */
+ void createUserRole(CreateUserRoleDTO dto);
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/dto/TriggerJobDTO.java b/server/services/src/main/java/com/doumee/biz/system/dto/TriggerJobDTO.java
new file mode 100644
index 0000000..7cc4926
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/dto/TriggerJobDTO.java
@@ -0,0 +1,39 @@
+package com.doumee.biz.system.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瑙﹀彂浠诲姟鍙傛暟")
+public class TriggerJobDTO {
+
+ @ApiModelProperty(value = "浠诲姟ID", example = "1")
+ @NotNull(message = "浠诲姟ID涓嶈兘涓虹┖")
+ private Integer id;
+
+ @ApiModelProperty(value = "涓氬姟鏃堕棿")
+ @NotNull(message = "涓氬姟鏃堕棿涓嶈兘涓虹┖")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private Date businessTime;
+
+ @ApiModelProperty(value = "棰勮鎵ц鏃堕棿", hidden = true)
+ private Date scheduledFireTime;
+
+ @ApiModelProperty(value = "瀹為檯鎵ц鏃堕棿", hidden = true)
+ private Date fireTime;
+
+ @ApiModelProperty(value = "棰勮涓嬫鎵ц鏃堕棿", hidden = true)
+ private Date nextFireTime;
+
+ @ApiModelProperty(value = "瑙﹀彂绫诲瀷", hidden = true)
+ private String triggerType;
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/dto/TriggerJobSnippetDTO.java b/server/services/src/main/java/com/doumee/biz/system/dto/TriggerJobSnippetDTO.java
new file mode 100644
index 0000000..af982c4
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/dto/TriggerJobSnippetDTO.java
@@ -0,0 +1,24 @@
+package com.doumee.biz.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瑙﹀彂鍒嗙墖浠诲姟鍙傛暟")
+public class TriggerJobSnippetDTO {
+
+ @ApiModelProperty(value = "鍒嗙墖ID", example = "1")
+ @NotNull(message = "鍒嗙墖ID涓嶈兘涓虹┖")
+ private Integer id;
+
+ @ApiModelProperty(value = "瑙﹀彂绫诲瀷", hidden = true)
+ @NotNull(message = "瑙﹀彂绫诲瀷")
+ private String triggerType;
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/impl/SystemDictBizImpl.java b/server/services/src/main/java/com/doumee/biz/system/impl/SystemDictBizImpl.java
new file mode 100644
index 0000000..2dd0f75
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/impl/SystemDictBizImpl.java
@@ -0,0 +1,40 @@
+package com.doumee.biz.system.impl;
+
+import com.doumee.biz.system.SystemDictBiz;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.dao.system.model.SystemDict;
+import com.doumee.service.system.SystemDictService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SystemDictBizImpl implements SystemDictBiz {
+
+ @Autowired
+ private SystemDictService systemDictService;
+
+ @Override
+ public Integer create(SystemDict systemDict) {
+ SystemDict queryDto = new SystemDict();
+ queryDto.setCode(systemDict.getCode());
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemDict dict = systemDictService.findOne(queryDto);
+ if (dict != null) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "瀛楀吀缂栫爜宸插瓨鍦�");
+ }
+ return systemDictService.create(systemDict);
+ }
+
+ @Override
+ public void updateById(SystemDict systemDict) {
+ SystemDict queryDto = new SystemDict();
+ queryDto.setCode(systemDict.getCode());
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemDict dict = systemDictService.findOne(queryDto);
+ if (dict != null && !dict.getId().equals(systemDict.getId())) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "瀛楀吀缂栫爜宸插瓨鍦�");
+ }
+ systemDictService.updateById(systemDict);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/impl/SystemDictDataBizImpl.java b/server/services/src/main/java/com/doumee/biz/system/impl/SystemDictDataBizImpl.java
new file mode 100644
index 0000000..b602f4a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/impl/SystemDictDataBizImpl.java
@@ -0,0 +1,217 @@
+package com.doumee.biz.system.impl;
+
+import com.doumee.biz.system.SystemDictDataBiz;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.model.LoginUserInfo;
+import com.doumee.core.utils.qiyeweixin.QywxUtil;
+import com.doumee.dao.common.dto.UpdateSortDTO;
+import com.doumee.dao.system.model.SystemDict;
+import com.doumee.dao.system.model.SystemDictData;
+import com.doumee.service.system.SystemDictDataService;
+import com.doumee.service.system.SystemDictService;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.SecurityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+@Service
+public class SystemDictDataBizImpl implements SystemDictDataBiz {
+
+ @Autowired
+ private SystemDictDataService systemDictDataService;
+ @Autowired
+ private SystemDictService systemDictService;
+
+ @Override
+ public Integer create(SystemDictData systemDictData) {
+ SystemDictData queryDto = new SystemDictData();
+ queryDto.setDictId(systemDictData.getDictId());
+ queryDto.setCode(systemDictData.getCode());
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemDictData dictData = systemDictDataService.findOne(queryDto);
+ if (dictData != null) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "鏁版嵁鍊煎凡瀛樺湪");
+ }
+ // 鎺掑簭澶勭悊
+ queryDto = new SystemDictData();
+ queryDto.setDictId(systemDictData.getDictId());
+ queryDto.setDeleted(Boolean.FALSE);
+ long maxSort = systemDictDataService.count(queryDto);
+ systemDictData.setSort(Integer.valueOf("" + maxSort));
+ return systemDictDataService.create(systemDictData);
+ }
+
+ @Override
+ public void updateById(SystemDictData systemDictData) {
+ systemDictDataService.updateById(systemDictData);
+ }
+
+ @Override
+ public String updateQywxToken(){
+ String corpid = queryByCode(Constants.QYWX,Constants.QYWX_CORPID).getCode();
+ String secret = queryByCode(Constants.QYWX,Constants.QYWX_SECRET).getCode();
+ String token = QywxUtil.getAccessToken(corpid,secret);
+ SystemDictData dictData = queryByCode(Constants.QYWX,Constants.QYWX_TOKEN);
+ if (dictData != null ) {
+ dictData.setCode(token);
+ dictData.setUpdateTime(new Date());
+ systemDictDataService.updateById(dictData);
+ String ticket = QywxUtil.getJsApiTicket(token);
+ SystemDictData ticketDictData = queryByCode(Constants.QYWX,Constants.QYWX_JS_API_TICKET);
+ if (dictData != null ) {
+ ticketDictData.setCode(ticket);
+ ticketDictData.setUpdateTime(new Date());
+ systemDictDataService.updateById(ticketDictData);
+ }
+ }
+ return token;
+ }
+
+ @Override
+ public void sort(UpdateSortDTO dto) {
+ SystemDictData dictData = systemDictDataService.findById(dto.getId());
+ if (dictData == null || dictData.getDeleted()) {
+ throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "鎺掑簭鐨勬暟鎹笉瀛樺湪鎴栧凡琚垹闄�");
+ }
+ SystemDictData queryDto = new SystemDictData();
+ queryDto.setDictId(dictData.getDictId());
+ queryDto.setDeleted(Boolean.FALSE);
+ List<SystemDictData> dictDataList = systemDictDataService.findList(queryDto);
+ int index = 0;
+ for (int i = 0; i < dictDataList.size(); i++) {
+ if (dictDataList.get(i).getId().equals(dto.getId())) {
+ index = i;
+ break;
+ }
+ }
+ // 涓婄Щ
+ if ("top".equals(dto.getDirection())) {
+ if (index - 1 < 0) {
+ return;
+ }
+ SystemDictData preDictData = dictDataList.remove(index - 1);
+ dictDataList.add(index, preDictData);
+ }
+ // 涓嬬Щ
+ else {
+ if (index + 1 > dictDataList.size() - 1) {
+ return;
+ }
+ SystemDictData nextDictData = dictDataList.remove(index + 1);
+ dictDataList.add(index, nextDictData);
+ }
+ for (int i = 0; i < dictDataList.size(); i++) {
+ dictDataList.get(i).setSort(i);
+ }
+ // 淇敼
+ systemDictDataService.updateByIdInBatch(dictDataList);
+ }
+
+ @Override
+ public SystemDictData queryByCode(String dicCode, String label){
+ SystemDict queryDto = new SystemDict();
+ queryDto.setCode(dicCode);
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemDict dictData = systemDictService.findOne(queryDto);
+ if (dictData == null) {
+ return new SystemDictData();
+// throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "鏁版嵁鍊间笉瀛樺湪");
+ }
+ SystemDictData data = new SystemDictData();
+ data.setDictId(dictData.getId());
+ data.setLabel(label);
+ data.setDeleted(Boolean.FALSE);
+ data = systemDictDataService.findOne(data);
+ if(data == null){
+ data = new SystemDictData();
+ }
+ return data;
+ }
+ @Override
+ public String queryCodeById(Integer id){
+ SystemDictData data = systemDictDataService.findById(id);
+ if(data != null){
+ return data.getCode();
+ }
+ return null;
+ }
+
+
+ @Override
+ public List<SystemDictData> queryListByCode(String dicCode, String label){
+ SystemDict queryDto = new SystemDict();
+ queryDto.setCode(dicCode);
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemDict dictData = systemDictService.findOne(queryDto);
+ if (dictData == null) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "鏁版嵁鍊间笉瀛樺湪");
+ }
+ SystemDictData data = new SystemDictData();
+ data.setDictId(dictData.getId());
+ data.setLabel(label);
+ data.setDeleted(Boolean.FALSE);
+ List<SystemDictData> list= systemDictDataService.findList(data);
+
+ return list;
+ }
+
+ @Override
+ public void updateByIdNew(SystemDictData systemDictData) {
+ systemDictDataService.updateById(systemDictData);
+ }
+
+ @Override
+ public List<SystemDictData> queryDataByCode(String dicCode, String code){
+ SystemDict queryDto = new SystemDict();
+ queryDto.setCode(dicCode);
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemDict dictData = systemDictService.findOne(queryDto);
+ if (dictData == null) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "鏁版嵁鍊间笉瀛樺湪");
+ }
+ SystemDictData data = new SystemDictData();
+ data.setDictId(dictData.getId());
+ data.setCode(code);
+ data.setDeleted(Boolean.FALSE);
+ List<SystemDictData> list= systemDictDataService.findList(data);
+
+ return list;
+ }
+
+ @Override
+ public void updateByDicId(List<SystemDictData> list) {
+ LoginUserInfo user = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
+ list.stream().forEach(s->{
+ s.setUpdateTime(new Date());
+ s.setUpdateUser(user.getId());
+ systemDictDataService.updateById(s);
+ });
+
+ }
+
+ @Override
+ public String getPreFixPath(String resourceCode, String targetCode) {
+
+ if (StringUtils.isBlank(resourceCode) || StringUtils.isBlank(targetCode)){
+ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"璺緞鍙傛暟涓嶅畬鏁�");
+ }
+ SystemDict queryDto = new SystemDict();
+ queryDto.setCode(Constants.FTP);
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemDict dictData = systemDictService.findOne(queryDto);
+ if (dictData == null) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "鏁版嵁鍊间笉瀛樺湪");
+ }
+ List<SystemDictData> list = systemDictDataService.findList(dictData.getId(), Arrays.asList(resourceCode, targetCode));
+ String resourcePath = list.stream().filter(s->s.getLabel().equals(resourceCode)).findFirst().map(s->s.getCode()).orElse("");
+ String targetPath = list.stream().filter(s -> s.getLabel().equals(targetCode)).findFirst().map(s -> s.getCode()).orElse("");
+ return resourcePath+targetPath;
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/impl/SystemJobBizImpl.java b/server/services/src/main/java/com/doumee/biz/system/impl/SystemJobBizImpl.java
new file mode 100644
index 0000000..e785cc6
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/impl/SystemJobBizImpl.java
@@ -0,0 +1,49 @@
+package com.doumee.biz.system.impl;
+
+import com.doumee.biz.system.SystemJobBiz;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.dao.system.model.SystemJob;
+import com.doumee.service.system.SystemJobService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class SystemJobBizImpl implements SystemJobBiz {
+
+ @Autowired
+ private SystemJobService systemJobService;
+
+ @Override
+ public Integer create(SystemJob job) {
+ job.setDisabled(Boolean.FALSE);
+ SystemJob queryDto = new SystemJob();
+ queryDto.setDisabled(Boolean.FALSE);
+ queryDto.setDeleted(Boolean.FALSE);
+ queryDto.setHandler(job.getHandler());
+ job.setStatus(Constants.Job.JobStatus.READY.getCode());
+ if (systemJobService.count(queryDto) > 0) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "宸插瓨鍦ㄤ换鍔″鐞嗗櫒'" + job.getHandler() + "'锛岃鍕块噸澶嶇粦瀹�");
+ }
+ return systemJobService.create(job);
+ }
+
+ @Override
+ public void updateById(SystemJob job) {
+ SystemJob queryDto = new SystemJob();
+ queryDto.setDisabled(Boolean.FALSE);
+ queryDto.setDeleted(Boolean.FALSE);
+ queryDto.setHandler(job.getHandler());
+ List<SystemJob> jobs = systemJobService.findList(queryDto);
+ if (jobs.size() > 1) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "宸插瓨鍦ㄤ换鍔″鐞嗗櫒'" + job.getHandler() + "'锛岃鍕块噸澶嶇粦瀹�");
+ }
+ if (jobs.size() == 1 && !jobs.get(0).getId().equals(job.getId())) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "宸插瓨鍦ㄤ换鍔″鐞嗗櫒'" + job.getHandler() + "'锛岃鍕块噸澶嶇粦瀹�");
+ }
+ systemJobService.updateById(job);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/impl/SystemJobSnippetTriggerBizImpl.java b/server/services/src/main/java/com/doumee/biz/system/impl/SystemJobSnippetTriggerBizImpl.java
new file mode 100644
index 0000000..4a7c66c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/impl/SystemJobSnippetTriggerBizImpl.java
@@ -0,0 +1,231 @@
+package com.doumee.biz.system.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.doumee.biz.system.SystemJobSnippetTriggerBiz;
+import com.doumee.biz.system.dto.TriggerJobSnippetDTO;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.exception.LockedException;
+import com.doumee.core.job.BaseDistributer;
+import com.doumee.core.job.BaseJob;
+import com.doumee.core.job.JobContext;
+import com.doumee.core.job.JobParam;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.SystemJobSnippetMapper;
+import com.doumee.dao.system.model.SystemJobLog;
+import com.doumee.dao.system.model.SystemJobSnippet;
+import com.doumee.service.system.SystemJobLogService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+@Slf4j
+@Service
+public class SystemJobSnippetTriggerBizImpl implements SystemJobSnippetTriggerBiz {
+
+ @Autowired
+ private SystemJobLogService systemJobLogService;
+
+ @Autowired
+ private SystemJobSnippetMapper systemJobSnippetMapper;
+
+ @Override
+ public void trigger(TriggerJobSnippetDTO dto) {
+ Utils.ThreadPool.start(() -> {
+ SystemJobSnippet snippet = systemJobSnippetMapper.selectById(dto.getId());
+ SystemJobLog systemJobLog = new SystemJobLog();
+ // 楠岃瘉鍒嗙墖
+ if(!this.checkSnippet(snippet)) {
+ return;
+ }
+ boolean locked = false;
+ try {
+ log(snippet, "Snippet started");
+ // 璁板綍鏃ュ織
+ if (snippet.getWithLog()) {
+ systemJobLog.setRunTimeStart(new Date());
+ systemJobLog.setJobId(snippet.getJobId());
+ systemJobLog.setJobName(snippet.getJobName());
+ systemJobLog.setJobDistributeGroup(snippet.getJobDistributeGroup());
+ systemJobLog.setSnippetId(snippet.getId());
+ systemJobLog.setSnippetCode(snippet.getSnippetCode());
+ systemJobLog.setBusinessTime(snippet.getJobBusinessTime());
+ systemJobLog.setRemark("鍒嗙墖姝e湪鎵ц涓�");
+ systemJobLog.setServerIp(Utils.Server.getIP());
+ systemJobLog.setStatus(Constants.Job.LogStatus.NONE.getCode());
+ systemJobLog.setTriggerType(dto.getTriggerType());
+ systemJobLogService.create(systemJobLog);
+ }
+ // 閿佸畾褰撳墠鍒嗙墖锛岄槻姝㈠叾浠栨湇鍔″櫒閲嶅鎵ц
+ this.lock(snippet);
+ locked = true;
+ BaseJob jobBean = Utils.SpringContext.getBean(snippet.getHandler(), BaseJob.class);
+ JobParam jobParam = new JobParam();
+ jobParam.setId(snippet.getId());
+ jobParam.setSnippetIndex(snippet.getSnippetIndex());
+ jobParam.setBusinessTime(snippet.getJobBusinessTime());
+ jobParam.setRuntimeData(snippet.getSnippetData());
+ // 濡傛灉璇ュ垎鐗囧瓨鍦ㄥ垎鐗囧櫒锛屽垯鎵ц鍒嗙墖鍣ㄥ仛杩涗竴姝ュ垎鍙�
+ if (StringUtils.isNotBlank(snippet.getDistributeHandler())) {
+ String distributeGroup = UUID.randomUUID().toString();
+ int snippetCount = this.distribute(snippet, jobParam, distributeGroup);
+ // 鏇存柊鏃ュ織鐘舵��
+ if (snippet.getWithLog()) {
+ systemJobLog.setStatus(Constants.Job.LogStatus.SUCCESS.getCode());
+ systemJobLog.setRemark("浠诲姟宸插垎鍙戞垚" + snippetCount + "涓垎鐗囦换鍔★紝鍒嗗彂缁勶細" + distributeGroup);
+ }
+ // 鏇存柊鍒嗙墖鐘舵��
+ snippet.setStatus(Constants.Job.SnippetStatus.SUCCESS.getCode());
+ return;
+ }
+ // 鎵ц浠诲姟
+ JobContext jobContext = jobBean.execute(jobParam);
+ log(snippet, "Snippet context: {}", jobContext);
+ // 鏇存柊鏃ュ織鐘舵��
+ if (snippet.getWithLog()) {
+ systemJobLog.setHandleTotalSize(jobContext.getHandleTotalSize());
+ systemJobLog.setHandleSuccessSize(jobContext.getHandleSuccessSize());
+ systemJobLog.setContext(jobContext.getContext());
+ systemJobLog.setStatus(Constants.Job.LogStatus.SUCCESS.getCode());
+ systemJobLog.setRemark("鍒嗙墖鎵ц瀹屾垚");
+ }
+ // 鏇存柊鍒嗙墖鐘舵��
+ snippet.setStatus(Constants.Job.SnippetStatus.SUCCESS.getCode());
+ } catch (LockedException e) {
+ log(snippet, "Snippet execute end.");
+ // 鏇存柊鏃ュ織鐘舵��
+ if (snippet.getWithLog()) {
+ systemJobLog.setStatus(Constants.Job.LogStatus.IGNORE.getCode());
+ systemJobLog.setRemark("鍒嗙墖姝e湪琚叾浠栨湇鍔℃墽琛屾垨閿佸畾");
+ }
+ } catch (Exception e) {
+ error(snippet, e);
+ // 鏇存柊鍒嗙墖鐘舵��
+ snippet.setStatus(Constants.Job.SnippetStatus.FAILED.getCode());
+ // 鏇存柊鏃ュ織鐘舵��
+ if (snippet.getWithLog()) {
+ systemJobLog.setStatus(Constants.Job.LogStatus.FAILED.getCode());
+ systemJobLog.setRemark("鍑虹幇寮傚父锛�" + e.getMessage());
+ }
+ } finally {
+ // 鏇存柊鏃ュ織
+ if (systemJobLog.getId() != null && snippet.getWithLog()) {
+ systemJobLog.setRunTimeEnd(new Date());
+ systemJobLog.setRunSpendTime(Integer.valueOf("" + (systemJobLog.getRunTimeEnd().getTime() - systemJobLog.getRunTimeStart().getTime())));
+ systemJobLogService.updateById(systemJobLog);
+ }
+ // 瑙i攣鍒嗙墖
+ if (locked) {
+ this.unlock(snippet);
+ }
+ }
+ });
+ }
+
+ /**
+ * 閿佸畾鍒嗙墖
+ *
+ * @param snippet 鍒嗙墖
+ */
+ private void lock (SystemJobSnippet snippet) throws LockedException {
+ log(snippet, "Lock snippet.");
+ SystemJobSnippet newSnippet = new SystemJobSnippet();
+ newSnippet.setStatus(Constants.Job.SnippetStatus.RUNNING.getCode());
+ newSnippet.setLockNumber(snippet.getLockNumber() + 1);
+ int result = systemJobSnippetMapper.update(newSnippet, new LambdaUpdateWrapper<SystemJobSnippet>()
+ .eq(SystemJobSnippet::getId, snippet.getId())
+ .eq(SystemJobSnippet::getLockNumber, snippet.getLockNumber())
+ );
+ if (result == 0) {
+ throw new LockedException("EVA: snippet is locked.");
+ }
+ log(snippet, "Lock snippet completed.");
+ }
+
+ /**
+ * 瀹屾垚鍒嗙墖澶勭悊
+ *
+ * @param snippet 鍒嗙墖
+ */
+ private void unlock (SystemJobSnippet snippet) {
+ SystemJobSnippet newSnippet = new SystemJobSnippet();
+ newSnippet.setStatus(snippet.getStatus());
+ systemJobSnippetMapper.update(newSnippet, new LambdaUpdateWrapper<SystemJobSnippet>()
+ .eq(SystemJobSnippet::getId, snippet.getId())
+ );
+ log(snippet, "Snippet execute completed.");
+ }
+
+ /**
+ * 鍒嗗彂
+ *
+ * @param snippet 鍒嗙墖瀹炰緥
+ * @param jobParam JOB鎵ц鍙傛暟
+ * @param distributeGroup 鍒嗗彂缁�
+ * @return int
+ */
+ private int distribute (SystemJobSnippet snippet, JobParam jobParam, String distributeGroup) {
+ log(snippet, "Begin distribute.");
+ BaseDistributer distributer = Utils.SpringContext.getBean(snippet.getDistributeHandler(), BaseDistributer.class);
+ List<List<?>> snippetDatas = distributer.getSnippetData(new BaseDistributer.DistributeDTO(snippet.getDistributeLimit()), jobParam);
+ for (int i = 0; i < snippetDatas.size(); i++) {
+ List snippetData = snippetDatas.get(i);
+ SystemJobSnippet subSnippet = new SystemJobSnippet();
+ subSnippet.setJobId(snippet.getJobId());
+ subSnippet.setJobName(snippet.getJobName());
+ subSnippet.setJobBusinessTime(jobParam.getBusinessTime());
+ subSnippet.setJobDistributeGroup(distributeGroup);
+ subSnippet.setHandler(snippet.getHandler());
+ subSnippet.setSnippetIndex(i);
+ subSnippet.setSnippetCode(UUID.randomUUID().toString());
+ subSnippet.setSnippetData(JSON.toJSONString(snippetData));
+ subSnippet.setSnippetDataSize(snippetData.size());
+ subSnippet.setWithLog(snippet.getWithLog());
+ subSnippet.setAllowServerIps(snippet.getAllowServerIps());
+ subSnippet.setStatus(Constants.Job.JobStatus.READY.getCode());
+ systemJobSnippetMapper.insert(subSnippet);
+ }
+ log(snippet, "distribute completed.");
+ return snippetDatas.size();
+ }
+
+ /**
+ * 楠岃瘉鍒嗙墖鏄惁鍙墽琛�
+ *
+ * @param snippet 鍒嗙墖
+ * @return boolean
+ */
+ private boolean checkSnippet (SystemJobSnippet snippet) {
+ // 鏈嶅姟鍣ㄩ獙璇�
+ if (StringUtils.isNotBlank(snippet.getAllowServerIps())) {
+ return snippet.getAllowServerIps().contains(Utils.Server.getIP());
+ }
+ return Boolean.TRUE;
+ }
+
+ /**
+ * 鎵撳嵃鏃ュ織
+ *
+ * @param snippet 鍒嗙墖
+ * @param text 鏃ュ織妯$増鍐呭
+ * @param params 鏃ュ織鍙傛暟
+ */
+ private void log (SystemJobSnippet snippet, String text, Object... params) {
+ log.trace("{}: " + text, String.format("%s-SNIPPET-%s", snippet.getJobName(), snippet.getSnippetCode()), params);
+ }
+
+ /**
+ * 鎵撳嵃閿欒鏃ュ織
+ *
+ * @param snippet 鍒嗙墖
+ * @param e 寮傚父瀵硅薄
+ */
+ private void error (SystemJobSnippet snippet, Exception e) {
+ log.error(String.format("EVA: %s-SNIPPET-%s", snippet.getJobName(), snippet.getSnippetCode()) + ": Handle snippet throw an exception.", e);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/impl/SystemJobTriggerBizImpl.java b/server/services/src/main/java/com/doumee/biz/system/impl/SystemJobTriggerBizImpl.java
new file mode 100644
index 0000000..b802b3c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/impl/SystemJobTriggerBizImpl.java
@@ -0,0 +1,288 @@
+package com.doumee.biz.system.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.doumee.biz.system.SystemJobTriggerBiz;
+import com.doumee.biz.system.dto.TriggerJobDTO;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.exception.LockedException;
+import com.doumee.core.job.BaseDistributer;
+import com.doumee.core.job.BaseJob;
+import com.doumee.core.job.JobContext;
+import com.doumee.core.job.JobParam;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.SystemJobLogMapper;
+import com.doumee.dao.system.SystemJobMapper;
+import com.doumee.dao.system.SystemJobSnippetMapper;
+import com.doumee.dao.system.model.SystemJob;
+import com.doumee.dao.system.model.SystemJobLog;
+import com.doumee.dao.system.model.SystemJobSnippet;
+import com.doumee.service.system.SystemJobLogService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+@Slf4j
+@Service
+public class SystemJobTriggerBizImpl implements SystemJobTriggerBiz {
+
+ @Autowired
+ private SystemJobLogMapper systemJobLogMapper;
+
+ @Autowired
+ private SystemJobMapper systemJobMapper;
+
+ @Autowired
+ private SystemJobSnippetMapper systemJobSnippetMapper;
+
+ private ThreadLocal<String> jobUnique = new ThreadLocal<>();
+
+ @Override
+ public void trigger(TriggerJobDTO dto) {
+ SystemJob job = null;
+ JobParam jobParam = new JobParam();
+ boolean locked = false;
+ SystemJobLog systemJobLog = new SystemJobLog();
+ try {
+ Integer jobId = dto.getId();
+ job = systemJobMapper.selectById(jobId);
+ // 楠岃瘉JOB
+ if (!this.checkJob(job, dto.getBusinessTime())) {
+ return;
+ }
+ // 鍒濆鍖朖OB鏁版嵁
+ jobUnique.set(RandomStringUtils.randomAlphabetic(8));
+ log(job, "Job started");
+ log(job, "Job thread name: {}", Thread.currentThread().getName());
+ log(job, "Job scheduled fire time: {}", Utils.Date.format(dto.getScheduledFireTime()));
+ log(job, "Job fire time: {}", Utils.Date.format(dto.getFireTime()));
+ log(job, "Job business time: {}", Utils.Date.format(dto.getBusinessTime()));
+ jobParam.setId(jobId);
+ jobParam.setTriggerType(dto.getTriggerType());
+ jobParam.setBusinessTime(dto.getBusinessTime());
+ // 璁板綍鏃ュ織
+ if (job.getWithLog()) {
+ systemJobLog.setJobId(jobId);
+ systemJobLog.setJobName(job.getJobName());
+ systemJobLog.setRunTimeStart(new Date());
+ systemJobLog.setServerIp(Utils.Server.getIP());
+ systemJobLog.setBusinessTime(dto.getBusinessTime());
+ systemJobLog.setStatus(Constants.Job.LogStatus.NONE.getCode());
+ systemJobLog.setTriggerType(dto.getTriggerType());
+ systemJobLog.setRemark("浠诲姟姝e湪鎵ц涓�");
+ systemJobLogMapper.insert(systemJobLog);
+ }
+ // 浠诲姟鍔犻攣锛岄槻姝㈠鏈嶅姟鍣ㄩ噸澶嶆墽琛�
+ this.lock(job);
+ locked = true;
+ // 濡傛灉寮�鍚簡寮傛鎵ц锛屽垯鍒涘缓涓�涓垎鐗�
+ if (job.getWithAsync()) {
+ String snippetCode = this.createAsyncSnippet(job, jobParam);
+ systemJobLog.setStatus(Constants.Job.LogStatus.SUCCESS.getCode());
+ systemJobLog.setRemark("寮傛浠诲姟宸茶浆涓哄垎鐗囦换鍔★紝鍒嗙墖缂栫爜锛�" + snippetCode);
+ return;
+ }
+ // 濡傛灉瀛樺湪鍒嗙墖
+ if (StringUtils.isNotBlank(job.getDistributeHandler())) {
+ String distributeGroup = UUID.randomUUID().toString();
+ int snippetCount = this.distribute(job, jobParam, distributeGroup);
+ systemJobLog.setStatus(Constants.Job.LogStatus.SUCCESS.getCode());
+ systemJobLog.setRemark("浠诲姟宸插垎鍙戞垚" + snippetCount + "涓垎鐗囦换鍔★紝鍒嗗彂缁勶細" + distributeGroup);
+ return;
+ }
+ // 涓嶅瓨鍦ㄥ垎鐗囷紝鐩存帴鎵ц浠诲姟锛堟牴鎹换鍔″鐞嗗櫒鍚嶇О鑾峰彇浠诲姟澶勭悊鍣ㄥ疄渚嬪苟鎵ц锛�
+ BaseJob jobBean = Utils.SpringContext.getBean(job.getHandler(), BaseJob.class);
+ JobContext jobContext = jobBean.execute(jobParam);
+ // 瑙i攣浠诲姟
+ this.unlock(job, dto.getNextFireTime());
+ locked = false;
+ // 淇敼鏃ュ織淇℃伅
+ if (job.getWithLog()) {
+ systemJobLog.setRemark("浠诲姟鎵ц瀹屾垚");
+ systemJobLog.setHandleTotalSize(jobContext.getHandleTotalSize());
+ systemJobLog.setHandleSuccessSize(jobContext.getHandleSuccessSize());
+ systemJobLog.setContext(jobContext.getContext());
+ systemJobLog.setStatus(Constants.Job.LogStatus.SUCCESS.getCode());
+ }
+ } catch (LockedException e) {
+ log(job, e.getMessage());
+ // 淇敼鏃ュ織鐘舵��
+ if (job.getWithLog()) {
+ systemJobLog.setStatus(Constants.Job.LogStatus.IGNORE.getCode());
+ systemJobLog.setRemark("浠诲姟姝e湪琚叾浠栨湇鍔℃墽琛屾垨閿佸畾");
+ }
+ } catch (Exception e) {
+ if (job != null) {
+ error(job, e);
+ // 淇敼鏃ュ織鐘舵��
+ if (job.getWithLog()) {
+ systemJobLog.setStatus(Constants.Job.LogStatus.FAILED.getCode());
+ systemJobLog.setRemark("浠诲姟鎵ц澶辫触锛屽嚭鐜板紓甯革細" + e.getMessage());
+ }
+ } else {
+ e.printStackTrace();
+ }
+ } finally {
+ // 鏇存柊鏃ュ織
+ if (job != null && job.getWithLog() && systemJobLog.getId() != null) {
+ systemJobLog.setRunTimeEnd(new Date());
+ systemJobLog.setRunSpendTime(Integer.valueOf("" + (systemJobLog.getRunTimeEnd().getTime() - systemJobLog.getRunTimeStart().getTime())));
+ systemJobLogMapper.updateById(systemJobLog);
+ }
+ // 浠诲姟瑙i攣
+ if (locked) {
+ this.unlock(job, dto.getNextFireTime());
+ log(job, "Job execute completed.");
+ }
+ }
+ }
+
+ /**
+ * 閿佸畾JOB
+ *
+ * @param job JOB
+ */
+ private void lock (SystemJob job) throws LockedException{
+ log(job, "Lock job.");
+ if (Constants.equalsInteger(job.getStatus(),Constants.Job.JobStatus.RUNNING.getCode())) {
+ throw new LockedException("EVA: job is running.");
+ }
+ SystemJob newJob = new SystemJob();
+ newJob.setStatus(Constants.Job.JobStatus.RUNNING.getCode());
+ newJob.setLockNumber(job.getLockNumber() + 1);
+ // 涓嶄慨鏀规洿鏂颁汉鍜屾洿鏂版椂闂�
+ newJob.setUpdateUser(Constants.Ignore.IGNORE_USER);
+ newJob.setUpdateTime(Constants.Ignore.IGNORE_TIME);
+ int result = systemJobMapper.update(newJob, new UpdateWrapper<SystemJob>()
+ .lambda()
+ .eq(SystemJob::getId, job.getId())
+ .eq(SystemJob::getLockNumber, job.getLockNumber())
+ );
+ if (result == 0) {
+ throw new LockedException("EVA: job is locked.");
+ }
+ log(job, "Lock job completed.");
+ }
+
+ /**
+ * 瑙i攣JOB
+ *
+ * @param job JOB
+ */
+ private void unlock(SystemJob job, Date nextFireTime) {
+ log(job, "Unlock job.");
+ SystemJob newJob = new SystemJob();
+ newJob.setId(job.getId());
+ newJob.setStatus(Constants.Job.JobStatus.READY.getCode());
+ newJob.setNextFireTime(nextFireTime);
+ // 涓嶄慨鏀规洿鏂颁汉鍜屾洿鏂版椂闂�
+ newJob.setUpdateUser(Constants.Ignore.IGNORE_USER);
+ newJob.setUpdateTime(Constants.Ignore.IGNORE_TIME);
+ systemJobMapper.updateById(newJob);
+ log(job, "Unlock job completed.");
+ }
+
+ /**
+ * 鍒涘缓寮傛鍒嗙墖
+ *
+ * @param job JOB
+ * @param jobParam JOB鍙傛暟
+ */
+ private String createAsyncSnippet (SystemJob job, JobParam jobParam) {
+ log(job, "Begin create async snippet.");
+ String distributeGroup = UUID.randomUUID().toString();
+ SystemJobSnippet snippet = new SystemJobSnippet();
+ snippet.setJobId(job.getId());
+ snippet.setJobName(job.getJobName());
+ snippet.setJobBusinessTime(jobParam.getBusinessTime());
+ snippet.setJobDistributeGroup(distributeGroup);
+ snippet.setDistributeHandler(job.getDistributeHandler());
+ snippet.setDistributeLimit(job.getDistributeLimit());
+ snippet.setHandler(job.getHandler());
+ snippet.setSnippetIndex(0);
+ snippet.setSnippetCode(UUID.randomUUID().toString());
+ snippet.setWithLog(job.getWithLog());
+ snippet.setAllowServerIps(job.getAllowServerIps());
+ snippet.setStatus(Constants.Job.JobStatus.READY.getCode());
+ systemJobSnippetMapper.insert(snippet);
+ log(job, "Create async snippet completed.");
+ return snippet.getSnippetCode();
+ }
+
+ /**
+ * 鍒嗗彂
+ *
+ * @param job JOB
+ * @param jobParam JOB鍙傛暟
+ * @param distributeGroup 鍒嗗彂缁�
+ * @return int
+ */
+ private int distribute (SystemJob job, JobParam jobParam, String distributeGroup) {
+ log(job, "Begin distribute.");
+ BaseDistributer distributer = Utils.SpringContext.getBean(job.getDistributeHandler(), BaseDistributer.class);
+ List<List<?>> snippetDatas = distributer.getSnippetData(new BaseDistributer.DistributeDTO(job.getDistributeLimit()), jobParam);
+ for (int i = 0; i < snippetDatas.size(); i++) {
+ List snippetData = snippetDatas.get(i);
+ SystemJobSnippet snippet = new SystemJobSnippet();
+ snippet.setJobId(job.getId());
+ snippet.setJobName(job.getJobName());
+ snippet.setJobBusinessTime(jobParam.getBusinessTime());
+ snippet.setJobDistributeGroup(distributeGroup);
+ snippet.setHandler(job.getHandler());
+ snippet.setSnippetIndex(i);
+ snippet.setSnippetCode(UUID.randomUUID().toString());
+ snippet.setSnippetData(JSON.toJSONString(snippetData));
+ snippet.setSnippetDataSize(snippetData.size());
+ snippet.setWithLog(job.getWithLog());
+ snippet.setAllowServerIps(job.getAllowServerIps());
+ snippet.setStatus(Constants.Job.JobStatus.READY.getCode());
+ systemJobSnippetMapper.insert(snippet);
+ }
+ log(job, "distribute completed.");
+ return snippetDatas.size();
+ }
+
+ /**
+ * 楠岃瘉Job鏄惁鍙墽琛�
+ *
+ * @param job JOB
+ */
+ private boolean checkJob (SystemJob job, Date businessTime) {
+ // 鎵ц鏃堕棿楠岃瘉锛堜换鍔¢璁′笅涓�娆℃墽琛�<=褰撳墠鎵ц鏃堕棿鍗冲彲鎵ц)
+ if (businessTime != null && job.getNextFireTime() != null && job.getNextFireTime().compareTo(businessTime) == 1) {
+ return Boolean.FALSE;
+ }
+ // 鏈嶅姟鍣ㄩ獙璇�
+ if (StringUtils.isNotBlank(job.getAllowServerIps())) {
+ return job.getAllowServerIps().contains(Utils.Server.getIP());
+ }
+ return Boolean.TRUE;
+ }
+
+ /**
+ * 鎵撳嵃鏃ュ織
+ *
+ * @param job JOB
+ * @param text 鏃ュ織妯$増鍐呭
+ * @param params 鏃ュ織鍙傛暟
+ */
+ private void log (SystemJob job, String text, Object... params) {
+ log.trace("{}: " + text, String.format("%s_%s", job.getJobName(), jobUnique.get()), params);
+ }
+
+ /**
+ * 鎵撳嵃閿欒鏃ュ織
+ *
+ * @param job JOB
+ * @param e 寮傚父瀵硅薄
+ */
+ private void error (SystemJob job, Exception e) {
+ log.error(String.format("EVA: %s_%s", job.getJobName(), jobUnique.get()) + ": Handle job throw an exception.", e);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/impl/SystemMenuBizImpl.java b/server/services/src/main/java/com/doumee/biz/system/impl/SystemMenuBizImpl.java
new file mode 100644
index 0000000..5c4f44b
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/impl/SystemMenuBizImpl.java
@@ -0,0 +1,226 @@
+package com.doumee.biz.system.impl;
+
+import com.doumee.biz.system.SystemMenuBiz;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.dao.common.dto.UpdateSortDTO;
+import com.doumee.dao.system.model.SystemMenu;
+import com.doumee.dao.system.vo.SystemMenuListVO;
+import com.doumee.dao.system.vo.SystemMenuNodeVO;
+import com.doumee.service.system.SystemMenuService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class SystemMenuBizImpl implements SystemMenuBiz {
+
+ @Autowired
+ private SystemMenuService systemMenuService;
+
+ @Override
+ public Integer create(SystemMenu systemMenu) {
+ // 缁熻涓婄骇鑿滃崟涓嬪瓙鑿滃崟鏁伴噺
+ SystemMenu countDto = new SystemMenu();
+ countDto.setParentId(systemMenu.getParentId());
+ countDto.setDeleted(Boolean.FALSE);
+ long subMenuCount = systemMenuService.count(countDto);
+ // 璁剧疆鏂板缓鑿滃崟鐨勯『搴�
+ systemMenu.setSort(Integer.valueOf("" + subMenuCount));
+ return systemMenuService.create(systemMenu);
+ }
+
+ @Override
+ public void updateById(SystemMenu systemMenu) {
+ SystemMenu dbMenu = systemMenuService.findById(systemMenu.getId());
+ // 濡傛灉涓婄骇鑿滃崟鍙戠敓浜嗗彉鍖栵紝鍒欓噸鏂拌皟鏁磋彍鍗曠殑鎺掑簭
+ if (dbMenu.getParentId() != null && !dbMenu.getParentId().equals(systemMenu.getParentId())) {
+ // 缁熻涓婄骇鑿滃崟涓嬪瓙鑿滃崟鏁伴噺
+ SystemMenu countDto = new SystemMenu();
+ countDto.setParentId(systemMenu.getParentId());
+ countDto.setDeleted(Boolean.FALSE);
+ long subMenuCount = systemMenuService.count(countDto);
+ systemMenu.setSort(Integer.valueOf("" + subMenuCount));
+ }
+ systemMenuService.updateById(systemMenu);
+ }
+
+ @Override
+ public void updateSort(UpdateSortDTO dto) {
+ SystemMenu currentMenu = systemMenuService.findById(dto.getId());
+ List<SystemMenu> menuPool;
+ if (currentMenu.getParentId() == null) {
+ menuPool = systemMenuService.findRootList();
+ } else {
+ SystemMenu queryDto = new SystemMenu();
+ queryDto.setParentId(currentMenu.getParentId());
+ menuPool = systemMenuService.findList(queryDto);
+ }
+ int currentMenuIndex = 0;
+ for (int i = 0; i < menuPool.size(); i++) {
+ if (menuPool.get(i).getId().equals(dto.getId())) {
+ currentMenuIndex = i;
+ break;
+ }
+ }
+ // 涓婄Щ
+ if ("top".equals(dto.getDirection())) {
+ if (currentMenuIndex - 1 < 0) {
+ return;
+ }
+ SystemMenu preMenu = menuPool.remove(currentMenuIndex - 1);
+ menuPool.add(currentMenuIndex, preMenu);
+ }
+ // 涓嬬Щ
+ else {
+ if (currentMenuIndex + 1 > menuPool.size() - 1) {
+ return;
+ }
+ SystemMenu nextMenu = menuPool.remove(currentMenuIndex + 1);
+ menuPool.add(currentMenuIndex, nextMenu);
+ }
+ for (int i = 0; i < menuPool.size(); i++) {
+ menuPool.get(i).setSort(i);
+ }
+ // 淇敼
+ systemMenuService.updateByIdInBatch(menuPool);
+ }
+
+ @Override
+ public List<SystemMenuListVO> findTree() {
+ List<SystemMenuListVO> menus = systemMenuService.findList();
+ List<SystemMenuListVO> rootMenus = new ArrayList<>();
+ // 娣诲姞鏍硅彍鍗�
+ for (SystemMenu menu : menus) {
+ if (menu.getParentId() == null) {
+ SystemMenuListVO rootMenu = new SystemMenuListVO();
+ BeanUtils.copyProperties(menu, rootMenu, "children");
+ rootMenu.setChildren(new ArrayList<>());
+ rootMenus.add(rootMenu);
+ }
+ }
+ menus.removeIf(menu -> menu.getParentId() == null);
+ for (SystemMenuListVO child : rootMenus) {
+ this.fillChildren(child, menus);
+ }
+ return rootMenus;
+ }
+
+ @Override
+ public List<SystemMenuNodeVO> findTree (Integer userId) {
+ SystemMenu queryDto = new SystemMenu();
+ queryDto.setDeleted(Boolean.FALSE);
+ List<SystemMenu> menus = systemMenuService.findByUserId(userId);
+ List<SystemMenuNodeVO> rootNodes = new ArrayList<>();
+ // 娣诲姞鏍硅彍鍗�
+ for (SystemMenu menu : menus) {
+ if (menu.getParentId() == null) {
+ SystemMenuNodeVO nodeVO = new SystemMenuNodeVO();
+ nodeVO.setId(menu.getId());
+ nodeVO.setIndex("menu_" + menu.getId());
+ nodeVO.setLabel(menu.getName());
+ nodeVO.setUrl(menu.getPath());
+ nodeVO.setIcon(menu.getIcon());
+ nodeVO.setChildren(new ArrayList<>());
+ rootNodes.add(nodeVO);
+ }
+ }
+ menus.removeIf(menu -> menu.getParentId() == null);
+ for (SystemMenuNodeVO child : rootNodes) {
+ this.fillChildren(child, menus);
+ }
+ return rootNodes;
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ List<Integer> ids = systemMenuService.findChildren(id);
+ ids.add(id);
+ for (Integer id2 : ids) {
+ SystemMenu menu = systemMenuService.findById(id2);
+ if (menu == null) {
+ continue;
+ }
+ if (menu.getFixed()) {
+ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "璇峰嬁鍒犻櫎" + menu.getName() + ", 鍥犱负杩欐槸鍥哄畾鑿滃崟");
+ }
+ }
+ systemMenuService.deleteByIdInBatch(ids);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ /**
+ * 濉厖瀛愯彍鍗�
+ *
+ * @author dm
+ * @since 2022/02/19 18:03
+ */
+ private void fillChildren(SystemMenuListVO parent, List<SystemMenuListVO> menus) {
+ if (menus.size() == 0) {
+ return;
+ }
+ List<Integer> handledIds = new ArrayList<>();
+ for (SystemMenu menu : menus) {
+ if (parent.getId().equals(menu.getParentId())) {
+ SystemMenuListVO child = new SystemMenuListVO();
+ BeanUtils.copyProperties(menu, child, "children");
+ child.setChildren(new ArrayList<>());
+ parent.getChildren().add(child);
+ handledIds.add(menu.getId());
+ }
+ }
+ menus.removeIf(menu -> handledIds.contains(menu.getId()));
+ parent.setHasChildren(Boolean.TRUE);
+ if (parent.getChildren().size() > 0) {
+ parent.setHasChildren(Boolean.FALSE);
+ for (SystemMenuListVO child : parent.getChildren()) {
+ this.fillChildren(child, menus);
+ }
+ }
+ }
+
+ /**
+ * 濉厖瀛愯彍鍗�
+ *
+ * @author dm
+ * @since 2022/02/19 18:03
+ */
+ private void fillChildren(SystemMenuNodeVO parent, List<SystemMenu> menus) {
+ if (menus.size() == 0) {
+ return;
+ }
+ List<Integer> handledIds = new ArrayList<>();
+ for (SystemMenu menu : menus) {
+ if (parent.getId().equals(menu.getParentId())) {
+ SystemMenuNodeVO child = new SystemMenuNodeVO();
+ child.setId(menu.getId());
+ child.setLabel(menu.getName());
+ child.setUrl(menu.getPath());
+ child.setIcon(menu.getIcon());
+ child.setIndex("menu_" + menu.getId());
+ child.setChildren(new ArrayList<>());
+ parent.getChildren().add(child);
+ handledIds.add(menu.getId());
+ }
+ }
+ menus.removeIf(menu -> handledIds.contains(menu.getId()));
+ for (SystemMenuNodeVO child : parent.getChildren()) {
+ this.fillChildren(child, menus);
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/impl/SystemPermissionBizImpl.java b/server/services/src/main/java/com/doumee/biz/system/impl/SystemPermissionBizImpl.java
new file mode 100644
index 0000000..181d24f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/impl/SystemPermissionBizImpl.java
@@ -0,0 +1,67 @@
+package com.doumee.biz.system.impl;
+
+import com.doumee.biz.system.SystemPermissionBiz;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.dao.system.model.SystemPermission;
+import com.doumee.service.system.SystemPermissionService;
+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;
+
+@Service
+public class SystemPermissionBizImpl implements SystemPermissionBiz {
+
+ @Autowired
+ private SystemPermissionService systemPermissionService;
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemPermission permission = systemPermissionService.findById(id);
+ if (permission == null) {
+ return;
+ }
+ if (permission.getFixed()) {
+ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "璇峰嬁鍒犻櫎" + permission.getName() + "锛屽洜涓鸿繖鏄浐瀹氭潈闄�");
+ }
+ systemPermissionService.deleteById(id);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ public Integer create(SystemPermission systemPermission) {
+ SystemPermission queryDto = new SystemPermission();
+ queryDto.setCode(systemPermission.getCode());
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemPermission permission = systemPermissionService.findOne(queryDto);
+ if (permission != null) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "鏉冮檺缂栫爜宸插瓨鍦�");
+ }
+ return systemPermissionService.create(systemPermission);
+ }
+
+ @Override
+ public void updateById(SystemPermission systemPermission) {
+ SystemPermission queryDto = new SystemPermission();
+ queryDto.setCode(systemPermission.getCode());
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemPermission permission = systemPermissionService.findOne(queryDto);
+ if (permission != null && !systemPermission.getId().equals(permission.getId())) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "鏉冮檺缂栫爜宸插瓨鍦�");
+ }
+ systemPermissionService.updateById(systemPermission);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/impl/SystemRoleBizImpl.java b/server/services/src/main/java/com/doumee/biz/system/impl/SystemRoleBizImpl.java
new file mode 100644
index 0000000..480e738
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/impl/SystemRoleBizImpl.java
@@ -0,0 +1,113 @@
+package com.doumee.biz.system.impl;
+
+import com.doumee.biz.system.SystemRoleBiz;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.dao.system.dto.CreateRoleMenuDTO;
+import com.doumee.dao.system.dto.CreateRolePermissionDTO;
+import com.doumee.dao.system.model.SystemRole;
+import com.doumee.dao.system.model.SystemRoleMenu;
+import com.doumee.dao.system.model.SystemRolePermission;
+import com.doumee.service.system.SystemRoleMenuService;
+import com.doumee.service.system.SystemRolePermissionService;
+import com.doumee.service.system.SystemRoleService;
+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;
+
+@Service
+public class SystemRoleBizImpl implements SystemRoleBiz {
+
+ @Autowired
+ private SystemRoleService systemRoleService;
+
+ @Autowired
+ private SystemRolePermissionService systemRolePermissionService;
+
+ @Autowired
+ private SystemRoleMenuService systemRoleMenuService;
+
+ @Override
+ public Integer create(SystemRole systemRole) {
+ // 楠岃瘉鐢ㄦ埛鍚�
+ SystemRole queryDto = new SystemRole();
+ queryDto.setCode(systemRole.getCode());
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemRole role = systemRoleService.findOne(queryDto);
+ if (role != null) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "瑙掕壊缂栫爜宸插瓨鍦�");
+ }
+ return systemRoleService.create(systemRole);
+ }
+
+ @Override
+ public void updateById(SystemRole systemRole) {
+ // 楠岃瘉瑙掕壊缂栫爜
+ SystemRole queryDto = new SystemRole();
+ queryDto.setCode(systemRole.getCode());
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemRole role = systemRoleService.findOne(queryDto);
+ if (role != null && !role.getId().equals(systemRole.getId())) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "瑙掕壊缂栧彿宸插瓨鍦�");
+ }
+ systemRoleService.updateById(systemRole);
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemRole role = systemRoleService.findById(id);
+ if (role == null) {
+ return;
+ }
+ if (role.getFixed()) {
+ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "璇峰嬁鍒犻櫎" + role.getName() + "锛屽洜涓鸿繖鏄浐瀹氳鑹�");
+ }
+ systemRoleService.deleteById(id);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ @Transactional
+ public void createRolePermission(CreateRolePermissionDTO dto) {
+ // 鍒犻櫎鍏宠仈鏉冮檺
+ SystemRolePermission deleteDto = new SystemRolePermission();
+ deleteDto.setRoleId(dto.getRoleId());
+ systemRolePermissionService.delete(deleteDto);
+ // 鏂板鏂扮殑鏉冮檺
+ for (Integer permissionId : dto.getPermissionIds()) {
+ SystemRolePermission newRolePermission = new SystemRolePermission();
+ newRolePermission.setRoleId(dto.getRoleId());
+ newRolePermission.setPermissionId(permissionId);
+ systemRolePermissionService.create(newRolePermission);
+ }
+ }
+
+ @Override
+ @Transactional
+ public void createRoleMenu(CreateRoleMenuDTO dto) {
+ // 鍒犻櫎鍏宠仈鏉冮檺
+ SystemRoleMenu deleteDto = new SystemRoleMenu();
+ deleteDto.setRoleId(dto.getRoleId());
+ systemRoleMenuService.delete(deleteDto);
+ // 鏂板鏂扮殑鏉冮檺
+ for (Integer menuId : dto.getMenuIds()) {
+ SystemRoleMenu newRoleMenu = new SystemRoleMenu();
+ newRoleMenu.setRoleId(dto.getRoleId());
+ newRoleMenu.setMenuId(menuId);
+ systemRoleMenuService.create(newRoleMenu);
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/biz/system/impl/SystemUserBizImpl.java b/server/services/src/main/java/com/doumee/biz/system/impl/SystemUserBizImpl.java
new file mode 100644
index 0000000..5a9c7a0
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/biz/system/impl/SystemUserBizImpl.java
@@ -0,0 +1,177 @@
+package com.doumee.biz.system.impl;
+
+import com.doumee.biz.system.SystemUserBiz;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.utils.PwdCheckUtil;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.dto.CreateSystemUserDTO;
+import com.doumee.dao.system.dto.CreateUserRoleDTO;
+import com.doumee.dao.system.dto.ResetSystemUserPwdDTO;
+import com.doumee.dao.system.dto.UpdatePwdDto;
+import com.doumee.dao.system.model.SystemUser;
+import com.doumee.dao.system.model.SystemUserRole;
+import com.doumee.service.system.SystemUserRoleService;
+import com.doumee.service.system.SystemUserService;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
+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.Date;
+import java.util.List;
+
+@Service
+public class SystemUserBizImpl implements SystemUserBiz {
+
+ @Autowired
+ private SystemUserService systemUserService;
+
+ @Autowired
+ private SystemUserRoleService systemUserRoleService;
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemUser user = systemUserService.findById(id);
+ if (user == null) {
+ return;
+ }
+ if (user.getFixed()) {
+ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "璇峰嬁鍒犻櫎" + user.getUsername() + "锛屽洜涓鸿繖鏄浐瀹氱敤鎴�");
+ }
+ systemUserService.deleteById(id);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ public void updatePwd(UpdatePwdDto dto) {
+ if(StringUtils.isBlank(dto.getNewPwd())
+ ||dto.getNewPwd().length()>20
+ ||dto.getNewPwd().length()<6
+ ||!PwdCheckUtil.checkPassword(dto.getNewPwd())){
+ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "瀵逛笉璧凤紝瀵嗙爜澶嶆潅搴︿笉婊¤冻瑕佹眰锛�6-20涓瓧绗︼紝鑷冲皯鍖呭惈瀛楁瘝銆佹暟瀛楀強鐗规畩瀛楃2绉�");
+ }
+ SystemUser user = systemUserService.findById(dto.getUserId());
+ if (user.getDeleted()) {
+ throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "鐢ㄦ埛涓嶅瓨鍦ㄦ垨宸茶鍒犻櫎");
+ }
+ // 楠岃瘉鍘熷瀵嗙爜
+ if (!user.getPassword().equals(Utils.Secure.encryptPassword(dto.getOldPwd(), user.getSalt()))) {
+ throw new BusinessException(ResponseStatus.PWD_INCORRECT.getCode(), "鍘熷瀵嗙爜涓嶆纭�");
+ }
+ // 淇敼瀵嗙爜
+ SystemUser newUser = new SystemUser();
+ newUser.setId(dto.getUserId());
+ newUser.setPassword(Utils.Secure.encryptPassword(dto.getNewPwd(), user.getSalt()));
+ systemUserService.updateById(newUser);
+ }
+
+ @Override
+ public void resetPwd(ResetSystemUserPwdDTO dto) {
+ if(StringUtils.isBlank(dto.getPassword())
+ ||dto.getPassword().length()>20
+ ||dto.getPassword().length()<6
+ ||!PwdCheckUtil.checkPassword(dto.getPassword())){
+ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "瀵逛笉璧凤紝瀵嗙爜澶嶆潅搴︿笉婊¤冻瑕佹眰锛�6-20涓瓧绗︼紝鑷冲皯鍖呭惈瀛楁瘝銆佹暟瀛楀強鐗规畩瀛楃2绉�");
+ }
+ // 鏌ヨ鐢ㄦ埛
+ SystemUser systemUser = systemUserService.findById(dto.getId());
+ if (systemUser == null || systemUser.getDeleted()) {
+ throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(), "鐢ㄦ埛涓嶅瓨鍦ㄦ垨宸茶鍒犻櫎");
+ }
+ // 淇敼瀵嗙爜
+ SystemUser updateUserDto = new SystemUser();
+ updateUserDto.setId(dto.getId());
+ updateUserDto.setPassword(Utils.Secure.encryptPassword(dto.getPassword(), systemUser.getSalt()));
+ systemUserService.updateById(updateUserDto);
+ }
+
+ @Override
+ @Transactional
+ public void create(CreateSystemUserDTO systemUser) {
+ if(StringUtils.isBlank(systemUser.getPassword())
+ ||systemUser.getPassword().length()>20
+ ||systemUser.getPassword().length()<6
+ ||!PwdCheckUtil.checkPassword(systemUser.getPassword())){
+ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "瀵逛笉璧凤紝瀵嗙爜澶嶆潅搴︿笉婊¤冻瑕佹眰锛�6-20涓瓧绗︼紝鑷冲皯鍖呭惈瀛楁瘝銆佹暟瀛楀強鐗规畩瀛楃2绉�");
+ }
+ // 楠岃瘉鐢ㄦ埛鍚�
+ SystemUser queryUserDto = new SystemUser();
+ queryUserDto.setUsername(systemUser.getUsername());
+ queryUserDto.setDeleted(Boolean.FALSE);
+ SystemUser user = systemUserService.findOne(queryUserDto);
+ if (user != null) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "鐢ㄦ埛鍚嶅凡瀛樺湪");
+ }
+ // 楠岃瘉宸ュ彿
+ if (StringUtils.isNotBlank(systemUser.getEmpNo())) {
+ queryUserDto = new SystemUser();
+ queryUserDto.setDeleted(Boolean.FALSE);
+ queryUserDto.setEmpNo(systemUser.getEmpNo());
+ user = systemUserService.findOne(queryUserDto);
+ if (user != null) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "宸ュ彿宸插瓨鍦�");
+ }
+ }
+
+ // 鐢熸垚瀵嗙爜鐩�
+ String salt = RandomStringUtils.randomAlphabetic(6);
+ // 鐢熸垚瀵嗙爜
+ systemUser.setPassword(Utils.Secure.encryptPassword(systemUser.getPassword(), salt));
+ systemUser.setSalt(salt);
+ // 鍒涘缓鐢ㄦ埛璁板綍
+ systemUserService.create(systemUser);
+ }
+
+ @Override
+ public void updateById(CreateSystemUserDTO systemUser) {
+ // 楠岃瘉鐢ㄦ埛鍚�
+ SystemUser queryUserDto = new SystemUser();
+ queryUserDto.setUsername(systemUser.getUsername());
+ queryUserDto.setDeleted(Boolean.FALSE);
+ SystemUser user = systemUserService.findOne(queryUserDto);
+ if (user != null && !user.getId().equals(systemUser.getId())) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "鐢ㄦ埛鍚嶅凡瀛樺湪");
+ }
+ // 楠岃瘉宸ュ彿
+ if (StringUtils.isNotBlank(systemUser.getEmpNo())) {
+ queryUserDto = new SystemUser();
+ queryUserDto.setEmpNo(systemUser.getEmpNo());
+ queryUserDto.setDeleted(Boolean.FALSE);
+ user = systemUserService.findOne(queryUserDto);
+ if (user != null && !user.getId().equals(systemUser.getId())) {
+ throw new BusinessException(ResponseStatus.DATA_EXISTS.getCode(), "宸ュ彿宸插瓨鍦�");
+ }
+ }
+ // 淇敼鐢ㄦ埛
+ systemUserService.updateById(systemUser);
+ }
+
+ @Override
+ @Transactional
+ public void createUserRole(CreateUserRoleDTO dto) {
+ // 鍒犻櫎鍏宠仈瑙掕壊
+ SystemUserRole deleteDto = new SystemUserRole();
+ deleteDto.setUserId(dto.getUserId());
+ systemUserRoleService.delete(deleteDto);
+ // 鏂板鏂扮殑瑙掕壊
+ for (Integer roleId : dto.getRoleIds()) {
+ SystemUserRole newUserRole = new SystemUserRole();
+ newUserRole.setUserId(dto.getUserId());
+ newUserRole.setRoleId(roleId);
+ systemUserRoleService.create(newUserRole);
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/annotation/EncryptionReq.java b/server/services/src/main/java/com/doumee/config/annotation/EncryptionReq.java
new file mode 100644
index 0000000..a96a6e6
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/annotation/EncryptionReq.java
@@ -0,0 +1,14 @@
+package com.doumee.config.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @Date: 2024/3/29 18:30
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EncryptionReq {
+}
diff --git a/server/services/src/main/java/com/doumee/config/annotation/EncryptionResp.java b/server/services/src/main/java/com/doumee/config/annotation/EncryptionResp.java
new file mode 100644
index 0000000..0ca4bfc
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/annotation/EncryptionResp.java
@@ -0,0 +1,14 @@
+package com.doumee.config.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @Date: 2024/3/29 18:30
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EncryptionResp {
+}
diff --git a/server/services/src/main/java/com/doumee/config/annotation/LoginRequired.java b/server/services/src/main/java/com/doumee/config/annotation/LoginRequired.java
new file mode 100644
index 0000000..87409ed
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/annotation/LoginRequired.java
@@ -0,0 +1,10 @@
+package com.doumee.config.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LoginRequired {}
diff --git a/server/services/src/main/java/com/doumee/config/annotation/UserLoginRequired.java b/server/services/src/main/java/com/doumee/config/annotation/UserLoginRequired.java
new file mode 100644
index 0000000..b3e74c2
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/annotation/UserLoginRequired.java
@@ -0,0 +1,12 @@
+package com.doumee.config.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UserLoginRequired {
+
+}
diff --git a/server/services/src/main/java/com/doumee/config/cache/RedisConfig.java b/server/services/src/main/java/com/doumee/config/cache/RedisConfig.java
new file mode 100644
index 0000000..de523ca
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/cache/RedisConfig.java
@@ -0,0 +1,32 @@
+package com.doumee.config.cache;
+
+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.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.io.Serializable;
+
+/**
+ * Redis閰嶇疆
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Configuration
+public class RedisConfig {
+
+ @Bean
+ public RedisTemplate<Serializable, Serializable> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
+ RedisTemplate<Serializable, Serializable> redisTemplate = new RedisTemplate<>();
+ redisTemplate.setConnectionFactory(redisConnectionFactory);
+ // 榛樿搴忓垪鍖栨柟寮�
+ redisTemplate.setDefaultSerializer(new StringRedisSerializer());
+ // 鍊煎簭鍒楀寲鏂瑰紡
+ RedisValueDefaultSerializer<Object> serializer = new RedisValueDefaultSerializer<>(Object.class);
+ redisTemplate.setValueSerializer(serializer);
+ redisTemplate.setHashValueSerializer(serializer);
+ redisTemplate.afterPropertiesSet();
+ return redisTemplate;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/cache/RedisValueDefaultSerializer.java b/server/services/src/main/java/com/doumee/config/cache/RedisValueDefaultSerializer.java
new file mode 100644
index 0000000..b3f13e1
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/cache/RedisValueDefaultSerializer.java
@@ -0,0 +1,56 @@
+package com.doumee.config.cache;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.parser.ParserConfig;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.SerializationException;
+import org.springframework.lang.Nullable;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Redis 鍊煎簭鍒楀寲鍣�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+class RedisValueDefaultSerializer<T> implements RedisSerializer<T> {
+
+ private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
+
+ private final ParserConfig parserConfig = new ParserConfig();
+
+ {
+ parserConfig.setAutoTypeSupport(true);
+ }
+
+ private final Class<T> type;
+
+ RedisValueDefaultSerializer(Class<T> type) {
+ this.type = type;
+ }
+
+ public T deserialize(@Nullable byte[] bytes) throws SerializationException {
+ if (bytes == null || bytes.length == 0) {
+ return null;
+ }
+ try {
+ return JSON.parseObject(new String(bytes, DEFAULT_CHARSET), type, parserConfig);
+ } catch (Exception e) {
+ throw new SerializationException("Could not serialize value of redis: " + e.getMessage(), e);
+ }
+ }
+
+ public byte[] serialize(@Nullable Object value) throws SerializationException {
+ if (value == null) {
+ return new byte[0];
+ }
+ try {
+ return JSON.toJSONBytes(value, SerializerFeature.WriteClassName, SerializerFeature.PrettyFormat);
+ } catch (Exception e) {
+ throw new SerializationException("Could not serialize value of redis: " + e.getMessage(), e);
+ }
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/config/exception/GlobalExceptionAdvice.java b/server/services/src/main/java/com/doumee/config/exception/GlobalExceptionAdvice.java
new file mode 100644
index 0000000..f216846
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/exception/GlobalExceptionAdvice.java
@@ -0,0 +1,79 @@
+package com.doumee.config.exception;
+
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.constants.ResponseStatus;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authz.UnauthorizedException;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.MissingServletRequestParameterException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鍏ㄥ眬寮傚父澶勭悊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+@RestControllerAdvice
+public class GlobalExceptionAdvice {
+
+ /**
+ * 涓氬姟寮傚父澶勭悊
+ */
+ @ExceptionHandler(BusinessException.class)
+ public Object handleBusinessException (BusinessException e) {
+ log.error(e.getMessage(), e);
+ return ApiResponse.failed(e.getCode(), e.getMessage());
+ }
+
+ /**
+ * 鏃犳潈闄愬紓甯稿鐞�
+ */
+ @ExceptionHandler(UnauthorizedException.class)
+ public Object handleUnauthorizedException (UnauthorizedException e) {
+ log.error(e.getMessage(), e);
+ return ApiResponse.failed("娌℃湁鎿嶄綔鏉冮檺");
+ }
+
+ /**
+ * 鍙傛暟楠岃瘉鏈�氳繃寮傚父澶勭悊
+ */
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public Object handleMethodArgumentNotValidException (MethodArgumentNotValidException e) {
+ log.error(e.getMessage(), e);
+ BindingResult bindingResult = e.getBindingResult();
+ List<String> errors = new ArrayList<>();
+ for(FieldError fieldError : bindingResult.getFieldErrors()){
+ errors.add(fieldError.getDefaultMessage());
+ }
+ return ApiResponse.failed(ResponseStatus.BAD_REQUEST.getCode(), StringUtils.join(errors));
+ }
+
+ /**
+ * 鍙傛暟楠岃瘉鏈�氳繃寮傚父澶勭悊
+ */
+ @ExceptionHandler(MissingServletRequestParameterException.class)
+ public Object handleMissingServletRequestParameterException (MissingServletRequestParameterException e) {
+ log.error(e.getMessage(), e);
+ return ApiResponse.failed(ResponseStatus.BAD_REQUEST.getCode(), e.getMessage());
+ }
+
+ /**
+ * 鍏跺畠寮傚父澶勭悊
+ */
+ @ExceptionHandler(Exception.class)
+ public Object handleException (Exception e) {
+ log.error(e.getMessage(), e);
+ return ApiResponse.failed(ResponseStatus.SERVER_ERROR, e);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/interfaceencryption/DecryptRequestBodyAdvice.java b/server/services/src/main/java/com/doumee/config/interfaceencryption/DecryptRequestBodyAdvice.java
new file mode 100644
index 0000000..1861cac
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/interfaceencryption/DecryptRequestBodyAdvice.java
@@ -0,0 +1,101 @@
+package com.doumee.config.interfaceencryption;
+
+import com.alibaba.fastjson.JSONObject;
+import com.doumee.config.annotation.EncryptionReq;
+import com.doumee.config.annotation.EncryptionResp;
+import com.doumee.config.interfaceencryption.tool.RSAEncrypt;
+import com.doumee.core.utils.AESUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpInputMessage;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.util.StreamUtils;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Type;
+import java.util.Base64;
+
+/**
+ * 銆愰棶棰樸�戠兢缁勮〃
+ * github鍦板潃 http://www.github.com/wanyushu
+ * gitee鍦板潃 http://www.gitee.com/wanyushu
+ * @author yushu
+ * @email 921784721@qq.com
+ * 瀵硅姹傜殑鍙傛暟杩涜瑙e瘑
+ **/
+@ControllerAdvice
+public class DecryptRequestBodyAdvice implements RequestBodyAdvice {
+
+ private Logger log = LoggerFactory.getLogger(this.getClass());
+
+ private boolean encrypt;
+
+ @Override
+ public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
+ if (methodParameter.getMethod().isAnnotationPresent(EncryptionReq.class) || methodParameter.getClass().isAnnotationPresent(EncryptionReq.class) ) {
+ encrypt = true;
+ }else{
+ encrypt=false;
+ }
+ return encrypt;
+ }
+
+ @Override
+ public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
+ return body;
+ }
+
+ @Override
+ public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
+ Class<? extends HttpMessageConverter<?>> converterType){
+ if (encrypt) {
+ try {
+ byte[] payload = StreamUtils.copyToByteArray(inputMessage.getBody());
+ String content =new String(payload);
+ JSONObject jsonObject = JSONObject.parseObject(content);
+ if(jsonObject.get("data")!=null){
+ content = jsonObject.getString("data");
+ }
+ // 璇诲彇瀹屾暣鐨勫鎴风璇锋眰浣擄紝涔熷氨鏄姞瀵�/缂栫爜鍚庣殑鏁版嵁
+ String key = jsonObject.getString("ivKey");
+ log.info("鍔犲瘑 key锛歿}", key);
+ String decrypt = RSAEncrypt.decrypt(key, RSAEncrypt.privateKey);
+
+ log.info("鍔犲瘑 Payload锛歿}",content);
+ String decrypt1 = AESUtils.decrypt(content, decrypt);
+ // 瑙g爜涓哄師濮嬫暟鎹�
+ byte[] rawPayload = decrypt1.getBytes();
+ log.info("鍘熷 Payload锛歿}", decrypt);
+ // 杩斿洖 HttpInputMessage 鍖垮悕瀵硅薄
+ return new HttpInputMessage() {
+ @Override
+ public HttpHeaders getHeaders() {
+// inputMessage.getHeaders().set("Content-Type","application/json;charset=UTF-8");
+ return inputMessage.getHeaders();
+ }
+ @Override
+ public InputStream getBody() throws IOException {
+ // 浣跨敤鍘熷鏁版嵁鏋勫缓涓� ByteArrayInputStream
+ return new ByteArrayInputStream(rawPayload);
+ }
+ };
+ } catch (Exception e) {
+ log.error("Decryption failed", e);
+ }
+ }
+ return inputMessage;
+ }
+
+ @Override
+ public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
+ Class<? extends HttpMessageConverter<?>> converterType) {
+ return body;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/interfaceencryption/EncryptResponseBodyAdvice.java b/server/services/src/main/java/com/doumee/config/interfaceencryption/EncryptResponseBodyAdvice.java
new file mode 100644
index 0000000..6be1ebc
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/interfaceencryption/EncryptResponseBodyAdvice.java
@@ -0,0 +1,105 @@
+package com.doumee.config.interfaceencryption;
+
+import com.doumee.config.annotation.EncryptionResp;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.utils.AESUtils;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.util.Random;
+
+/**
+ * github鍦板潃 http://www.github.com/wanyushu
+ * gitee鍦板潃 http://www.gitee.com/wanyushu
+ * @author yushu
+ * @email 921784721@qq.com
+ * 瀵硅姹傜殑鍙傛暟杩涜鍔犲瘑
+ **/
+@ControllerAdvice
+public class EncryptResponseBodyAdvice implements ResponseBodyAdvice<Object> {
+
+ private Logger log = LoggerFactory.getLogger(this.getClass());
+
+ private boolean encrypt;
+
+ @Override
+ public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
+ encrypt = false;
+ if (returnType.getMethod().isAnnotationPresent(EncryptionResp.class) || returnType.getClass().isAnnotationPresent(EncryptionResp.class) ) {
+ encrypt = true;
+ }
+ return encrypt;
+ }
+
+ @Override
+ public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
+ Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
+ if (encrypt) {
+ try {
+ String str = generateRandomLetters(16);
+ String afterDealStr = newEncrypt(str);
+ ApiResponse apiResponse = (ApiResponse) body;
+ //瀵瑰搷搴斿唴瀹硅繘琛屽姞瀵�
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
+ String aesEncryptData = AESUtils.encrypt(objectMapper.writeValueAsString(apiResponse.getData()), str);
+
+ apiResponse.setData(aesEncryptData);
+ String aesEncryptMessage = AESUtils.encrypt(objectMapper.writeValueAsString(apiResponse.getMessage()), str);
+ apiResponse.setMessage(aesEncryptMessage + " " + afterDealStr);
+ return body;
+ } catch (Exception e) {
+ log.error("Encrypted data exception", e);
+ }
+ }
+ return body;
+ }
+ private static String newEncrypt(String s) {
+ //鍊掑簭鎺掑垪
+ StringBuilder reverse = new StringBuilder(s).reverse();
+ System.out.println("鍊掑簭鎺掑垪鍚庣殑鍊� " + reverse);
+
+ //鏍规嵁褰撳墠鏈堜唤鍜屾棩鏈燂紝鏉ュ垽鏂湪瀛楃涓蹭腑鐨勫摢涓綅缃姞瀛楃涓诧紝姣斿 瀛楃涓叉槸 abcdefghijklmn浠婂ぉ鏄�2鏈�14鍙凤紝灏卞湪绗簩涓瓧绗︿覆鍚庨潰鍔�26涓瓧绗︿覆涓浜�14浣嶇殑瀛楃锛屽鏋滄棩鏈熻秴杩�26锛屽氨浠巃閲嶆柊寮�濮�
+ LocalDate today = LocalDate.now(); // 鑾峰彇褰撳墠鏃ユ湡
+ int monthValue = today.getMonthValue();
+ int dayOfMonth = today.getDayOfMonth(); // 鑾峰彇鏃ユ湡涓殑鏃�
+ int position = dayOfMonth % 26; // 璁$畻鍦ㄥ瓧姣嶈〃涓殑浣嶇疆锛�1-26锛�
+
+ // 璁$畻瑕佹彃鍏ョ殑瀛楃
+ char charToInsert = (char) ('a' + (position - 1));
+
+ // 璁$畻鎻掑叆浣嶇疆锛�0-based index锛�
+ int insertPosition = monthValue % (reverse.length() + 1); // 淇濊瘉涓嶈秴鍑鸿寖鍥�
+
+ // 鎻掑叆瀛楃
+ String result = insertCharacter(reverse.toString(), charToInsert, insertPosition);
+ return result;
+ }
+ public static String insertCharacter(String original, char ch, int position) {
+ StringBuilder sb = new StringBuilder(original);
+ sb.insert(position, ch);
+ return sb.toString();
+ }
+
+ public String generateRandomLetters(int length) {
+ Random random = new Random();
+ StringBuilder sb = new StringBuilder();
+
+ for (int i = 0; i < length; i++) {
+ char randomChar = (char) (random.nextInt(26) + 'a');
+ sb.append(randomChar);
+ }
+ return sb.toString();
+ }
+}
+
diff --git a/server/services/src/main/java/com/doumee/config/interfaceencryption/tool/RSAEncrypt.java b/server/services/src/main/java/com/doumee/config/interfaceencryption/tool/RSAEncrypt.java
new file mode 100644
index 0000000..236ea03
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/interfaceencryption/tool/RSAEncrypt.java
@@ -0,0 +1,104 @@
+package com.doumee.config.interfaceencryption.tool;
+
+
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.binary.Base64;
+
+import javax.crypto.Cipher;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+public class RSAEncrypt {
+ private static Map<Integer, String> keyMap = new HashMap<Integer, String>(); //鐢ㄤ簬灏佽闅忔満浜х敓鐨勫叕閽ヤ笌绉侀挜
+
+ public static String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAM6CtRbiMzljaKtQKm+nIGfjVpNF8Yc1C4EcgHIr19tyU1de3v9C5CPc1AJ/CScEEIdwzsDfx4Lbj1TGMWQscCb4j2jXkg2MX9Ose2XOTPNL2OJ6SCh2FS4zh5XFdBRwM10CBKQoW31PlZFeDZyMRlDKiLkOUhYuY6qLGbHw4oVFAgMBAAECgYAt6S0tWzicJ5ebjoUAsZ0ou4gB0ejycD6Qg6+islCY/v+8SuE0ysBBoNSZgXidbe/mzJOKmbWXSAzDghR0+tQrz3v2jEmm/MoBXoHS+YXuZvG6OX7n7rN4GPKm8wYNWGv3IU6NeggOZqMf+kT3JUvqQx5JxjeK/lEBlifmU0wmQQJBAPCGEmGtjbKJnMT4GurzsCJniy2rGAHvu+S51j60eusUuTnEIu78tMJGd8zkjNPlShKqyk+AUdhNoaigIZLclfkCQQDbzF444oJWkZ32iDipWcFxMqEkvn49elUZPHFzDVMN+D0mJ0uN0lGErDZAovCLu095+XecCsduXkki95HtdYytAkA3ph18ogYFx9cQr4Ky15zp6OEHuO0+DXSAkAqkyWcjGtFcLygR+T/tLxaqvjpjEEraFM/oIv1MuXFsrVf3PbgpAkB8OZVHMT3ZD5PnsjXUARaDk8nfqopO1MUj7jVwgSdfzd1BoxPgo+3OvkYrYevyDXttxMEFQFJW3pMXYDTpsHZBAkAX9R4KsvqC3FJkOk6zmGw2tsJBEFL5cqAnXQByoY3XriNgUeHJa/vCXJR7Q+vIYstnLzLzMJl7EMVOrxH4bBwF";
+ public static String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZDoLPxa4aV7N0M3YYkPXhXSuxxAjzT2nYXnCQOUlNpBMfhZUZ2wO2ff06oPUWFeM7rsad3GKfX2vAMsEc1SB2CwqJLd/W1GCLBFSUHYeCka9brJf8fFr9uBo3J7g5bC58AIErKjXFTP+F4bWnqsq5jTBG0+2KsSYwRiTWpsEn1wIDAQAB";
+
+// public static void main(String[] args) throws Exception {
+// String phone = "18256057064";
+// String encrypt = encrypt(phone, publicKey);
+// System.out.println("鍔犲瘑鍚�"+encrypt);
+// System.out.println("瑙e瘑鍚�"+decrypt(encrypt, privateKey));
+// }
+
+ /**
+ * 闅忔満鐢熸垚瀵嗛挜瀵�
+ *
+ * @throws NoSuchAlgorithmException
+ */
+ public static void genKeyPair() throws NoSuchAlgorithmException {
+ // KeyPairGenerator绫荤敤浜庣敓鎴愬叕閽ュ拰绉侀挜瀵癸紝鍩轰簬RSA绠楁硶鐢熸垚瀵硅薄
+ KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
+ // 鍒濆鍖栧瘑閽ュ鐢熸垚鍣紝瀵嗛挜澶у皬涓�96-1024浣�
+ keyPairGen.initialize(1024, new SecureRandom());
+ // 鐢熸垚涓�涓瘑閽ュ锛屼繚瀛樺湪keyPair涓�
+ KeyPair keyPair = keyPairGen.generateKeyPair();
+ RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 寰楀埌绉侀挜
+ RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 寰楀埌鍏挜
+ String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
+ // 寰楀埌绉侀挜瀛楃涓�
+ String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
+ // 灏嗗叕閽ュ拰绉侀挜淇濆瓨鍒癕ap
+ keyMap.put(0, publicKeyString); //0琛ㄧず鍏挜
+ keyMap.put(1, privateKeyString); //1琛ㄧず绉侀挜
+
+ System.out.println("鍏挜:" + publicKeyString);
+ System.out.println("绉侀挜:" + privateKeyString);
+ }
+
+
+ /**
+ * RSA鍏挜鍔犲瘑
+ *
+ * @param str 鍔犲瘑瀛楃涓�
+ * @param publicKey 鍏挜
+ * @return 瀵嗘枃
+ * @throws Exception 鍔犲瘑杩囩▼涓殑寮傚父淇℃伅
+ */
+ public static String encrypt(String str, String publicKey) throws Exception {
+ //base64缂栫爜鐨勫叕閽�
+ byte[] decoded = Base64.decodeBase64(publicKey);
+ RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
+ //RSA鍔犲瘑
+ Cipher cipher = Cipher.getInstance("RSA");
+ cipher.init(Cipher.ENCRYPT_MODE, pubKey);
+ String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
+ return outStr;
+ }
+
+ /**
+ * RSA绉侀挜瑙e瘑
+ *
+ * @param str 鍔犲瘑瀛楃涓�
+ * @param privateKey 绉侀挜
+ * @return 閾枃
+ * @throws Exception 瑙e瘑杩囩▼涓殑寮傚父淇℃伅
+ */
+ public static String decrypt(String str, String privateKey) throws Exception {
+ try {
+ log.info("RSA绉侀挜瑙e瘑 str = " + str);
+ log.info("RSA绉侀挜瑙e瘑 privateKey = " + privateKey);
+ //64浣嶈В鐮佸姞瀵嗗悗鐨勫瓧绗︿覆
+ byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
+ //base64缂栫爜鐨勭閽�
+ byte[] decoded = Base64.decodeBase64(privateKey);
+ RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
+ //RSA瑙e瘑
+ Cipher cipher = Cipher.getInstance("RSA");
+
+ cipher.init(Cipher.DECRYPT_MODE, priKey);
+ String outStr = new String(cipher.doFinal(inputByte));
+ return outStr;
+ }catch (Exception e){
+ return "{}";
+ }
+ }
+}
\ No newline at end of file
diff --git a/server/services/src/main/java/com/doumee/config/interfaceencryption/tool/RSAEncryptTest.java b/server/services/src/main/java/com/doumee/config/interfaceencryption/tool/RSAEncryptTest.java
new file mode 100644
index 0000000..e6ca073
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/interfaceencryption/tool/RSAEncryptTest.java
@@ -0,0 +1,87 @@
+package com.doumee.config.interfaceencryption.tool;
+
+
+import org.apache.commons.codec.binary.Base64;
+
+import javax.crypto.Cipher;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+public class RSAEncryptTest {
+ private static Map<Integer, String> keyMap = new HashMap<Integer, String>(); //鐢ㄤ簬灏佽闅忔満浜х敓鐨勫叕閽ヤ笌绉侀挜
+
+
+ /**
+ * 闅忔満鐢熸垚瀵嗛挜瀵�
+ *
+ * @throws NoSuchAlgorithmException
+ */
+ public static void genKeyPair() throws NoSuchAlgorithmException {
+ // KeyPairGenerator绫荤敤浜庣敓鎴愬叕閽ュ拰绉侀挜瀵癸紝鍩轰簬RSA绠楁硶鐢熸垚瀵硅薄
+ KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
+ // 鍒濆鍖栧瘑閽ュ鐢熸垚鍣紝瀵嗛挜澶у皬涓�96-1024浣�
+ keyPairGen.initialize(1024, new SecureRandom());
+ // 鐢熸垚涓�涓瘑閽ュ锛屼繚瀛樺湪keyPair涓�
+ KeyPair keyPair = keyPairGen.generateKeyPair();
+ RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 寰楀埌绉侀挜
+ RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 寰楀埌鍏挜
+ String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
+ // 寰楀埌绉侀挜瀛楃涓�
+ String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
+ // 灏嗗叕閽ュ拰绉侀挜淇濆瓨鍒癕ap
+ keyMap.put(0, publicKeyString); //0琛ㄧず鍏挜
+ keyMap.put(1, privateKeyString); //1琛ㄧず绉侀挜
+
+ System.out.println("鍏挜:" + publicKeyString);
+ System.out.println("绉侀挜:" + privateKeyString);
+ }
+
+
+ /**
+ * RSA鍏挜鍔犲瘑
+ *
+ * @param str 鍔犲瘑瀛楃涓�
+ * @param publicKey 鍏挜
+ * @return 瀵嗘枃
+ * @throws Exception 鍔犲瘑杩囩▼涓殑寮傚父淇℃伅
+ */
+ public static String encrypt(String str, String publicKey) throws Exception {
+ //base64缂栫爜鐨勫叕閽�
+ byte[] decoded = Base64.decodeBase64(publicKey);
+ RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
+ //RSA鍔犲瘑
+ Cipher cipher = Cipher.getInstance("RSA");
+ cipher.init(Cipher.ENCRYPT_MODE, pubKey);
+ String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
+ return outStr;
+ }
+
+ /**
+ * RSA绉侀挜瑙e瘑
+ *
+ * @param str 鍔犲瘑瀛楃涓�
+ * @param privateKey 绉侀挜
+ * @return 閾枃
+ * @throws Exception 瑙e瘑杩囩▼涓殑寮傚父淇℃伅
+ */
+ public static String decrypt(String str, String privateKey) throws Exception {
+ //64浣嶈В鐮佸姞瀵嗗悗鐨勫瓧绗︿覆
+ byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
+ //base64缂栫爜鐨勭閽�
+ byte[] decoded = Base64.decodeBase64(privateKey);
+ RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
+ //RSA瑙e瘑
+ Cipher cipher = Cipher.getInstance("RSA");
+
+ cipher.init(Cipher.DECRYPT_MODE, priKey);
+ String outStr = new String(cipher.doFinal(inputByte));
+ return outStr;
+ }
+
+
+}
\ No newline at end of file
diff --git a/server/services/src/main/java/com/doumee/config/mybatis/DmStdOutImpl.java b/server/services/src/main/java/com/doumee/config/mybatis/DmStdOutImpl.java
new file mode 100644
index 0000000..1f5d305
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/mybatis/DmStdOutImpl.java
@@ -0,0 +1,62 @@
+package com.doumee.config.mybatis;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.logging.stdout.StdOutImpl;
+
+@Slf4j
+public class DmStdOutImpl extends StdOutImpl {
+ private Boolean isOff = false;
+
+ public Boolean isOff() {
+ return isOff;
+ }
+
+ public void setOff(Boolean off) {
+ isOff = off;
+ }
+
+ public DmStdOutImpl(String clazz) {
+ super(clazz);
+ }
+ public DmStdOutImpl(String clazz,Boolean off) {
+ super(clazz);
+ this.isOff = off;
+ }
+
+ public boolean isDebugEnabled() {
+ return true;
+ }
+
+ public boolean isTraceEnabled() {
+ return true;
+ }
+
+ public void error(String s, Throwable e) {
+ log.error(s);
+// System.err.println(s);
+ e.printStackTrace(System.err);
+ }
+
+ public void error(String s) {
+ log.error(s);
+// System.err.println(s);
+ }
+
+ public void debug(String s) {
+ if(isOff!=null && isOff()){
+ return;
+ }
+ log.info(s);
+// System.out.println(s);
+ }
+
+ public void trace(String s) {
+ log.trace(s);
+// System.out.println(s);
+ }
+
+ public void warn(String s) {
+ log.warn(s);
+// System.out.println(s);
+ }
+}
\ No newline at end of file
diff --git a/server/services/src/main/java/com/doumee/config/mybatis/MyBatisInterceptor.java b/server/services/src/main/java/com/doumee/config/mybatis/MyBatisInterceptor.java
new file mode 100644
index 0000000..a4c4d48
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/mybatis/MyBatisInterceptor.java
@@ -0,0 +1,125 @@
+package com.doumee.config.mybatis;
+
+import com.doumee.core.model.LoginUserInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.binding.MapperMethod;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.logging.Log;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlCommandType;
+import org.apache.ibatis.plugin.*;
+import org.apache.shiro.SecurityUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ReflectionUtils;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * MyBatis 鎷︽埅鍣�
+ * - INSERT璇彞榛樿濉厖鍒涘缓浜哄拰鍒涘缓鏃堕棿瀛楁
+ * - UPDATE璇彞榛樿濉厖鏇存柊浜哄拰鏇存柊鏃堕棿瀛楁
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+@Intercepts({
+ @Signature(type= Executor.class, method = "update", args={MappedStatement.class, Object.class})
+})
+public class MyBatisInterceptor implements Interceptor {
+
+ private static final String CREATE_TIME = "createTime";
+
+ private static final String CREATE_USER = "createUser";
+
+ private static final String UPDATE_TIME = "updateTime";
+
+ private static final String UPDATE_USER = "updateUser";
+
+ @Override
+ public Object intercept(Invocation invocation) throws Throwable {
+ MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
+ SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
+ Object target = invocation.getArgs()[1];
+
+ if(target instanceof MapperMethod.ParamMap) {
+ try {
+ target = ((MapperMethod.ParamMap) target).get("param1");
+ } catch (Exception e) {
+ }
+ }
+ if (target == null)
+ return invocation.proceed();
+ // 鍒涘缓璇彞
+ if (SqlCommandType.INSERT == sqlCommandType) {
+ this.handleOperaStatement(target, CREATE_TIME, CREATE_USER);
+ }
+ // 鏇存柊璇彞
+ else if (SqlCommandType.UPDATE == sqlCommandType) {
+ this.handleOperaStatement(target, UPDATE_TIME, UPDATE_USER);
+ }
+ return invocation.proceed();
+ }
+
+ @Override
+ public Object plugin(Object o) {
+ return Plugin.wrap(o, this);
+ }
+
+ /**
+ * 澶勭悊鏂板鍜岀紪杈戣鍙�
+ */
+ private void handleOperaStatement(Object target, String... fieldNames) throws Exception{
+ // 鎿嶄綔鏃堕棿
+ Field operaTimeField = ReflectionUtils.findField(target.getClass(), fieldNames[0]);
+ if (operaTimeField != null) {
+ Object operaTime = this.getFieldValue(operaTimeField, target);
+ if (operaTime == null) {
+ this.setFieldValue(operaTimeField, target, new Date());
+ }
+ }
+ // 鎿嶄綔浜�
+ Field operaUserField = ReflectionUtils.findField(target.getClass(), fieldNames[1]);
+ if (operaUserField != null) {
+ Object operaUser = this.getFieldValue(operaUserField, target);
+ LoginUserInfo user = this.getLoginUser();
+ if (operaUser == null && user!=null) {
+ this.setFieldValue(operaUserField, target, user.getId());
+ }
+ }
+ }
+
+ /**
+ * 缁欏睘鎬ц祴鍊�
+ */
+ private void setFieldValue(Field field, Object target, Object value) throws Exception {
+ field.setAccessible(true);
+ field.set(target, value);
+ field.setAccessible(false);
+ }
+
+ /**
+ * 鑾峰彇灞炴�у��
+ */
+ private Object getFieldValue(Field field, Object target) throws Exception {
+ field.setAccessible(true);
+ Object value = field.get(target);
+ field.setAccessible(false);
+ return value;
+ }
+
+ /**
+ * 鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅
+ */
+ private LoginUserInfo getLoginUser () {
+ try {
+ return (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
+ }catch (Exception e){
+
+ }
+ return null;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/mybatis/MyBatisPlusConfig.java b/server/services/src/main/java/com/doumee/config/mybatis/MyBatisPlusConfig.java
new file mode 100644
index 0000000..df51bbe
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/mybatis/MyBatisPlusConfig.java
@@ -0,0 +1,23 @@
+package com.doumee.config.mybatis;
+
+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;
+
+/**
+ * MyBatisPlus閰嶇疆
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Configuration
+public class MyBatisPlusConfig {
+
+ @Bean
+ public MybatisPlusInterceptor mybatisPlusInterceptor() {
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+ return interceptor;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/quartz/JobHandler.java b/server/services/src/main/java/com/doumee/config/quartz/JobHandler.java
new file mode 100644
index 0000000..e150977
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/quartz/JobHandler.java
@@ -0,0 +1,37 @@
+package com.doumee.config.quartz;
+
+import com.doumee.biz.system.SystemJobTriggerBiz;
+import com.doumee.biz.system.dto.TriggerJobDTO;
+import com.doumee.core.constants.Constants;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.JobExecutionContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+import org.springframework.stereotype.Component;
+
+/**
+ * JOB澶勭悊鍣�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+public class JobHandler extends QuartzJobBean {
+
+ @Autowired
+ private SystemJobTriggerBiz systemJobTriggerBiz;
+
+ @Override
+ protected void executeInternal(JobExecutionContext jobExecutionContext) {
+ Integer jobId = jobExecutionContext.getMergedJobDataMap().getInt(Constants.Job.JOB_DATA_MAP_JOB_ID);
+ TriggerJobDTO dto = new TriggerJobDTO();
+ dto.setId(jobId);
+ dto.setTriggerType(Constants.Job.TriggerType.SYSTEM.getCode());
+ dto.setScheduledFireTime(jobExecutionContext.getScheduledFireTime());
+ dto.setBusinessTime(jobExecutionContext.getScheduledFireTime());
+ dto.setFireTime(jobExecutionContext.getFireTime());
+ dto.setNextFireTime(jobExecutionContext.getTrigger().getNextFireTime());
+ systemJobTriggerBiz.trigger(dto);
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/config/quartz/JobHandlerWithDisallowConcurrent.java b/server/services/src/main/java/com/doumee/config/quartz/JobHandlerWithDisallowConcurrent.java
new file mode 100644
index 0000000..f85ad47
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/quartz/JobHandlerWithDisallowConcurrent.java
@@ -0,0 +1,39 @@
+package com.doumee.config.quartz;
+
+import com.doumee.biz.system.SystemJobTriggerBiz;
+import com.doumee.biz.system.dto.TriggerJobDTO;
+import com.doumee.core.constants.Constants;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.JobExecutionContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+import org.springframework.stereotype.Component;
+
+/**
+ * JOB澶勭悊鍣�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+@DisallowConcurrentExecution
+public class JobHandlerWithDisallowConcurrent extends QuartzJobBean {
+
+ @Autowired
+ private SystemJobTriggerBiz systemJobTriggerBiz;
+
+ @Override
+ protected void executeInternal(JobExecutionContext jobExecutionContext) {
+ Integer jobId = jobExecutionContext.getMergedJobDataMap().getInt(Constants.Job.JOB_DATA_MAP_JOB_ID);
+ TriggerJobDTO dto = new TriggerJobDTO();
+ dto.setId(jobId);
+ dto.setTriggerType(Constants.Job.TriggerType.SYSTEM.getCode());
+ dto.setScheduledFireTime(jobExecutionContext.getScheduledFireTime());
+ dto.setBusinessTime(jobExecutionContext.getScheduledFireTime());
+ dto.setFireTime(jobExecutionContext.getFireTime());
+ dto.setNextFireTime(jobExecutionContext.getTrigger().getNextFireTime());
+ systemJobTriggerBiz.trigger(dto);
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/config/quartz/JobInitializer.java b/server/services/src/main/java/com/doumee/config/quartz/JobInitializer.java
new file mode 100644
index 0000000..bbf214f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/quartz/JobInitializer.java
@@ -0,0 +1,81 @@
+package com.doumee.config.quartz;
+
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.job.SchedulerProxy;
+import com.doumee.dao.system.SystemJobMapper;
+import com.doumee.dao.system.SystemJobSnippetMapper;
+import com.doumee.dao.system.model.SystemJob;
+import com.doumee.dao.system.model.SystemJobSnippet;
+import com.doumee.service.system.SystemJobService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
+
+/**
+ * 浠诲姟鍒濆鍖�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+public class JobInitializer {
+
+ @Autowired
+ private SystemJobService systemJobService;
+
+ @Autowired
+ private SystemJobMapper systemJobMapper;
+
+ @Autowired
+ private SystemJobSnippetMapper systemJobSnippetMapper;
+
+ @Autowired
+ private SchedulerProxy schedulerProxy;
+
+ /**
+ * 鍒濆鍖朖obs
+ */
+// @PostConstruct
+ public void initJobs () {
+ log.debug("Initializing jobs");
+ // 淇JOB
+ this.repairJobs();
+ // 鍒濆鍖朖OB
+ long startTime = System.currentTimeMillis();
+ SystemJob queryJobDto = new SystemJob();
+ queryJobDto.setStatus(Constants.Job.JobStatus.READY.getCode());
+ queryJobDto.setDisabled(Boolean.FALSE);
+ queryJobDto.setDeleted(Boolean.FALSE);
+ List<SystemJob> jobs = systemJobService.findList(queryJobDto);
+ for (SystemJob job : jobs) {
+ schedulerProxy.createJob(new SchedulerProxy.Job(job.getId(), job.getHandler(), job.getCronExpression(), job.getDisallowConcurrent()));
+ log.debug("job '{}' initialized.", job.getJobName());
+ }
+ log.debug("Jobs initialization completed in {} ms", System.currentTimeMillis() - startTime);
+ }
+
+ /**
+ * 淇Jobs鍜孲nippets锛岄槻姝㈠洜鏈嶅姟鍣ㄥ畷鏈哄鑷存鍦ㄦ墽琛屼腑鐨凧ob鎴朣nippet鐘舵�佹湭寰楀埌澶勭悊锛屽鑷翠换鍔℃垨鍒嗙墖涓㈠け
+ */
+ private void repairJobs () {
+ log.debug("Repair jobs");
+ // 灏嗚繍琛屼腑鐨凧OB璋冩暣涓哄噯澶囩姸鎬� & 灏嗛璁′笅涓�娆℃墽琛屾椂闂磋皟鏁翠负null
+ systemJobMapper.update(null, new LambdaUpdateWrapper<SystemJob>()
+ .set(SystemJob::getStatus, Constants.Job.JobStatus.READY.getCode())
+ .set(SystemJob::getNextFireTime, null)
+ .eq(SystemJob::getStatus, Constants.Job.JobStatus.RUNNING.getCode())
+ .eq(SystemJob::getDeleted, Boolean.FALSE)
+ );
+ log.debug("Repair job snippets");
+ // 灏嗚繍琛屼腑鐨凷NIPPET璋冩暣涓哄噯澶囩姸鎬�
+ SystemJobSnippet newSnippet = new SystemJobSnippet();
+ newSnippet.setStatus(Constants.Job.SnippetStatus.READY.getCode());
+ systemJobSnippetMapper.update(newSnippet, new LambdaUpdateWrapper<SystemJobSnippet>()
+ .eq(SystemJobSnippet::getStatus, Constants.Job.SnippetStatus.READY.getCode())
+ );
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/quartz/SnippetScanner.java b/server/services/src/main/java/com/doumee/config/quartz/SnippetScanner.java
new file mode 100644
index 0000000..c1a61ed
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/quartz/SnippetScanner.java
@@ -0,0 +1,60 @@
+package com.doumee.config.quartz;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.doumee.biz.system.SystemJobSnippetTriggerBiz;
+import com.doumee.biz.system.dto.TriggerJobSnippetDTO;
+import com.doumee.core.constants.Constants;
+import com.doumee.dao.system.SystemJobSnippetMapper;
+import com.doumee.dao.system.model.SystemJobSnippet;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 鍒嗙墖浠诲姟鎵弿鍣�
+ * 璇ュ鐞嗗櫒姣�1绉掓壂鎻廠YSTEM_JOB_SNIPPET琛紝鎵ц杩樻湭鎵ц鐨勫垎鐗囦换鍔�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+@DisallowConcurrentExecution
+public class SnippetScanner extends QuartzJobBean {
+
+ @Autowired
+ private SystemJobSnippetTriggerBiz systemJobSnippetTriggerBiz;
+
+ @Autowired
+ private SystemJobSnippetMapper systemJobSnippetMapper;
+
+ @Override
+ protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+ try {
+ log.trace("Snippet scanner started.");
+ // 1. 鏌ヨ鎵�鏈夋湭鎵ц鐨勫垎鐗囦换鍔�
+ List<SystemJobSnippet> snippets = systemJobSnippetMapper.selectList(new LambdaQueryWrapper<SystemJobSnippet>()
+ .select(SystemJobSnippet::getId)
+ .eq(SystemJobSnippet::getStatus, Constants.Job.JobStatus.READY.getCode())
+ .orderByAsc(SystemJobSnippet::getCreateTime)
+ );
+ // 2. 寰幆鎵ц
+ for (SystemJobSnippet snippet : snippets) {
+ TriggerJobSnippetDTO dto = new TriggerJobSnippetDTO();
+ dto.setId(snippet.getId());
+ dto.setTriggerType(Constants.Job.TriggerType.SYSTEM.getCode());
+ systemJobSnippetTriggerBiz.trigger(dto);
+ }
+ } catch (Exception e) {
+ throw new JobExecutionException("EVA: trigger snippet throw an exception", e);
+ } finally {
+ log.trace("Snippet scanner execute completed.");
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/quartz/SnippetScannerConfig.java b/server/services/src/main/java/com/doumee/config/quartz/SnippetScannerConfig.java
new file mode 100644
index 0000000..27fd766
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/quartz/SnippetScannerConfig.java
@@ -0,0 +1,32 @@
+package com.doumee.config.quartz;
+
+import org.quartz.*;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 鍒嗙墖浠诲姟鎵弿鍣ㄩ厤缃�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Configuration
+public class SnippetScannerConfig {
+
+ @Bean
+ public JobDetail getSnippetScanner () {
+ return JobBuilder.newJob(SnippetScanner.class)
+ .withIdentity("snippetScanner")
+ .storeDurably()
+ .build();
+ }
+
+ @Bean
+ public Trigger getSnippetScannerTrigger() {
+ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?");
+ return TriggerBuilder.newTrigger()
+ .forJob(getSnippetScanner())
+ .withIdentity("snippetScannerTrigger")
+ .withSchedule(scheduleBuilder)
+ .build();
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java b/server/services/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java
new file mode 100644
index 0000000..ad18d51
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/shiro/ShiroAuthFilter.java
@@ -0,0 +1,27 @@
+package com.doumee.config.shiro;
+
+import com.doumee.core.model.ApiResponse;
+import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
+import org.springframework.http.HttpStatus;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Shiro璁よ瘉杩囨护鍣紝澶勭悊鏈璇佹儏鍐电殑鍝嶅簲
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public class ShiroAuthFilter extends FormAuthenticationFilter {
+
+ public ShiroAuthFilter() {
+ super();
+ }
+
+ @Override
+ protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
+ ApiResponse.response((HttpServletResponse) response, ApiResponse.failed(HttpStatus.UNAUTHORIZED.value(), "鏈櫥褰曟垨鐧诲綍淇℃伅宸茶繃鏈�"));
+ return Boolean.FALSE;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/shiro/ShiroCache.java b/server/services/src/main/java/com/doumee/config/shiro/ShiroCache.java
new file mode 100644
index 0000000..6238ac5
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/shiro/ShiroCache.java
@@ -0,0 +1,159 @@
+package com.doumee.config.shiro;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.CacheException;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.shiro.util.CollectionUtils;
+import org.springframework.context.annotation.Scope;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.SerializationException;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Shiro缂撳瓨
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Scope(value = "prototype")
+@Slf4j
+@Component
+public class ShiroCache implements Cache<Object, Serializable> {
+
+ private String keyPrefix = "";
+
+ @Resource(name="sessionRedisTemplate")
+ private RedisTemplate<Object, Serializable> redisTemplate;
+
+ public ShiroCache () {
+ log.debug("ShiroCache: new, keyPrefix = [" + keyPrefix + "]");
+ }
+
+ public ShiroCache(String keyPrefix) {
+ log.debug("ShiroCache: new, keyPrefix = [" + keyPrefix + "]");
+ this.keyPrefix = keyPrefix;
+ }
+
+ @Override
+ public Serializable get(Object key) throws CacheException {
+ if (key == null) {
+ return null;
+ }
+ return redisTemplate.opsForValue().get(getKey(key));
+ }
+
+ @Override
+ public Serializable put(Object key, Serializable value) throws CacheException {
+ if (key == null) {
+ return null;
+ }
+ redisTemplate.opsForValue().set(getKey(key), value);
+ return value;
+ }
+
+ public Serializable put(Object key, Serializable value, int timeout) throws CacheException {
+ if (key == null) {
+ return null;
+ }
+ redisTemplate.opsForValue().set(getKey(key), value, timeout, TimeUnit.SECONDS);
+ return value;
+ }
+
+ @Override
+ public void clear() throws CacheException {
+ Set<Object> keys = this.keys();
+ redisTemplate.delete(keys);
+ }
+
+ @Override
+ public int size() {
+ return this.keys().size();
+ }
+
+ @Override
+ public Set<Object> keys() {
+ Set<Object> keys = redisTemplate.keys(keyPrefix + "*");
+ if (CollectionUtils.isEmpty(keys)) {
+ return Collections.emptySet();
+ }
+ return keys;
+ }
+
+ @Override
+ public Collection<Serializable> values() {
+ Collection<Serializable> values = new ArrayList<>();
+ Set<Object> keys = this.keys();
+ if (CollectionUtils.isEmpty(keys)) {
+ return values;
+ }
+ for (Object k : keys) {
+ values.add(redisTemplate.opsForValue().get(k));
+ }
+ return values;
+ }
+
+ @Override
+ public Serializable remove(Object key) throws CacheException {
+ if (key == null) {
+ return null;
+ }
+ Serializable value = this.get(getKey(key));
+ redisTemplate.delete(getKey(key));
+ return value;
+ }
+
+ private Object getKey (Object key) {
+ if (key instanceof PrincipalCollection) {
+ return this.keyPrefix + getRedisKeyFromPrincipalIdField((PrincipalCollection)key);
+ }
+ return (key instanceof String ? (this.keyPrefix + key) : key);
+ }
+
+ /**
+ * 鑾峰彇redis cache key
+ */
+ private String getRedisKeyFromPrincipalIdField(PrincipalCollection key) {
+ Object principalObject = key.getPrimaryPrincipal();
+ if (principalObject instanceof String) {
+ return principalObject.toString();
+ } else {
+ Method pincipalIdGetter = this.getPrincipalIdGetter(principalObject);
+ return this.getIdObj(principalObject, pincipalIdGetter);
+ }
+ }
+
+ private Method getPrincipalIdGetter(Object principalObject) {
+ Method pincipalIdGetter;
+ String principalIdMethodName = this.getPrincipalIdMethodName();
+
+ try {
+ pincipalIdGetter = principalObject.getClass().getMethod(principalIdMethodName);
+ return pincipalIdGetter;
+ } catch (NoSuchMethodException e) {
+ throw new SerializationException(e.getMessage(), e);
+ }
+ }
+
+ private String getIdObj(Object principalObject, Method pincipalIdGetter) {
+ try {
+ Object idObj = pincipalIdGetter.invoke(principalObject);
+ String redisKey = idObj.toString();
+ return redisKey;
+ } catch (Exception e) {
+ throw new SerializationException(e.getMessage(), e);
+ }
+ }
+
+ private String getPrincipalIdMethodName() {
+ return "getId";
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java b/server/services/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java
new file mode 100644
index 0000000..98f1451
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/shiro/ShiroCacheManager.java
@@ -0,0 +1,44 @@
+package com.doumee.config.shiro;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.CacheException;
+import org.apache.shiro.cache.CacheManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * 鑷畾涔塖hiro CacheManager
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+public class ShiroCacheManager implements CacheManager {
+
+ private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap();
+
+ private static ApplicationContext applicationContext;
+
+ @Override
+ public <K, V> Cache<K, V> getCache(String name) throws CacheException {
+ log.debug("get cache, name=" + name);
+ Cache cache = this.caches.get(name);
+ if (cache == null) {
+ cache = applicationContext.getBean(ShiroCache.class, "shiro:cache:");
+ this.caches.put(name, cache);
+ }
+ return cache;
+ }
+
+ @Autowired
+ public void setApplicationContext (ApplicationContext applicationContext) {
+ if (ShiroCacheManager.applicationContext == null) {
+ ShiroCacheManager.applicationContext = applicationContext;
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/shiro/ShiroConfig.java b/server/services/src/main/java/com/doumee/config/shiro/ShiroConfig.java
new file mode 100644
index 0000000..b4603cb
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/shiro/ShiroConfig.java
@@ -0,0 +1,126 @@
+package com.doumee.config.shiro;
+
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+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;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import javax.servlet.Filter;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Shiro閰嶇疆
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Configuration
+public class ShiroConfig {
+
+ @Value("${cache.session.expire}")
+ private int sessionExpireTime;
+
+ @Autowired
+ private ShiroCredentialsMatcher shiroCredentialsMatcher;
+
+ @Autowired
+ private ShiroSessionDAO shiroSessionDAO;
+
+ @Autowired
+ private ShiroCacheManager shiroCacheManager;
+
+ @Autowired
+ private ShiroRealm shiroRealm;
+
+ @Bean("sessionRedisTemplate")
+ public RedisTemplate<Object, Serializable> sessionRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
+ RedisTemplate<Object, Serializable> redisTemplate = new RedisTemplate<>();
+ redisTemplate.setConnectionFactory(redisConnectionFactory);
+ // 榛樿搴忓垪鍖栨柟寮�
+ redisTemplate.setDefaultSerializer(new StringRedisSerializer());
+ // 鍊煎簭鍒楀寲鏂瑰紡
+ ShiroSessionSerializer serializer = new ShiroSessionSerializer();
+ redisTemplate.setValueSerializer(serializer);
+ redisTemplate.setHashValueSerializer(serializer);
+ redisTemplate.afterPropertiesSet();
+ return redisTemplate;
+ }
+
+ @Bean
+ public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
+ DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
+ autoProxyCreator.setProxyTargetClass(true);
+ return autoProxyCreator;
+ }
+
+ @Bean
+ public SessionManager sessionManager() {
+ ShiroSessionManager sessionManager = new ShiroSessionManager();
+ sessionManager.setSessionDAO(shiroSessionDAO);
+ return sessionManager;
+ }
+
+ @Bean
+ public SecurityManager securityManager() {
+ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
+ securityManager.setRealm(shiroRealm);
+ securityManager.setSessionManager(this.sessionManager());
+ securityManager.setCacheManager(shiroCacheManager);
+ return securityManager;
+ }
+
+ @Bean
+ public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
+ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
+ shiroFilterFactoryBean.setSecurityManager(securityManager);
+ Map<String, String> map = new LinkedHashMap<>();
+ // 璺緞鎷︽埅閰嶇疆
+ map.put("/system/login", "anon");
+ map.put("/system/logout", "anon");
+ map.put("/common/captcha", "anon");
+ // - 鏀捐swagger
+ map.put("/doc.html", "anon");
+ map.put("/webjars/**", "anon");
+ map.put("/web/api/**", "anon");
+ map.put("/swagger-resources/**", "anon");
+ map.put("/v2/api-docs/**", "anon");
+ // - 鍏朵粬鎺ュ彛缁熶竴鎷︽埅
+ map.put("/**", "authc");
+ shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
+ // 娣诲姞璁よ瘉杩囨护鍣�
+ Map<String, Filter> filters = new LinkedHashMap<>();
+ filters.put("authc", new ShiroAuthFilter());
+ shiroFilterFactoryBean.setFilters(filters);
+ return shiroFilterFactoryBean;
+ }
+
+ @Bean
+ public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
+ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
+ authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
+ return authorizationAttributeSourceAdvisor;
+ }
+
+ @Bean
+ public ShiroSessionDAO getShiroSessionDAO () {
+ shiroSessionDAO.setExpireTime(sessionExpireTime);
+ return shiroSessionDAO;
+ }
+
+ @Bean
+ public ShiroRealm getShiroRealm () {
+ shiroRealm.setCredentialsMatcher(shiroCredentialsMatcher);
+ return shiroRealm;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java b/server/services/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java
new file mode 100644
index 0000000..9f66e68
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java
@@ -0,0 +1,41 @@
+package com.doumee.config.shiro;
+
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.model.SystemUser;
+import com.doumee.service.system.SystemUserService;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+/**
+ * Shiro瀵嗙爜姣斿澶勭悊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Component
+public class ShiroCredentialsMatcher extends HashedCredentialsMatcher {
+
+ @Lazy
+ @Autowired
+ private SystemUserService systemUserService;
+
+ @Override
+ public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
+ UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
+ SystemUser queryUserDto = new SystemUser();
+ queryUserDto.setUsername(usernamePasswordToken.getUsername());
+ queryUserDto.setDeleted(Boolean.FALSE);
+ SystemUser systemUser = systemUserService.findOne(queryUserDto);
+ if (systemUser == null) {
+ return Boolean.FALSE;
+ }
+ // 鍔犲瘑瀵嗙爜
+ String pwd = Utils.Secure.encryptPassword(new String(usernamePasswordToken.getPassword()), systemUser.getSalt());
+ // 姣旇緝瀵嗙爜
+ return this.equals(pwd, systemUser.getPassword());
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/shiro/ShiroRealm.java b/server/services/src/main/java/com/doumee/config/shiro/ShiroRealm.java
new file mode 100644
index 0000000..f451a1c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/shiro/ShiroRealm.java
@@ -0,0 +1,80 @@
+package com.doumee.config.shiro;
+
+import com.doumee.core.model.LoginUserInfo;
+import com.doumee.dao.system.model.SystemPermission;
+import com.doumee.dao.system.model.SystemRole;
+import com.doumee.dao.system.model.SystemUser;
+import com.doumee.service.system.SystemPermissionService;
+import com.doumee.service.system.SystemRoleService;
+import com.doumee.service.system.SystemUserService;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationInfo;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.SimpleAuthenticationInfo;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.realm.AuthorizingRealm;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 鑷畾涔塕ealm锛屽鐞嗚璇佸拰鏉冮檺
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Component
+public class ShiroRealm extends AuthorizingRealm {
+
+ @Lazy
+ @Autowired
+ private SystemUserService systemUserService;
+
+ @Lazy
+ @Autowired
+ private SystemRoleService systemRoleService;
+
+ @Lazy
+ @Autowired
+ private SystemPermissionService systemPermissionService;
+
+ /**
+ * 鏉冮檺澶勭悊
+ */
+ @Override
+ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
+ LoginUserInfo loginUserInfo = (LoginUserInfo)principalCollection.getPrimaryPrincipal();
+ // 璁剧疆鐢ㄦ埛瑙掕壊鍜屾潈闄�
+ SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
+ authorizationInfo.addRoles(loginUserInfo.getRoles());
+ authorizationInfo.addStringPermissions(loginUserInfo.getPermissions());
+ return authorizationInfo;
+ }
+
+ /**
+ * 璁よ瘉澶勭悊
+ */
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
+ // 鑾峰彇鐢ㄦ埛鍚�
+ String username = authenticationToken.getPrincipal().toString();
+ // 鏍规嵁鐢ㄦ埛鍚嶆煡璇㈢敤鎴峰璞�
+ SystemUser queryDto = new SystemUser();
+ queryDto.setUsername(username);
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemUser user = systemUserService.findOne(queryDto);
+ if (user == null) {
+ return null;
+ }
+ // 鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅
+ List<SystemRole> roles = systemRoleService.findByUserId(user.getId());
+ List<SystemPermission> permissions = systemPermissionService.findByUserId(user.getId());
+ LoginUserInfo userInfo = LoginUserInfo.from(user, roles, permissions);
+ // 楠岃瘉鐢ㄦ埛
+ return new SimpleAuthenticationInfo(userInfo, user.getPassword(), this.getName());
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java b/server/services/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java
new file mode 100644
index 0000000..39b6075
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/shiro/ShiroSessionDAO.java
@@ -0,0 +1,112 @@
+package com.doumee.config.shiro;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.UnknownSessionException;
+import org.apache.shiro.session.mgt.SimpleSession;
+import org.apache.shiro.session.mgt.eis.SessionDAO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * 鑷畾涔塖hiro SessionDAO锛屽皢浼氳瘽淇℃伅瀛樺叆缂撳瓨涓�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@Slf4j
+@Component
+public class ShiroSessionDAO implements SessionDAO {
+
+ private static final String KEY_PREFIX = "shiro:session:";
+
+ @Autowired
+ private ShiroCache shiroCache;
+
+ @Value("${cache.session.expire:1800}")
+ private int expireTime;
+
+ @Autowired
+ private ShiroTokenManager shiroTokenManager;
+
+ @Override
+ public Serializable create(Session session) {
+ if (session == null) {
+ log.error("session is null");
+ throw new UnknownSessionException("session is null");
+ }
+ Serializable sessionId = shiroTokenManager.build();
+ ((SimpleSession)session).setId(sessionId);
+ this.saveSession(session);
+ return sessionId;
+ }
+
+ @Override
+ public Session readSession(Serializable sessionId) throws UnknownSessionException{
+ if (sessionId == null) {
+ log.warn("session id is null");
+ return null;
+ }
+ if (sessionId instanceof String) {
+ // 瀵筍essionId杩涜楠岃瘉锛堝彲鐢ㄤ簬闃叉Session鎹曡幏銆佹毚鍔涙崟鎹夌瓑涓�绯诲垪瀹夊叏闂锛屾渶缁堝畨鍏ㄦ�у彇鍐充簬check濡備綍瀹炵幇锛�
+ shiroTokenManager.check((String) sessionId);
+ }
+ log.debug("read session from cache");
+ Session session = getSessionFromCache(sessionId);
+ if (session == null) {
+ throw new UnknownSessionException("There is no session with id [" + sessionId + "]");
+ }
+ return session;
+ }
+
+ @Override
+ public void update(Session session) throws UnknownSessionException {
+ this.saveSession(session);
+ }
+
+ @Override
+ public void delete(Session session) {
+ if (session != null && session.getId() != null) {
+ shiroCache.remove(KEY_PREFIX + session.getId());
+ }
+ }
+
+ @Override
+ public Collection<Session> getActiveSessions() {
+ Set<Session> sessions = new HashSet<>();
+ Set<Object> keys = shiroCache.keys();
+ if (keys != null && keys.size() > 0) {
+ Iterator iter = keys.iterator();
+ while(iter.hasNext()) {
+ sessions.add((Session) shiroCache.get(iter.next()));
+ }
+ }
+ return sessions;
+ }
+
+ private void saveSession(Session session) throws UnknownSessionException {
+ if (session == null || session.getId() == null) {
+ log.error("session or session id is null");
+ throw new UnknownSessionException("session or session id is null");
+ }
+ shiroCache.put(KEY_PREFIX + session.getId(), (SimpleSession)session, expireTime);
+ }
+
+ private Session getSessionFromCache (Serializable sessionId) {
+ Serializable object = shiroCache.get(KEY_PREFIX + sessionId);
+ Session session = null;
+ if (object != null) {
+ session = (Session)shiroCache.get(KEY_PREFIX + sessionId);
+ }
+ return session;
+ }
+
+ public void setExpireTime (int expireTime) {
+ this.expireTime = expireTime;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java b/server/services/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java
new file mode 100644
index 0000000..d0ce8ed
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/shiro/ShiroSessionManager.java
@@ -0,0 +1,87 @@
+package com.doumee.config.shiro;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.DefaultSessionManager;
+import org.apache.shiro.session.mgt.SessionContext;
+import org.apache.shiro.session.mgt.SessionKey;
+import org.apache.shiro.web.servlet.Cookie;
+import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
+import org.apache.shiro.web.servlet.SimpleCookie;
+import org.apache.shiro.web.session.mgt.WebSessionManager;
+import org.apache.shiro.web.util.WebUtils;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.Serializable;
+
+/**
+ * 鑷畾涔変細璇濈鐞嗗櫒
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+public class ShiroSessionManager extends DefaultSessionManager implements WebSessionManager {
+
+ private static final String AUTH_TOKEN = "doumee-auth-token";
+
+ @Override
+ protected void onStart(Session session, SessionContext context) {
+ super.onStart(session, context);
+ if (!WebUtils.isHttp(context)) {
+ log.debug("SessionContext argument is not Http compatible or does not have an Http request/response pair. No session ID cookie will be set.");
+ return;
+ }
+ HttpServletRequest request = WebUtils.getHttpRequest(context);
+ HttpServletResponse response = WebUtils.getHttpResponse(context);
+ Serializable sessionId = session.getId();
+ this.storeSessionId(sessionId, request, response);
+ request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE);
+ request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
+ }
+
+ @Override
+ public Serializable getSessionId(SessionKey key) {
+ Serializable sessionId = super.getSessionId(key);
+ if (sessionId == null && WebUtils.isWeb(key)) {
+ ServletRequest servletRequest = WebUtils.getRequest(key);
+ if (!(servletRequest instanceof HttpServletRequest)) {
+ log.trace("Can not get sessionId from header, the request is not HttpServletRequest");
+ return null;
+ }
+ HttpServletRequest request = (HttpServletRequest) servletRequest;
+ // 浠巆ookie涓幏鍙栬璇�
+ javax.servlet.http.Cookie[] cookies = request.getCookies();
+ if (cookies != null) {
+ for (javax.servlet.http.Cookie cookie : cookies) {
+ if (AUTH_TOKEN.equals(cookie.getName())) {
+ return cookie.getValue();
+ }
+ }
+ }
+ // 浠巋eader涓幏鍙栬璇�
+ return request.getHeader(AUTH_TOKEN);
+ }
+ return sessionId;
+ }
+
+ @Override
+ public boolean isServletContainerSessions() {
+ return false;
+ }
+
+ private void storeSessionId(Serializable currentId, HttpServletRequest request, HttpServletResponse response) {
+ if (currentId == null) {
+ String msg = "sessionId cannot be null when persisting for subsequent requests.";
+ throw new IllegalArgumentException(msg);
+ }
+ Cookie cookie = new SimpleCookie(AUTH_TOKEN);
+ cookie.setHttpOnly(false);
+ cookie.setPath("/");
+ String idString = currentId.toString();
+ cookie.setValue(idString);
+ cookie.saveTo(request, response);
+ log.trace("Set session ID cookie for session with id {}", idString);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/shiro/ShiroSessionSerializer.java b/server/services/src/main/java/com/doumee/config/shiro/ShiroSessionSerializer.java
new file mode 100644
index 0000000..e0c3c4d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/shiro/ShiroSessionSerializer.java
@@ -0,0 +1,36 @@
+package com.doumee.config.shiro;
+
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.shiro.codec.Base64;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.SerializationException;
+
+import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Session搴忓垪鍖�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public class ShiroSessionSerializer implements RedisSerializer<Serializable> {
+
+ @Override
+ public byte[] serialize(Serializable obj) throws SerializationException {
+ if (obj == null) {
+ return new byte[0];
+ }
+ String sessionBase64 = Base64.encodeToString(SerializationUtils.serialize(obj));
+ return sessionBase64.getBytes(StandardCharsets.UTF_8);
+ }
+
+ @Override
+ public Serializable deserialize(byte[] bytes) throws SerializationException {
+ if (bytes == null || bytes.length == 0) {
+ return null;
+ }
+ String sessionString = new String(bytes, StandardCharsets.UTF_8);
+ byte[] sessionBytes = Base64.decode(sessionString);
+ return SerializationUtils.deserialize(sessionBytes);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java b/server/services/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java
new file mode 100644
index 0000000..139fa96
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/shiro/ShiroTokenManager.java
@@ -0,0 +1,25 @@
+package com.doumee.config.shiro;
+
+import com.doumee.core.exception.UnSafeSessionException;
+import org.springframework.stereotype.Component;
+
+import java.util.UUID;
+
+/**
+ * 榛樿Token绠$悊鍣�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Component
+public class ShiroTokenManager {
+
+ String build() {
+ return UUID.randomUUID().toString();
+ }
+
+ void check(String token) throws UnSafeSessionException {
+ if (token == null || token.length() != 36) {
+ throw new UnSafeSessionException();
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/swagger/SwaggerConfig.java b/server/services/src/main/java/com/doumee/config/swagger/SwaggerConfig.java
new file mode 100644
index 0000000..5deebde
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/swagger/SwaggerConfig.java
@@ -0,0 +1,118 @@
+package com.doumee.config.swagger;
+
+import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.RequestHandler;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.oas.annotations.EnableOpenApi;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+
+import java.util.function.Predicate;
+
+/**
+ * Swagger閰嶇疆
+ * @author dm
+ * @date 2022/03/11 10:24
+ */
+@Configuration
+@EnableOpenApi
+@EnableKnife4j
+public class SwaggerConfig {
+
+ @Value("${swagger.host:}")
+ private String host;
+
+ @Value("${swagger.title:鎺ュ彛鏂囨。}")
+ private String title;
+ @Value("${swagger.enabled:}")
+ private Boolean enabled;
+
+ @Value("${swagger.description:}")
+ private String description;
+
+ @Value("${project.version:}")
+ private String version;
+
+ @Bean
+ public ApiInfo getApiInfo() {
+ return new ApiInfoBuilder()
+ .title(title)
+ .description(description)
+ .version(version)
+ .build();
+ }
+ @Bean
+ public Docket getDocket() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(this.getApiInfo()).groupName("涓氬姟鎺ュ彛")
+ .host(host)
+ .enable(enabled)
+ .select()
+ .apis( basePackage("com.doumee.api.business;com.doumee.api.system"))
+ // 璁剧疆闇�瑕佽鎵弿鐨勭被锛岃繖閲岃缃负娣诲姞浜咢Api娉ㄨВ鐨勭被
+// .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
+ .paths(PathSelectors.any())
+ .build();
+ }
+ @Bean
+ public Docket getDocket1() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(this.getApiInfo()).groupName("鍏叡涓氬姟鎺ュ彛")
+ .host(host)
+ .enable(enabled)
+ .select()
+ .apis( basePackage("com.doumee.api.common"))
+ // 璁剧疆闇�瑕佽鎵弿鐨勭被锛岃繖閲岃缃负娣诲姞浜咢Api娉ㄨВ鐨勭被
+// .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
+ .paths(PathSelectors.any())
+ .build();
+ }
+
+ @Bean
+ public Docket getDocket2() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(this.getApiInfo()).groupName("Web涓氬姟鎺ュ彛")
+ .host(host)
+ .enable(enabled)
+ .select()
+ .apis( basePackage("com.doumee.api.web"))
+ // 璁剧疆闇�瑕佽鎵弿鐨勭被锛岃繖閲岃缃负娣诲姞浜咢Api娉ㄨВ鐨勭被
+// .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
+ .paths(PathSelectors.any())
+ .build();
+ }
+
+ /**
+ * 閲嶅啓basePackage鏂规硶锛屼娇鑳藉瀹炵幇澶氬寘璁块棶锛屽鍒惰创涓婂幓
+ * @author teavamc
+ * @date 2019/1/26
+ * @return com.google.common.base.Predicate<springfox.documentation.RequestHandler>
+ */
+ public static Predicate<RequestHandler> basePackage(String basePackage) {
+ return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);
+ }
+
+ private static Function<Class<?>, Boolean> handlerPackage(String basePackage) {
+ return input -> {
+ // 寰幆鍒ゆ柇鍖归厤
+ for (String strPackage : basePackage.split(";")) {
+ boolean isMatch = input.getPackage().getName().startsWith(strPackage);
+ if (isMatch) {
+ return true;
+ }
+ }
+ return false;
+ };
+ }
+
+ private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
+ return Optional.fromNullable(input.declaringClass());
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/swagger/SwaggerInterceptor.java b/server/services/src/main/java/com/doumee/config/swagger/SwaggerInterceptor.java
new file mode 100644
index 0000000..7751d01
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/swagger/SwaggerInterceptor.java
@@ -0,0 +1,45 @@
+package com.doumee.config.swagger;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Swagger鎷︽埅鍣�
+ * @author dm
+ * @date 2022/04/18 18:12
+ */
+@Slf4j
+@Component
+public class SwaggerInterceptor implements HandlerInterceptor {
+
+ @Value("${swagger.enabled:false}")
+ private Boolean enabledSwagger;
+
+ @Value("${swagger.redirect-uri:/}")
+ private String redirectUri;
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+ if (!enabledSwagger) {
+ String uri = request.getContextPath();
+ if (StringUtils.isNotBlank(redirectUri))
+ uri = request.getContextPath() + redirectUri;
+ if (StringUtils.isBlank(uri))
+ uri = "/";
+ try {
+ response.sendRedirect(uri);
+ } catch (IOException e) {
+ log.error(String.format("Redirect to '%s' for swagger throw an exception : %s", uri, e.getMessage()), e);
+ }
+ return Boolean.FALSE;
+ }
+ return Boolean.TRUE;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/config/swagger/SwaggerInterceptorConfig.java b/server/services/src/main/java/com/doumee/config/swagger/SwaggerInterceptorConfig.java
new file mode 100644
index 0000000..45fb818
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/config/swagger/SwaggerInterceptorConfig.java
@@ -0,0 +1,23 @@
+package com.doumee.config.swagger;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * Swagger鎷︽埅鍣ㄩ厤缃�
+ * @author dm
+ * @date 2022/04/18 18:12
+ */
+@Configuration
+public class SwaggerInterceptorConfig implements WebMvcConfigurer {
+
+ @Autowired
+ private SwaggerInterceptor swaggerInterceptor;
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(swaggerInterceptor).addPathPatterns("/swagger-ui.html", "/doc.html");
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelColumn.java b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelColumn.java
new file mode 100644
index 0000000..c0de11a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelColumn.java
@@ -0,0 +1,115 @@
+package com.doumee.core.annotation.excel;
+
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+
+import java.lang.annotation.*;
+
+/**
+ * 鏍囪涓篍xcel鍒�
+ * @author Eva.Caesar Liu
+ * @date 2023/02/14 11:14
+ */
+@Inherited
+//@Target(ElementType.FIELD)
+@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExcelColumn {
+ /**
+ * 瀵煎嚭瀛楁鍚嶏紙榛樿璋冪敤褰撳墠瀛楁鐨勨�済et鈥濇柟娉曪紝濡傛寚瀹氬鍑哄瓧娈典负瀵硅薄锛岃濉啓鈥滃璞″悕.瀵硅薄灞炴�р�濓紝渚嬶細鈥渁rea.name鈥濄�佲�渙ffice.name鈥濓級
+ */
+ String value() default "";
+ /**
+ * 瀛楁绫诲瀷锛�0锛氬鍑哄鍏ワ紱1锛氫粎瀵煎嚭锛�2锛氫粎瀵煎叆锛�
+ */
+ int type() default 0;
+ /**
+ * 鍒楀悕
+ */
+ String name();
+
+ /**
+ * 鍒楀锛堝崟浣嶄负瀛楃锛夛紝-1鑷姩璁$畻
+ */
+ int width() default -1;
+
+ /**
+ * 鎺掑簭锛屽�艰秺灏忚秺闈犲墠锛�-1鎸夊瓧娈靛弽灏勯『搴忔帓搴�
+ */
+ int index() default -1;
+
+ /**
+ * 瀵归綈鏂瑰紡
+ */
+ HorizontalAlignment align() default HorizontalAlignment.LEFT;
+
+ /**
+ * 鍒楄儗鏅壊
+ */
+ IndexedColors backgroundColor() default IndexedColors.GREY_25_PERCENT;
+
+ /**
+ * 鍒楁暟鎹崟鍏冩牸鑳屾櫙鑹�
+ */
+ IndexedColors dataBackgroundColor() default IndexedColors.WHITE;
+
+ /**
+ * 瀛椾綋棰滆壊
+ */
+ IndexedColors color() default IndexedColors.BLACK;
+
+ /**
+ * 瀛椾綋澶у皬锛堝儚绱狅級
+ */
+ short fontSize() default 12;
+
+ /**
+ * 绮椾綋
+ */
+ boolean bold() default false;
+
+ /**
+ * 鏂滀綋
+ */
+ boolean italic() default false;
+
+ /**
+ * 鍊兼槧灏勶紝濡�0=濂�;1=鐢�
+ */
+ String valueMapping() default "";
+
+ /**
+ * 鏁版嵁鍓嶇紑
+ */
+ String prefix() default "";
+
+ /**
+ * 鏁版嵁鍚庣紑
+ */
+ String suffix() default "";
+
+ /**
+ * 鏃ユ湡鏍煎紡
+ */
+ String dateFormat() default "yyyy-MM-dd";
+
+ /**
+ * 鑷畾涔夋暟鎹鐞嗗櫒
+ */
+ Class handler() default ExcelDataHandlerAdapter.class;
+
+ /**
+ * 鑷畾涔夋暟鎹鐞嗗櫒鍙傛暟
+ */
+ String[] args() default {};
+
+ /**
+ * 鍙嶅皠绫诲瀷
+ */
+ Class<?> fieldType() default Class.class;
+
+ /**
+ * 瀛楁褰掑睘缁勶紙鏍规嵁鍒嗙粍瀵煎嚭瀵煎叆锛�
+ */
+ int[] groups() default {};
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelDataHandlerAdapter.java b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelDataHandlerAdapter.java
new file mode 100644
index 0000000..33a153b
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelDataHandlerAdapter.java
@@ -0,0 +1,17 @@
+package com.doumee.core.annotation.excel;
+
+/**
+ * Excel鏁版嵁鏍煎紡澶勭悊閫傞厤鍣�
+ * @author Eva.Caesar Liu
+ * @date 2023/02/14 11:14
+ */
+public interface ExcelDataHandlerAdapter {
+
+ /**
+ * 鏍煎紡鍖�
+ * @param args 鍙傛暟闆嗗悎锛岀涓�涓弬鏁颁负鍗曞厓鏍兼暟鎹�
+ *
+ * @return String
+ */
+ Object format (Object... args);
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelExporter.java b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelExporter.java
new file mode 100644
index 0000000..477d2fd
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelExporter.java
@@ -0,0 +1,431 @@
+package com.doumee.core.annotation.excel;
+
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.springframework.core.annotation.AnnotationConfigurationException;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.URLEncoder;
+import java.nio.charset.Charset;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * Excel瀵煎嚭瀹炵幇
+ * @author Eva.Caesar Liu
+ * @date 2023/02/14 11:14
+ */
+@Data
+public class ExcelExporter<T> {
+
+ private static final String DEFAULT_SHEET_NAME = "Sheet1";
+
+ private Class<T> modelClass;
+ private static int maxrows = 50000;
+
+ private ExcelExporter(){}
+
+ /**
+ * 鏋勯�犲櫒
+ * @param modelClass 瀹炰綋Class瀵硅薄
+ */
+ public static <T> ExcelExporter<T> build(Class<T> modelClass) {
+ ExcelExporter<T> excelExporter = new ExcelExporter<>();
+ excelExporter.setModelClass(modelClass);
+ return excelExporter;
+ }
+ /**
+ * 瀵煎嚭鍒版寚瀹氳緭鍑烘祦
+ * @param data 鏁版嵁
+ * @param sheetName Sheet鍚嶇О
+ */
+ public void exportWithFirstAndEnd (List<T> data, String sheetName,String first,String end, OutputStream os) {
+ SXSSFWorkbook sxssfWorkbook;
+ try {
+ sxssfWorkbook = new SXSSFWorkbook();
+ Sheet sheet = sxssfWorkbook.createSheet(sheetName);
+ // 鍒涘缓鍒楀ご
+ sheet.createFreezePane(0, 2);
+ sheet.addMergedRegion(new CellRangeAddress(0 ,0,0,this.getColumns().size()-1));
+ Row title = sheet.createRow(0);
+ title.setHeight((short) 1000);
+ Cell c = title.createCell(0);
+ c.setCellValue(first);
+ configFirstCell(sxssfWorkbook,c);
+
+ Row header = sheet.createRow(1);
+ List<ColumnInfo> columns = this.getColumns();
+ for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
+ ColumnInfo column = columns.get(columnIndex);
+ Cell cell = header.createCell(columnIndex);
+ cell.setCellValue(column.columnConfig.name());
+ // 鍒楀璁剧疆
+ if (column.columnConfig.width() == -1) {
+ sheet.setColumnWidth(columnIndex, column.columnConfig.name().length() * 2 * 256);
+ } else {
+ sheet.setColumnWidth(columnIndex, column.columnConfig.width() * 2 * 256);
+ }
+ // 璁剧疆鍒楀ご鍗曞厓鏍�
+ configHeaderCell(sxssfWorkbook, cell, column.columnConfig);
+ }
+ List<CellStyle> styleList = new ArrayList<>();
+ for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
+ ColumnInfo column = columns.get(columnIndex);
+ styleList.add( configDataCell(sxssfWorkbook, column.columnConfig));
+ }
+ // 鍒涘缓鏁版嵁璁板綍
+ for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) {
+ Row row = sheet.createRow(rowIndex + 2);
+ for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
+ ColumnInfo column = columns.get(columnIndex);
+ Cell cell = row.createCell(columnIndex);
+ cell.setCellValue(getCellData(column, data.get(rowIndex)));
+ cell.setCellStyle(styleList.get(columnIndex));
+ }
+ }
+ sheet.addMergedRegion(new CellRangeAddress(data.size()+2 ,data.size()+2,0,this.getColumns().size()-1));
+ Row endRow = sheet.createRow(data.size()+2);
+// endRow.setHeight((short) 600);
+ Cell c1 = endRow.createCell(0);
+ c1.setCellValue(end);
+ c1.setCellStyle( configEndCell(sxssfWorkbook));
+ sxssfWorkbook.write(os);
+ os.close();
+ } catch (Exception e) {
+ throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e);
+ } finally {
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /**
+ * 瀵煎嚭鍒版寚瀹氳緭鍑烘祦
+ * @param data 鏁版嵁
+ * @param sheetName Sheet鍚嶇О
+ * @param os 杈撳嚭娴�
+ */
+ public void export (List<T> data, String sheetName, OutputStream os) {
+ SXSSFWorkbook sxssfWorkbook;
+ try {
+ sxssfWorkbook = new SXSSFWorkbook();
+ int totalSheet =1;
+ if( data!=null && data.size()>0){
+ totalSheet = data.size()/maxrows;
+ if(data.size()%maxrows !=0){
+ totalSheet += 1;
+ }
+ }
+ for (int i = 0; i < totalSheet; i++) {
+ List<T> list = null;
+ if(data.size() < maxrows * (i+1)) {
+ list = data.subList(maxrows*i,data.size());
+ }else{
+ list = data.subList(maxrows*i,maxrows*(i+1));
+ }
+ createSheetDataBiz(list,"銆�"+(i+1)+"銆�"+sheetName,sxssfWorkbook);
+ }
+ sxssfWorkbook.write(os);
+ os.close();
+ } catch (Exception e) {
+ throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e);
+ } finally {
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void createSheetDataBiz(List<T> data, String sheetName, SXSSFWorkbook sxssfWorkbook) throws Exception{
+ Sheet sheet = sxssfWorkbook.createSheet(sheetName);
+ // 鍒涘缓鍒楀ご
+ sheet.createFreezePane(0, 1);
+ Row header = sheet.createRow(0);
+ List<ColumnInfo> columns = this.getColumns();
+ for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
+ ColumnInfo column = columns.get(columnIndex);
+ Cell cell = header.createCell(columnIndex);
+ cell.setCellValue(column.columnConfig.name());
+ // 鍒楀璁剧疆
+ if (column.columnConfig.width() == -1) {
+ sheet.setColumnWidth(columnIndex, column.columnConfig.name().length() * 2 * 256);
+ } else {
+ sheet.setColumnWidth(columnIndex, column.columnConfig.width() * 2 * 256);
+ }
+ // 璁剧疆鍒楀ご鍗曞厓鏍�
+ configHeaderCell(sxssfWorkbook, cell, column.columnConfig);
+ }
+ List<CellStyle> styleList = new ArrayList<>();
+ for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
+ ColumnInfo column = columns.get(columnIndex);
+ styleList.add( configDataCell(sxssfWorkbook, column.columnConfig));
+ }
+ // 鍒涘缓鏁版嵁璁板綍
+ for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) {
+ Row row = sheet.createRow(rowIndex + 1);
+ for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
+ ColumnInfo column = columns.get(columnIndex);
+ Cell cell = row.createCell(columnIndex);
+ cell.setCellValue(getCellData(column, data.get(rowIndex)));
+ // 璁剧疆鏁版嵁鍗曞厓鏍兼牱寮�
+ cell.setCellStyle(styleList.get(columnIndex));
+ }
+ }
+ }
+
+ /**
+ * 瀵煎嚭鑷冲搷搴旀祦
+ * @param data 鏁版嵁
+ * @param fileName Excel鏂囦欢鍚�
+ * @param sheetName Sheet鍚嶇О
+ * @param response HttpServletResponse瀵硅薄
+ */
+ public void export (List<T> data, String fileName, String sheetName, HttpServletResponse response) {
+ try {
+ String encodeFileName = URLEncoder.encode(fileName, Charset.forName("UTF-8").toString()) + ".xlsx";
+ response.setHeader("Content-Disposition","attachment;filename=" + encodeFileName);
+ response.setContentType("application/octet-stream");
+ response.setHeader("doumee-opera-type", "download");
+ response.setHeader("doumee-download-filename", encodeFileName);
+ this.export(data, sheetName, response.getOutputStream());
+ } catch (IOException e) {
+ throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e);
+ }
+ }
+ /**
+ * 瀵煎嚭鑷冲搷搴旀祦
+ * @param data 鏁版嵁
+ * @param fileName Excel鏂囦欢鍚�
+ * @param sheetName Sheet鍚嶇О
+ * @param response HttpServletResponse瀵硅薄
+ */
+ public void exportWithFirstAndEnd (List<T> data, String fileName, String sheetName, String first,String end ,HttpServletResponse response) {
+ try {
+ String encodeFileName = URLEncoder.encode(fileName, Charset.forName("UTF-8").toString()) + ".xlsx";
+ response.setHeader("Content-Disposition","attachment;filename=" + encodeFileName);
+ response.setContentType("application/octet-stream");
+ response.setHeader("doumee-opera-type", "download");
+ response.setHeader("doumee-download-filename", encodeFileName);
+ this.exportWithFirstAndEnd(data, sheetName,first,end, response.getOutputStream());
+ } catch (IOException e) {
+ throw new BusinessException(ResponseStatus.EXPORT_EXCEL_ERROR, e);
+ }
+ }
+
+ /**
+ * 瀵煎嚭鑷冲搷搴旀祦
+ * @param data 鏁版嵁
+ * @param fileName Excel鏂囦欢鍚�
+ * @param response HttpServletResponse瀵硅薄
+ */
+ public void export (List<T> data, String fileName, HttpServletResponse response) {
+
+ this.export(data, fileName, DEFAULT_SHEET_NAME, response);
+ }
+ /**
+ * 瀵煎嚭鑷冲搷搴旀祦
+ * @param data 鏁版嵁
+ * @param fileName Excel鏂囦欢鍚�
+ * @param response HttpServletResponse瀵硅薄
+ */
+ public void exportWithFirstAndEnd (List<T> data, String fileName,String first,String end, HttpServletResponse response) {
+ this.exportWithFirstAndEnd(data, fileName, DEFAULT_SHEET_NAME, first,end,response);
+ }
+
+ /**O
+ * 鑾峰彇鍒楅泦鍚�
+ */
+ private List<ColumnInfo> getColumns () {
+ Map<Integer, ColumnInfo> sortedFields = new TreeMap<>();
+ Field[] fields = modelClass.getDeclaredFields();
+ int index = 0;
+ for (Field field : fields) {
+ ExcelColumn excelColumn = field.getAnnotation(ExcelColumn.class);
+ if (excelColumn == null) {
+ continue;
+ }
+ if (sortedFields.get(excelColumn.index()) != null) {
+ throw new AnnotationConfigurationException("Excel column contains the same index.");
+ }
+ sortedFields.put(excelColumn.index() == -1 ? index : excelColumn.index(), new ColumnInfo(excelColumn, field));
+ index++;
+ }
+ return new ArrayList<>(sortedFields.values());
+ }
+
+ /**
+ * 閰嶇疆鏁版嵁鍗曞厓鏍�
+ */
+ private CellStyle configDataCell (SXSSFWorkbook workbook, ExcelColumn columnConfig) {
+ CellStyle configDataCellStyle = workbook.createCellStyle();
+ configDataCellStyle.setAlignment(columnConfig.align());
+ configDataCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+ // 璁剧疆鑳屾櫙
+ configDataCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+ configDataCellStyle.setFillForegroundColor(columnConfig.dataBackgroundColor().getIndex());
+ // 瀛椾綋
+ Font font = workbook.createFont();
+ font.setFontHeightInPoints(columnConfig.fontSize());
+ // 瀛椾綋棰滆壊
+ font.setColor(columnConfig.color().getIndex());
+ // 绮椾綋
+ font.setBold(columnConfig.bold());
+ // 鏂滀綋
+ font.setItalic(columnConfig.italic());
+ configDataCellStyle.setFont(font);
+ // 杈规
+ configCellBorder(configDataCellStyle);
+ configDataCellStyle.setWrapText(true);
+
+ return configDataCellStyle;
+// cell.setCellStyle(configDataCellStyle);
+ }
+
+ /**
+ * 閰嶇疆鍒楀ご鍗曞厓鏍�
+ */
+ private void configHeaderCell (SXSSFWorkbook workbook, Cell cell, ExcelColumn columnConfig) {
+ CellStyle style = workbook.createCellStyle();
+ style.setAlignment(columnConfig.align());
+ style.setVerticalAlignment(VerticalAlignment.CENTER);
+ // 璁剧疆鑳屾櫙
+ style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+ style.setFillForegroundColor(columnConfig.backgroundColor().getIndex());
+ // 瀛椾綋
+ Font font = workbook.createFont();
+ font.setFontHeightInPoints(columnConfig.fontSize());
+ style.setFont(font);
+ // 璁剧疆杈规
+ configCellBorder(style);
+ cell.setCellStyle(style);
+ }
+ /**
+ * 閰嶇疆鍒楀ご鍗曞厓鏍�
+ */
+ private void configFirstCell (SXSSFWorkbook workbook, Cell cell ) {
+ CellStyle style = workbook.createCellStyle();
+ style.setAlignment(HorizontalAlignment.CENTER);
+ style.setVerticalAlignment(VerticalAlignment.CENTER);
+ // 璁剧疆鑳屾櫙
+ style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+ style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+ // 瀛椾綋
+ Font font = workbook.createFont();
+ font.setFontHeightInPoints((short)18);
+ style.setFont(font);
+ // 璁剧疆杈规
+ configCellBorder(style);
+ cell.setCellStyle(style);
+ }
+// public static CellStyle configEndCellStyle =null;
+ /**
+ * 閰嶇疆鍒楀ご鍗曞厓鏍�
+ */
+ private CellStyle configEndCell (SXSSFWorkbook workbook ) {
+ CellStyle style = workbook.createCellStyle();
+ style.setAlignment(HorizontalAlignment.RIGHT);
+ style.setVerticalAlignment(VerticalAlignment.CENTER);
+ // 璁剧疆鑳屾櫙
+ style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+ style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+ // 瀛椾綋
+ Font font = workbook.createFont();
+ font.setFontHeightInPoints((short)14);
+ style.setFont(font);
+ // 璁剧疆杈规
+ configCellBorder(style);
+ return style;
+
+ }
+
+ /**
+ * 閰嶇疆鍗曞厓鏍艰竟妗�
+ */
+ private void configCellBorder (CellStyle style) {
+ style.setBorderTop(BorderStyle.THIN);
+ style.setBorderRight(BorderStyle.THIN);
+ style.setBorderBottom(BorderStyle.THIN);
+ style.setBorderLeft(BorderStyle.THIN);
+ style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+ style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+ style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+ style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+ }
+
+ /**
+ * 澶勭悊鍗曞厓鏍兼暟鎹�
+ */
+ private String getCellData (ColumnInfo columnInfo, T row) throws Exception {
+ columnInfo.field.setAccessible(Boolean.TRUE);
+ Object value = columnInfo.field.get(row);
+ columnInfo.field.setAccessible(Boolean.FALSE);
+ if (value == null) {
+ return "";
+ }
+ String stringValue = value.toString();
+ // 瀛樺湪鑷畾涔夋暟鎹鐞嗗櫒
+ if (!columnInfo.columnConfig.handler().equals(ExcelDataHandlerAdapter.class)) {
+ try {
+ Object instance = columnInfo.columnConfig.handler().newInstance();
+ Method formatMethod = columnInfo.columnConfig.handler().getMethod("format", Object[].class);
+ List<Object> args = new ArrayList<>();
+ args.add(value);
+ for (String arg : columnInfo.columnConfig.args()) {
+ args.add(arg);
+ }
+ value = formatMethod.invoke(instance, new Object[]{args.toArray()});
+ stringValue = value.toString();
+ } catch (Exception e) {
+ throw new IllegalStateException("Can not format data by " + columnInfo.columnConfig.handler(), e);
+ }
+ }
+ // 鏃ユ湡澶勭悊
+ if (!"".equals(columnInfo.columnConfig.dateFormat()) && value instanceof Date) {
+ SimpleDateFormat sdf = new SimpleDateFormat(columnInfo.columnConfig.dateFormat());
+ stringValue = sdf.format((Date) value);
+ }
+ // 鍊兼槧灏�
+ if (!"".equals(columnInfo.columnConfig.valueMapping())) {
+ String[] segs = columnInfo.columnConfig.valueMapping().split(";");
+ for (String seg : segs) {
+ String[] mapping = seg.split("=");
+ if (value.toString().equals(mapping[0].trim())) {
+ stringValue = mapping[1].trim();
+ }
+ }
+ }
+ // 鍓嶇紑澶勭悊
+ stringValue = columnInfo.columnConfig.prefix() + stringValue;
+ // 鍚庣紑澶勭悊
+ stringValue = stringValue + columnInfo.columnConfig.suffix();
+ return stringValue;
+ }
+
+ @Data
+ @AllArgsConstructor
+ private static class ColumnInfo {
+
+ private ExcelColumn columnConfig;
+
+ private Field field;
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelImporter.java b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelImporter.java
new file mode 100644
index 0000000..f8f067c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/excel/ExcelImporter.java
@@ -0,0 +1,394 @@
+package com.doumee.core.annotation.excel;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * 瀵煎叆Excel鏂囦欢锛堟敮鎸佲�淴LS鈥濆拰鈥淴LSX鈥濇牸寮忥級
+ */
+public class ExcelImporter {
+
+ private static Logger log = LoggerFactory.getLogger(ExcelImporter.class);
+
+ /**
+ * 宸ヤ綔钖勫璞�
+ */
+ private Workbook wb;
+
+ /**
+ * 宸ヤ綔琛ㄥ璞�
+ */
+ private Sheet sheet;
+
+ /**
+ * 鏍囬琛屽彿
+ */
+ private int headerNum;
+ /**
+ * 鏍囬琛屽彿
+ */
+ private CellType changeType;
+
+ /**
+ * 鏋勯�犲嚱鏁�
+ * @param--path 瀵煎叆鏂囦欢锛岃鍙栫涓�涓伐浣滆〃
+ * @param headerNum 鏍囬琛屽彿锛屾暟鎹鍙�=鏍囬琛屽彿+1
+ * @throws InvalidFormatException
+ * @throws IOException
+ */
+ public ExcelImporter(String fileName, int headerNum)
+ throws InvalidFormatException, IOException {
+ this(new File(fileName), headerNum);
+ }
+
+ /**
+ * 鏋勯�犲嚱鏁�
+ * @param--path 瀵煎叆鏂囦欢瀵硅薄锛岃鍙栫涓�涓伐浣滆〃
+ * @param headerNum 鏍囬琛屽彿锛屾暟鎹鍙�=鏍囬琛屽彿+1 (eg: 1)
+ * @throws InvalidFormatException
+ * @throws IOException
+ */
+ public ExcelImporter(File file, int headerNum)
+ throws InvalidFormatException, IOException {
+ this(file, headerNum, 0);
+ }
+
+ /**
+ * 鏋勯�犲嚱鏁�
+ * @param--path 瀵煎叆鏂囦欢
+ * @param headerNum 鏍囬琛屽彿锛屾暟鎹鍙�=鏍囬琛屽彿+1
+ * @param sheetIndex 宸ヤ綔琛ㄧ紪鍙�
+ * @throws InvalidFormatException
+ * @throws IOException
+ */
+ public ExcelImporter(String fileName, int headerNum, int sheetIndex)
+ throws InvalidFormatException, IOException {
+ this(new File(fileName), headerNum, sheetIndex);
+ }
+
+ /**
+ * 鏋勯�犲嚱鏁�
+ * @param--path 瀵煎叆鏂囦欢瀵硅薄
+ * @param headerNum 鏍囬琛屽彿锛屾暟鎹鍙�=鏍囬琛屽彿+1
+ * @param sheetIndex 宸ヤ綔琛ㄧ紪鍙�
+ * @throws InvalidFormatException
+ * @throws IOException
+ */
+ public ExcelImporter(File file, int headerNum, int sheetIndex)
+ throws InvalidFormatException, IOException {
+ this(file.getName(), new FileInputStream(file), headerNum, sheetIndex);
+ }
+
+ /**
+ * 鏋勯�犲嚱鏁� (閲嶈)
+ * @param--file 瀵煎叆鏂囦欢瀵硅薄
+ * @param headerNum 鏍囬琛屽彿锛屾暟鎹鍙�=鏍囬琛屽彿+1
+ * @param sheetIndex 宸ヤ綔琛ㄧ紪鍙�
+ * @throws InvalidFormatException
+ * @throws IOException
+ */
+ public ExcelImporter(MultipartFile multipartFile, int headerNum, int sheetIndex)
+ throws InvalidFormatException, IOException {
+ this(multipartFile.getOriginalFilename(), multipartFile.getInputStream(), headerNum, sheetIndex);
+ }
+ /**
+ * 鏋勯�犲嚱鏁� (閲嶈)
+ * @param--file 瀵煎叆鏂囦欢瀵硅薄
+ * @param headerNum 鏍囬琛屽彿锛屾暟鎹鍙�=鏍囬琛屽彿+1
+ * @param sheetIndex 宸ヤ綔琛ㄧ紪鍙�
+ * @throws InvalidFormatException
+ * @throws IOException
+ */
+ public ExcelImporter(MultipartFile multipartFile, int headerNum, int sheetIndex, CellType cellType)
+ throws InvalidFormatException, IOException {
+ this(multipartFile.getOriginalFilename(), multipartFile.getInputStream(), headerNum, sheetIndex,cellType);
+ }
+
+ /**
+ * 鏋勯�犲嚱鏁� 锛堬級
+ * @param--path 瀵煎叆鏂囦欢瀵硅薄
+ * @param headerNum 鏍囬琛屽彿锛屾暟鎹鍙�=鏍囬琛屽彿+1
+ * @param sheetIndex 宸ヤ綔琛ㄧ紪鍙� (eg: 0)
+ * @throws InvalidFormatException
+ * @throws IOException
+ */
+ public ExcelImporter(String fileName, InputStream in, int headerNum, int sheetIndex)
+ throws InvalidFormatException, IOException {
+ if (StringUtils.isBlank(fileName)){
+ throw new RuntimeException("瀵煎叆鏂囨。涓虹┖!");
+ }else if(fileName.toLowerCase().endsWith("xls")){
+ this.wb = new HSSFWorkbook(in);
+ }else if(fileName.toLowerCase().endsWith("xlsx")){
+ this.wb = new XSSFWorkbook(in);
+ }else{
+ throw new RuntimeException("鏂囨。鏍煎紡涓嶆纭�!");
+ }
+ if (this.wb.getNumberOfSheets()<sheetIndex){
+ throw new RuntimeException("鏂囨。涓病鏈夊伐浣滆〃!");
+ }
+ this.sheet = this.wb.getSheetAt(sheetIndex);
+ this.headerNum = headerNum;
+ log.debug("Initialize success.");
+ }
+ public ExcelImporter(String fileName, InputStream in, int headerNum, int sheetIndex,CellType cellType)
+ throws InvalidFormatException, IOException {
+ if (StringUtils.isBlank(fileName)){
+ throw new RuntimeException("瀵煎叆鏂囨。涓虹┖!");
+ }else if(fileName.toLowerCase().endsWith("xls")){
+ this.wb = new HSSFWorkbook(in);
+ }else if(fileName.toLowerCase().endsWith("xlsx")){
+ this.wb = new XSSFWorkbook(in);
+ }else{
+ throw new RuntimeException("鏂囨。鏍煎紡涓嶆纭�!");
+ }
+ if (this.wb.getNumberOfSheets()<sheetIndex){
+ throw new RuntimeException("鏂囨。涓病鏈夊伐浣滆〃!");
+ }
+ this.sheet = this.wb.getSheetAt(sheetIndex);
+ this.headerNum = headerNum;
+ this.changeType = cellType;
+ log.debug("Initialize success.");
+ }
+
+
+
+ /**
+ * 鑾峰彇琛屽璞�
+ * @param rownum
+ * @return
+ */
+ public Row getRow(int rownum){
+ return this.sheet.getRow(rownum);
+ }
+
+ /**
+ * 鑾峰彇鏁版嵁琛屽彿
+ * @return
+ */
+ public int getDataRowNum(){
+ return headerNum+1;
+ }
+
+ /**
+ * 鑾峰彇鏈�鍚庝竴涓暟鎹鍙�
+ * @return
+ */
+ public int getLastDataRowNum(){
+ return this.sheet.getLastRowNum()+headerNum;
+ }
+
+ /**
+ * 鑾峰彇鏈�鍚庝竴涓垪鍙�
+ * @return
+ */
+ public int getLastCellNum(){
+ return this.getRow(headerNum).getLastCellNum();
+ }
+
+ /**
+ * 鑾峰彇鍗曞厓鏍煎��
+ * @param row 鑾峰彇鐨勮
+ * @param column 鑾峰彇鍗曞厓鏍煎垪鍙�
+ * @return 鍗曞厓鏍煎��
+ */
+ public Object getCellValue(Row row, int column){
+ Object val = "";
+ try{
+ Cell cell = row.getCell(column);
+ if (cell != null){
+ if (cell.getCellType() == CellType.NUMERIC){
+ cell.setCellType(CellType.STRING); // 纭繚鍗曞厓鏍肩被鍨嬩负瀛楃涓�
+ val = cell.getStringCellValue();
+ }else if (cell.getCellType() == CellType.STRING){
+ val = cell.getStringCellValue();
+ }else if (cell.getCellType() == CellType.FORMULA){
+ val = cell.getCellFormula();
+ }else if (cell.getCellType() == CellType.BOOLEAN){
+ val = cell.getBooleanCellValue();
+ }else if (cell.getCellType() == CellType.ERROR){
+ val = cell.getErrorCellValue();
+ }
+ }
+ }catch (Exception e) {
+ return val;
+ }
+ return val;
+ }
+
+ /**
+ * 鑾峰彇瀵煎叆鏁版嵁鍒楄〃
+ * @param cls 瀵煎叆瀵硅薄绫诲瀷
+ * @param groups 瀵煎叆鍒嗙粍 鍙负绌�
+ */
+ public <E> List<E> getDataList(Class<E> cls, int... groups) throws InstantiationException, IllegalAccessException{
+ List<Object[]> annotationList = new ArrayList<>();
+ // Get annotation field
+ Field[] fs = cls.getDeclaredFields();
+ for (Field f : fs){
+ ExcelColumn ef = f.getAnnotation(ExcelColumn.class);
+ if (ef != null && (ef.type()==0 || ef.type()==2)){
+ if (groups!=null && groups.length>0){
+ boolean inGroup = false;
+ for (int g : groups){
+ if (inGroup){
+ break;
+ }
+ for (int efg : ef.groups()){
+ if (g == efg){
+ inGroup = true;
+ annotationList.add(new Object[]{ef, f});
+ break;
+ }
+ }
+ }
+ }else{
+ annotationList.add(new Object[]{ef, f});
+ }
+ }
+ }
+ // Get annotation method
+ Method[] ms = cls.getDeclaredMethods();
+ for (Method m : ms){
+ ExcelColumn ef = m.getAnnotation(ExcelColumn.class);
+ if (ef != null && (ef.type()==0 || ef.type()==2)){
+ if (groups!=null && groups.length>0){
+ boolean inGroup = false;
+ for (int g : groups){
+ if (inGroup){
+ break;
+ }
+ for (int efg : ef.groups()){
+ if (g == efg){
+ inGroup = true;
+ annotationList.add(new Object[]{ef, m});
+ break;
+ }
+ }
+ }
+ }else{
+ annotationList.add(new Object[]{ef, m});
+ }
+ }
+ }
+ // Field sorting
+ Collections.sort(annotationList, (o1, o2) -> {
+ int index1 =((ExcelColumn)o1[0]).index(), index2=((ExcelColumn)o2[0]).index();
+ if(index1 == -1){
+ index1 = annotationList.size()+99999;
+ }
+ if(index2 == -1){
+ index2 = annotationList.size()+99999;
+ }
+ return new Integer(index1).compareTo(new Integer(index2));
+ });
+ //log.debug("Import column count:"+annotationList.size());
+ // Get excel data
+ List<E> dataList = new ArrayList<>();
+ System.out.println("璧峰鏁版嵁琛�:"+getDataRowNum());
+ System.out.println("缁撴潫鏁版嵁琛�:"+getLastDataRowNum());
+ for (int i = this.getDataRowNum(); i <= this.getLastDataRowNum(); i++) {
+ E e = (E)cls.newInstance();
+ int column = 0;
+ Row row = this.getRow(i);
+ if (Objects.isNull(row)){
+ continue;
+ }
+ StringBuilder sb = new StringBuilder();
+ for (Object[] os : annotationList){
+ Object val = this.getCellValue(row, column++);
+ if (val != null){
+ ExcelColumn ef = (ExcelColumn)os[0];
+ // Get param type and type cast
+ Class<?> valType = Class.class;
+ if (os[1] instanceof Field){
+ valType = ((Field)os[1]).getType();
+ }else if(os[1] instanceof Method){
+ Method method = ((Method)os[1]);
+ if ("get".equals(method.getName().substring(0, 3))){
+ valType = method.getReturnType();
+ }else if("set".equals(method.getName().substring(0, 3))){
+ valType = ((Method)os[1]).getParameterTypes()[0];
+ }
+ }
+ //log.debug("Import value type: ["+i+","+column+"] " + valType);
+ try {
+ if (valType == String.class){
+ String s = String.valueOf(val.toString());
+ if(StringUtils.endsWith(s, ".0")){
+ val = StringUtils.substringBefore(s, ".0");
+ }else{
+ val = String.valueOf(val.toString()).trim();
+ }
+ }
+ else if (valType == Integer.class){
+ val = Double.valueOf(val.toString()).intValue();
+ }else if (valType == Long.class){
+ val = Double.valueOf(val.toString()).longValue();
+ }else if (valType == Double.class){
+ val = Double.valueOf(val.toString());
+ }else if (valType == Float.class){
+ val = Float.valueOf(val.toString());
+ }else if (valType == Date.class){
+ val = DateUtil.getJavaDate((Double)val);
+ }else{
+ if (ef.fieldType() != Class.class){
+ val = ef.fieldType().getMethod("getValue", String.class).invoke(null, val.toString());
+ }else{
+ val = Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(),
+ "fieldtype."+valType.getSimpleName()+"Type")).getMethod("getValue", String.class).invoke(null, val.toString());
+ }
+ }
+ } catch (Exception ex) {
+ log.info("Get cell value ["+i+","+column+"] error: " + ex.toString());
+ val = null;
+ }
+ // set entity value
+ if (os[1] instanceof Field){
+ Reflections.invokeSetter(e, ((Field)os[1]).getName(), val);
+ }else if (os[1] instanceof Method){
+ String mthodName = ((Method)os[1]).getName();
+ if ("get".equals(mthodName.substring(0, 3))){
+ mthodName = "set"+StringUtils.substringAfter(mthodName, "get");
+ }
+ Reflections.invokeMethod(e, mthodName, new Class[] {valType}, new Object[] {val});
+ }
+ }
+ sb.append(val+", ");
+ }
+ dataList.add(e);
+ log.debug("Read success: ["+i+"] "+sb.toString());
+ }
+ return dataList;
+ }
+
+ /**
+ * 鍏抽棴娴� 娓呯悊涓存椂鏂囦欢
+ */
+ public void dispose(){
+ try {
+ if(wb!=null){
+ wb.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/server/services/src/main/java/com/doumee/core/annotation/excel/Reflections.java b/server/services/src/main/java/com/doumee/core/annotation/excel/Reflections.java
new file mode 100644
index 0000000..044dc97
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/excel/Reflections.java
@@ -0,0 +1,294 @@
+package com.doumee.core.annotation.excel;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.Validate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.Assert;
+
+import java.lang.reflect.*;
+
+/**
+ * 鍙嶅皠宸ュ叿绫�.
+ * 鎻愪緵璋冪敤getter/setter鏂规硶, 璁块棶绉佹湁鍙橀噺, 璋冪敤绉佹湁鏂规硶, 鑾峰彇娉涘瀷绫诲瀷Class, 琚獳OP杩囩殑鐪熷疄绫荤瓑宸ュ叿鍑芥暟.
+ */
+@SuppressWarnings("rawtypes")
+public class Reflections {
+
+ private static final String SETTER_PREFIX = "set";
+
+ private static final String GETTER_PREFIX = "get";
+
+ private static final String CGLIB_CLASS_SEPARATOR = "$$";
+
+ private static Logger logger = LoggerFactory.getLogger(Reflections.class);
+
+ /**
+ * 璋冪敤Getter鏂规硶.
+ * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶
+ */
+ public static Object invokeGetter(Object obj, String propertyName) {
+ Object object = obj;
+ for (String name : StringUtils.split(propertyName, ".")){
+ String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
+ object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
+ }
+ return object;
+ }
+
+ /**
+ * 璋冪敤Setter鏂规硶, 浠呭尮閰嶆柟娉曞悕銆�
+ * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶
+ */
+ public static void invokeSetter(Object obj, String propertyName, Object value) {
+ Object object = obj;
+ String[] names = StringUtils.split(propertyName, ".");
+ for (int i=0; i<names.length; i++){
+ if(i<names.length-1){
+ String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
+ object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
+ }else{
+ String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
+ invokeMethodByName(object, setterMethodName, new Object[] { value });
+ }
+ }
+ }
+
+ /**
+ * 鐩存帴璇诲彇瀵硅薄灞炴�у��, 鏃犺private/protected淇グ绗�, 涓嶇粡杩噂etter鍑芥暟.
+ */
+ public static Object getFieldValue(final Object obj, final String fieldName) {
+ Field field = getAccessibleField(obj, fieldName);
+
+ if (field == null) {
+ throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
+ }
+
+ Object result = null;
+ try {
+ result = field.get(obj);
+ } catch (IllegalAccessException e) {
+ logger.error("闈炴硶璁块棶鐨勫紓甯竰}", e.getMessage());
+ }
+ return result;
+ }
+
+ /**
+ * 鐩存帴璁剧疆瀵硅薄灞炴�у��, 鏃犺private/protected淇グ绗�, 涓嶇粡杩噑etter鍑芥暟.
+ */
+ public static void setFieldValue(final Object obj, final String fieldName, final Object value) {
+ Field field = getAccessibleField(obj, fieldName);
+
+ if (field == null) {
+ throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");
+ }
+
+ try {
+ field.set(obj, value);
+ } catch (IllegalAccessException e) {
+ logger.error("闈炴硶璁块棶鐨勫紓甯�:{}", e.getMessage());
+ }
+ }
+
+ /**
+ * 鐩存帴璋冪敤瀵硅薄鏂规硶, 鏃犺private/protected淇グ绗�.
+ * 鐢ㄤ簬涓�娆℃�ц皟鐢ㄧ殑鎯呭喌锛屽惁鍒欏簲浣跨敤getAccessibleMethod()鍑芥暟鑾峰緱Method鍚庡弽澶嶈皟鐢�.
+ * 鍚屾椂鍖归厤鏂规硶鍚�+鍙傛暟绫诲瀷锛�
+ */
+ public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
+ final Object[] args) {
+ Method method = getAccessibleMethod(obj, methodName, parameterTypes);
+ if (method == null) {
+ throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
+ }
+
+ try {
+ return method.invoke(obj, args);
+ } catch (Exception e) {
+ throw convertReflectionExceptionToUnchecked(e);
+ }
+ }
+
+ /**
+ * 鐩存帴璋冪敤瀵硅薄鏂规硶, 鏃犺private/protected淇グ绗︼紝
+ * 鐢ㄤ簬涓�娆℃�ц皟鐢ㄧ殑鎯呭喌锛屽惁鍒欏簲浣跨敤getAccessibleMethodByName()鍑芥暟鑾峰緱Method鍚庡弽澶嶈皟鐢�.
+ * 鍙尮閰嶅嚱鏁板悕锛屽鏋滄湁澶氫釜鍚屽悕鍑芥暟璋冪敤绗竴涓��
+ */
+ public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) {
+ Method method = getAccessibleMethodByName(obj, methodName);
+ if (method == null) {
+ throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
+ }
+
+ try {
+ return method.invoke(obj, args);
+ } catch (Exception e) {
+ throw convertReflectionExceptionToUnchecked(e);
+ }
+ }
+
+ /**
+ * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredField, 骞跺己鍒惰缃负鍙闂�.
+ *
+ * 濡傚悜涓婅浆鍨嬪埌Object浠嶆棤娉曟壘鍒�, 杩斿洖null.
+ */
+ public static Field getAccessibleField(final Object obj, final String fieldName) {
+ Validate.notNull(obj, "object can't be null");
+ Validate.notBlank(fieldName, "fieldName can't be blank");
+ for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
+ try {
+ Field field = superClass.getDeclaredField(fieldName);
+ makeAccessible(field);
+ return field;
+ } catch (NoSuchFieldException e) {//NOSONAR
+ // Field涓嶅湪褰撳墠绫诲畾涔�,缁х画鍚戜笂杞瀷
+ continue;// new add
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredMethod,骞跺己鍒惰缃负鍙闂�.
+ * 濡傚悜涓婅浆鍨嬪埌Object浠嶆棤娉曟壘鍒�, 杩斿洖null.
+ * 鍖归厤鍑芥暟鍚�+鍙傛暟绫诲瀷銆�
+ *
+ * 鐢ㄤ簬鏂规硶闇�瑕佽澶氭璋冪敤鐨勬儏鍐�. 鍏堜娇鐢ㄦ湰鍑芥暟鍏堝彇寰桵ethod,鐒跺悗璋冪敤Method.invoke(Object obj, Object... args)
+ */
+ public static Method getAccessibleMethod(final Object obj, final String methodName,
+ final Class<?>... parameterTypes) {
+ Validate.notNull(obj, "object can't be null");
+ Validate.notBlank(methodName, "methodName can't be blank");
+
+ for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {
+ try {
+ Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
+ makeAccessible(method);
+ return method;
+ } catch (NoSuchMethodException e) {
+ // Method涓嶅湪褰撳墠绫诲畾涔�,缁х画鍚戜笂杞瀷
+ continue;// new add
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredMethod,骞跺己鍒惰缃负鍙闂�.
+ * 濡傚悜涓婅浆鍨嬪埌Object浠嶆棤娉曟壘鍒�, 杩斿洖null.
+ * 鍙尮閰嶅嚱鏁板悕銆�
+ *
+ * 鐢ㄤ簬鏂规硶闇�瑕佽澶氭璋冪敤鐨勬儏鍐�. 鍏堜娇鐢ㄦ湰鍑芥暟鍏堝彇寰桵ethod,鐒跺悗璋冪敤Method.invoke(Object obj, Object... args)
+ */
+ public static Method getAccessibleMethodByName(final Object obj, final String methodName) {
+ Validate.notNull(obj, "object can't be null");
+ Validate.notBlank(methodName, "methodName can't be blank");
+
+ for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {
+ Method[] methods = searchType.getDeclaredMethods();
+ for (Method method : methods) {
+ if (method.getName().equals(methodName)) {
+ makeAccessible(method);
+ return method;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 鏀瑰彉private/protected鐨勬柟娉曚负public锛屽敖閲忎笉璋冪敤瀹為檯鏀瑰姩鐨勮鍙ワ紝閬垮厤JDK鐨凷ecurityManager鎶辨�ㄣ��
+ */
+ public static void makeAccessible(Method method) {
+ if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
+ && !method.isAccessible()) {
+ method.setAccessible(true);
+ }
+ }
+
+ /**
+ * 鏀瑰彉private/protected鐨勬垚鍛樺彉閲忎负public锛屽敖閲忎笉璋冪敤瀹為檯鏀瑰姩鐨勮鍙ワ紝閬垮厤JDK鐨凷ecurityManager鎶辨�ㄣ��
+ */
+ public static void makeAccessible(Field field) {
+ if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier
+ .isFinal(field.getModifiers())) && !field.isAccessible()) {
+ field.setAccessible(true);
+ }
+ }
+
+ /**
+ * 閫氳繃鍙嶅皠, 鑾峰緱Class瀹氫箟涓0鏄庣殑娉涘瀷鍙傛暟鐨勭被鍨�, 娉ㄦ剰娉涘瀷蹇呴』瀹氫箟鍦ㄧ埗绫诲
+ * 濡傛棤娉曟壘鍒�, 杩斿洖Object.class.
+ * eg.
+ * public UserDao extends HibernateDao<User>
+ *
+ * @param clazz The class to introspect
+ * @return the first generic declaration, or Object.class if cannot be determined
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Class<T> getClassGenricType(final Class clazz) {
+ return getClassGenricType(clazz, 0);
+ }
+
+ /**
+ * 閫氳繃鍙嶅皠, 鑾峰緱Class瀹氫箟涓0鏄庣殑鐖剁被鐨勬硾鍨嬪弬鏁扮殑绫诲瀷.
+ * 濡傛棤娉曟壘鍒�, 杩斿洖Object.class.
+ *
+ * 濡俻ublic UserDao extends HibernateDao<User,Long>
+ *
+ * @param clazz clazz The class to introspect
+ * @param index the Index of the generic ddeclaration,start from 0.
+ * @return the index generic declaration, or Object.class if cannot be determined
+ */
+ public static Class getClassGenricType(final Class clazz, final int index) {
+
+ Type genType = clazz.getGenericSuperclass();
+
+ if (!(genType instanceof ParameterizedType)) {
+ logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
+ return Object.class;
+ }
+
+ Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
+
+ if (index >= params.length || index < 0) {
+ logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
+ + params.length);
+ return Object.class;
+ }
+ if (!(params[index] instanceof Class)) {
+ logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
+ return Object.class;
+ }
+
+ return (Class) params[index];
+ }
+
+ public static Class<?> getUserClass(Object instance) {
+ Assert.notNull(instance, "Instance must not be null");
+ Class clazz = instance.getClass();
+ if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
+ Class<?> superClass = clazz.getSuperclass();
+ if (superClass != null && !Object.class.equals(superClass)) {
+ return superClass;
+ }
+ }
+ return clazz;
+
+ }
+
+ /**
+ * 灏嗗弽灏勬椂鐨刢hecked exception杞崲涓簎nchecked exception.
+ */
+ public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) {
+ if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException
+ || e instanceof NoSuchMethodException) {
+ return new IllegalArgumentException(e);
+ } else if (e instanceof InvocationTargetException) {
+ return new RuntimeException(((InvocationTargetException) e).getTargetException());
+ } else if (e instanceof RuntimeException) {
+ return (RuntimeException) e;
+ }
+ return new RuntimeException("Unexpected Checked Exception.", e);
+ }
+}
\ No newline at end of file
diff --git a/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeat.java b/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeat.java
new file mode 100644
index 0000000..64ecc64
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeat.java
@@ -0,0 +1,45 @@
+package com.doumee.core.annotation.pr;
+
+import java.lang.annotation.*;
+
+/**
+ * 闃查噸澶嶆彁浜ゆ敞瑙�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Inherited
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PreventRepeat {
+
+ /**
+ * 闃查噸澶嶈鍒欒瀹氱被
+ */
+ Class value() default PreventRepeatDefaultHandler.class;
+
+ /**
+ * 闂撮殧鏃堕棿(ms)锛屽皬浜庢鏃堕棿瑙嗕负閲嶅鎻愪氦
+ */
+ int interval() default 800;
+
+ /**
+ * 閿欒娑堟伅
+ */
+ String message() default "";
+
+ /**
+ * 1鍒嗛挓鍐呴檺鍒剁殑璇锋眰娆℃暟锛�<=0鏃惰〃绀轰笉闄愬埗锛�
+ */
+ int limit() default 0;
+
+ /**
+ * 琚檺鍒舵椂鐨勯敊璇秷鎭�
+ */
+ String limitMessage() default "";
+
+ /**
+ * 瓒呭嚭璇锋眰闄愬埗娆℃暟鏃堕攣瀹氱殑鏃堕暱(ms)
+ */
+ int lockTime() default 600000;
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatAdapter.java b/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatAdapter.java
new file mode 100644
index 0000000..14c3a76
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatAdapter.java
@@ -0,0 +1,107 @@
+package com.doumee.core.annotation.pr;
+
+import com.doumee.service.common.CacheProxy;
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * 闃查噸澶嶆彁浜ゅ疄鐜版帴鍙�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public abstract class PreventRepeatAdapter {
+
+ // 璇锋眰Key鍓嶇紑
+ private static final String REQUEST_KEY_PREFIX = "eva:pr:";
+
+ // 鏆村姏璇锋眰Key鍓嶇紑
+ private static final String MASSIVE_KEY_PREFIX = "eva:massive:";
+
+ @Autowired
+ private CacheProxy<String, Object> cacheProxy;
+
+ /**
+ * 楠岃瘉鏄惁閲嶅
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @param interval 闂撮殧
+ * @return Boolean
+ */
+ public Boolean prevent(HttpServletRequest request, int interval) {
+ String requestKey = REQUEST_KEY_PREFIX + this.sign(request);
+ boolean isRepeat = cacheProxy.get(requestKey) != null;
+ if (!isRepeat) {
+ cacheProxy.put(requestKey, System.currentTimeMillis(), Long.valueOf(interval));
+ }
+ return isRepeat;
+ }
+
+ /**
+ * 楠岃瘉鏄惁鏆村姏娑屽叆
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @param maxFreq 鍙涓轰繚鐣欒姹傜殑棰戠巼
+ * @param lockTime 閿佸畾鏃堕棿
+ * @return Boolean
+ */
+ public Boolean massive (HttpServletRequest request, int maxFreq, int lockTime) {
+ String massiveKey = MASSIVE_KEY_PREFIX + this.sign(request);
+ Object unit = cacheProxy.get(massiveKey);
+ if (unit == null) {
+ cacheProxy.put(massiveKey, new MassiveUnit(maxFreq, lockTime), 60);
+ return Boolean.FALSE;
+ }
+ MassiveUnit massiveUnit = (MassiveUnit) unit;
+ if (massiveUnit.getLock() == 1) {
+ return Boolean.TRUE;
+ }
+ if (massiveUnit.getFreq() >= massiveUnit.getMaxFreq()) {
+ massiveUnit.setLock((byte)1);
+ cacheProxy.put(massiveKey, massiveUnit, Long.valueOf(massiveUnit.getLockTime()));
+ return Boolean.TRUE;
+ }
+ massiveUnit.increment();
+ cacheProxy.put(massiveKey, massiveUnit);
+ return Boolean.FALSE;
+ }
+
+
+ /**
+ * 鍙傛暟绛惧悕
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @return String
+ */
+ public abstract String sign (HttpServletRequest request);
+
+ /**
+ * 鏆村姏楠岃瘉鍗曞厓
+ */
+ @Data
+ static class MassiveUnit implements Serializable {
+
+ private byte lock = 0;
+
+ // 璇锋眰棰戠巼
+ private int freq = 1;
+
+ // 鏈�楂橀鐜�
+ private int maxFreq;
+
+ // 閿佸畾鏃堕暱
+ private int lockTime;
+
+ MassiveUnit (int maxFreq, int lockTime) {
+ this.maxFreq = maxFreq;
+ this.lockTime = lockTime;
+ }
+
+ void increment () {
+ this.freq++;
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatDefaultHandler.java b/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatDefaultHandler.java
new file mode 100644
index 0000000..780998d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatDefaultHandler.java
@@ -0,0 +1,50 @@
+package com.doumee.core.annotation.pr;
+
+import com.doumee.core.servlet.ServletDuplicateInputStream;
+import com.doumee.core.utils.Utils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.util.DigestUtils;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 榛樿闃查噸澶嶆彁浜ゅ疄鐜�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+public class PreventRepeatDefaultHandler extends PreventRepeatAdapter {
+
+ @Override
+ public String sign(HttpServletRequest request) {
+ // 鑾峰彇鍙傛暟
+ Map<String, Object> parameters = this.getParameters(request);
+ // 鏋勫缓鍙傛暟绛惧悕瀛楃涓�
+ StringBuilder signString = new StringBuilder();
+ for(String key : parameters.keySet()) {
+ signString.append(key).append("=").append(parameters.get(key)).append(";");
+ }
+ // 鍙傛暟绛惧悕
+ return DigestUtils.md5DigestAsHex(signString.toString().getBytes());
+ }
+
+ /**
+ * 鑾峰彇鍙傛暟
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @return Map<String, Object>
+ */
+ private Map<String, Object> getParameters(HttpServletRequest request) {
+ HashMap<String, Object> paramMap = new HashMap<>();
+ paramMap.put("REQUEST_URI", request.getRequestURI());
+ paramMap.put("USER_TOKEN", String.valueOf(request.getHeader("doumee-auth-token")));
+ paramMap.put("IP", Utils.User_Client.getIP(request));
+ return paramMap;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatInterceptor.java b/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatInterceptor.java
new file mode 100644
index 0000000..7599f61
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatInterceptor.java
@@ -0,0 +1,79 @@
+package com.doumee.core.annotation.pr;
+
+import com.alibaba.fastjson.JSON;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.constants.ResponseStatus;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+
+/**
+ * 闃查噸澶嶆彁浜ゅ鐞�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+public class PreventRepeatInterceptor extends HandlerInterceptorAdapter {
+
+ private static ApplicationContext applicationContext;
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+ if (!(handler instanceof HandlerMethod)) {
+ return Boolean.TRUE;
+ }
+ try {
+ HandlerMethod handlerMethod = (HandlerMethod) handler;
+ Method method = handlerMethod.getMethod();
+ PreventRepeat prAnnotation = method.getAnnotation(PreventRepeat.class);
+ // 鎺ュ彛鏈坊鍔犻槻閲嶅鎻愪氦娉ㄨВ
+ if (prAnnotation == null) {
+ return Boolean.TRUE;
+ }
+ // 鑾峰彇楠岃瘉瀵硅薄鍜屾柟娉�
+ PreventRepeatAdapter adapter = (PreventRepeatAdapter)applicationContext.getBean(prAnnotation.value());
+ // 楠岃瘉鏆村姏璇锋眰
+ if(prAnnotation.limit() > 0 && prAnnotation.lockTime() > 0 && adapter.massive(request, prAnnotation.limit(), prAnnotation.lockTime())) {
+ log.warn("Eva Intercept a massive request锛寀rl锛歿}", request.getRequestURI());
+ response.setHeader("content-type", "application/json;charset=UTF-8");
+ ApiResponse apiResponse = ApiResponse.failed(ResponseStatus.MASSIVE_REQUEST);
+ if (!"".equals(prAnnotation.message())) {
+ apiResponse.setMessage(prAnnotation.message());
+ }
+ response.getWriter().write(JSON.toJSONString(apiResponse));
+ return Boolean.FALSE;
+ }
+ // 楠岃瘉閲嶅璇锋眰
+ if(prAnnotation.interval() > 0 && adapter.prevent(request, prAnnotation.interval())) {
+ log.warn("Eva Intercept a repeat request锛寀rl锛歿}", request.getRequestURI());
+ response.setHeader("content-type", "application/json;charset=UTF-8");
+ ApiResponse apiResponse = ApiResponse.failed(ResponseStatus.REPEAT_REQUEST);
+ if (!"".equals(prAnnotation.limitMessage())) {
+ apiResponse.setMessage(prAnnotation.limitMessage());
+ }
+ response.getWriter().write(JSON.toJSONString(apiResponse));
+ return Boolean.FALSE;
+ }
+ } catch (Exception e) {
+ log.warn("Eva @PreventRepeat throw an exception, you can get detail message by debug mode");
+ log.debug(e.getMessage(), e);
+ }
+ return Boolean.TRUE;
+ }
+
+ @Autowired
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ if (PreventRepeatInterceptor.applicationContext == null) {
+ PreventRepeatInterceptor.applicationContext = applicationContext;
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatInterceptorConfig.java b/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatInterceptorConfig.java
new file mode 100644
index 0000000..862fdb5
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/pr/PreventRepeatInterceptorConfig.java
@@ -0,0 +1,23 @@
+package com.doumee.core.annotation.pr;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * Swagger鎷︽埅鍣ㄩ厤缃�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Configuration
+public class PreventRepeatInterceptorConfig implements WebMvcConfigurer {
+
+ @Autowired
+ private PreventRepeatInterceptor preventRepeatInterceptor;
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(preventRepeatInterceptor).addPathPatterns("/**");
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/trace/Trace.java b/server/services/src/main/java/com/doumee/core/annotation/trace/Trace.java
new file mode 100644
index 0000000..099b8d2
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/trace/Trace.java
@@ -0,0 +1,44 @@
+package com.doumee.core.annotation.trace;
+
+import java.lang.annotation.*;
+
+/**
+ * 璺熻釜鏃ュ織娉ㄨВ
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Trace {
+
+ /**
+ * 妯″潡鍚嶇О
+ */
+ String module() default "";
+
+ /**
+ * 鎿嶄綔绫诲瀷
+ */
+ TraceType type() default TraceType.AUTO;
+
+ /**
+ * 澶囨敞锛屽鏋滀负绌猴紝鍒欎粠鎿嶄綔绫诲瀷涓鍙栧娉�
+ */
+ String remark() default "";
+
+ /**
+ * 鏄惁涓嶅仛鏃ュ織璁板綍
+ */
+ boolean exclude() default false;
+
+ /**
+ * 鏄惁璁板綍璇锋眰鍙傛暟
+ */
+ boolean withRequestParameters() default true;
+
+ /**
+ * 鏄惁璁板綍璇锋眰缁撴灉
+ */
+ boolean withRequestResult () default true;
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/trace/TraceInterceptor.java b/server/services/src/main/java/com/doumee/core/annotation/trace/TraceInterceptor.java
new file mode 100644
index 0000000..b68e4c1
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/trace/TraceInterceptor.java
@@ -0,0 +1,396 @@
+package com.doumee.core.annotation.trace;
+
+import com.alibaba.fastjson.JSON;
+import com.doumee.core.config.ProjectConfig;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.core.model.LoginUserInfo;
+import com.doumee.core.servlet.ServletDuplicateInputStream;
+import com.doumee.core.servlet.ServletDuplicateOutputStream;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.model.SystemTraceLog;
+import com.doumee.service.system.SystemTraceLogService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpMethod;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Date;
+
+/**
+ * 璺熻釜鏃ュ織澶勭悊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+public class TraceInterceptor extends HandlerInterceptorAdapter {
+
+ @Autowired
+ private ProjectConfig projectConfig;
+
+ @Value("${trace.exclude-patterns:}")
+ private String excludePatterns;
+
+ @Value("${trace.smart}")
+ private Boolean isSmart;
+
+ private static final String ATTRIBUTE_TRACE_ID = "eva-trace-id";
+
+ private static final String ATTRIBUTE_TRACE_TIME = "eva-trace-time";
+
+ private static final int MAX_STORE_REQUEST_PARAM_SIZE = 1888;
+
+ private static final int MAX_STORE_REQUEST_RESULT_SIZE = 1888;
+
+ private static final int MAX_STORE_EXCEPTION_STACK_SIZE = 4888;
+
+ private static final String MORE_DETAIL_STRING = "\n\n---------- more content is ignore here ... ----------\n\n";
+
+ @Autowired
+ private SystemTraceLogService systemTraceLogService;
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+ try {
+ if (!(handler instanceof HandlerMethod) || !(request instanceof ShiroHttpServletRequest)) {
+ return Boolean.TRUE;
+ }
+ if (!this.allowTrace(request, handler)) {
+ return Boolean.TRUE;
+ }
+ SystemTraceLog traceLog = new SystemTraceLog();
+ Date now = new Date();
+ HandlerMethod handlerMethod = (HandlerMethod) handler;
+ Method method = handlerMethod.getMethod();
+ Trace methodTrace = method.getAnnotation(Trace.class);
+ Trace classTrace = method.getDeclaringClass().getAnnotation(Trace.class);
+ // 鑾峰彇璺熻釜绫诲瀷
+ TraceType traceType = methodTrace == null ? null : methodTrace.type();
+ if (traceType == null) {
+ traceType = this.smartType(request);
+ }
+ // 鐢ㄦ埛淇℃伅
+ LoginUserInfo userInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
+ if (userInfo != null) {
+ traceLog.setUserId(userInfo.getId());
+ traceLog.setUsername(userInfo.getUsername());
+ traceLog.setUserRealname(userInfo.getRealname());
+ traceLog.setUserRoles(StringUtils.join(userInfo.getRoles(), ","));
+ traceLog.setUserPermissions(StringUtils.join(userInfo.getPermissions(), ","));
+ }
+ // 鎿嶄綔淇℃伅
+ traceLog.setOperaModule(this.getModule(handler));
+ traceLog.setOperaType(traceType.getType());
+ traceLog.setOperaRemark(this.getOperaRemark(handler, traceType));
+ traceLog.setOperaTime(now);
+ // 璇锋眰淇℃伅
+ traceLog.setRequestUri(request.getRequestURI());
+ traceLog.setRequestMethod(request.getMethod());
+ if (methodTrace == null || methodTrace.withRequestParameters() || (classTrace != null && classTrace.withRequestParameters())) {
+ String requestParameters = request.getQueryString();
+ if (HttpMethod.POST.matches(request.getMethod())) {
+ requestParameters = ((ServletDuplicateInputStream)request.getInputStream()).getBody();
+ }
+ traceLog.setRequestParams(
+ requestParameters != null && requestParameters.length() > MAX_STORE_REQUEST_PARAM_SIZE
+ ? requestParameters.substring(0, MAX_STORE_REQUEST_PARAM_SIZE) + MORE_DETAIL_STRING
+ : requestParameters
+ );
+ }
+ // 杈呭姪淇℃伅
+ traceLog.setServerIp(Utils.Server.getIP());
+ traceLog.setIp(Utils.User_Client.getIP(request));
+ traceLog.setSystemVersion(projectConfig.getVersion());
+ traceLog.setPlatform(Utils.User_Client.getPlatform(request));
+ traceLog.setClientInfo(Utils.User_Client.getBrowser(request));
+ traceLog.setOsInfo(Utils.User_Client.getOS(request));
+ systemTraceLogService.create(traceLog);
+ request.setAttribute(ATTRIBUTE_TRACE_ID, traceLog.getId());
+ request.setAttribute(ATTRIBUTE_TRACE_TIME, now.getTime());
+ } catch (Exception e) {
+ log.warn("Eva @Trace throw an exception, you can get detail message by debug mode.");
+ log.debug(e.getMessage(), e);
+ }
+ return Boolean.TRUE;
+ }
+
+ @Override
+ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws IOException {
+ // 鑾峰彇璺熻釜ID
+ Object traceId = request.getAttribute(ATTRIBUTE_TRACE_ID);
+ Object traceTime = request.getAttribute(ATTRIBUTE_TRACE_TIME);
+ request.removeAttribute(ATTRIBUTE_TRACE_ID);
+ request.removeAttribute(ATTRIBUTE_TRACE_TIME);
+ if (traceId == null) {
+ return;
+ }
+ // 璁$畻鎿嶄綔鑰楁椂
+ SystemTraceLog traceLog = new SystemTraceLog();
+ traceLog.setId(Integer.valueOf(traceId.toString()));
+ traceLog.setOperaSpendTime(Integer.valueOf("" + (System.currentTimeMillis() - Long.valueOf(traceTime.toString()))));
+ // 璁板綍鎿嶄綔鏃ュ織鐘舵��
+ String operaType = response.getHeader("doumee-opera-type");
+ // - 涓嬭浇鎺ュ彛澶勭悊锛屾棤闇�璁板綍鍝嶅簲鍐呭
+ if ("download".equals(operaType)) {
+ handleDownloadResponse(traceLog, ex);
+ return;
+ }
+ // - 杩斿洖json鐨勬帴鍙e鐞�
+ handleJsonResponse(traceLog, response, handler, ex);
+ }
+
+ /**
+ * JSON鍝嶅簲澶勭悊
+ */
+ private void handleJsonResponse(SystemTraceLog traceLog, HttpServletResponse response, Object handler, Exception ex) throws IOException {
+ HandlerMethod handlerMethod = (HandlerMethod) handler;
+ Method method = handlerMethod.getMethod();
+ Trace methodTrace = method.getAnnotation(Trace.class);
+ Trace classTrace = method.getDeclaringClass().getAnnotation(Trace.class);
+ String responseBody = ((ServletDuplicateOutputStream) response.getOutputStream()).getContent();
+ ApiResponse apiResponse = null;
+ try {
+ apiResponse = JSON.parseObject(responseBody, ApiResponse.class);
+ } catch (Exception e) {
+ }
+ // 璁板綍鍝嶅簲缁撴灉
+ if (methodTrace == null || methodTrace.withRequestResult() || (classTrace != null && classTrace.withRequestResult())) {
+ String requestResult = responseBody;
+ if (apiResponse != null) {
+ // 鎺掗櫎exception淇℃伅
+ String e = apiResponse.getException();
+ apiResponse.setException(null);
+ requestResult = JSON.toJSONString(apiResponse);
+ apiResponse.setException(e);
+ }
+ traceLog.setRequestResult(
+ requestResult != null && requestResult.length() > MAX_STORE_REQUEST_RESULT_SIZE
+ ? requestResult.substring(0, MAX_STORE_REQUEST_RESULT_SIZE) + MORE_DETAIL_STRING
+ : requestResult
+ );
+ }
+ // 璇锋眰鎴愬姛
+ if (ex == null && (apiResponse != null && apiResponse.isSuccess())) {
+ traceLog.setStatus(TraceStatus.SUCCESS.getCode());
+ systemTraceLogService.updateById(traceLog);
+ return;
+ }
+ // 璇锋眰澶辫触
+ traceLog.setStatus(TraceStatus.FAILED.getCode());
+ String exceptionStack = null;
+ // 鍏ㄥ眬鎹曡幏鍒扮殑鏈鐞嗙殑寮傚父
+ if (apiResponse != null && apiResponse.getException() != null) {
+ exceptionStack = apiResponse.getException();
+ traceLog.setExceptionLevel(Constants.ExceptionLevel.DANGER.getLevel());
+ }
+ // 鍏跺畠寮傚父鎯呭喌
+ if (exceptionStack == null) {
+ // 鏈崟鑾峰埌鐨勬湭澶勭悊鐨勫紓甯�
+ if (ex != null) {
+ StackTraceElement[] trace = ex.getStackTrace();
+ StringBuilder exception = new StringBuilder(ex + "\n");
+ for (StackTraceElement traceElement : trace) {
+ exception.append("\tat ").append(traceElement).append("\n");
+ }
+ exceptionStack = exception.toString();
+ traceLog.setExceptionLevel(Constants.ExceptionLevel.DANGER.getLevel());
+ }
+ // 涓氬姟寮傚父
+ else if (apiResponse != null) {
+ traceLog.setExceptionLevel(Constants.ExceptionLevel.LOW.getLevel());
+ exceptionStack = apiResponse.getMessage();
+ }
+ // 鍝嶅簲鏍煎紡闈濲SON鐨勫紓甯革紙鍦ㄨ璁¤搴︿笂锛岃繖绫绘帴鍙d笉搴旇褰曟搷浣滄棩蹇楋紝姝ゅ鍋氫竴涓鍛婂鐞嗭級
+ else {
+ traceLog.setExceptionLevel(Constants.ExceptionLevel.WARN.getLevel());
+ exceptionStack = responseBody;
+ }
+ }
+ traceLog.setExceptionStack(
+ exceptionStack != null && exceptionStack.length() > MAX_STORE_EXCEPTION_STACK_SIZE
+ ? exceptionStack.substring(0, MAX_STORE_EXCEPTION_STACK_SIZE) + MORE_DETAIL_STRING
+ : exceptionStack);
+ systemTraceLogService.updateById(traceLog);
+ }
+
+ /**
+ * 涓嬭浇鍝嶅簲澶勭悊
+ *
+ * @param traceLog 璺熻釜鏃ュ織
+ * @param ex 寮傚父
+ */
+ private void handleDownloadResponse (SystemTraceLog traceLog, Exception ex) {
+ if (ex == null) {
+ traceLog.setStatus(TraceStatus.SUCCESS.getCode());
+ systemTraceLogService.updateById(traceLog);
+ return;
+ }
+ // 鍑虹幇寮傚父
+ traceLog.setStatus(TraceStatus.FAILED.getCode());
+ StackTraceElement[] trace = ex.getStackTrace();
+ StringBuilder exception = new StringBuilder(ex + "\n");
+ for (StackTraceElement traceElement : trace) {
+ exception.append("\tat ").append(traceElement).append("\n");
+ }
+ traceLog.setExceptionStack(exception.length() > MAX_STORE_EXCEPTION_STACK_SIZE
+ ? exception.substring(0, MAX_STORE_EXCEPTION_STACK_SIZE) + MORE_DETAIL_STRING
+ : exception.toString());
+ traceLog.setExceptionLevel(Constants.ExceptionLevel.DANGER.getLevel());
+ systemTraceLogService.updateById(traceLog);
+ }
+
+ /**
+ * 鑾峰彇璺熻釜妯″潡
+ * 浠嶵race娉ㄨВ鎴朅pi娉ㄨВ涓幏鍙�
+ *
+ * @param handler 澶勭悊鍣�
+ * @return String
+ */
+ private String getModule (Object handler) {
+ HandlerMethod handlerMethod = (HandlerMethod) handler;
+ Method method = handlerMethod.getMethod();
+ // 浼樺厛璇诲彇鏂规硶涓婄殑@Trace妯″潡閰嶇疆锛屽鏋滄棤娉ㄨВ鎴栨棤澶囨敞锛屽垯璇诲彇绫讳笂@Trace妯″潡閰嶇疆
+ Trace trace = method.getAnnotation(Trace.class);
+ if (trace == null || "".equals(trace.module())) {
+ trace = method.getDeclaringClass().getAnnotation(Trace.class);
+ }
+ String module = "";
+ if (trace != null && StringUtils.isNotBlank(trace.module())) {
+ module = trace.module();
+ }
+ // 浠嶡Api娉ㄨВ涓鍙�
+ if (StringUtils.isBlank(module)) {
+ Api api = method.getDeclaringClass().getAnnotation(Api.class);
+ if (api != null) {
+ module = StringUtils.join(api.tags(), ", ");
+ }
+ }
+ return module;
+ }
+
+ /**
+ * 鑾峰彇鎿嶄綔澶囨敞
+ *
+ * @param handler 澶勭悊鍣�
+ * @param traceType 璺熻釜绫诲瀷
+ * @return String
+ */
+ private String getOperaRemark (Object handler, TraceType traceType) {
+ HandlerMethod handlerMethod = (HandlerMethod) handler;
+ Method method = handlerMethod.getMethod();
+ // 浠嶵race娉ㄨВ涓幏鍙�
+ Trace trace = method.getAnnotation(Trace.class);
+ if (trace != null && StringUtils.isNotBlank(trace.remark())) {
+ return trace.remark();
+ }
+ // 浠嶢piOperation娉ㄨВ涓幏鍙�
+ ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
+ if (apiOperation != null && StringUtils.isNotBlank(apiOperation.value())) {
+ return apiOperation.value();
+ }
+ return traceType.getRemark();
+ }
+
+ /**
+ * 鏄惁鍏佽璺熻釜
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @param handler 澶勭悊鍣�
+ * @return Boolean
+ */
+ private Boolean allowTrace (HttpServletRequest request, Object handler) {
+ HandlerMethod handlerMethod = (HandlerMethod) handler;
+ Method method = handlerMethod.getMethod();
+ Trace methodTrace = method.getAnnotation(Trace.class);
+ Trace classTrace = method.getDeclaringClass().getAnnotation(Trace.class);
+ // 闈炴櫤鑳芥ā寮�
+ if (!isSmart) {
+ if (methodTrace == null && classTrace == null) {
+ return Boolean.FALSE;
+ }
+ if (methodTrace == null && classTrace.exclude()) {
+ return Boolean.FALSE;
+ }
+ }
+ // 鏂规硶鎺掗櫎
+ if (methodTrace != null && methodTrace.exclude()) {
+ return Boolean.FALSE;
+ }
+ // 绫绘帓闄�
+ if (methodTrace == null && classTrace != null && classTrace.exclude()) {
+ return Boolean.FALSE;
+ }
+ // 璺緞鎺掗櫎
+ String[] patterns = excludePatterns.split(",");
+ if (methodTrace == null && patterns.length > 0) {
+ String uri = request.getRequestURI();
+ for (String pattern : patterns) {
+ if (uri.matches(pattern.trim())) {
+ return Boolean.FALSE;
+ }
+ }
+ }
+ return Boolean.TRUE;
+ }
+
+ /**
+ * 鑾峰彇璺熻釜绫诲瀷
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @return TraceType
+ */
+ private TraceType smartType (HttpServletRequest request) {
+ // 鎵归噺鍒犻櫎
+ if (request.getRequestURI().matches(smartPattern("delete/batch"))) {
+ return TraceType.DELETE_BATCH;
+ }
+ // 鍒犻櫎
+ if (request.getRequestURI().matches(smartPattern("delete"))) {
+ return TraceType.DELETE;
+ }
+ // 鏂板
+ if (request.getRequestURI().matches(smartPattern("create"))) {
+ return TraceType.CREATE;
+ }
+ // 淇敼
+ if (request.getRequestURI().matches(smartPattern("update"))) {
+ return TraceType.UPDATE;
+ }
+ // 瀵煎叆
+ if (request.getRequestURI().matches(smartPattern("import"))) {
+ return TraceType.IMPORT;
+ }
+ // 瀵煎嚭
+ if (request.getRequestURI().matches(smartPattern("exportData"))) {
+ return TraceType.EXPORT;
+ }
+ // 閲嶇疆
+ if (request.getRequestURI().matches(smartPattern("reset"))) {
+ return TraceType.RESET;
+ }
+ return TraceType.UNKNOWN;
+ }
+
+ /**
+ * 鑾峰彇鑷姩閫傞厤姝e垯
+ *
+ * @param keyword 璺緞鍏抽敭瀛�
+ * @return String
+ */
+ private String smartPattern (String keyword) {
+ return ".+/" + keyword + "[a-zA-Z0-9\\-\\_]*$";
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/trace/TraceInterceptorConfig.java b/server/services/src/main/java/com/doumee/core/annotation/trace/TraceInterceptorConfig.java
new file mode 100644
index 0000000..232243f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/trace/TraceInterceptorConfig.java
@@ -0,0 +1,23 @@
+package com.doumee.core.annotation.trace;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * 璺熻釜鎷︽埅鍣ㄩ厤缃�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Configuration
+public class TraceInterceptorConfig implements WebMvcConfigurer {
+
+ @Autowired
+ private TraceInterceptor logInterceptor;
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(logInterceptor).addPathPatterns("/**");
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/trace/TraceStatus.java b/server/services/src/main/java/com/doumee/core/annotation/trace/TraceStatus.java
new file mode 100644
index 0000000..b448bd6
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/trace/TraceStatus.java
@@ -0,0 +1,21 @@
+package com.doumee.core.annotation.trace;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 璺熻釜鐘舵��
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Getter
+@AllArgsConstructor
+public enum TraceStatus {
+ SUCCESS((int)1, "鎴愬姛"),
+ FAILED((int)0, "澶辫触"),
+ ;
+
+ private int code;
+
+ private String remark;
+}
diff --git a/server/services/src/main/java/com/doumee/core/annotation/trace/TraceType.java b/server/services/src/main/java/com/doumee/core/annotation/trace/TraceType.java
new file mode 100644
index 0000000..4b2d989
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/annotation/trace/TraceType.java
@@ -0,0 +1,34 @@
+package com.doumee.core.annotation.trace;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 璺熻釜绫诲瀷
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Getter
+@AllArgsConstructor
+public enum TraceType {
+ AUTO("AUTO", "鑷姩璇嗗埆"),
+ CREATE("CREATE", "鏂板缓"),
+ UPDATE("UPDATE", "淇敼"),
+ DELETE("DELETE", "鍒犻櫎"),
+ DELETE_BATCH("DELETE_BATCH", "鎵归噺鍒犻櫎"),
+ IMPORT("IMPORT", "瀵煎叆"),
+ EXPORT("EXPORT", "瀵煎嚭"),
+ RESET("RESET", "閲嶇疆"),
+ UNKNOWN("UNKNOWN", "鏈煡鎿嶄綔"),
+ ;
+
+ /**
+ * 璺熻釜绫诲瀷
+ */
+ private String type;
+
+ /**
+ * 璺熻釜澶囨敞
+ */
+ private String remark;
+}
diff --git a/server/services/src/main/java/com/doumee/core/config/ProjectConfig.java b/server/services/src/main/java/com/doumee/core/config/ProjectConfig.java
new file mode 100644
index 0000000..d078cdb
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/config/ProjectConfig.java
@@ -0,0 +1,45 @@
+package com.doumee.core.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 椤圭洰灞炴�ч厤缃�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "project", ignoreInvalidFields = true)
+public class ProjectConfig {
+
+ // 鐢熶骇鐜
+ private static final String ENV_PRODUCTION = "production";
+
+ // 娴嬭瘯妯″紡
+ private static final String MODE_TESTING = "testing";
+
+ // 妯″紡
+ private String mode;
+
+ // 鐜
+ private String env;
+
+ // 鐗堟湰
+ private String version;
+
+ /**
+ * 鍒ゆ柇鏄惁涓烘祴璇曟ā寮忥紝褰撳墠娴嬭瘯妯″紡涓嬪畬鎴愪互涓嬩簨椤�
+ * - 涓嶆牎楠岄獙璇佺爜
+ *
+ * @return boolean
+ */
+ public boolean isTestingMode () {
+ // 鐢熶骇鐜鏃犳祴璇曟ā寮�
+ if (ENV_PRODUCTION.equals(env)) {
+ return Boolean.FALSE;
+ }
+ return MODE_TESTING.equalsIgnoreCase(mode);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/constants/Constants.java b/server/services/src/main/java/com/doumee/core/constants/Constants.java
new file mode 100644
index 0000000..46e31ec
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/constants/Constants.java
@@ -0,0 +1,330 @@
+package com.doumee.core.constants;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.*;
+
+/**
+ * 妗嗘灦绾у父閲�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public class Constants {
+
+ public static final String AZURE_BLOB ="AZURE_BLOB" ;
+ public static final String AZURE_BLOB_ACCESSNAME ="AZURE_BLOB_ACCESSNAME" ;
+ public static final String AZURE_BLOB_ACCESSKEY ="AZURE_BLOB_ACCESSKEY" ;
+ public static final String AZURE_BLOB_ENDPOINT ="AZURE_BLOB_ENDPOINT" ;
+ public static final String AZURE_BLOB_CONTAINER ="AZURE_BLOB_CONTAINER" ;
+ public static final String FTP ="FTP" ;
+ public static final String FTP_HOST ="FTP_HOST" ;
+ public static final String FTP_PORT ="FTP_PORT" ;
+ public static final String FTP_USERNAME ="FTP_USERNAME" ;
+ public static final String FTP_PWD ="FTP_PWD" ;
+ public static final String FTP_RESOURCE_PATH ="FTP_RESOURCE_PATH" ;
+ public static final String FTP_LOCAL_RESOURCE_PATH ="FTP_LOCAL_RESOURCE_PATH" ;
+ public static final String QYWX_CORPID = "QYWX_CORPID";
+ public static final String QYWX_SECRET = "QYWX_SECRET";
+ public static final String QYWX_TOKEN = "QYWX_TOKEN";
+ public static final String QYWX_AGENTID = "QYWX_AGENTID";
+ public static final String QYWX_JS_API_TICKET = "QYWX_JS_API_TICKET";
+ public static final String JUMP_OUT_URL = "JUMP_OUT_URL";
+ public static final String SYSTEM ="SYSTEM" ;
+ public static final String IMG_DIR = "IMG_DIR";
+ public static final String FILE_DIR ="FILE_DIR" ;
+ public static final String FOOT_IMGURL ="FOOT_IMGURL" ;
+ public static final String LINK_PHONE ="LINK_PHONE" ;
+ public static final String LINK_MOBILE ="LINK_MOBILE" ;
+ public static final String SERVER_TIME ="SERVER_TIME" ;
+ public static final String ADDRESS ="ADDRESS" ;
+ public static final String SOLVE_SCHEME ="SOLVE_SCHEME" ;
+ public static final String WISDOM_SYSTEM ="WISDOM_SYSTEM" ;
+ public static final String FOOT_WORDS ="FOOT_WORDS" ;
+
+
+ public static final String QYWX = "QYWX";
+ public static final Integer ONE = 1;
+ public static final Integer TWO = 2;
+ public static final Integer ZERO = 0;
+ public static final Integer THREE = 3;
+ public static final Integer FOUR = 4;
+ public static final Integer SIX = 6;
+ public static final Integer FIVE = 5;
+ public static boolean WORKORDER_SHE_EMAIL_SENDING = false;
+ public static boolean DEALING_COMPANY_SYNC = false ;
+ public static boolean DEALING_MEMBER_SYNC = false ;
+ public static final String WORKORDER_FILE_PATH ="WORKORDER_FILE_PATH" ;
+ public static final String WORKORDER_LOG_FILE_PATH ="WORKORDER_LOG_FILE_PATH" ;
+
+ public static final String REDIS_TOKEN_KEY = "token_";
+ public interface uploadType{
+ String blob = "blob";
+ String ftp = "ftp";
+ }
+
+ /**
+ * 缂撳瓨Key
+ */
+ interface CacheKey {
+ }
+ public interface RedisKeys {
+ public static final String IMPORTING_CATEGORY = "IMPORTING_CATEGORY";
+ }
+ /**
+ * 鎿嶄綔绫诲瀷锛岀敤浜庡仛鎺ュ彛楠岃瘉鍒嗙粍
+ */
+ public interface OperaType {
+
+ /**
+ * 鍒涘缓
+ */
+ interface Create {}
+
+ /**
+ * 淇敼
+ */
+ interface Update {}
+
+ /**
+ * 淇敼鐘舵��
+ */
+ interface UpdateStatus {}
+ }
+
+
+ public static boolean equalsInteger(Integer a, Integer b) {
+ if (formatIntegerNum(a) == formatIntegerNum(b)) {
+ return true;
+ }
+ return false;
+ }
+
+ public static int formatIntegerNum(Integer d) {
+ if (d == null) {
+ d = 0;
+ }
+ return d.intValue();
+ }
+
+ public static long formatLongNum(Long d) {
+ if (d == null) {
+ d = 0L;
+ }
+ return d.longValue();
+ }
+
+ /**
+ * Job甯搁噺
+ */
+ public interface Job {
+
+ // jobId鍦↗OB瀹炰緥涓殑瀛樺偍鍙傛暟閿�
+ String JOB_DATA_MAP_JOB_ID = "JOB_ID";
+
+ /**
+ * JOB鐘舵��
+ */
+ @Getter
+ @AllArgsConstructor
+ enum JobStatus {
+ PAUSE( -1, "鏆傚仠"),
+ READY( 0, "宸插噯澶�"),
+ RUNNING( 1, "杩愯涓�"),
+ ;
+ private int code;
+ private String remark;
+ }
+
+ /**
+ * 鍒嗙墖鐘舵��
+ */
+ @Getter
+ @AllArgsConstructor
+ enum SnippetStatus {
+ READY((int) 0, "宸插噯澶�"),
+ RUNNING((int) 1, "杩愯涓�"),
+ SUCCESS((int) 2, "鎵ц鎴愬姛"),
+ FAILED((int) -2, "鎵ц澶辫触"),
+ ;
+ private int code;
+ private String remark;
+ }
+
+ /**
+ * 鍒嗙墖鐘舵��
+ */
+ @Getter
+ @AllArgsConstructor
+ enum LogStatus {
+ FAILED((int) 0, "鎵ц澶辫触"),
+ SUCCESS((int) 1, "鎵ц鎴愬姛"),
+ IGNORE((int) 2, "璺宠繃"),
+ NONE((int) -1, "鎵ц涓�"),
+ ;
+ private int code;
+ private String remark;
+ }
+
+ /**
+ * 瑙﹀彂绫诲瀷
+ */
+ @Getter
+ @AllArgsConstructor
+ enum TriggerType {
+ SYSTEM("SYSTEM", "绯荤粺"),
+ MANUAL("MANUAL", "鎵嬪姩"),
+ ;
+ private String code;
+ private String remark;
+ }
+ }
+
+ /**
+ * 璺熻釜鏃ュ織寮傚父绛夌骇
+ */
+ @Getter
+ @AllArgsConstructor
+ public enum ExceptionLevel {
+ DANGER((int)10, "楂�"),
+ WARN((int)5, "涓�"),
+ LOW((int)0, "浣�"),
+ ;
+
+ private int level;
+
+ private String remark;
+ }
+
+ /**
+ * MyBatis鑷姩娉ㄥ叆蹇界暐
+ */
+ public interface Ignore {
+ /**
+ * 蹇界暐鏃堕棿锛屽綋涓嶉渶瑕佹洿鏂癱reateTime/updateTime鏃讹紝鍙娇鐢ㄨ甯搁噺杩涜濉厖銆�
+ */
+ Date IGNORE_TIME = new IgnoreDate();
+
+ /**
+ * 蹇界暐鐢ㄦ埛锛屽綋涓嶉渶瑕佹洿鏂癱reateUser/updateUser鏃讹紝鍙娇鐢ㄨ甯搁噺杩涜濉厖銆�
+ */
+ Integer IGNORE_USER = -1;
+
+ /**
+ * 蹇界暐鏃堕棿绫�
+ */
+ class IgnoreDate extends Date {}
+ }
+
+
+ /**
+ * 鏂囦欢闄勪欢绫诲瀷
+ */
+ public interface multiFileType{
+ //0闂涓婃姤 1璺岀粖婊戜笂鎶� 2璺岀粖婊戝鐞� 3鍒嗛厤鐗╀笟涓荤 4鍒嗛厤澶勭悊浜� 5DCA椋庨櫓涓婃姤 6DCA椋庨櫓澶勭悊 7DCA闂宸ュ崟鍥剧墖
+// int sheUpload = 0;
+// int dbhUpload = 1;
+// int dbhDeal = 2;
+// int dbhAllocation = 3;
+// int dbhDealUser = 4;
+// int dcaUpload = 5;
+// int dcaDeal = 6;
+// int dcaWorkOrder= 7;
+
+ //0宸ュ崟涓婃姤 1宸ュ崟澶勭悊 2宸ュ崟杞氦
+ int upload = 0;
+ int deal = 1;
+ int passOn = 2;
+ }
+
+
+ public enum WorkOrderStatus{
+ waitConfirm( 0, "寰呭垎閰峎TS","{title}涓婃姤","","寰呭垎閰峎TS" ),
+ waitAllocation(1, "寰呭垎閰嶄换鍔�","寰呭垎閰嶄换鍔�","","寰呭垎閰嶄换鍔�"),
+ waitDeal(2, "寰呭鐞�","寰呭鐞�","","寰呭伐绋嬪笀澶勭悊"),
+ sheClose(3, "宸茶В鍐�","SHE宸插叧闂�","","SHE宸插叧闂�"),
+ wtsClose(4, "宸茶В鍐�","WTS宸插叧闂�","","WTS宸插叧闂�"),
+ close(5, "宸茶В鍐�","宸茶В鍐�","","宸ョ▼甯堝叧闂�"),
+ urge (6, "鍌績","","","")
+ ;
+
+ private int status;
+ private String statusInfo;
+ private String statusName;
+ private String logTitle;
+ private String noticeContent;
+
+ // 鏋勯�犳柟娉�
+ WorkOrderStatus(int status, String statusInfo,String logTitle,String noticeContent,String statusName ) {
+ this.status = status;
+ this.statusInfo = statusInfo;
+ this.logTitle = logTitle;
+ this.noticeContent = noticeContent;
+ this.statusName = statusName;
+ }
+ public static String getName(int index) {
+ for (WorkOrderStatus c : WorkOrderStatus.values()) {
+ if (c.getKey() == index) {
+ return c.statusInfo;
+ }
+ }
+ return null;
+ }
+ public static String getStatusName(int index) {
+ for (WorkOrderStatus c : WorkOrderStatus.values()) {
+ if (c.getKey() == index) {
+ return c.statusName;
+ }
+ }
+ return null;
+ }
+
+ public int getKey() {
+ return status;
+ }
+
+ public void setKey(int key) {
+ this.status = status;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public String getStatusName() {
+ return statusName;
+ }
+
+ public void setStatusName(String statusName) {
+ this.statusName = statusName;
+ }
+
+ public String getStatusInfo() {
+ return statusInfo;
+ }
+
+ public void setStatusInfo(String statusInfo) {
+ this.statusInfo = statusInfo;
+ }
+
+ public String getLogTitle() {
+ return logTitle;
+ }
+
+ public void setLogTitle(String logTitle) {
+ this.logTitle = logTitle;
+ }
+
+ public String getNoticeContent() {
+ return noticeContent;
+ }
+
+ public void setNoticeContent(String noticeContent) {
+ this.noticeContent = noticeContent;
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/constants/ResponseStatus.java b/server/services/src/main/java/com/doumee/core/constants/ResponseStatus.java
new file mode 100644
index 0000000..68680c8
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/constants/ResponseStatus.java
@@ -0,0 +1,37 @@
+package com.doumee.core.constants;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 鍝嶅簲鐘舵�佸畾涔�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Getter
+@AllArgsConstructor
+public enum ResponseStatus {
+ // 400寮�澶磋〃绀哄弬鏁伴敊璇�
+ BAD_REQUEST(4000, "鍙傛暟閿欒"),
+ DATA_EMPTY(4001, "鎵句笉鍒扮洰鏍囨暟鎹�"),
+ DATA_EXISTS(4002, "璁板綍宸插瓨鍦�"),
+ PWD_INCORRECT(4003, "瀵嗙爜涓嶆纭�"),
+ VERIFICATION_CODE_INCORRECT(4004, "楠岃瘉鐮佷笉姝g‘鎴栧凡杩囨湡"),
+ ACCOUNT_INCORRECT(4005, "璐﹀彿鎴栧瘑鐮佷笉姝g‘"),
+ TWO_FA_INCORRECT(4006, "鐧诲綍瀵嗙爜涓嶆纭�"),
+ LOCAL_FILE_NOT_EXISTS(4007, "鏂囦欢涓嶅瓨鍦�"),
+ // 500寮�澶磋〃绀烘湭鐭ョ殑鏈嶅姟寮傚父
+ SERVER_ERROR(5000, "绯荤粺绻佸繖锛岃鑱旂郴绯荤粺绠$悊鍛�"),
+ EXPORT_EXCEL_ERROR(5010, "瀵煎嚭Excel澶辫触锛岃鑱旂郴绯荤粺绠$悊鍛�"),
+ IMPORT_EXCEL_ERROR(5011, "瀵煎叆Excel澶辫触锛岃鑱旂郴绯荤粺绠$悊鍛�"),
+ // 510寮�澶磋〃绀哄彲鑳藉鑷存暟鎹敊璇殑寮傚父
+ REPEAT_REQUEST(5100, "璇峰嬁閲嶅鎻愪氦"),
+ MASSIVE_REQUEST(5101, "璇锋眰杩囦簬棰戠箒"),
+ NOT_ALLOWED(5110, "涓嶅厑璁哥殑鎿嶄綔"),
+ NO_LOGIN(5112, "鏈櫥褰�"),
+ ;
+
+ private int code;
+
+ private String message;
+}
diff --git a/server/services/src/main/java/com/doumee/core/exception/BusinessException.java b/server/services/src/main/java/com/doumee/core/exception/BusinessException.java
new file mode 100644
index 0000000..ef08559
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/exception/BusinessException.java
@@ -0,0 +1,35 @@
+package com.doumee.core.exception;
+
+import com.doumee.core.constants.ResponseStatus;
+import lombok.Data;
+
+/**
+ * 涓氬姟寮傚父瀵硅薄
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+public class BusinessException extends RuntimeException {
+
+ private Integer code;
+
+ public BusinessException(Integer code, String message) {
+ super(message);
+ this.code = code;
+ }
+
+ public BusinessException(Integer code, String message, Throwable e) {
+ super(message, e);
+ this.code = code;
+ }
+
+ public BusinessException(ResponseStatus status) {
+ super(status.getMessage());
+ this.code = status.getCode();
+ }
+
+ public BusinessException(ResponseStatus status, Throwable e) {
+ super(status.getMessage(), e);
+ this.code = status.getCode();
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/exception/LockedException.java b/server/services/src/main/java/com/doumee/core/exception/LockedException.java
new file mode 100644
index 0000000..bb39f5b
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/exception/LockedException.java
@@ -0,0 +1,13 @@
+package com.doumee.core.exception;
+
+/**
+ * 鏁版嵁宸茶閿佸畾寮傚父
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public class LockedException extends Exception {
+
+ public LockedException(String message) {
+ super(message);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/exception/UnSafeSessionException.java b/server/services/src/main/java/com/doumee/core/exception/UnSafeSessionException.java
new file mode 100644
index 0000000..bbedf6c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/exception/UnSafeSessionException.java
@@ -0,0 +1,13 @@
+package com.doumee.core.exception;
+
+/**
+ * 涓嶅畨鍏ㄧ殑浼氳瘽寮傚父
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public class UnSafeSessionException extends RuntimeException {
+
+ public UnSafeSessionException () {
+ super("涓嶅畨鍏ㄧ殑浼氳瘽");
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/job/BaseDistributer.java b/server/services/src/main/java/com/doumee/core/job/BaseDistributer.java
new file mode 100644
index 0000000..ca0ed81
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/job/BaseDistributer.java
@@ -0,0 +1,58 @@
+package com.doumee.core.job;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鍒嗗彂鍣ㄧ埗绫伙紝鎵�鏈夊垎鍙戝櫒缁ф壙璇ョ埗绫�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public abstract class BaseDistributer<T> {
+
+ /**
+ * 鑾峰彇涓氬姟鏁版嵁
+ *
+ * @param jobParam JOB鍙傛暟
+ * @return List<T>
+ */
+ public abstract List<T> getBusinessData(JobParam jobParam);
+
+ /**
+ * 鑾峰彇job鍒嗙墖鏁版嵁
+ *
+ * @param dto 鍒嗗彂鍙傛暟
+ * @param jobParam JOB鍙傛暟
+ * @return List<List<T>>
+ */
+ public List<List<T>> getSnippetData (DistributeDTO dto, JobParam jobParam) {
+ List<List<T>> snippetData = new ArrayList<>();
+ List<T> allData = this.getBusinessData(jobParam);
+ int snippetCount = allData.size() / dto.getLimit();
+ if (allData.size() % dto.getLimit() > 0) {
+ snippetCount++;
+ }
+ for (int i = 0 ; i < snippetCount; i++) {
+ int endLimit = dto.getLimit() * (i + 1);
+ if (endLimit >= allData.size()) {
+ endLimit = allData.size();
+ }
+ snippetData.add(allData.subList(dto.getLimit() * i, endLimit));
+ }
+ return snippetData;
+ }
+
+ /**
+ * 鍒嗗彂鍙傛暟
+ */
+ @Data
+ @AllArgsConstructor
+ public static class DistributeDTO {
+
+ // 鏁版嵁闄愬埗
+ private Integer limit;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/job/BaseJob.java b/server/services/src/main/java/com/doumee/core/job/BaseJob.java
new file mode 100644
index 0000000..0ed7116
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/job/BaseJob.java
@@ -0,0 +1,17 @@
+package com.doumee.core.job;
+
+/**
+ * JOB鐖剁被锛屾墍鏈塉OB鍧囩户鎵胯绫�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public abstract class BaseJob {
+
+ /**
+ * 鎵ц鏂规硶
+ *
+ * @param param JOB鎵ц鍏ュ弬鏁�
+ * @return JobContext
+ */
+ public abstract JobContext execute(JobParam param);
+}
diff --git a/server/services/src/main/java/com/doumee/core/job/JobContext.java b/server/services/src/main/java/com/doumee/core/job/JobContext.java
new file mode 100644
index 0000000..f176795
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/job/JobContext.java
@@ -0,0 +1,21 @@
+package com.doumee.core.job;
+
+import lombok.Data;
+
+/**
+ * 浠诲姟鎵ц涓婁笅鏂�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+public class JobContext {
+
+ // 澶勭悊鎴愬姛鏁�
+ private int handleSuccessSize;
+
+ // 澶勭悊鎬绘暟
+ private int handleTotalSize;
+
+ // 涓婁笅鏂囨弿杩�
+ private String context;
+}
diff --git a/server/services/src/main/java/com/doumee/core/job/JobParam.java b/server/services/src/main/java/com/doumee/core/job/JobParam.java
new file mode 100644
index 0000000..718e2d2
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/job/JobParam.java
@@ -0,0 +1,73 @@
+package com.doumee.core.job;
+
+import com.alibaba.fastjson.JSON;
+import com.doumee.core.constants.Constants;
+
+import java.util.*;
+
+/**
+ * JOB鍏ュ弬
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public class JobParam extends HashMap<String, Object> {
+
+ // JOB鎴栧垎鐗嘔D
+ private static final String KEY_ID = "id";
+
+ // 涓氬姟鏃堕棿
+ private static final String KEY_BUSINESS_TIME = "businessTime";
+
+ // 鍒嗙墖绱㈠紩
+ private static final String KEY_SNIPPET_INDEX = "snippetIndex";
+
+ // 瑙﹀彂鏂瑰紡
+ private static final String KEY_TRIGGER_TYPE = "triggerType";
+
+ // 涓氬姟鏁版嵁
+ private static final String KEY_RUNTIME_DATA = "runtimeData";
+
+ public void setId (Integer id) {
+ this.put(KEY_ID, id);
+ }
+
+ public Integer getId () {
+ return (Integer) this.get(KEY_ID);
+ }
+
+ public void setBusinessTime(Date date) {
+ this.put(KEY_BUSINESS_TIME, date);
+ }
+
+ public <T> List<T> getRuntimeData(Class<T> clazz) {
+ return JSON.parseArray((String)this.get(KEY_RUNTIME_DATA), clazz);
+ }
+
+ public void setSnippetIndex (Integer index) {
+ this.put(KEY_SNIPPET_INDEX, index);
+ }
+
+ public Integer getSnippetIndex () {
+ Object indexObject = this.get(KEY_SNIPPET_INDEX);
+ if (indexObject == null) {
+ return null;
+ }
+ return (Integer) indexObject;
+ }
+
+ public void setTriggerType (String triggerType) {
+ this.put(KEY_TRIGGER_TYPE, triggerType);
+ }
+
+ public String getTriggerType () {
+ return (String) this.get(KEY_TRIGGER_TYPE);
+ }
+
+ public Date getBusinessTime() {
+ return (Date) this.get(KEY_BUSINESS_TIME);
+ }
+
+ public void setRuntimeData(String runtimeData) {
+ this.put(KEY_RUNTIME_DATA, runtimeData);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/job/SchedulerProxy.java b/server/services/src/main/java/com/doumee/core/job/SchedulerProxy.java
new file mode 100644
index 0000000..4ecf7a1
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/job/SchedulerProxy.java
@@ -0,0 +1,69 @@
+package com.doumee.core.job;
+
+import com.doumee.config.quartz.JobHandler;
+import com.doumee.config.quartz.JobHandlerWithDisallowConcurrent;
+import com.doumee.core.constants.Constants;
+import com.doumee.core.utils.Utils;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * 浠诲姟璋冨害鍣ㄤ唬鐞�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+public class SchedulerProxy {
+
+ @Autowired
+ private Scheduler scheduler;
+
+ /**
+ * 鍒涘缓JOB
+ *
+ * @param job 璇﹁SchedulerProxy$Job
+ */
+ public void createJob (Job job) {
+ try {
+ // 鍒涘缓Job
+ Class handleClass = JobHandler.class;
+ if (job.getDisallowConcurrent()) {
+ handleClass = JobHandlerWithDisallowConcurrent.class;
+ }
+ JobDetail newJob = JobBuilder.newJob(handleClass).withIdentity(job.getHandler()).build();
+ // - 娣诲姞JOB杩愯鏃舵暟鎹�
+ newJob.getJobDataMap().put(Constants.Job.JOB_DATA_MAP_JOB_ID, job.getId());
+ // 鍒涘缓Trigger
+ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression())
+ .withMisfireHandlingInstructionDoNothing();
+ CronTrigger trigger = TriggerBuilder.newTrigger()
+ .withIdentity(job.getHandler() + "Trigger")
+ .withSchedule(scheduleBuilder).build();
+ // 鍔犲叆璋冨害
+ scheduler.scheduleJob(newJob, trigger);
+ } catch (SchedulerException e) {
+ log.error("EVA: create job throw an exception", e);
+ }
+ }
+
+ /**
+ * JOB浠g悊瀵硅薄锛屼笉渚濊禆鍏朵粬閫昏緫灞�
+ */
+ @Data
+ @AllArgsConstructor
+ public static class Job {
+
+ private Integer id;
+
+ private String handler;
+
+ private String cronExpression;
+
+ private Boolean disallowConcurrent;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/model/ApiResponse.java b/server/services/src/main/java/com/doumee/core/model/ApiResponse.java
new file mode 100644
index 0000000..17ac27f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/model/ApiResponse.java
@@ -0,0 +1,146 @@
+package com.doumee.core.model;
+
+import com.alibaba.fastjson.JSON;
+import com.doumee.core.constants.ResponseStatus;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 鎺ュ彛杩斿洖瀵硅薄
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@ApiModel("鍝嶅簲瀵硅薄")
+@Data
+@AllArgsConstructor
+public class ApiResponse<T> implements Serializable {
+
+ @ApiModelProperty(value = "鍝嶅簲鐮�")
+ private int code;
+
+ @ApiModelProperty(value = "璇锋眰鏄惁鎴愬姛")
+ private boolean success;
+
+ @ApiModelProperty(value = "閿欒娑堟伅")
+ private String message;
+
+ @ApiModelProperty(value = "鏁版嵁")
+ private T data;
+
+ @ApiModelProperty(value = "寮傚父娑堟伅")
+ private String exception;
+
+ public ApiResponse () {}
+
+ /**
+ * 璇锋眰鎴愬姛
+ *
+ * @param data 鏁版嵁
+ * @return ApiResponse
+ */
+ public static <T> ApiResponse<T> success(T data) {
+ return ApiResponse.success("璇锋眰鎴愬姛", data);
+ }
+
+ /**
+ * 璇锋眰鎴愬姛
+ *
+ * @param message 娑堟伅
+ * @param data 鏁版嵁
+ * @return ApiResponse
+ */
+ public static <T> ApiResponse<T> success(String message, T data) {
+ return new ApiResponse<>(HttpStatus.OK.value(), Boolean.TRUE, message, data, null);
+ }
+
+ /**
+ * 璇锋眰澶辫触
+ *
+ * @param message 娑堟伅
+ * @return ApiResponse
+ */
+ public static <T> ApiResponse<T> failed(String message) {
+ return ApiResponse.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), message);
+ }
+
+ /**
+ * 璇锋眰澶辫触
+ *
+ * @param status 鍝嶅簲鐘舵��
+ * @return ApiResponse
+ */
+ public static <T> ApiResponse<T> failed(ResponseStatus status) {
+ return ApiResponse.failed(status.getCode(), status.getMessage());
+ }
+
+ /**
+ * 璇锋眰澶辫触
+ *
+ * @param status 鍝嶅簲鐘舵��
+ * @param ex 寮傚父瀵硅薄
+ * @return ApiResponse
+ */
+ public static <T> ApiResponse<T> failed(ResponseStatus status, Throwable ex) {
+ return ApiResponse.failed(status.getCode(), status.getMessage(), ex);
+ }
+
+ /**
+ * 璇锋眰澶辫触
+ *
+ * @param code 鍝嶅簲鐮�
+ * @param message 娑堟伅
+ * @return ApiResponse
+ */
+ public static <T> ApiResponse<T> failed(Integer code, String message) {
+ return ApiResponse.failed(code, message, null);
+ }
+
+ /**
+ * 璇锋眰澶辫触
+ *
+ * @param code 鍝嶅簲鐮�
+ * @param message 娑堟伅
+ * @param ex 寮傚父
+ * @return ApiResponse
+ */
+ public static <T> ApiResponse<T> failed(Integer code, String message, Throwable ex) {
+ if (ex == null) {
+ return new ApiResponse<>(code, Boolean.FALSE, message, null, null);
+ }
+ // 澶勭悊寮傚父鏍堬紝闃叉杩囧鍐呭瀵艰嚧鍝嶅簲鍐呭杩囧ぇ
+ StackTraceElement[] trace = ex.getStackTrace();
+ StringBuilder exceptionStack = new StringBuilder(ex + "\n");
+ for (StackTraceElement traceElement : trace) {
+ exceptionStack.append("\tat ").append(traceElement).append("\n");
+ if (exceptionStack.length() > 5000) {
+ break;
+ }
+ }
+ return new ApiResponse<>(code, Boolean.FALSE, message, null, exceptionStack.toString());
+ }
+
+ /**
+ * 鐩存帴閫氳繃HttpServletResponse鍐欏嚭鍝嶅簲缁撴灉
+ *
+ * @param response 鍝嶅簲
+ * @param apiResponse ApiResponse
+ */
+ public static void response (HttpServletResponse response, ApiResponse apiResponse) {
+ try {
+ response.setHeader("content-type", "application/json;charset=UTF-8");
+ response.getOutputStream().write(JSON.toJSONString(apiResponse).getBytes(StandardCharsets.UTF_8));
+ } catch (IOException e) {
+ log.error("EVA: response throw an exception", e);
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/model/LoginUserInfo.java b/server/services/src/main/java/com/doumee/core/model/LoginUserInfo.java
new file mode 100644
index 0000000..7ccba6a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/model/LoginUserInfo.java
@@ -0,0 +1,74 @@
+package com.doumee.core.model;
+
+import com.doumee.dao.system.model.SystemPermission;
+import com.doumee.dao.system.model.SystemRole;
+import com.doumee.dao.system.model.SystemUser;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+import org.springframework.beans.BeanUtils;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 鐧诲綍鐢ㄦ埛淇℃伅
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+public class LoginUserInfo implements Serializable {
+
+ private Integer id;
+
+ private String username;
+
+ private String realname;
+
+ private String avatar;
+
+ private Date birthday;
+
+ private String sex;
+
+ private List<String> roles;
+
+ private List<String> permissions;
+
+ @JsonIgnore
+ private String password;
+
+ @JsonIgnore
+ private String salt;
+
+ /**
+ * 灏嗙敤鎴峰疄浣撹浆涓虹櫥褰曠敤鎴蜂俊鎭�
+ *
+ * @param user 鐢ㄦ埛瀹炰綋
+ * @param roles 瑙掕壊鍒楄〃
+ * @param permissions 鏉冮檺鍒楄〃
+ * @return LoginUserInfo
+ */
+ public static LoginUserInfo from(SystemUser user, List<SystemRole> roles, List<SystemPermission> permissions) {
+ if (user == null) {
+ return null;
+ }
+ // 鎷疯礉鐢ㄦ埛淇℃伅
+ LoginUserInfo loginUserInfo = new LoginUserInfo();
+ BeanUtils.copyProperties(user, loginUserInfo);
+ // 璁剧疆瑙掕壊淇℃伅
+ List<String> rs = new ArrayList<>();
+ for (SystemRole role : roles) {
+ rs.add(role.getCode());
+ }
+ loginUserInfo.setRoles(rs);
+ // 璁剧疆鏉冮檺淇℃伅
+ List<String> pms = new ArrayList<>();
+ for (SystemPermission permission : permissions) {
+ pms.add(permission.getCode());
+ }
+ loginUserInfo.setPermissions(pms);
+ return loginUserInfo;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/model/PageData.java b/server/services/src/main/java/com/doumee/core/model/PageData.java
new file mode 100644
index 0000000..da20ae8
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/model/PageData.java
@@ -0,0 +1,82 @@
+package com.doumee.core.model;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鍒嗛〉瀵硅薄")
+public class PageData<T> implements Serializable {
+
+ @ApiModelProperty("鐩爣椤�")
+ private long page;
+
+ @ApiModelProperty("椤靛閲�")
+ private long capacity;
+
+ @ApiModelProperty("鎬昏褰曟暟")
+ private long total;
+
+ @ApiModelProperty("褰撳墠椤电殑鏁版嵁")
+ private List<T> records;
+
+ public PageData(long page, long capacity) {
+ this.page = page;
+ this.capacity = capacity;
+ }
+
+ /**
+ * 鏍规嵁MyBatis Plus鍒嗛〉瀵硅薄缁勮
+ *
+ * @param pageInfo MyBatisPlus鍒嗛〉瀵硅薄
+ * @return PageData<T>
+ */
+ public static <T> PageData<T> from(IPage<T> pageInfo) {
+ PageData<T> pageData = new PageData<T>(pageInfo.getCurrent(), pageInfo.getSize());
+ pageData.total = pageInfo.getTotal();
+ pageData.records = pageInfo.getRecords();
+ return pageData;
+ }
+
+ /**
+ * 鏍规嵁MyBatis鍘熺敓鍒嗛〉瀵硅薄缁勮
+ *
+ * @param pageInfo MyBatis鍒嗛〉瀵硅薄
+ * @return PageData<T>
+ */
+ public static <T> PageData<T> from(PageInfo<T> pageInfo) {
+ PageData<T> pageData = new PageData<>(pageInfo.getPageNum(), pageInfo.getPageSize());
+ pageData.total = pageInfo.getTotal();
+ pageData.records = pageInfo.getList();
+ return pageData;
+ }
+
+ /**
+ * 澶勭悊寮傚父椤靛閲�
+ */
+ public long getCapacity () {
+ return capacity <= 0 ? 10 : capacity;
+ }
+
+ /**
+ * 鑾峰彇鎬婚〉鏁�
+ */
+ @ApiModelProperty("鎬婚〉鏁�")
+ public long getPageCount(){
+ if(this.getTotal() % this.getCapacity() == 0){
+ long pc = this.getTotal()/this.getCapacity();
+ return pc == 0 ? 1 : pc;
+ }
+ return this.getTotal()/this.getCapacity() + 1;
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/model/PageWrap.java b/server/services/src/main/java/com/doumee/core/model/PageWrap.java
new file mode 100644
index 0000000..56a093f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/model/PageWrap.java
@@ -0,0 +1,105 @@
+package com.doumee.core.model;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鍒嗛〉璇锋眰鍙傛暟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鍒嗛〉璇锋眰鍙傛暟")
+public class PageWrap<M> implements Serializable {
+
+ // 闄嶅簭
+ public static final String DESC = "DESC";
+
+ // 鍗囧簭
+ public static final String ASC = "ASC";
+
+ @ApiModelProperty("鏉′欢鍙傛暟")
+ private M model;
+
+ @ApiModelProperty(value = "鐩爣椤�", example = "1")
+ private int page;
+
+ @ApiModelProperty(value = "涓�椤靛灏戣", example = "10")
+ private int capacity;
+
+ @ApiModelProperty(value = "鎺掑簭鍙傛暟", example = "[]")
+ private List<SortData> sorts;
+
+ /**
+ * 鑾峰彇鎺掑簭鍒楄〃
+ */
+ public List<SortData> getSorts () {
+ List<SortData> sorts = new ArrayList<>();
+ if (this.sorts == null) {
+ return sorts;
+ }
+ for (SortData sort: this.sorts) {
+ if (sort.getProperty() == null || sort.getProperty().trim().length() == 0) {
+ continue;
+ }
+ if (sort.getDirection() == null || sort.getDirection().trim().length() == 0 || (!sort.getDirection().trim().equalsIgnoreCase("asc") && !sort.getDirection().trim().equalsIgnoreCase("desc"))) {
+ continue;
+ }
+ sorts.add(sort);
+ }
+ return sorts;
+ }
+
+ /**
+ * 鑾峰彇椤电爜
+ */
+ public int getPage () {
+ return page <= 0 ? 1 : page;
+ }
+
+ /**
+ * 鑾峰彇椤靛閲�
+ */
+ public int getCapacity () {
+ return capacity <= 0 ? 10 : capacity;
+ }
+
+ /**
+ * 鑾峰彇鎺掑簭瀛楃涓�
+ */
+ @ApiModelProperty(hidden = true)
+ public String getOrderByClause () {
+ List<SortData> sorts = this.getSorts();
+ StringBuilder stringBuilder = new StringBuilder();
+ for (SortData sortData: sorts) {
+ // 闃叉敞鍏�
+ if (!sortData.getProperty().matches("[a-zA-Z0-9_\\.]+")) {
+ continue;
+ }
+ stringBuilder.append(sortData.getProperty().trim());
+ stringBuilder.append(" ");
+ stringBuilder.append(sortData.getDirection().trim());
+ stringBuilder.append(",");
+ }
+ if (stringBuilder.length() == 0) {
+ return null;
+ }
+ return "ORDER BY " + stringBuilder.substring(0, stringBuilder.length() - 1);
+ }
+
+ @Data
+ @ApiModel("鎺掑簭瀵硅薄")
+ public static class SortData {
+
+ @ApiModelProperty("鎺掑簭瀛楁")
+ private String property;
+
+ @ApiModelProperty("鎺掑簭鏂瑰悜锛圓SC锛氬崌搴忥紝DESC锛氶檷搴忥級")
+ private String direction;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateInputStream.java b/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateInputStream.java
new file mode 100644
index 0000000..1a4bc38
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateInputStream.java
@@ -0,0 +1,109 @@
+package com.doumee.core.servlet;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 鍖呭惈鍓湰鐨勮緭鍏ユ祦
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public class ServletDuplicateInputStream extends ServletInputStream {
+
+ private ServletInputStream stream;
+
+ private ByteArrayInputStream duplicate;
+
+ private String body;
+
+ public ServletDuplicateInputStream (ServletInputStream servletInputStream) {
+ this.stream = servletInputStream;
+ this.setBody(this.getBodyString());
+ }
+
+ @Override
+ public int read() {
+ return duplicate.read();
+ }
+
+ @Override
+ public boolean isFinished() {
+ return stream.isFinished();
+ }
+
+ @Override
+ public boolean isReady() {
+ return stream.isReady();
+ }
+
+ @Override
+ public void setReadListener(ReadListener readListener) {
+ stream.setReadListener(readListener);
+ }
+
+ /**
+ * 鑾峰彇璇锋眰浣撳弬鏁板瓧绗︿覆
+ */
+ private String getBodyString() {
+ StringBuilder sb = new StringBuilder();
+ InputStream inputStream = null;
+ BufferedReader reader = null;
+ try {
+ inputStream = cloneInputStream(this.stream);
+ reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ if (reader != null) {
+ try {
+ reader.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 澶嶅埗杈撳叆娴�
+ */
+ private InputStream cloneInputStream(ServletInputStream inputStream) {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int len;
+ try {
+ while ((len = inputStream.read(buffer)) > -1) {
+ byteArrayOutputStream.write(buffer, 0, len);
+ }
+ byteArrayOutputStream.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public void setBody(String body) {
+ this.body = body;
+ this.duplicate = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateOutputStream.java b/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateOutputStream.java
new file mode 100644
index 0000000..f9cc6ea
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateOutputStream.java
@@ -0,0 +1,70 @@
+package com.doumee.core.servlet;
+
+import lombok.Data;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.WriteListener;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * 鍖呭惈鍓湰鐨勮緭鍑烘祦
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+ @Data
+public class ServletDuplicateOutputStream extends ServletOutputStream {
+
+ private ServletOutputStream stream;
+
+ private ByteArrayOutputStream duplicate;
+
+ public ServletDuplicateOutputStream(ServletOutputStream servletOutputStream) {
+ this.stream = servletOutputStream;
+ this.duplicate = new ByteArrayOutputStream();
+ }
+
+ @Override
+ public boolean isReady() {
+ return stream.isReady();
+ }
+
+ @Override
+ public void setWriteListener(WriteListener writeListener) {
+ stream.setWriteListener(writeListener);
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ stream.write(b);
+ duplicate.write(b);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ stream.write(b, off, len);
+ duplicate.write(b, off, len);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ stream.flush();
+ duplicate.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ stream.close();
+ duplicate.close();
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ stream.write(b);
+ duplicate.write(b);
+ }
+
+ public String getContent() {
+ return duplicate.toString();
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateRequestWrapper.java b/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateRequestWrapper.java
new file mode 100644
index 0000000..88a39d8
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateRequestWrapper.java
@@ -0,0 +1,78 @@
+package com.doumee.core.servlet;
+
+import lombok.Getter;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.*;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 澧炲姞璇锋眰娴佸壇鏈�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Getter
+public class ServletDuplicateRequestWrapper extends HttpServletRequestWrapper {
+
+ private ServletDuplicateInputStream servletDuplicateInputStream;
+
+ private Map<String, String[]> parameters = new HashMap<>();
+
+ public ServletDuplicateRequestWrapper(HttpServletRequest request) {
+ super(request);
+ }
+
+ /**
+ * 娣诲姞鍙傛暟
+ */
+ public void addParameter (String name, Object value) {
+ if (value == null) {
+ return;
+ }
+ if (value instanceof String[]) {
+ this.parameters.put(name, (String[]) value);
+ } else if (value instanceof String) {
+ this.parameters.put(name, new String[]{(String) value});
+ } else {
+ this.parameters.put(name, new String[]{String.valueOf(value)});
+ }
+ }
+
+ @Override
+ public Map<String, String[]> getParameterMap() {
+ if (this.parameters.isEmpty()) {
+ return super.getParameterMap();
+ }
+ return this.parameters;
+ }
+
+ @Override
+ public String[] getParameterValues(String name) {
+ if (this.parameters.isEmpty()) {
+ return super.getParameterValues(name);
+ }
+ return this.parameters.get(name);
+ }
+
+ @Override
+ public Enumeration<String> getParameterNames() {
+ if (this.parameters.isEmpty()) {
+ return super.getParameterNames();
+ }
+ return Collections.enumeration(this.parameters.keySet());
+ }
+
+ @Override
+ public ServletInputStream getInputStream() throws IOException{
+ if (servletDuplicateInputStream == null) {
+ servletDuplicateInputStream = new ServletDuplicateInputStream(super.getInputStream());
+ }
+ return servletDuplicateInputStream;
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateResponseWrapper.java b/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateResponseWrapper.java
new file mode 100644
index 0000000..759a487
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/servlet/ServletDuplicateResponseWrapper.java
@@ -0,0 +1,53 @@
+package com.doumee.core.servlet;
+
+import lombok.extern.slf4j.Slf4j;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import java.io.IOException;
+
+/**
+ * 澧炲姞鍝嶅簲娴佸壇鏈�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+public class ServletDuplicateResponseWrapper extends HttpServletResponseWrapper {
+
+/*
+ private ServletDuplicateOutputStream servletDuplicateOutputStream;
+
+ public ServletDuplicateResponseWrapper(HttpServletResponse httpServletResponse) {
+ super(httpServletResponse);
+ try {
+ servletDuplicateOutputStream = new ServletDuplicateOutputStream(httpServletResponse.getOutputStream());
+ } catch (IOException e) {
+ log.error("EVA: build ServletDuplicateResponseWrapper throw an exception", e);
+ }
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() {
+ if (servletDuplicateOutputStream == null) {
+ servletDuplicateOutputStream = new ServletDuplicateOutputStream(super.getOutputStream());
+ }
+ return servletDuplicateOutputStream;
+ }
+*/
+
+ private ServletDuplicateOutputStream servletDuplicateOutputStream;
+
+ public ServletDuplicateResponseWrapper(HttpServletResponse httpServletResponse) {
+ super(httpServletResponse);
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() throws IOException {
+ if (servletDuplicateOutputStream == null) {
+ servletDuplicateOutputStream = new ServletDuplicateOutputStream(super.getOutputStream());
+ }
+ return servletDuplicateOutputStream;
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/servlet/ServletRewriteFilter.java b/server/services/src/main/java/com/doumee/core/servlet/ServletRewriteFilter.java
new file mode 100644
index 0000000..c8abfa9
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/servlet/ServletRewriteFilter.java
@@ -0,0 +1,45 @@
+package com.doumee.core.servlet;
+
+import org.springframework.stereotype.Component;
+
+import javax.servlet.*;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 浼犻�掕姹傛祦/鍝嶅簲娴佸壇鏈�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Component
+@WebFilter(urlPatterns = "/*", filterName = "servletRewriteFilter")
+public class ServletRewriteFilter implements Filter {
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+ /*HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
+ HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
+ // 闃叉璇锋眰娴佽鎷︽埅鍣ㄨ繘琛屼竴娆¤鍙栧悗鍏抽棴瀵艰嚧娴佹棤娉曡繛缁鍙栫殑闂
+ ServletRequest requestWrapper = servletRequest;
+ if (!(requestWrapper instanceof ServletDuplicateRequestWrapper)) {
+ requestWrapper = new ServletDuplicateRequestWrapper(httpServletRequest);
+ }
+ // 鍏佽鍝嶅簲娴佽鍙栧搷搴旂粨鏋�
+ ServletResponse responseWrapper = servletResponse;
+ if (!(servletResponse instanceof ServletDuplicateResponseWrapper)) {
+ responseWrapper = new ServletDuplicateResponseWrapper(httpServletResponse);
+ }
+ filterChain.doFilter(requestWrapper, responseWrapper);*/
+
+ HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
+ HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
+ // 闃叉璇锋眰娴佽鎷︽埅鍣ㄨ繘琛屼竴娆¤鍙栧悗鍏抽棴瀵艰嚧娴佹棤娉曡繛缁鍙栫殑闂
+ ServletRequest requestWrapper = new ServletDuplicateRequestWrapper(httpServletRequest);
+ // 鍏佽鍝嶅簲娴佽鍙栧搷搴旂粨鏋�
+ ServletResponse responseWrapper = new ServletDuplicateResponseWrapper(httpServletResponse);
+ filterChain.doFilter(requestWrapper, responseWrapper);
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/AES.java b/server/services/src/main/java/com/doumee/core/utils/AES.java
new file mode 100644
index 0000000..9e8651d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/AES.java
@@ -0,0 +1,96 @@
+package com.doumee.core.utils;
+
+import java.nio.charset.StandardCharsets;
+import java.security.Security;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Base64;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * AES鍔犺В瀵�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@Component
+public class AES {
+
+ // 瀵嗛挜
+ @Value("${security.aes.key}")
+ private String key;
+
+ // 鍋忕Щ閲�
+ @Value("${security.aes.iv}")
+ private String iv;
+
+ // 瀵嗛挜闀垮害
+ private Integer keyLen = 128;
+
+ public AES() {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ /**
+ * 鍔犲瘑
+ *
+ * @return String
+ */
+ public String encrypt(String plainText) throws SecurityException {
+ try {
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");// 鍒涘缓瀵嗙爜鍣�
+ cipher.init(Cipher.ENCRYPT_MODE, this.getAESKey(), new IvParameterSpec(paddingIv(iv)));// 鍒濆鍖�
+ return new Base64().encodeAsString(cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)));
+ } catch (Exception e) {
+ throw new SecurityException("AES encrypt throw an exception", e);
+ }
+ }
+
+ /**
+ * 瑙e瘑
+ *
+ * @param cipherText 瀵嗘枃
+ * @return String
+ */
+ public String decrypt(String cipherText) throws SecurityException {
+ try {
+ byte[] encrypted = new Base64().decode(cipherText);
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
+ cipher.init(Cipher.DECRYPT_MODE, this.getAESKey(), new IvParameterSpec(paddingIv(iv)));
+ return new String(cipher.doFinal(encrypted), StandardCharsets.UTF_8);
+ } catch (Exception e) {
+ throw new SecurityException("AES decrypt throw an exception", e);
+ }
+ }
+
+ /**
+ * 鑾峰彇AES key
+ *
+ * @return SecretKeySpec
+ */
+ private SecretKeySpec getAESKey() {
+ /* 浣跨敤鍘熷瀵嗛挜杩涜鍔犲瘑锛岃姹傚瘑閽ヤ负瀵嗛挜闀垮害鐨勫�嶆暟 */
+ byte[] raw = key.getBytes(StandardCharsets.UTF_8);
+ return new SecretKeySpec(raw, "AES");
+ }
+
+ /**
+ * 鍒濆鍖栧悜閲忎竴鐩翠繚鎸�16浣�
+ *
+ * @param iv 鍚戦噺
+ * @return byte[]
+ */
+ private byte[] paddingIv(String iv) {
+ byte[] ivBytes = iv.getBytes(StandardCharsets.UTF_8);
+ byte[] bs = new byte[keyLen / 8];
+ System.arraycopy(ivBytes, 0, bs, 0, ivBytes.length);
+ return bs;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/AESUtils.java b/server/services/src/main/java/com/doumee/core/utils/AESUtils.java
new file mode 100644
index 0000000..516c46d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/AESUtils.java
@@ -0,0 +1,35 @@
+package com.doumee.core.utils;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+public class AESUtils {
+
+ private static final String ALGORITHM = "AES";
+ private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding"; // 浣跨敤 ECB 妯″紡骞朵娇鐢� PKCS5Padding 濉厖
+
+ public static String encrypt(String data, String key) throws Exception {
+ SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
+ Cipher cipher = Cipher.getInstance(TRANSFORMATION);
+ cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
+ byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
+ return Base64.getEncoder().encodeToString(encryptedBytes);
+ }
+
+ public static String decrypt(String encryptedData, String key) throws Exception {
+ SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
+ Cipher cipher = Cipher.getInstance(TRANSFORMATION);
+ cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
+ byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
+ return new String(decryptedBytes, StandardCharsets.UTF_8);
+ }
+
+ public static void main(String[] args) throws Exception {
+ String key = "qtixtsujiokdgrqq"; // 16 瀛楄妭鐨勫瘑閽�
+ String decryptedData = decrypt("/V65QRvmgommnLLJQV+JwE7L2FShGboL3TojZL4Up2JzeR/NK7rxwFqVHU4f9BTT2PYgDX5ULBGjbWnrwNpfhB1j1aUWSuItXvAAutz5L7f+bnZGmNNsUzG0KRyDu77e1fkweqfuSqZ7C4dmt6vy+DdYAMSC/RVBx/dOCU4gNcf0SupvH57WHPTt3KpB3OmbXBg74DiAi2JG7+giWDLnDrDBahhTgMSu0u1f3K5SMcE9tVVZCHGkzNAV5owwo/7yyvFMdBELqO/pgtfI1syaHgPdskMXUwa1j6HdLUcAqvaF7PzJOv++VGNqnCm2n2UBoIPEvKkn9TuI3LHHT26v2H0KoRmJdPIhme0eGqyXqAkTYFbAd/6OGUiwJO1vZYZDW/fmtKNThP0UOFLvJ6jVW5XrvIdmjzoF8iOxyyj+N3/3Mp4SinH9gSBuz/TbabH4zXL0Np1UvRmJjtkIEa+q8DEch0HcyH2ABULnu/xyxbIXhLQ1lgBZ2GJ8lO3ynvSSwkbzbd1vP5zWxKIYRDTf5qRk3eDwzXNbmcY6DFPYepS3ceh0kl4iScqG+AO/bvxTqnmm6/nrYVI8qHq7GCWthiTYX0AzulhT7ceyEfMMD4zuz8gbWTfqQtIcDGHeN7gZuFUcwRfHG9sEN7Vkle6QSDZumjODSbrYiTTruQXCSSiDVoXFDK24GvKaNMKB2lh8qcV1sldpyAlgeOKCbYWyBiEG/5ZNZH0iHtrIXn/ebrs6kzMSFREw+CVvgrkpZZ04MP5QGMFEMr3+Zg4KtwYraSoWGg8Pn1MgN/dBCHOKnpCOMW2I8n+sKKZMJh5YkhrEtknf7Zvi8lpZX5Sjz5DOA3vaxy8E0YPbrjRxqlgW8psy5R6ZwDP9jfGIOG0gS0gPewm8xJRYYLEk7vbhwBW2hQ==", key);
+
+ System.out.println("" + decryptedData);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/ApplicationContextHelper.java b/server/services/src/main/java/com/doumee/core/utils/ApplicationContextHelper.java
new file mode 100644
index 0000000..98f063e
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/ApplicationContextHelper.java
@@ -0,0 +1,48 @@
+package com.doumee.core.utils;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+/**
+ * Spring涓婁笅鏂囧伐鍏�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Component
+public class ApplicationContextHelper {
+
+ @Autowired
+ public ApplicationContext applicationContext;
+
+ /**
+ * 鑾峰彇Bean瀹炰緥
+ *
+ * @param name 绫绘敞鍐屽悕绉�
+ * @return Object
+ */
+ public Object getBean(String name) {
+ return applicationContext.getBean(name);
+ }
+
+ /**
+ * 鑾峰彇Bean瀹炰緥
+ *
+ * @param clazz Class
+ * @return T
+ */
+ public <T> T getBean(Class<T> clazz){
+ return applicationContext.getBean(clazz);
+ }
+
+ /**
+ * 鑾峰彇Bean瀹炰緥
+ *
+ * @param name 绫绘敞鍐屽悕绉�
+ * @param clazz Class
+ * @return T
+ */
+ public <T> T getBean(String name, Class<T> clazz) {
+ return applicationContext.getBean(name, clazz);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/DateHelper.java b/server/services/src/main/java/com/doumee/core/utils/DateHelper.java
new file mode 100644
index 0000000..9084802
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/DateHelper.java
@@ -0,0 +1,81 @@
+package com.doumee.core.utils;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+/**
+ * 鏃ユ湡宸ュ叿
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public final class DateHelper {
+
+ /**
+ * 鑾峰彇鏃ユ湡鐨勫紑濮嬫椂闂�
+ *
+ * @param date 鏃ユ湡
+ * @return java.util.Date
+ */
+ public java.util.Date getStart (java.util.Date date) {
+ if (date == null) {
+ return null;
+ }
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ return calendar.getTime();
+ }
+
+ /**
+ * 鑾峰彇鏃ユ湡鐨勭粨鏉熸椂闂�
+ *
+ * @param date 鏃ユ湡
+ * @return java.util.Date
+ */
+ public java.util.Date getEnd (java.util.Date date) {
+ if (date == null) {
+ return null;
+ }
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + 1);
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ return calendar.getTime();
+ }
+
+ /**
+ * 鏍煎紡鍖�
+ *
+ * @param date 鏃ユ湡
+ * @return String
+ */
+ public String format (java.util.Date date) {
+ if (date == null) {
+ return null;
+ }
+ return this.format(date, "yyyy-MM-dd HH:mm:ss:sss");
+ }
+
+ /**
+ * 鏍煎紡鍖�
+ *
+ * @param date 鏃ユ湡
+ * @param format 鏍煎紡
+ * @return String
+ */
+ public String format (java.util.Date date, String format) {
+ if (date == null || StringUtils.isBlank(format)) {
+ return null;
+ }
+ SimpleDateFormat sdf = new SimpleDateFormat(format);
+ return sdf.format(date);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/DateUtil.java b/server/services/src/main/java/com/doumee/core/utils/DateUtil.java
new file mode 100644
index 0000000..dcf6ec1
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/DateUtil.java
@@ -0,0 +1,3630 @@
+package com.doumee.core.utils;
+
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.sql.Timestamp;
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.*;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalAdjusters;
+import java.util.*;
+
+/**
+ * 鏃ユ湡宸ュ叿绫�
+ * @author: jiangping
+ * @date: 2021骞�7鏈�21鏃�09:27:13
+ */
+public class DateUtil {
+
+ static SimpleDateFormat sdfShort = new SimpleDateFormat("yyyyMMdd");
+ static SimpleDateFormat sdfLong = new SimpleDateFormat("yyyy-MM-dd");
+ static SimpleDateFormat sdfLongSlash = new SimpleDateFormat("yyyy/MM/dd");
+ static SimpleDateFormat sdfShortPoint = new SimpleDateFormat("yyyy.MM.dd");
+ static SimpleDateFormat sdfLongCn = new SimpleDateFormat("yyyy骞碝M鏈坉d鏃�");
+ static SimpleDateFormat sdfShortU = new SimpleDateFormat("MMM dd", Locale.ENGLISH);
+ static SimpleDateFormat sdfLongU = new SimpleDateFormat("MMM dd,yyyy", Locale.ENGLISH);
+ static SimpleDateFormat sdfLongTime = new SimpleDateFormat("yyyyMMddHHmmss");
+ static SimpleDateFormat sdfLongTimePlus = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ static SimpleDateFormat sdfLongTimePlusSecond = new SimpleDateFormat("HH:mm:ss");
+ static SimpleDateFormat sdfShortLongTimePlusCn = new SimpleDateFormat("yyyy骞碝M鏈坉d鏃� HH:mm");
+ static SimpleDateFormat sdfShortLongTimePlusCn2 = new SimpleDateFormat("yyyy骞碝M鏈坉d鏃� HH:mm:ss");
+ static SimpleDateFormat sdfLongTimePlusMill = new SimpleDateFormat("yyyyMMddHHmmssSSSS");
+ static SimpleDateFormat sdfMd = new SimpleDateFormat("MM鏈坉d鏃�");
+ static SimpleDateFormat sdfMdHourMinute = new SimpleDateFormat("MM鏈坉d鏃� HH鏃秏m鍒�");
+ private static long DAY_IN_MILLISECOND = 0x5265c00L;
+
+ public DateUtil() {
+ }
+
+ /**
+ * 浼犲叆Data绫诲瀷鏃ユ湡锛岃繑鍥炲瓧绗︿覆绫诲瀷鏃堕棿锛圛SO8601鏍囧噯鏃堕棿锛�
+ * @param date
+ * @return
+ */
+ public static String getISO8601Timestamp(Date date){
+ try {
+ TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+ //TimeZone tz = TimeZone.getTimeZone("GMT-01");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'+'08:00");
+ df.setTimeZone(tz);
+ String nowAsISO = df.format(date);
+ return nowAsISO;
+ }catch (Exception e){
+ }
+ return null;
+ }
+ /**
+ * 浼犲叆Data绫诲瀷鏃ユ湡锛岃繑鍥炲瓧绗︿覆绫诲瀷鏃堕棿锛圛SO8601鏍囧噯鏃堕棿锛�
+ * @param date
+ * @return
+ */
+ public static String getISO8601Timestamp2(Date date){
+ try {
+ TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+ //TimeZone tz = TimeZone.getTimeZone("GMT-01");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'+'08:00");
+ df.setTimeZone(tz);
+ String nowAsISO = df.format(date);
+ return nowAsISO;
+ }catch (Exception e){
+ }
+ return null;
+ }
+ public static Date getISO8601DateByStr(String date) {
+ TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+ if(date!=null ){
+ int i = date.indexOf("+");
+ if(i >0){
+ date = date.substring(0,i);
+ }
+ }
+ //TimeZone tz = TimeZone.getTimeZone("GMT-01");2024-10-21T10:40:04+08:00
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
+// DateFormat df = new SimpleDateFormat("2023-12-08 T 09:25:54.698+08:00");
+ df.setTimeZone(tz);
+ Date nowAsISO = null;
+ try {
+ nowAsISO = df.parse(date);
+ } catch (ParseException e) {
+ }
+ return nowAsISO;
+ }
+ public static Date getISO8601DateByStr2(String date) {
+ TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+ if(date!=null ){
+ int i = date.indexOf("+");
+ if(i >0){
+ date = date.substring(0,i);
+ }
+ }
+ //TimeZone tz = TimeZone.getTimeZone("GMT-01");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+// DateFormat df = new SimpleDateFormat("2023-12-08 T 09:25:54.698+08:00");
+ df.setTimeZone(tz);
+ Date nowAsISO = null;
+ try {
+ nowAsISO = df.parse(date);
+ } catch (ParseException e) {
+ }
+ return nowAsISO;
+ }
+
+ public static Date StringToDate2(String DATE) {
+ if(StringUtils.isBlank(DATE)){
+ return null;
+ }
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ Date dt1 = null;
+ try {
+ dt1 = df.parse(DATE);
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ return dt1;
+ }
+
+ /**
+ * @author Pablo Descrption:取锟矫碉拷前锟斤拷锟斤拷getgetg get Date format
+ * Example锛�2008-05-15
+ * @return String
+ * @throws Exception
+ */
+ public static String getDateLong(Date date) {
+ String nowDate = "";
+ try {
+ if (date != null)
+ nowDate = sdfLong.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ System.out.println("Error at getDate:" + e.getMessage());
+ return "";
+ }
+ }
+
+ public static String getDateLongSlash(Date date) {
+ String nowDate = "";
+ try {
+ if (date != null)
+ nowDate = sdfLongSlash.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ System.out.println("Error at getDate:" + e.getMessage());
+ return "";
+ }
+ }
+
+ /**
+ * 寰楀嚭涓や釜鏃ユ湡涔嬮棿鐨勯棿闅斿皬鏃�
+ *
+ * @param fromDate
+ * 鏍煎紡涓簓yyy-MM-dd
+ * @param toDate
+ * 鏍煎紡涓簓yyy-MM-dd
+ * @return int
+ */
+ public static long getBetweenHours(Date fromDate, Date toDate) {
+ long m_intervalday = 0;// 鍒濆鍖栨椂闂撮棿闅旂殑鍊间负0
+ // 浣跨敤鐨勬椂闂存牸寮忎负yyyy-MM-dd
+ try {
+ m_intervalday = toDate.getTime() - fromDate.getTime();// 璁$畻鎵�寰椾负寰鏁�
+ m_intervalday = m_intervalday / 1000 / 60 / 60;// 璁$畻鎵�寰楃殑澶╂暟
+
+ return m_intervalday + 1;
+ } catch (Exception e) {
+ return Integer.MIN_VALUE;
+ }
+ }
+
+ /**
+ * @author Pablo Descrption:取锟矫碉拷前锟斤拷锟斤拷getgetg get Date format
+ * Example锛�2008.03.15
+ * @return String
+ * @throws Exception
+ */
+ public static String getDateShortPoint(Date date) {
+ String nowDate = "";
+ try {
+ if (date != null)
+ nowDate = sdfShortPoint.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ System.out.println("Error at getDate:" + e.getMessage());
+ return "";
+ }
+ }
+
+ public static int getDateNum(Date date) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ try {
+ return calendar.get(Calendar.DAY_OF_MONTH);
+ } catch (Exception e) {
+ System.out.println("Error at getDate:" + e.getMessage());
+ return 0;
+ }
+ }
+
+ /**
+ * @author Pablo Descrption:取锟矫碉拷前锟斤拷锟斤拷getgetg get Date format
+ * Example锛�2008骞�-05鏈�-15鏃�
+ * @return String
+ * @throws Exception
+ */
+ public static String getDateLongCn(Date date) {
+ String nowDate = "";
+ try {
+ if (date != null)
+ nowDate = sdfLongCn.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ System.out.println("Error at getDate:" + e.getMessage());
+ return "";
+ }
+ }
+
+ /**
+ * @author vowo Descrption:取锟矫碉拷前锟斤拷锟斤拷getgetg get Date format Example锛�05鏈�-15鏃�
+ * @return String
+ * @throws Exception
+ */
+ public static String getDateMD(Date date) {
+ String nowDate = "";
+ try {
+ if (date != null)
+ nowDate = sdfMd.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ System.out.println("Error at getDate:" + e.getMessage());
+ return "";
+ }
+ }
+
+ /**
+ * @author Pablo Descrption:取锟矫碉拷前锟斤拷锟斤拷getgetg get Date format
+ * Example锛�2008骞�-05鏈�-15鏃� 11:05
+ * @return String
+ * @throws Exception
+ */
+ public static String getDateShortLongTimeCn(Date date) {
+ String nowDate = "";
+ try {
+ if (date != null)
+ nowDate = sdfShortLongTimePlusCn.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ System.out.println("Error at getDate:" + e.getMessage());
+ return "";
+ }
+ }
+
+ /**
+ * @author Pablo Descrption:取锟矫碉拷前锟斤拷锟斤拷getgetg get Date format Example锛欰ug 28,
+ * 2007
+ * @return String
+ * @throws Exception
+ */
+ public static String getDateUS(Date date) {
+ String nowDate = "";
+ try {
+ if (date != null)
+ nowDate = sdfLongU.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ System.out.println("Error at getDate:" + e.getMessage());
+ return "";
+ }
+ }
+
+ /**
+ * @author Pablo Descrption:取锟矫碉拷前锟斤拷锟斤拷getgetg get Date format Example锛欰ug 28,
+ * 2007
+ * @return String
+ * @throws Exception
+ */
+ public static String getDateUSShort(Date date) {
+ String nowDate = "";
+ try {
+ if (date != null)
+ nowDate = sdfShortU.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ System.out.println("Error at getDate:" + e.getMessage());
+ return "";
+ }
+ }
+
+ /**
+ * 绠�鍗曡浆鎹㈡棩鏈熺被鍨嬪埌瀛楃涓茬被鍨嬶紝鏈湴淇℃伅璁句负UK
+ *
+ * @param date
+ * @param format
+ * @return String
+ */
+ public static String getFomartDate(Date date, String format) {
+ try {
+ return new SimpleDateFormat(format, Locale.UK).format(date);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return (date == null) ? new Date().toString() : date.toString();
+ }
+ }
+
+ /**
+ * 鑾峰彇X鏈堜唤涔嬪墠鐨勬湀浠芥暟
+ * @param currentDate
+ * @param month
+ * @return
+ */
+ public static List<String> getBeforMonth(Date currentDate , Integer month) {
+ SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");
+ SimpleDateFormat sdfMonth = new SimpleDateFormat("MM");
+ int currentYear = Integer.parseInt(sdfYear.format(currentDate));
+ int currentMonth = Integer.parseInt(sdfMonth.format(currentDate));
+ List<String> list = new ArrayList<>();
+
+ for (int i = 0; i < month; i++) {
+ int tempYear = currentYear;
+ int tempMonth = currentMonth - i;
+
+ if (tempMonth <= 0) {
+ tempYear--;
+ tempMonth += 12;
+ }
+ list.add(tempYear +"-" + StringUtils.leftPad(Integer.toString(tempMonth),2,"0"));
+ }
+ return list;
+ }
+ /**
+ * 鑾峰彇X鏈堜唤涔嬪墠鐨勬湀浠芥暟
+ * @param currentDate
+ * @param month
+ * @return
+ */
+ public static List<String> getDateListBeforMonth(Date currentDate , Integer month) {
+ SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");
+ SimpleDateFormat sdfMonth = new SimpleDateFormat("MM");
+ int currentYear = Integer.parseInt(sdfYear.format(currentDate));
+ int currentMonth = Integer.parseInt(sdfMonth.format(currentDate));
+ List<String> list = new ArrayList<>();
+
+ for (int i = 0; i < month; i++) {
+ int tempYear = currentYear;
+ int tempMonth = currentMonth - i;
+
+ if (tempMonth <= 0) {
+ tempYear--;
+ tempMonth += 12;
+ }
+ list.add(tempYear +"-" + StringUtils.leftPad(Integer.toString(tempMonth),2,"0"));
+ }
+ return list;
+ }
+
+ public static List<String> getBeforDays(Date currentDate,Integer days){
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(currentDate);
+ Date endDate = currentDate; // 鑾峰彇褰撳墠鏃ユ湡
+ calendar.add(Calendar.DAY_OF_YEAR, -days); // 寰�鍓嶆帹7澶�
+ Date startDate = calendar.getTime(); // 鑾峰彇鎺ㄧ畻鍚庣殑鏃ユ湡
+ List<String> list = new ArrayList<>();
+ while (startDate.before(endDate)) {
+ calendar.add(Calendar.DAY_OF_YEAR, 1); // 鑾峰彇涓嬩竴澶╂棩鏈�
+ startDate = calendar.getTime();
+ list.add(DateUtil.dateToString(startDate,"yyyy-MM-dd"));
+ System.out.println(DateUtil.dateToString(startDate,"yyyy-MM-dd"));
+ }
+ return list;
+ }
+ public static List<Date> getDateListBeforDays(Date currentDate,Integer days){
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(currentDate);
+ Date endDate = currentDate; // 鑾峰彇褰撳墠鏃ユ湡
+ calendar.add(Calendar.DAY_OF_YEAR, -days); // 寰�鍓嶆帹7澶�
+ Date startDate = calendar.getTime(); // 鑾峰彇鎺ㄧ畻鍚庣殑鏃ユ湡
+ List<Date> list = new ArrayList<>();
+ while (startDate.before(endDate)) {
+ calendar.add(Calendar.DAY_OF_YEAR, 1); // 鑾峰彇涓嬩竴澶╂棩鏈�
+ startDate = calendar.getTime();
+ list.add(startDate);
+ }
+ return list;
+ }
+
+ /**
+ * Descrption:鍙栧緱褰撳墠鏃ユ湡鏃堕棿,鏍煎紡涓�:YYYYMMDDHHMISS
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getNowLongTime() throws Exception {
+ String nowTime = "";
+ try {
+ java.sql.Date date = null;
+ date = new java.sql.Date(new Date().getTime());
+ nowTime = sdfLongTime.format(date);
+ return nowTime;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ /**
+ * Descrption:鍙栧緱褰撳墠鏃ユ湡鏃堕棿,鏍煎紡涓�:MM鏈坉d鏃� HH鏃秏m鍒�
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getHourMinute(Date date) throws Exception {
+ String nowTime = "";
+ try {
+ if (date != null) {
+ nowTime = sdfMdHourMinute.format(date);
+ }
+ return nowTime;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ /**
+ * Descrption:鍙栧緱褰撳墠鏃ユ湡,鏍煎紡涓�:YYYYMMDD
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getNowShortDate() throws Exception {
+ String nowDate = "";
+ try {
+ java.sql.Date date = null;
+ date = new java.sql.Date(new Date().getTime());
+ nowDate = sdfShort.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ /**
+ * Descrption:鍙栧緱褰撳墠鏃ユ湡,鏍煎紡涓�:YYYY-MM-DD
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getNowFormateDate() throws Exception {
+ String nowDate = "";
+ try {
+ java.sql.Date date = null;
+ date = new java.sql.Date(new Date().getTime());
+ nowDate = sdfLong.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ /**
+ * Descrption:鍙栧緱褰撳墠鏃ユ湡,鏍煎紡涓�:yyyy-MM-dd HH:mm:ss
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getNowPlusTime() {
+ String nowDate = "";
+ try {
+ java.sql.Date date = null;
+ date = new java.sql.Date(new Date().getTime());
+ nowDate = sdfLongTimePlus.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ /**
+ * Descrption:鍙栧緱褰撳墠鏃ユ湡,鏍煎紡涓�:yyyy-MM-dd HH:mm:ss
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getPlusTime(Date date) {
+ if (date == null)
+ return null;
+ try {
+ String nowDate = sdfLongTimePlus.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ /**
+ * Descrption:鍙栧緱褰撳墠鏃ユ湡,鏍煎紡涓�:yyyy-MM-dd HH:mm:ss
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getShortTime(Date date) {
+
+ if (date == null)
+ return "";
+ try {
+ String nowDate = sdfLong.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ public static String getShortTimeToNull(Date date) {
+
+ if (date == null)
+ return null;
+ try {
+ String nowDate = sdfLong.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+ /**
+ * Descrption:鍙栧緱褰撳墠鏃ユ湡,鏍煎紡涓�:yyyy-MM-dd HH:mm:ss
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getPlusTime2(Date date) {
+
+ if (date == null)
+ return "";
+ try {
+ String nowDate = sdfLongTimePlus.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ /**
+ * Descrption:鍙栧緱褰撳墠鏃ユ湡鍒版绉掓瀬,鏍煎紡涓�:yyyyMMddHHmmssSSSS
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getNowPlusTimeMill() throws Exception {
+ String nowDate = "";
+ try {
+ java.sql.Date date = null;
+ date = new java.sql.Date(new Date().getTime());
+ nowDate = sdfLongTimePlusMill.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ /**
+ * 寰楀埌褰撳墠骞翠唤鍊�:1900
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getNowYear() {
+ String nowYear = "";
+ try {
+ String strTemp = getNowLongTime();
+ nowYear = strTemp.substring(0, 4);
+ return nowYear;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return nowYear;
+ }
+
+ /**
+ * 寰楀埌褰撳墠鏈堜唤鍊�:12
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static Integer getNowMonth() {
+ String nowMonth = "";
+ try {
+ String strTemp = getNowLongTime();
+ nowMonth = strTemp.substring(4, 6);
+ return Integer.valueOf(nowMonth);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 寰楀埌褰撳墠鏃ユ湡鍊�:30
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getNowDay() {
+ String nowDay = "";
+ try {
+ String strTemp = getNowLongTime();
+ nowDay = strTemp.substring(6, 8);
+ return nowDay;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return nowDay;
+ }
+
+ /**
+ * 寰楀埌褰撳墠灏忔椂鍊�:23
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getNowHour() throws Exception {
+ String nowHour = "";
+ try {
+ String strTemp = getNowPlusTimeMill();
+ nowHour = strTemp.substring(8, 10);
+ return nowHour;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ /**
+ * 鏍规嵁绉掓暟杩斿洖鏃跺垎绉�
+ *
+ * @param _second
+ * 绉掓暟
+ * @return String
+ * @throws Exception
+ */
+ public static String getTimeBySecond(String _second) throws Exception {
+ String returnTime = "";
+ long longHour = 0;
+ long longMinu = 0;
+ long longSec = 0;
+ try {
+ longSec = Long.parseLong(_second);
+ if (longSec == 0) {
+ returnTime = "0鏃�0鍒�0绉�";
+ return returnTime;
+ }
+ longHour = longSec / 3600; // 鍙栧緱灏忔椂鏁�
+ longSec = longSec % 3600; // 鍙栧緱浣欎笅鐨勭
+ longMinu = longSec / 60; // 鍙栧緱鍒嗘暟
+ longSec = longSec % 60; // 鍙栧緱浣欎笅鐨勭
+ returnTime = longHour + "鏃�" + longMinu + "鍒�" + longSec + "绉�";
+ return returnTime;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+ public static String getTimeStrBySecond(Long seconds) {
+ String returnTime ="0鏃�0鍒�0绉�";
+ long longHour = 0;
+ long longMinu = 0;
+ long longSec =seconds ==null?0:seconds;
+ try {
+ if (longSec == 0) {
+ returnTime = "0鏃�0鍒�0绉�";
+ return returnTime;
+ }
+ longHour = longSec / 3600; // 鍙栧緱灏忔椂鏁�
+ longSec = longSec % 3600; // 鍙栧緱浣欎笅鐨勭
+ longMinu = longSec / 60; // 鍙栧緱鍒嗘暟
+ longSec = longSec % 60; // 鍙栧緱浣欎笅鐨勭
+ returnTime = longHour + "鏃�" + longMinu + "鍒�" + longSec + "绉�";
+ return returnTime;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return returnTime;
+ }
+
+ /**
+ * Descrption:鍙栧緱褰撳墠鏃ユ湡,鏍煎紡涓�:yyyy-MM-dd HH:mm:ss
+ *
+ * @return String
+ * @throws Exception
+ */
+ public static String getPlusTimeSecond(Date date) throws Exception {
+ if (date == null)
+ return null;
+ try {
+ String nowDate = sdfLongTimePlusSecond.format(date);
+ return nowDate;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ /**
+ * pablo 鏍规嵁姣鏁拌繑鍥炴椂鍒嗙姣
+ *
+ * @param ms_second
+ * 绉掓暟
+ * @return String
+ * @throws Exception
+ */
+ public static String getTimeBySecond(long ms_second) throws Exception {
+ String returnTime = "";
+ long longHour = 0;
+ long longMinu = 0;
+ long longSec = 0;
+ long longMs = ms_second;
+ try {
+ if (longMs == 0) {
+ returnTime = "0鏃�0鍒�0绉�0姣";
+ return returnTime;
+ }
+ longHour = longMs / 3600000; // 鍙栧緱灏忔椂鏁�
+ longMs = longMs % 3600000; // 鍙栧緱浣欎笅鐨勬绉�
+ longMinu = longMs / 60000; // 鍙栧緱鍒嗘暟
+ longMs = longMs % 60000; // 鍙栧緱浣欎笅鐨勬绉�
+ longSec = longMs / 1000; // 鍙栧緱浣欎笅鐨勭
+ longMs = longMs % 1000; // 鍙栧緱浣欎笅鐨勬绉�
+ returnTime = longHour + "鏃�" + longMinu + "鍒�" + longSec + "绉�" + longMs + "姣";
+ return returnTime;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ /**
+ * 寰楀埌鏃ユ湡涓殑骞翠唤
+ *
+ * @param date
+ * 鏃ユ湡
+ * @return yyyy鏍煎紡鐨勫勾浠�
+ */
+ public static int convertDateToYear(Date date) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy", new DateFormatSymbols());
+ return Integer.parseInt(df.format(date));
+ }
+
+ /**
+ * 寰楀埌鏃ユ湡涓勾鏈堢粍鎴愮殑瀛楃涓�
+ *
+ * @param d
+ * 鏃ユ湡
+ * @return yyyyMM鏍煎紡鐨勫勾鏈堝瓧绗︿覆
+ */
+ public static String convertDateToYearMonth(Date d) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyyMM", new DateFormatSymbols());
+ return df.format(d);
+ }
+
+ /**
+ * 寰楀埌鏃ユ湡涓勾鏈堟棩缁勬垚鐨勫瓧绗︿覆
+ *
+ * @param d
+ * 鏃ユ湡
+ * @return yyyyMMdd鏍煎紡鐨勫勾鏈堟棩瀛楃涓�
+ */
+ public static String convertDateToYearMonthDay(Date d) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd", new DateFormatSymbols());
+ return df.format(d);
+ }
+
+ /**
+ * 寰楀埌鏃ユ湡涓殑鏈堜唤
+ *
+ * @param d
+ * 鏃ユ湡
+ * @return yyyy鏍煎紡鐨勫勾浠�
+ */
+ public static String convertDateToMonth(Date d) {
+ SimpleDateFormat df = new SimpleDateFormat("MM", new DateFormatSymbols());
+ return df.format(d);
+ }
+
+ /**
+ * 寰楀埌鏃ユ湡涓殑鏃�
+ *
+ * 鏃ユ湡
+ * @return yyyy鏍煎紡鐨勫勾浠�
+ */
+ public static String convertDateToDay(Date d) {
+ SimpleDateFormat df = new SimpleDateFormat("dd", new DateFormatSymbols());
+ return df.format(d);
+ }
+
+ /**
+ * 寰楀埌鏃ユ湡涓殑灏忔椂
+ *
+ * 鏃ユ湡
+ * @return HH鏍煎紡鐨勫皬鏃�
+ */
+ public static String convertDateToHour(Date d) {
+ SimpleDateFormat df = new SimpleDateFormat("HH", new DateFormatSymbols());
+ return df.format(d);
+ }
+
+ /**
+ * 寰楀埌鏃ユ湡涓殑鍒嗛挓
+ *
+ * @param d
+ * 鏃ユ湡
+ * @return mm鏍煎紡鐨勫垎閽�
+ */
+ public static String convertDateToMinute(Date d) {
+ SimpleDateFormat df = new SimpleDateFormat("mm", new DateFormatSymbols());
+ return df.format(d);
+ }
+
+ /**
+ * 鑾峰彇褰撳墠鏃ユ湡涓烘棩鏈熷瀷
+ *
+ * @return 褰撳墠鏃ユ湡锛宩ava.util.Date绫诲瀷
+ */
+ public static Date getCurrentDate() {
+ Calendar cal = Calendar.getInstance();
+
+ // String currentDate = null;
+ Date d = cal.getTime();
+
+ return d;
+ }
+
+
+ /**
+ * 鑾峰彇褰撳墠鏃ユ湡涓烘棩鏈熷瀷
+ *
+ * @return 褰撳墠鏃ユ湡锛宩ava.util.Date绫诲瀷
+ */
+ public static Date getCurrentDateDelay() {
+ Calendar cal = Calendar.getInstance();
+ cal.add(Calendar.SECOND, 1);
+ // String currentDate = null;
+ Date d = cal.getTime();
+
+ return d;
+ }
+
+ /**
+ * 鑾峰彇褰撳墠骞存湀鐨勫瓧绗︿覆
+ *
+ * @return 褰撳墠骞存湀锛寉yyyMM鏍煎紡
+ */
+ public static String getCurrentYearMonth() {
+ Calendar cal = Calendar.getInstance();
+ String currentYear = (new Integer(cal.get(Calendar.YEAR))).toString();
+ String currentMonth = null;
+ if (cal.get(Calendar.MONTH) < 9)
+ currentMonth = "0" + (new Integer(cal.get(Calendar.MONTH) + 1)).toString();
+ else
+ currentMonth = (new Integer(cal.get(Calendar.MONTH) + 1)).toString();
+ return (currentYear + currentMonth);
+ }
+
+ /**
+ * 鑾峰彇褰撳墠骞翠负鏁村瀷
+ *
+ * @return 鑾峰彇褰撳墠鏃ユ湡涓殑骞达紝int鍨�
+ */
+ public static int getCurrentYear() {
+ Calendar cal = Calendar.getInstance();
+ int currentYear = cal.get(Calendar.YEAR);
+ return currentYear;
+ }
+
+ /**
+ * 鏂板鐨勬牸寮忓寲鏃堕棿绫�,灏嗘椂闂磋繘琛屾爣鍑嗗寲鏍煎紡,閫傜敤浜庡皢鍓嶅彴浼犲叆鐨勬棩鏈熸牸寮忓寲涓哄疄闄呭彲琛岀殑鏃ユ湡
+ * 濡傚皢20050600鏍煎紡鍖栦负20050601,鎴栧皢20050631鏍煎紡鍖栦负20050630
+ *
+ * @param _dateTime
+ * 浼犲叆鐨勫師鏃堕棿涓�
+ * @param _format
+ * 鏍煎紡绗�,YYYYMMDDHH24MISS,YYYYMMDDHH12MISS
+ * @return String
+ * @throws Exception
+ */
+ public static String formatDateTime(String _dateTime, String _format) throws Exception {
+ String returnValue = "";
+ String formatString = _format.toUpperCase();
+ String strYear = "";
+ String strMonth = "";
+ String strDay = "";
+ String strHour = "";
+ String strMinu = "";
+ String strSec = "";
+ int hourType = 12; // 12灏忔椂鍒�,24灏忔椂鍒�
+ int yearType = 1; // 1涓哄钩骞�,2涓洪棸骞�
+ try {
+ if (formatString.indexOf("YYYY") >= 0) {
+ int tempBeginPlace = formatString.indexOf("YYYY");
+ int temEndPlace = tempBeginPlace + 4;
+ strYear = _dateTime.substring(tempBeginPlace, temEndPlace);
+ }
+ if (formatString.indexOf("MM") >= 0) {
+ int tempBeginPlace = formatString.indexOf("MM");
+ int temEndPlace = tempBeginPlace + 2;
+ strMonth = _dateTime.substring(tempBeginPlace, temEndPlace);
+ }
+ if (formatString.indexOf("DD") >= 0) {
+ int tempBeginPlace = formatString.indexOf("DD");
+ int temEndPlace = tempBeginPlace + 2;
+ strDay = _dateTime.substring(tempBeginPlace, temEndPlace);
+ }
+ if (formatString.indexOf("HH24") >= 0) {
+ int tempBeginPlace = formatString.indexOf("HH24");
+ int temEndPlace = tempBeginPlace + 2;
+ strHour = _dateTime.substring(tempBeginPlace, temEndPlace);
+ formatString = formatString.replaceAll("24", "");
+ // 涓轰簡淇濇寔浣嶆暟涓�鑷�,鍘婚櫎24
+ hourType = 24;
+ } else if (formatString.indexOf("HH12") >= 0) {
+ int tempBeginPlace = formatString.indexOf("HH12");
+ int temEndPlace = tempBeginPlace + 2;
+ strHour = _dateTime.substring(tempBeginPlace, temEndPlace);
+ formatString = formatString.replaceAll("12", "");
+ // 涓轰簡淇濇寔浣嶆暟涓�鑷�,鍘婚櫎12
+ hourType = 12;
+ } else if (formatString.indexOf("HH") >= 0) {
+ int tempBeginPlace = formatString.indexOf("HH");
+ int temEndPlace = tempBeginPlace + 2;
+ strHour = _dateTime.substring(tempBeginPlace, temEndPlace);
+ hourType = 12; // 濡傛灉鏈寚瀹氬皬鏃跺埗,鍒欓粯璁や负12灏忔椂鍒�;
+ }
+ if (formatString.indexOf("MI") >= 0) {
+ int tempBeginPlace = formatString.indexOf("MI");
+ int temEndPlace = tempBeginPlace + 2;
+ strMinu = _dateTime.substring(tempBeginPlace, temEndPlace);
+ }
+ if (formatString.indexOf("SS") >= 0) {
+ int tempBeginPlace = formatString.indexOf("SS");
+ int temEndPlace = tempBeginPlace + 2;
+ strSec = _dateTime.substring(tempBeginPlace, temEndPlace);
+ }
+
+ // 鍒ゆ柇鏄惁鏄棸骞�
+ if (!strYear.equals("")) {
+ int intYear = Integer.parseInt(strYear);
+ // 鑳借4鏁撮櫎锛屼絾涓嶈兘琚�100鏁撮櫎鈶� 鑳借4鏁撮櫎锛屼笖鑳借400
+ if (intYear % 4 == 0) {
+ if (intYear % 100 != 0) {
+ yearType = 2;
+ }
+ }
+ if (intYear % 4 == 0) {
+ if (intYear % 400 == 0) {
+ yearType = 2;
+ }
+ }
+ }
+ // 鏍煎紡鍖栨湀
+ if (!strMonth.equals("")) {
+ int intMonth = Integer.parseInt(strMonth);
+ if (intMonth == 0) {
+ strMonth = "01";
+ intMonth = 1;
+ }
+ if (intMonth > 12) {
+ strMonth = "12";
+ intMonth = 12;
+ }
+ }
+
+ // 鏍煎紡鍖栨棩
+ if (!strDay.equals("")) {
+ int intDay = Integer.parseInt(strDay);
+ if (intDay == 0) {
+ strDay = "01";
+ intDay = 1;
+ }
+ if (intDay > 31) {
+ strDay = "31";
+ intDay = 31;
+ }
+ if ((strMonth.equals("01")) || (strMonth.equals("03")) || (strMonth.equals("05"))
+ || (strMonth.equals("07")) || (strMonth.equals("08")) || (strMonth.equals("10"))
+ || (strMonth.equals("12"))) {
+ if (intDay > 31) {
+ strDay = "31";
+ intDay = 31;
+ }
+ }
+ if ((strMonth.equals("02")) || (strMonth.equals("04")) || (strMonth.equals("06"))
+ || (strMonth.equals("09")) || (strMonth.equals("11"))) {
+ if (intDay > 30) {
+ strDay = "30";
+ intDay = 30;
+ }
+ if (strMonth.equals("02")) { // 瀵�2鏈堢殑鐗瑰埆澶勭悊
+ if (yearType == 2) {
+ if (intDay > 29) {
+ strDay = "29";
+ intDay = 29;
+ }
+ } else {
+ if (intDay > 28) {
+ strDay = "28";
+ intDay = 28;
+ }
+ }
+ }
+ }
+
+ // 鏍煎紡鍖栧皬鏃�
+ if (!strHour.equals("")) {
+ int intHour = Integer.parseInt(strHour);
+ if (intHour > 24) {
+ strHour = "24";
+ intHour = 24;
+ }
+ if (hourType == 12) {
+ if (intHour == 0) {
+ intHour = 1;
+ strHour = "01";
+ }
+ if (intHour > 12) {
+ intHour = intHour - 12;
+ strHour = "0" + intHour;
+ }
+ } else {
+ if (intHour > 23) {
+ intHour = 23;
+ strHour = "23";
+ }
+ }
+ }
+ // 鏍煎紡鍖栧垎
+ if (!strMinu.equals("")) {
+ int intMinu = Integer.parseInt(strMinu);
+ if (intMinu > 59) {
+ strMinu = "59";
+ intMinu = 59;
+ }
+ }
+ // 鏍煎紡鍖栫
+ if (!strSec.equals("")) {
+ int intSec = Integer.parseInt(strSec);
+ if (intSec > 59) {
+ strSec = "59";
+ intSec = 59;
+ }
+ }
+ }
+ returnValue = strYear + strMonth + strDay + strHour + strMinu + strSec;
+ return returnValue;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+
+ public static Date StringToDate(String DATE1) {
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ Date dt1 = null;
+ try {
+ dt1 = df.parse(DATE1);
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ return dt1;
+ }
+
+ /**
+ * 鑾峰彇杈撳叆鏍煎紡鐨勬棩鏈熷瓧绗︿覆锛屽瓧绗︿覆閬靛惊Oracle鏍煎紡
+ *
+ * @param d
+ * - 鏃ユ湡
+ * @param format
+ * - 鎸囧畾鏃ユ湡鏍煎紡锛屾牸寮忕殑鍐欐硶涓篛racle鏍煎紡
+ * @return 鎸夋寚瀹氱殑鏃ユ湡鏍煎紡杞崲鍚庣殑鏃ユ湡瀛楃涓�
+ */
+ public static String dateToString(Date d, String format) {
+ if (d == null)
+ return "";
+ Hashtable<Integer, String> h = new Hashtable<Integer, String>();
+ String javaFormat = new String();
+ String s = format.toLowerCase();
+ if (s.indexOf("yyyy") != -1)
+ h.put(new Integer(s.indexOf("yyyy")), "yyyy");
+ else if (s.indexOf("yy") != -1)
+ h.put(new Integer(s.indexOf("yy")), "yy");
+ if (s.indexOf("mm") != -1)
+ h.put(new Integer(s.indexOf("mm")), "MM");
+
+ if (s.indexOf("dd") != -1)
+ h.put(new Integer(s.indexOf("dd")), "dd");
+ if (s.indexOf("hh24") != -1)
+ h.put(new Integer(s.indexOf("hh24")), "HH");
+ if (s.indexOf("mi") != -1)
+ h.put(new Integer(s.indexOf("mi")), "mm");
+ if (s.indexOf("ss") != -1)
+ h.put(new Integer(s.indexOf("ss")), "ss");
+
+ int intStart = 0;
+ while (s.indexOf("-", intStart) != -1) {
+ intStart = s.indexOf("-", intStart);
+ h.put(new Integer(intStart), "-");
+ intStart++;
+ }
+
+ intStart = 0;
+ while (s.indexOf("/", intStart) != -1) {
+ intStart = s.indexOf("/", intStart);
+ h.put(new Integer(intStart), "/");
+ intStart++;
+ }
+
+ intStart = 0;
+ while (s.indexOf(" ", intStart) != -1) {
+ intStart = s.indexOf(" ", intStart);
+ h.put(new Integer(intStart), " ");
+ intStart++;
+ }
+
+ intStart = 0;
+ while (s.indexOf(":", intStart) != -1) {
+ intStart = s.indexOf(":", intStart);
+ h.put(new Integer(intStart), ":");
+ intStart++;
+ }
+
+ if (s.indexOf("骞�") != -1)
+ h.put(new Integer(s.indexOf("骞�")), "骞�");
+ if (s.indexOf("鏈�") != -1)
+ h.put(new Integer(s.indexOf("鏈�")), "鏈�");
+ if (s.indexOf("鏃�") != -1)
+ h.put(new Integer(s.indexOf("鏃�")), "鏃�");
+ if (s.indexOf("鏃�") != -1)
+ h.put(new Integer(s.indexOf("鏃�")), "鏃�");
+ if (s.indexOf("鍒�") != -1)
+ h.put(new Integer(s.indexOf("鍒�")), "鍒�");
+ if (s.indexOf("绉�") != -1)
+ h.put(new Integer(s.indexOf("绉�")), "绉�");
+
+ int i = 0;
+ while (h.size() != 0) {
+ Enumeration<Integer> e = h.keys();
+ int n = 0;
+ while (e.hasMoreElements()) {
+ i = ((Integer) e.nextElement()).intValue();
+ if (i >= n)
+ n = i;
+ }
+ String temp = (String) h.get(new Integer(n));
+ h.remove(new Integer(n));
+
+ javaFormat = temp + javaFormat;
+ }
+ SimpleDateFormat df = new SimpleDateFormat(javaFormat, new DateFormatSymbols());
+
+ return df.format(d);
+ }
+
+ /**
+ * 鑾峰彇杈撳叆鏍煎紡鐨勬棩鏈熷瓧绗︿覆锛屽瓧绗︿覆閬靛惊Oracle鏍煎紡
+ *
+ * @param d
+ * - 鏃ユ湡
+ * @param format
+ * - 鎸囧畾鏃ユ湡鏍煎紡锛屾牸寮忕殑鍐欐硶涓篛racle鏍煎紡
+ * @return 鎸夋寚瀹氱殑鏃ユ湡鏍煎紡杞崲鍚庣殑鏃ユ湡瀛楃涓�
+ */
+ public static String getDate(Date d, String format) {
+ if (d == null)
+ return "";
+ Hashtable<Integer, String> h = new Hashtable<Integer, String>();
+ String javaFormat = new String();
+ String s = format.toLowerCase();
+ if (s.indexOf("yyyy") != -1)
+ h.put(new Integer(s.indexOf("yyyy")), "yyyy");
+ else if (s.indexOf("yy") != -1)
+ h.put(new Integer(s.indexOf("yy")), "yy");
+ if (s.indexOf("mm") != -1)
+ h.put(new Integer(s.indexOf("mm")), "MM");
+
+ if (s.indexOf("dd") != -1)
+ h.put(new Integer(s.indexOf("dd")), "dd");
+ if (s.indexOf("hh24") != -1)
+ h.put(new Integer(s.indexOf("hh24")), "HH");
+ if (s.indexOf("mi") != -1)
+ h.put(new Integer(s.indexOf("mi")), "mm");
+ if (s.indexOf("ss") != -1)
+ h.put(new Integer(s.indexOf("ss")), "ss");
+
+ int intStart = 0;
+ while (s.indexOf("-", intStart) != -1) {
+ intStart = s.indexOf("-", intStart);
+ h.put(new Integer(intStart), "-");
+ intStart++;
+ }
+
+ intStart = 0;
+ while (s.indexOf("/", intStart) != -1) {
+ intStart = s.indexOf("/", intStart);
+ h.put(new Integer(intStart), "/");
+ intStart++;
+ }
+
+ intStart = 0;
+ while (s.indexOf(" ", intStart) != -1) {
+ intStart = s.indexOf(" ", intStart);
+ h.put(new Integer(intStart), " ");
+ intStart++;
+ }
+
+ intStart = 0;
+ while (s.indexOf(":", intStart) != -1) {
+ intStart = s.indexOf(":", intStart);
+ h.put(new Integer(intStart), ":");
+ intStart++;
+ }
+
+ if (s.indexOf("骞�") != -1)
+ h.put(new Integer(s.indexOf("骞�")), "骞�");
+ if (s.indexOf("鏈�") != -1)
+ h.put(new Integer(s.indexOf("鏈�")), "鏈�");
+ if (s.indexOf("鏃�") != -1)
+ h.put(new Integer(s.indexOf("鏃�")), "鏃�");
+ if (s.indexOf("鏃�") != -1)
+ h.put(new Integer(s.indexOf("鏃�")), "鏃�");
+ if (s.indexOf("鍒�") != -1)
+ h.put(new Integer(s.indexOf("鍒�")), "鍒�");
+ if (s.indexOf("绉�") != -1)
+ h.put(new Integer(s.indexOf("绉�")), "绉�");
+
+ int i = 0;
+ while (h.size() != 0) {
+ Enumeration<Integer> e = h.keys();
+ int n = 0;
+ while (e.hasMoreElements()) {
+ i = ((Integer) e.nextElement()).intValue();
+ if (i >= n)
+ n = i;
+ }
+ String temp = (String) h.get(new Integer(n));
+ h.remove(new Integer(n));
+
+ javaFormat = temp + javaFormat;
+ }
+ SimpleDateFormat df = new SimpleDateFormat(javaFormat, new DateFormatSymbols());
+
+ return df.format(d);
+ }
+
+ /**
+ * 鏍规嵁韬唤璇佸彿鐮佽幏鍙栧勾榫�
+ *
+ * @param id
+ * 韬唤璇佸彿
+ * @throws Exception
+ * 韬唤璇佸彿閿欒鏃跺彂鐢�
+ * @return int - 骞撮緞
+ */
+ public static int getAge(String id) throws Exception {
+ int age = -1;
+ int length = id.length();
+ String birthday = "";
+ if (length == 15) {
+ birthday = id.substring(6, 8);
+ birthday = "19" + birthday;
+ } else if (length == 18) {
+ birthday = id.substring(6, 10);
+ } else {
+ throw new Exception("閿欒鐨勮韩浠借瘉鍙�");
+ }
+ int currentYear = Calendar.getInstance().get(Calendar.YEAR);
+ age = currentYear - (new Integer(birthday)).intValue();
+ return age;
+ }
+
+ /**
+ * 鏍规嵁骞撮緞鑾峰彇鍑虹敓骞翠唤
+ *
+ * @param age
+ * int 骞撮緞
+ * @return Date - 鍑虹敓骞翠唤
+ */
+ public static java.sql.Date getDateByAge(int age) {
+ Calendar calendar = Calendar.getInstance(Locale.CHINESE);
+ @SuppressWarnings("unused")
+ long current = calendar.getTimeInMillis();
+ calendar.set(calendar.get(Calendar.YEAR) - age, calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE));
+ return new java.sql.Date((calendar.getTimeInMillis()));
+ }
+
+ /**
+ * 姣旇緝涓や釜鏃ユ湡(骞存湀鍨嬶紝鏍煎紡涓篩YYYMM)涔嬮棿鐩稿樊鏈堜唤
+ *
+ * @param dealMonth
+ * - 寮�濮嬪勾鏈�
+ * @param alterMonth
+ * - 缁撴潫骞存湀
+ * @return alterMonth-dealMonth鐩稿樊鐨勬湀鏁�
+ */
+ public static int calBetweenTwoMonth(String dealMonth, String alterMonth) {
+ int length = 0;
+ if ((dealMonth.length() != 6) || (alterMonth.length() != 6)) {
+ // 姣旇緝骞存湀瀛楃涓茬殑闀垮害涓嶆纭�
+ length = -1;
+
+ } else {
+ int dealInt = Integer.parseInt(dealMonth);
+ int alterInt = Integer.parseInt(alterMonth);
+ if (dealInt < alterInt) {
+ // 绗竴涓勾鏈堝彉閲忓簲澶т簬鎴栫瓑浜庣浜屼釜骞存湀鍙橀噺
+ length = -2;
+ } else {
+ int dealYearInt = Integer.parseInt(dealMonth.substring(0, 4));
+ int dealMonthInt = Integer.parseInt(dealMonth.substring(4, 6));
+ int alterYearInt = Integer.parseInt(alterMonth.substring(0, 4));
+ int alterMonthInt = Integer.parseInt(alterMonth.substring(4, 6));
+ length = (dealYearInt - alterYearInt) * 12 + (dealMonthInt - alterMonthInt);
+ }
+ }
+ return length;
+ }
+
+ /**
+ * 寰楀埌X鍒嗛挓鍚庣殑鏃堕棿(鏃堕棿鏍煎紡)
+ *
+ * @param date
+ * @param minute
+ * @return
+ */
+ public static Date getXMinuteAfterDate(Date date, int minute) {
+ if(date ==null){
+ date = new Date();
+ }
+ Calendar now = Calendar.getInstance();
+ now.setTime(date);
+ now.set(Calendar.MINUTE, now.get(Calendar.MINUTE) + minute);
+ return now.getTime();
+ }
+
+ /**
+ * 寰楀埌涓や釜鏃ユ湡涔嬮棿鐩稿樊鐨勫ぉ鏁�
+ *
+ * @param newDate
+ * 澶х殑鏃ユ湡
+ * @param oldDate
+ * 灏忕殑鏃ユ湡
+ * @return newDate-oldDate鐩稿樊鐨勫ぉ鏁�
+ */
+ public static int daysBetweenDates(Date newDate, Date oldDate) {
+ long days = 0;
+ try {
+ long nDay = 0;
+ long oldDay = 0;
+ if (oldDate == null) {
+ oldDay = 0;
+ } else {
+ oldDay = oldDate.getTime();
+ }
+ if (newDate == null) {
+ nDay = 0;
+ } else {
+ nDay = newDate.getTime();
+ }
+ days = (nDay - oldDay) / 1000 / 60 / 60 / 24;
+ } catch (Exception e) {
+ // TODO: handle exception
+ }
+
+ return (int) days;
+ }
+
+ public static int daysBetweenDates11(Date newDate, Date oldDate) {
+ int days = 0;
+ Calendar calo = Calendar.getInstance();
+ Calendar caln = Calendar.getInstance();
+ calo.setTime(oldDate);
+ caln.setTime(newDate);
+ int oday = calo.get(Calendar.DAY_OF_YEAR);
+ int nyear = caln.get(Calendar.YEAR);
+ int oyear = calo.get(Calendar.YEAR);
+ while (nyear > oyear) {
+ calo.set(Calendar.MONTH, 11);
+ calo.set(Calendar.DATE, 31);
+ days = days + calo.get(Calendar.DAY_OF_YEAR);
+ oyear = oyear + 1;
+ calo.set(Calendar.YEAR, oyear);
+ }
+ int nday = caln.get(Calendar.DAY_OF_YEAR);
+ days = days + nday - oday;
+ return days;
+ }
+
+ /**
+ * 鍙栧緱涓庡師鏃ユ湡鐩稿樊涓�瀹氬ぉ鏁扮殑鏃ユ湡锛岃繑鍥濪ate鍨嬫棩鏈�
+ *
+ * @param date
+ * 鍘熸棩鏈�
+ * @param intBetween
+ * 鐩稿樊鐨勫ぉ鏁�
+ * @return date鍔犱笂intBetween澶╁悗鐨勬棩鏈�
+ */
+ public static Date getDateBetween(Date date, int intBetween) {
+ Calendar calo = Calendar.getInstance();
+ calo.setTime(date);
+ calo.add(Calendar.DATE, intBetween);
+ return calo.getTime();
+ }
+
+ /**
+ * 鎸夋寚瀹氭牸寮忓彇寰椾笌鍘熸棩鏈熺浉宸竴瀹氬ぉ鏁扮殑鏃ユ湡锛岃繑鍥濻tring鍨嬫棩鏈�
+ *
+ * @param date
+ * 鍘熸棩鏈�
+ * @param intBetween
+ * 鐩稿樊鐨勬棩鏈�
+ * @param strFromat
+ * 杩斿洖鏃ユ湡鐨勬牸寮�
+ * @return date鍔犱笂intBetween澶╁悗鐨勬棩鏈�
+ */
+ public static String getDateBetween_String(Date date, int intBetween, String strFromat) {
+ Date dateOld = getDateBetween(date, intBetween);
+ return getDate(dateOld, strFromat);
+ }
+
+ /**
+ * 寰楀埌灏嗗勾鏈堝瀷瀛楃涓插鍔�1鏈堝悗鐨勬棩鏈熷瓧绗︿覆
+ *
+ * @param yearMonth
+ * yyyyMM鏍煎紡
+ * @return yearMonth澧炲姞涓�涓湀鍚庣殑鏃ユ湡锛寉yyyMM鏍煎紡
+ */
+ public static String increaseYearMonth(String yearMonth) {
+ int year = (new Integer(yearMonth.substring(0, 4))).intValue();
+ int month = (new Integer(yearMonth.substring(4, 6))).intValue();
+ month = month + 1;
+ if (month <= 12 && month >= 10)
+ {
+ return yearMonth.substring(0, 4) + (new Integer(month)).toString();
+ }
+ else if (month < 10)
+ {
+ return yearMonth.substring(0, 4) + "0" + (new Integer(month)).toString();
+ }
+ else{
+ // if(month>12)
+ return (new Integer(year + 1)).toString() + "0" + (new Integer(month - 12)).toString();
+ }
+
+ }
+
+ /**
+ * 寰楀埌灏嗗勾鏈堝瀷瀛楃涓插鍔犳寚瀹氭湀鏁板悗鐨勬棩鏈熷瓧绗︿覆
+ *
+ * @param yearMonth
+ * yyyyMM鏍煎紡鏃ユ湡
+ * @param addMonth
+ * 澧炲姞鎸囧畾鏈堟暟
+ * @return yearMonth 澧炲姞addMonth涓湀鍚庣殑鏃ユ湡锛寉yyyMM鏍煎紡
+ */
+ public static String increaseYearMonth(String yearMonth, int addMonth) {
+ int year = (new Integer(yearMonth.substring(0, 4))).intValue();
+ int month = (new Integer(yearMonth.substring(4, 6))).intValue();
+ month = month + addMonth;
+ year = year + month / 12;
+ month = month % 12;
+ if (month <= 12 && month >= 10)
+ return year + (new Integer(month)).toString();
+ else
+ return year + "0" + (new Integer(month)).toString();
+
+ }
+
+ /**
+ * 寰楀埌灏嗗勾鏈堝瀷瀛楃涓插噺鍘�1鏈堝悗鐨勬棩鏈熷瓧绗︿覆
+ *
+ * @param yearMonth
+ * - yyyyMM鏍煎紡
+ * @return - yearMonth鍑忓皯涓�涓湀鐨勬棩鏈燂紝yyyyMM鏍煎紡
+ */
+ public static String descreaseYearMonth(String yearMonth) {
+ int year = (new Integer(yearMonth.substring(0, 4))).intValue();
+ int month = (new Integer(yearMonth.substring(4, 6))).intValue();
+ month = month - 1;
+ if (month >= 10)
+ {
+ return yearMonth.substring(0, 4) + (new Integer(month)).toString();
+ }
+ else if (month > 0 && month < 10)
+ {
+ return yearMonth.substring(0, 4) + "0" + (new Integer(month)).toString();
+ }
+ else
+ {
+ // if(month>12)
+ return (new Integer(year - 1)).toString() + (new Integer(month + 12)).toString();
+ }
+
+ }
+
+ /**
+ * 寰楀埌灏嗗勾鏈堝瀷瀛楃涓插噺鍘�1鏈堝悗鐨勬棩鏈熷瓧绗︿覆
+ *
+ * @param yearMonthDay
+ * - yyyy-MM-dd鏍煎紡
+ * @return - yearMonth鍑忓皯涓�涓湀鐨勬棩鏈燂紝yyyy-MM-dd鏍煎紡
+ */
+ public static String descreaseYearMonth2(String yearMonthDay) {
+ int year = (new Integer(yearMonthDay.substring(0, 4))).intValue();
+ int month = (new Integer(yearMonthDay.substring(5, 7))).intValue();
+ String dd = yearMonthDay.substring(8, 10);
+ month = month - 1;
+ if (month >= 10)
+ return yearMonthDay.substring(0, 4) + "-" + (new Integer(month)).toString() + "-" + dd;
+ else if (month > 0 && month < 10)
+ return yearMonthDay.substring(0, 4) + "0" + "-" + (new Integer(month)).toString() + "-" + dd;
+ else
+ return (new Integer(year - 1)).toString() + "-" + (new Integer(month + 12)).toString() + "-" + dd;
+
+ }
+
+ /**
+ * 姣旇緝涓や釜骞存湀鍨嬫棩鏈熺殑澶у皬锛屾棩鏈熸牸寮忎负yyyyMM 涓や釜瀛椾覆6浣嶏紝鍓�4浠h〃骞达紝鍚�2浠h〃鏈堬紝 <br>
+ * IF 绗竴涓唬琛ㄧ殑鏃堕棿 > 绗簩涓唬琛ㄧ殑鏃堕棿锛岃繑鍥炵湡锛孍LSE 杩斿洖鍋� <br>
+ *
+ * @param s1
+ * 鏃ユ湡1
+ * @param s2
+ * 鏃ユ湡2
+ * @return boolean 濡傛灉s1澶т簬绛変簬s2鍒欒繑鍥炵湡锛屽惁鍒欒繑鍥炲亣
+ */
+ public static boolean yearMonthGreatEqual(String s1, String s2) {
+ String temp1 = s1.substring(0, 4);
+ String temp2 = s2.substring(0, 4);
+ String temp3 = s1.substring(4, 6);
+ String temp4 = s2.substring(4, 6);
+
+ if (Integer.parseInt(temp1) > Integer.parseInt(temp2))
+ return true;
+ else if (Integer.parseInt(temp1) == Integer.parseInt(temp2)) {
+ if (Integer.parseInt(temp3) >= Integer.parseInt(temp4))
+ return true;
+ else
+ return false;
+ } else
+ return false;
+ }
+
+ /**
+ * 姣旇緝涓や釜骞存湀鍨嬫棩鏈熺殑澶у皬锛屾棩鏈熸牸寮忎负yyyyMM 涓や釜瀛椾覆6浣嶏紝鍓�4浠h〃骞达紝鍚�2浠h〃鏈堬紝 <br>
+ * IF 绗竴涓唬琛ㄧ殑鏃堕棿 > 绗簩涓唬琛ㄧ殑鏃堕棿锛岃繑鍥炵湡锛孍LSE 杩斿洖鍋� <br>
+ *
+ * @param s1
+ * 鏃ユ湡1
+ * @param s2
+ * 鏃ユ湡2
+ * @return boolean 濡傛灉s1澶т簬s2鍒欒繑鍥炵湡锛屽惁鍒欒繑鍥炲亣
+ */
+ public static boolean yearMonthGreater(String s1, String s2) {
+ String temp1 = s1.substring(0, 4);
+ String temp2 = s2.substring(0, 4);
+ String temp3 = s1.substring(4, 6);
+ String temp4 = s2.substring(4, 6);
+
+ if (Integer.parseInt(temp1) > Integer.parseInt(temp2))
+ return true;
+ else if (Integer.parseInt(temp1) == Integer.parseInt(temp2)) {
+ if (Integer.parseInt(temp3) > Integer.parseInt(temp4))
+ return true;
+ else
+ return false;
+ } else
+ return false;
+ }
+
+ /**
+ * 灏嗘棩鏈熷瀷鏁版嵁杞崲鎴怬racle瑕佹眰鐨勬爣鍑嗘牸寮忕殑瀛楃涓�
+ *
+ * @param date
+ * 鏃ユ湡
+ * @return 鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+ */
+ public static String getOracleFormatDateStr(Date date) {
+ return getDate(date, "YYYY-MM-DD HH24:MI:SS");
+ }
+
+ /**
+ * 瀛椾覆6浣嶏紝鍓�4浠h〃骞达紝鍚�2浠h〃鏈堬紝 杩斿洖缁欏畾鏃ユ湡涓殑鏈堜唤涓殑鏈�鍚庝竴澶� param term(YYYYMMDD)
+ *
+ * @param term
+ * - 骞存湀锛屾牸寮忎负yyyyMM
+ * @return String 鎸囧畾骞存湀涓鏈堜唤鐨勫ぉ鏁�
+ */
+ public static String getLastDay(String term) {
+
+ int getYear = Integer.parseInt(term.substring(0, 4));
+ int getMonth = Integer.parseInt(term.substring(4, 6));
+
+ String getLastDay = "";
+
+ if (getMonth == 2) {
+ if (getYear % 4 == 0 && getYear % 100 != 0 || getYear % 400 == 0) {
+ getLastDay = "29";
+ } else {
+ getLastDay = "28";
+ }
+ } else if (getMonth == 4 || getMonth == 6 || getMonth == 9 || getMonth == 11) {
+ getLastDay = "30";
+ } else {
+ getLastDay = "31";
+ }
+ return String.valueOf(getYear) + "骞�" + String.valueOf(getMonth) + "鏈�" + getLastDay + "鏃�";
+ }
+
+ /**
+ * 杩斿洖涓や釜骞存湀(渚嬪锛�200206)涔嬮棿鐩稿樊鐨勬湀鏁帮紝骞存湀鏍煎紡涓簓yyyMM
+ *
+ * @param strDateBegin
+ * - String
+ * @param strDateEnd
+ * String
+ * @return String strDateEnd-strDateBegin鐩稿樊鐨勬湀鏁�
+ */
+ public static String getMonthBetween(String strDateBegin, String strDateEnd) {
+ try {
+ int intMonthBegin;
+ int intMonthEnd;
+ String strOut;
+ if (strDateBegin.equals("") || strDateEnd.equals("") || strDateBegin.length() != 6
+ || strDateEnd.length() != 6)
+ {
+ strOut = "";
+ }
+ else {
+ intMonthBegin = Integer.parseInt(strDateBegin.substring(0, 4)) * 12
+ + Integer.parseInt(strDateBegin.substring(4, 6));
+ intMonthEnd = Integer.parseInt(strDateEnd.substring(0, 4)) * 12
+ + Integer.parseInt(strDateEnd.substring(4, 6));
+ strOut = String.valueOf(intMonthBegin - intMonthEnd);
+ }
+ return strOut;
+ } catch (Exception e) {
+ return "0";
+ }
+ }
+
+ /**
+ * 灏唝yyyMMDD鏍煎紡鐨勬棩鏈熻浆鎹负yyyy-MM-DD鏍煎紡鐨勬棩鏈� 杩斿洖甯�'-'鐨勬棩鏈�(渚嬪锛�20020612 杞崲涓� 2002-06-12)
+ *
+ * @param strDate
+ * String yyyyMMDD鏍煎紡鐨勬棩鏈�
+ * @return String - yyyy-MM-DD鏍煎紡鐨勬棩鏈�
+ */
+ public static String getStrHaveAcross(String strDate) {
+ try {
+ return strDate.substring(0, 4) + "-" + strDate.substring(4, 6) + "-" + strDate.substring(6, 8);
+ } catch (Exception e) {
+ return strDate;
+ }
+ }
+
+ /**
+ * 鍙栧緱褰撳墠鏃ユ湡鐨勪笅涓�涓湀鐨勭涓�澶� add by yaojp 2002-10-08
+ *
+ * @return 褰撳墠鏃ユ湡鐨勪笅涓湀鐨勭涓�澶╋紝鏍煎紡涓簓yyyMMDD
+ */
+ public static String getFirstDayOfNextMonth() {
+ try {
+ return increaseYearMonth(getNowShortDate().substring(0, 6)) + "01";
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * 鍙栧緱褰撳墠鏃ユ湡鐨勪笅涓�涓湀鐨勭涓�澶� add by zhouning 2006-09-13
+ *
+ * @return 褰撳墠鏃ユ湡鐨勪笅涓湀鐨勭涓�澶╋紝鏍煎紡涓簓yyyMMDD
+ */
+ public static String getFirstDayOfThisMonth() {
+ try {
+ return getNowShortDate().substring(0, 6) + "01";
+ } catch (Exception e) {
+ return "";
+ }
+ }
+ public static List<Date> getThisMonthDateList() {
+ List<Date> dateList = new ArrayList<>();
+ try {
+ Calendar calendar = Calendar.getInstance();
+ int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+ calendar.set(Calendar.HOUR,0);
+ calendar.set(Calendar.MINUTE,0);
+ calendar.set(Calendar.SECOND,0);
+ calendar.set(Calendar.MILLISECOND,0);
+ for (int i = 0; i < daysInMonth; i++) {
+ calendar.set(Calendar.DAY_OF_MONTH,i+1);
+ dateList.add(calendar.getTime());
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ return dateList;
+ }
+ public static List<Date> getThisYearMonthList() {
+ List<Date> dateList = new ArrayList<>();
+ try {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(Calendar.DAY_OF_MONTH,1);
+ calendar.set(Calendar.HOUR,0);
+ calendar.set(Calendar.MINUTE,0);
+ calendar.set(Calendar.SECOND,0);
+ calendar.set(Calendar.MILLISECOND,0);
+ for (int i = 0; i < 12; i++) {
+ calendar.set(Calendar.MONTH,i);
+ dateList.add(calendar.getTime());
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ return dateList;
+ }
+ public static Date getFirstThisYearDate() {
+ try {
+ return sdfShort.parse( getNowShortDate().substring(0, 4) + "0101");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ public static String getFirstDayCurrentMonth() {
+ try {
+ return getDateLong(new Date()).substring(0, 7) + "-01";
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ /**
+ * 灏唝yyyMM鍚勫紡杞崲鎴恲yyy骞碝M鏈堟牸寮�
+ *
+ * @param yearMonth
+ * 骞存湀绫诲瀷鐨勫瓧绗︿覆
+ * @return String
+ */
+ public static String getYearAndMonth(String yearMonth) {
+ if (null == yearMonth)
+ return "";
+ String ym = yearMonth.trim();
+ if (6 != ym.length())
+ return ym;
+ String year = ym.substring(0, 4);
+ String month = ym.substring(4);
+ return new StringBuffer(year).append("骞�").append(month).append("鏈�").toString();
+ }
+ /**
+ * 灏唝yyyMM鍚勫紡杞崲鎴恲yyy骞碝M鏈堟牸寮�
+ *
+ * @param date
+ * 骞存湀绫诲瀷鐨勫瓧绗︿覆
+ * @return String
+ */
+ public static String getYear(Date date) {
+ if (null == date)
+ {
+ return "";
+ }
+
+ String ym = getPlusTime2(date).trim();
+ if (StringUtils.isBlank(ym))
+ {
+ return "";
+ }
+ String year = ym.substring(0, 4);
+ return year;
+ }
+
+ /**
+ * 灏嗚緭鍏ョ殑Integer绫诲瀷鐨勬湀鏁拌浆鍖栨垚"X骞碭鏈�"鏍煎紡鐨勫瓧绗︿覆
+ *
+ * @param month
+ * Integer
+ * @return String
+ */
+ public static String month2YearMonth(String month) {
+ String yearMonth = "";
+ int smonth = 0;
+ int year = 0;
+ int rmonth = 0;
+
+ if ((null == month) || ("0".equals(month)) || "".equals(month.trim())) {
+ return "0鏈�";
+ }
+
+ smonth = Integer.parseInt(month);
+ year = smonth / 12;
+ rmonth = smonth % 12;
+
+ if (year > 0) {
+ yearMonth = year + "骞�";
+ }
+ if (rmonth > 0) {
+ yearMonth += rmonth + "涓湀";
+ }
+
+ return yearMonth;
+ }
+
+ /**
+ * 灏唝yyyMM鍚勫紡杞崲鎴恲yyy骞碝M鏈堟牸寮�
+ *
+ * @param month
+ * 鏈�
+ * @return 杩斿洖骞存湀鍨嬫牸寮忕殑鏃ユ湡
+ */
+ public static String getYearMonthByMonth(String month) {
+ if (null == month)
+ return null;
+ String ym = month.trim();
+ if (6 != ym.length())
+ return ym;
+ String year = ym.substring(0, 4);
+ @SuppressWarnings("unused")
+ String month1 = ym.substring(4);
+ return new StringBuffer(year).append("骞�").append(month).append("鏈�").toString();
+ }
+
+ /**
+ * 寰楀埌灏哾ate澧炲姞鎸囧畾鏈堟暟鍚庣殑date
+ *
+ * @param date
+ * 鏃ユ湡
+ * @param intBetween
+ * 澧炲姞鐨勬湀浠�
+ * @return date 鍔犱笂intBetween鏈堟暟鍚庣殑鏃ユ湡
+ */
+ public static Date increaseMonth(Date date, int intBetween) {
+ Calendar calo = Calendar.getInstance();
+ calo.setTime(date);
+ calo.add(Calendar.MONTH, intBetween);
+ return calo.getTime();
+ }
+
+ /**
+ * 寰楀埌灏哾ate澧炲姞鎸囧畾澶╂暟鍚庣殑date
+ *
+ * @param date
+ * 鏃ユ湡
+ * @param intBetween
+ * 澧炲姞鐨勫ぉ鏁�
+ * @return date 鍔犱笂intBetween澶╂暟鍚庣殑鏃ユ湡
+ */
+ public static Date increaseDay(Date date, int intBetween) {
+ if (date == null) {
+ return null;
+ }
+ Calendar calo = Calendar.getInstance();
+ calo.setTime(date);
+ calo.add(Calendar.DATE, intBetween);
+ return calo.getTime();
+ }
+
+ /**
+ * 寰楀埌灏哾ate澧炲姞鎸囧畾骞存暟鍚庣殑date
+ *
+ * @param date
+ * 鏃ユ湡
+ * @param intBetween
+ * 澧炲姞鐨勫勾鏁�
+ * @return date鍔犱笂intBetween骞存暟鍚庣殑鏃ユ湡
+ */
+ public static Date increaseYear(Date date, int intBetween) {
+ Calendar calo = Calendar.getInstance();
+ calo.setTime(date);
+ calo.add(Calendar.YEAR, intBetween);
+ return calo.getTime();
+ }
+
+ /**
+ * 姣旇緝涓や釜鏃堕棿鍏堝悗
+ *
+ * @param str1
+ * 浼犲叆鐨勫瓧绗︿覆
+ * @param str2
+ * 浼犲叆鐨勫瓧绗︿覆
+ * @return int negative integer, zero, or a positive integer as str1 is less
+ * than, equal to, or greater than str2
+ */
+ public static int compareDate(String str1, String str2) {
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+ Date date1 = null, date2 = null;
+ try {
+ date1 = formatter.parse(str1);
+ date2 = formatter.parse(str2);
+ } catch (ParseException ex) {
+ ex.printStackTrace();
+ }
+ return date1.compareTo(date2);
+ }
+
+ /**
+ * 姣旇緝涓や釜鏃堕棿鍏堝悗
+ *
+ * @param date1
+ * 浼犲叆鐨勫瓧绗︿覆
+ * @param date2
+ * 浼犲叆鐨勫瓧绗︿覆
+ * @return int negative integer, zero, or a positive integer as str1 is less
+ * than, equal to, or greater than str2
+ */
+ public static int compareDate(Date date1, Date date2) {
+ if (date1 == null && date2 == null) {
+ return 0;
+ }
+ if (date1 == null) {
+ return -1;
+ }
+ if (date2 == null) {
+ return 1;
+ }
+
+ return date2.compareTo(date1);
+ }
+
+ public static int compare_date(Date dt1, Date dt2, Date dtime) {
+ try {
+ if (dtime.compareTo(dt1) >= 0 && dt2.compareTo(dtime) >= 0) {
+ return 1;
+ } else {
+ return -1;
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ return 0;
+ }
+
+ public static int compareDate(String str1, Date date2) {
+ Date date1 = getDateByString(str1);
+ return date1.compareTo(date2);
+ }
+
+ public static int compareDate(String format, String str1, Date date2) {
+ Date date1 = null;
+ try {
+ date1 = fromStringToDate(format, str1);
+ } catch (Exception e) {
+ // TODO 鑷姩鐢熸垚 catch 鍧�
+ e.printStackTrace();
+ }
+ return date1.compareTo(date2);
+ }
+
+ /**
+ * 鏍规嵁浼犲叆鐨勬棩鏈熷瓧绗︿覆杞崲鎴愮浉搴旂殑鏃ユ湡瀵硅薄锛屽鏋滃瓧绗︿覆涓虹┖鎴栦笉绗﹀悎鏃ユ湡鏍� 寮忥紝鍒欒繑鍥炲綋鍓嶆椂闂淬��
+ *
+ * @param strDate
+ * String 鏃ユ湡瀛楃涓�
+ * @return java.sql.Timestamp 鏃ユ湡瀵硅薄
+ */
+ public static Timestamp getDateByString(String strDate) {
+ if (strDate.trim().equals("")) {
+ return new Timestamp(System.currentTimeMillis());
+ }
+ try {
+ strDate = getFormattedDate(strDate, "yyyy-MM-dd HH:mm:ss") + ".000000000";
+ return Timestamp.valueOf(strDate);
+ } catch (Exception ex) {
+ return new Timestamp(System.currentTimeMillis());
+ }
+ }
+
+
+ // /**
+ // * 鏍规嵁鍙傛暟鍚嶇О锛屼粠request瀵硅薄涓彇鍑鸿鍙傛暟锛屽苟鎶婅鍙傛暟杞崲鎴怗B2312缂栫爜鐨勫瓧绗﹂泦銆�
+ // * @param request 璇锋眰瀵硅薄
+ // * @param strParamName 鍙傛暟鍚嶇О
+ // * @return java.sql.Date 杞崲鍚庣殑鍙傛暟鍊�
+ // * */
+ // public static java.sql.Timestamp getDateFromReqParam(HttpServletRequest
+ // request, String strParamName)
+ // {
+ // String strStr =
+ // StringUtil.getNotNullStr(request.getParameter(strParamName));
+ // return getDateByString(strStr);
+ // }
+
+ /**
+ * 寰楀埌褰撳墠鏃ユ湡锛屾牸寮弝yyy-MM-dd銆�
+ *
+ * @return String 鏍煎紡鍖栫殑鏃ユ湡瀛楃涓�
+ */
+ public static String getToday() {
+ Date cDate = new Date();
+ SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ return cSimpleDateFormat.format(cDate);
+ }
+
+ /**
+ * 寰楀埌褰撳墠鏃ユ湡锛屾牸寮弝yyy-MM-dd銆�
+ *
+ * @return String 鏍煎紡鍖栫殑鏃ユ湡瀛楃涓�
+ */
+ public static String getYesterday() {
+ Date cDate = new Date();
+ cDate.setTime(cDate.getTime() - 24 * 3600 * 1000);
+ SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ return cSimpleDateFormat.format(cDate);
+ }
+
+ /**
+ * 寰楀埌褰撳墠鏃ユ湡锛屾牸寮弝yyy-MM-dd銆�
+ *
+ * @return String 鏍煎紡鍖栫殑鏃ユ湡瀛楃涓�
+ */
+ public static String getTomorrow() {
+ Date cDate = new Date();
+ cDate.setTime(cDate.getTime() + 24 * 3600 * 1000);
+ SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ return cSimpleDateFormat.format(cDate);
+ }
+
+ /**
+ * 杩斿洖榛樿鐨勫姛鑳界敓鏁堢殑鏃堕棿锛�1900/01/01銆�
+ *
+ * @return String 榛樿鐨勫疄鏁堟椂闂村瓧绗︿覆
+ */
+ public static String getDefaultValidDate() {
+ return "1900-01-01";
+ }
+
+ /**
+ * 杩斿洖榛樿鐨勫姛鑳藉け鏁堢殑鏃堕棿锛�2099/12/31銆�
+ *
+ * @return String 榛樿鐨勫疄鏁堟椂闂村瓧绗︿覆
+ */
+ public static String getDefaultExpireDate() {
+ return "2099-12-31";
+ }
+
+ /**
+ * 寰楀埌褰撳墠鏃ユ湡鏃堕棿,鏍煎紡涓簓yyy-MM-dd hh:mm:ss.
+ *
+ * @return String
+ */
+ public static String getCurrDateTime() {
+ Timestamp date = new Timestamp(System.currentTimeMillis());
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+ return formatter.format(date);
+ }
+
+ /**
+ * 寰楀埌褰撳墠鏃ユ湡鏃堕棿,鏍煎紡涓簓yyy-MM-dd.
+ *
+ * @return String
+ */
+ public static String getCurrDate() {
+ Timestamp date = new Timestamp(System.currentTimeMillis());
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+ return formatter.format(date);
+ }
+
+ /**
+ * 寰楀埌鎸囧畾鐨勬棩鏈燂紝濡備竴骞翠笁涓湀闆朵節澶╁悗(浠yyy/MM/dd鏍煎紡鏄剧ず)鍙傛暟涓�("yyyy/MM/dd",1,3,9)
+ *
+ * @param strFormat
+ * strFormat
+ * @param iYear
+ * iYear
+ * @param iMonth
+ * iMonth
+ * @param iDate
+ * iDate
+ * @return String
+ */
+ public static String getSpecDate(String strFormat, int iYear, int iMonth, int iDate) {
+ Calendar rightNow = Calendar.getInstance();
+ rightNow.set(Calendar.YEAR, rightNow.get(Calendar.YEAR) + iYear);
+ rightNow.set(Calendar.MONTH, rightNow.get(Calendar.MONTH) + iMonth);
+ rightNow.set(Calendar.DATE, rightNow.get(Calendar.DATE) + iDate);
+ SimpleDateFormat df = new SimpleDateFormat(strFormat);
+ return df.format(rightNow.getTime());
+ }
+
+ /**
+ * 瀵硅緭鍏ョ殑鏃ユ湡瀛楃涓茶繘琛岄粯璁ょ殑鏍煎紡yyyy-MM-dd HH:mm:ss杞崲銆�
+ *
+ * @param strDate
+ * String 闇�瑕佽繘琛屾牸寮忓寲鐨勬棩鏈熷瓧绗︿覆
+ * @return String 缁忚繃鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+ */
+ public static String getDefaultFormattedDate(String strDate) {
+ return getFormattedDate(strDate, "yyyy-MM-dd HH:mm:ss");
+ }
+
+ /**
+ * 瀵硅緭鍏ョ殑鏃ユ湡杩涜榛樿鐨勬牸寮弝yyy-MM-dd HH:mm:ss杞崲銆�
+ *
+ * @param dtDate
+ * 闇�瑕佽繘琛屾牸寮忓寲鐨勬棩鏈�
+ * @return String 缁忚繃鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+ */
+ public static String getDefaultFormattedDate(Timestamp dtDate) {
+ return getFormattedDate(dtDate, "yyyy-MM-dd HH:mm:ss");
+ }
+
+ public static Timestamp getNullBirthDay() {
+ return new Timestamp(0);
+ }
+
+ /**
+ * 瀵硅緭鍏ョ殑鏃ユ湡瀛楃涓叉寜鐓ч粯璁ょ殑鏍煎紡yyyy-MM-dd杞崲.
+ *
+ * @param strDate
+ * String 闇�瑕佽繘琛屾牸寮忓寲鐨勬棩鏈熷瓧绗︿覆
+ * @return String 缁忚繃鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+ */
+ public static String getFormattedDate(String strDate) {
+ return getFormattedDate(strDate, "yyyy-MM-dd");
+ }
+
+ /**
+ * 瀵硅緭鍏ョ殑鏃ユ湡瀛楃涓茶繘琛屾牸寮忓寲,濡傛灉杈撳叆鐨勬槸0000/00/00 00:00:00鍒欒繑鍥炵┖涓�.
+ *
+ * @param strDate
+ * String 闇�瑕佽繘琛屾牸寮忓寲鐨勬棩鏈熷瓧绗︿覆
+ * @param strFormatTo
+ * String 瑕佽浆鎹㈢殑鏃ユ湡鏍煎紡
+ * @return String 缁忚繃鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+ */
+ public static String getFormattedDate(String strDate, String strFormatTo) {
+ if (strDate == null || strDate.trim().equals("")) {
+ return "";
+ }
+ strDate = strDate.replace('/', '-');
+ strFormatTo = strFormatTo.replace('/', '-');
+ if (strDate.equals("0000-00-00 00:00:00") || strDate.equals("1800-01-01 00:00:00")) {
+ return "";
+ }
+ String formatStr = strFormatTo; // "yyyyMMdd";
+ if (strDate == null || strDate.trim().equals("")) {
+ return "";
+ }
+ switch (strDate.trim().length()) {
+ case 6:
+ if (strDate.substring(0, 1).equals("0")) {
+ formatStr = "yyMMdd";
+ } else {
+ formatStr = "yyyyMM";
+ }
+ break;
+ case 8:
+ formatStr = "yyyyMMdd";
+ break;
+ case 10:
+ if (strDate.indexOf("-") == -1) {
+ formatStr = "yyyy/MM/dd";
+ } else {
+ formatStr = "yyyy-MM-dd";
+ }
+ break;
+ case 11:
+ if (strDate.getBytes().length == 14) {
+ formatStr = "yyyy骞碝M鏈坉d鏃�";
+ } else {
+ return "";
+ }
+ case 14:
+ formatStr = "yyyyMMddHHmmss";
+ break;
+ case 19:
+ if (strDate.indexOf("-") == -1) {
+ formatStr = "yyyy/MM/dd HH:mm:ss";
+ } else {
+ formatStr = "yyyy-MM-dd HH:mm:ss";
+ }
+ break;
+ case 21:
+ if (strDate.indexOf("-") == -1) {
+ formatStr = "yyyy/MM/dd HH:mm:ss.S";
+ } else {
+ formatStr = "yyyy-MM-dd HH:mm:ss.S";
+ }
+ break;
+ default:
+ return strDate.trim();
+ }
+ try {
+ SimpleDateFormat formatter = new SimpleDateFormat(formatStr);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(formatter.parse(strDate));
+ formatter = new SimpleDateFormat(strFormatTo);
+ return formatter.format(calendar.getTime());
+ } catch (Exception e) {
+ // Common.printLog("杞崲鏃ユ湡瀛楃涓叉牸寮忔椂鍑洪敊;" + e.getMessage());
+ return "";
+ }
+ }
+
+ /**
+ * 瀵硅緭鍏ョ殑鏃ユ湡鎸夌収榛樿鐨勬牸寮弝yyy-MM-dd杞崲.
+ *
+ * @param dtDate
+ * 闇�瑕佽繘琛屾牸寮忓寲鐨勬棩鏈熷瓧绗︿覆
+ * @return String 缁忚繃鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+ */
+ public static String getFormattedDate(Timestamp dtDate) {
+ return getFormattedDate(dtDate, "yyyy-MM-dd");
+ }
+
+ /**
+ * 瀵硅緭鍏ョ殑鏃ユ湡杩涜鏍煎紡鍖�, 濡傛灉杈撳叆鐨勬棩鏈熸槸null鍒欒繑鍥炵┖涓�.
+ *
+ * @param dtDate
+ * java.sql.Timestamp 闇�瑕佽繘琛屾牸寮忓寲鐨勬棩鏈熷瓧绗︿覆
+ * @param strFormatTo
+ * String 瑕佽浆鎹㈢殑鏃ユ湡鏍煎紡
+ * @return String 缁忚繃鏍煎紡鍖栧悗鐨勫瓧绗︿覆
+ */
+ public static String getFormattedDate(Timestamp dtDate, String strFormatTo) {
+ if (dtDate == null) {
+ return "";
+ }
+ if (dtDate.equals(new Timestamp(0))) {
+ return "";
+ }
+ strFormatTo = strFormatTo.replace('/', '-');
+ try {
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy");
+ if (Integer.parseInt(formatter.format(dtDate)) < 1900) {
+ return "";
+ } else {
+ formatter = new SimpleDateFormat(strFormatTo);
+ return formatter.format(dtDate);
+ }
+ } catch (Exception e) {
+ // Common.printLog("杞崲鏃ユ湡瀛楃涓叉牸寮忔椂鍑洪敊;" + e.getMessage());
+ return "";
+ }
+ }
+
+ /**
+ * 鎶婄鏁拌浆鎹㈡垚hh:mm:ss鏍煎紡
+ *
+ * @param lSecond
+ * long
+ * @return String
+ */
+ public static String getTimeFormat(long lSecond) {
+ String szTime = new String();
+
+ if (lSecond <= 0) {
+ szTime = "00" + ":" + "00" + ":" + "00";
+ } else {
+ long hour = lSecond / 3600;
+ long minute = (lSecond - hour * 3600) / 60;
+ long second = (lSecond - hour * 3600 - minute * 60);
+
+ if (hour <= 0) {
+ szTime = "00";
+ } else if (hour < 10) {
+ szTime = "0" + String.valueOf(hour);
+ } else {
+ szTime = String.valueOf(hour);
+ }
+ szTime = szTime + ":";
+
+ if (minute <= 0) {
+ szTime = szTime + "00";
+ } else if (minute < 10) {
+ szTime = szTime + "0" + String.valueOf(minute);
+ } else {
+ szTime = szTime + String.valueOf(minute);
+ }
+ szTime = szTime + ":";
+
+ if (second <= 0) {
+ szTime = szTime + "00";
+ } else if (second < 10) {
+ szTime = szTime + "0" + String.valueOf(second);
+ } else {
+ szTime = szTime + String.valueOf(second);
+ }
+ }
+
+ return szTime;
+ }
+
+ public static String getFormattedDateUtil(Date dtDate, String strFormatTo) {
+ if (dtDate == null) {
+ return "";
+ }
+ strFormatTo = strFormatTo.replace('/', '-');
+ try {
+ SimpleDateFormat formatter = new SimpleDateFormat(strFormatTo);
+ return formatter.format(dtDate);
+ } catch (Exception e) {
+ // Common.printLog("杞崲鏃ユ湡瀛楃涓叉牸寮忔椂鍑洪敊;" + e.getMessage());
+ return "";
+ }
+ }
+
+ /**
+ * 寰楀嚭涓や釜鏃ユ湡涔嬮棿鐨勯棿闅斿ぉ鏁�
+ *
+ * @param strFromDate
+ * 鏍煎紡涓簓yyy-MM-dd
+ * @param strToDate
+ * 鏍煎紡涓簓yyy-MM-dd
+ * @return int
+ */
+ public static long getBetweenDays(String strFromDate, String strToDate) {
+ long m_intervalday = 0;// 鍒濆鍖栨椂闂撮棿闅旂殑鍊间负0
+ // 浣跨敤鐨勬椂闂存牸寮忎负yyyy-MM-dd
+ SimpleDateFormat m_simpledateformat = new SimpleDateFormat("yyyy-MM-dd");
+ try {
+ Date fromDate = m_simpledateformat.parse(strFromDate);
+ Date toDate = m_simpledateformat.parse(strToDate);
+ m_intervalday = toDate.getTime() - fromDate.getTime();// 璁$畻鎵�寰椾负寰鏁�
+ m_intervalday = m_intervalday / 1000 / 60 / 60 / 24;// 璁$畻鎵�寰楃殑澶╂暟
+
+ return m_intervalday + 1;
+ } catch (Exception e) {
+ return Integer.MIN_VALUE;
+ }
+ }
+
+ // 鍘烡ateUtil鏂规硶
+ private static DateUtil instance = null;
+
+ private static final Locale local = Locale.ENGLISH;
+
+ public static synchronized DateUtil getInstance() {
+ if (instance == null) {
+ instance = new DateUtil();
+ }
+ return instance;
+ }
+
+ public static final long millisInDay = 86400000;
+
+ // some static date formats
+ private static SimpleDateFormat[] mDateFormats = loadDateFormats();
+
+ private static final SimpleDateFormat mFormat8chars = new SimpleDateFormat("yyyyMMdd");
+
+ private static final SimpleDateFormat mFormatIso8601Day = new SimpleDateFormat("yyyy-MM-dd");
+
+ private static final SimpleDateFormat mFormatIso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+
+ // http://www.w3.org/Protocols/rfc822/Overview.html#z28
+ private static final SimpleDateFormat mFormatRfc822 = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z");
+
+ private static final SimpleDateFormat mFormatTradeEasy = new SimpleDateFormat("MM/dd/yyyy HH:mm");
+
+ private static final SimpleDateFormat mFormatTradeEasyMMddyyyy = new SimpleDateFormat("MM/dd/yyyy");
+
+ // add by huyanzhi
+ private static final SimpleDateFormat mFormatTradeEasyProduct = new SimpleDateFormat("dd/MM/yyyy");
+ // end
+
+ private static final SimpleDateFormat mFormatExpire = new SimpleDateFormat("MMMM dd, yyyy", local);
+
+ private static SimpleDateFormat[] loadDateFormats() {
+ SimpleDateFormat[] temp = {
+ // new SimpleDateFormat("MM/dd/yyyy hh:mm:ss.SSS a"),
+ new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy"),
+ // standard Date.toString() results
+ new SimpleDateFormat("M/d/yy hh:mm:ss"), new SimpleDateFormat("M/d/yyyy hh:mm:ss"),
+ new SimpleDateFormat("M/d/yy hh:mm a"), new SimpleDateFormat("M/d/yyyy hh:mm a"),
+ new SimpleDateFormat("M/d/yy HH:mm"), new SimpleDateFormat("M/d/yyyy HH:mm"),
+ new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"), new SimpleDateFormat("yy-MM-dd HH:mm:ss.SSS"),
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"),
+ // standard Timestamp.toString() results
+ new SimpleDateFormat("M-d-yy HH:mm"), new SimpleDateFormat("M-d-yyyy HH:mm"),
+ new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS"), new SimpleDateFormat("M/d/yy"),
+ new SimpleDateFormat("M/d/yyyy"), new SimpleDateFormat("M-d-yy"), new SimpleDateFormat("M-d-yyyy"),
+ new SimpleDateFormat("MMMM d, yyyyy"), new SimpleDateFormat("MMM d, yyyyy") };
+
+ return temp;
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Gets the array of SimpleDateFormats that DateUtil knows about.
+ **/
+ private static SimpleDateFormat[] getFormats() {
+ return mDateFormats;
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Returns a Date set to the last possible millisecond of the day, just
+ * before midnight. If a null day is passed in, a new Date is created.
+ * midnight (00m 00h 00s)
+ */
+ public static Date getEndOfDay(Date day) {
+ return getEndOfDay(day, Calendar.getInstance());
+ }
+
+ public static Date getEndOfDay(Date day, Calendar cal) {
+ if (day == null)
+ day = new Date();
+ cal.setTime(day);
+ cal.set(Calendar.HOUR_OF_DAY, cal.getMaximum(Calendar.HOUR_OF_DAY));
+ cal.set(Calendar.MINUTE, cal.getMaximum(Calendar.MINUTE));
+ cal.set(Calendar.SECOND, cal.getMaximum(Calendar.SECOND));
+ cal.set(Calendar.MILLISECOND, cal.getMaximum(Calendar.MILLISECOND));
+ return cal.getTime();
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Returns a Date set to the first possible millisecond of the day, just
+ * after midnight. If a null day is passed in, a new Date is created.
+ * midnight (00m 00h 00s)
+ */
+ public static Date getStartOfDay(Date day) {
+ return getStartOfDay(day, Calendar.getInstance());
+ }
+
+ /**
+ * Returns a Date set to the first possible millisecond of the day, just
+ * after midnight. If a null day is passed in, a new Date is created.
+ * midnight (00m 00h 00s)
+ */
+ public static Date getStartOfDay(Date day, Calendar cal) {
+ if (day == null)
+ day = new Date();
+ cal.setTime(day);
+ cal.set(Calendar.HOUR_OF_DAY, cal.getMinimum(Calendar.HOUR_OF_DAY));
+ cal.set(Calendar.MINUTE, cal.getMinimum(Calendar.MINUTE));
+ cal.set(Calendar.SECOND, cal.getMinimum(Calendar.SECOND));
+ cal.set(Calendar.MILLISECOND, cal.getMinimum(Calendar.MILLISECOND));
+ return cal.getTime();
+ }
+
+ /**
+ * Returns a Date set just to Noon, to the closest possible millisecond of
+ * the day. If a null day is passed in, a new Date is created. nnoon (00m
+ * 12h 00s)
+ */
+ public static Date getNoonOfDay(Date day, Calendar cal) {
+ if (day == null)
+ {
+ day = new Date();
+ }
+ cal.setTime(day);
+ cal.set(Calendar.HOUR_OF_DAY, 12);
+ cal.set(Calendar.MINUTE, cal.getMinimum(Calendar.MINUTE));
+ cal.set(Calendar.SECOND, cal.getMinimum(Calendar.SECOND));
+ cal.set(Calendar.MILLISECOND, cal.getMinimum(Calendar.MILLISECOND));
+ return cal.getTime();
+ }
+
+ /**
+ * 鏍规嵁浼犲叆鐨勬棩鏈熷瓧绗︿覆杞崲鎴愮浉搴旂殑鏃ユ湡瀵硅薄锛屽鏋滃瓧绗︿覆涓虹┖鎴栦笉绗﹀悎鏃ユ湡鏍� 寮忥紝鍒欒繑鍥炲綋鍓嶆椂闂淬��
+ *
+ * @param strDate
+ * String 鏃ユ湡瀛楃涓�
+ * @return java.util.Date 鏃ユ湡瀵硅薄
+ */
+ public static Date getDateFromString(String strDate) {
+ if (StringUtils.isEmpty(strDate)) {
+ return new Date(System.currentTimeMillis());
+ }
+ try {
+ return sdfLongTimePlus.parse(strDate);
+ } catch (Exception ex) {
+ return new Timestamp(System.currentTimeMillis());
+ }
+ }
+ public static Date getDateFromString2(String strDate) {
+ if (StringUtils.isEmpty(strDate)) {
+ return null;
+ }
+ try {
+ return sdfLongTimePlus.parse(strDate);
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+
+ // -----------------------------------------------------------------------
+ public static Date parseFromFormats(String aValue) {
+ if (StringUtils.isEmpty(aValue))
+ return null;
+
+ // get DateUtil's formats
+ SimpleDateFormat formats[] = DateUtil.getFormats();
+ if (formats == null)
+ return null;
+
+ // iterate over the array and parse
+ Date myDate = null;
+ for (int i = 0; i < formats.length; i++) {
+ try {
+ myDate = DateUtil.parse(aValue, formats[i]);
+ // if (myDate instanceof Date)
+ return myDate;
+ } catch (Exception e) {
+ // do nothing because we want to try the next
+ // format if current one fails
+ }
+ }
+ // haven't returned so couldn't parse
+ return null;
+ }
+
+ // -----------------------------------------------------------------------
+ public static Timestamp parseTimestampFromFormats(String aValue) {
+ if (StringUtils.isEmpty(aValue))
+ {
+ return null;
+ }
+
+ // call the regular Date formatter
+ Date myDate = DateUtil.parseFromFormats(aValue);
+ if (myDate != null)
+ {
+ return new Timestamp(myDate.getTime());
+ }
+ return null;
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Returns a java.sql.Timestamp equal to the current time
+ **/
+ public static Timestamp now() {
+ return new Timestamp(System.currentTimeMillis());
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Returns a string the represents the passed-in date parsed according to
+ * the passed-in format. Returns an empty string if the date or the format
+ * is null.
+ **/
+ public static String format(Date aDate, SimpleDateFormat aFormat) {
+ if (aDate == null || aFormat == null) {
+ return "";
+ }
+ synchronized (aFormat) {
+ return aFormat.format(aDate);
+ }
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Tries to take the passed-in String and format it as a date string in the
+ * the passed-in format.
+ **/
+ public static String formatDateString(String aString, SimpleDateFormat aFormat) {
+ if (StringUtils.isEmpty(aString) || aFormat == null)
+ return "";
+ try {
+ Timestamp aDate = parseTimestampFromFormats(aString);
+ if (aDate != null) {
+ return DateUtil.format(aDate, aFormat);
+ }
+ } catch (Exception e) {
+ // Could not parse aString.
+ }
+ return "";
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Returns a Date using the passed-in string and format. Returns null if the
+ * string is null or empty or if the format is null. The string must match
+ * the format.
+ **/
+ public static Date parse(String aValue, SimpleDateFormat aFormat) throws ParseException {
+ if (StringUtils.isEmpty(aValue) || aFormat == null) {
+ return null;
+ }
+
+ return aFormat.parse(aValue);
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Returns true if endDate is after startDate or if startDate equals endDate
+ * or if they are the same date. Returns false if either value is null.
+ **/
+ public static boolean isValidDateRange(Date startDate, Date endDate) {
+ return isValidDateRange(startDate, endDate, true);
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Returns true if endDate is after startDate or if startDate equals
+ * endDate. Returns false if either value is null. If equalOK, returns true
+ * if the dates are equal.
+ **/
+ public static boolean isValidDateRange(Date startDate, Date endDate, boolean equalOK) {
+ // false if either value is null
+ if (startDate == null || endDate == null) {
+ return false;
+ }
+
+ if (equalOK) {
+ // true if they are equal
+ if (startDate.equals(endDate)) {
+ return true;
+ }
+ }
+
+ // true if endDate after startDate
+ if (endDate.after(startDate)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // -----------------------------------------------------------------------
+ // returns full timestamp format
+ public static SimpleDateFormat defaultTimestampFormat() {
+ return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method returns minimal date format
+ public static SimpleDateFormat get8charDateFormat() {
+ return DateUtil.mFormat8chars;
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method returns minimal date format
+ public static SimpleDateFormat defaultDateFormat() {
+ return DateUtil.friendlyDateFormat(true);
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method
+ public static String defaultTimestamp(Date date) {
+ return DateUtil.format(date, DateUtil.defaultTimestampFormat());
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method
+ public static String defaultDate(Date date) {
+ return DateUtil.format(date, DateUtil.defaultDateFormat());
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method returns long friendly timestamp format
+ public static SimpleDateFormat friendlyTimestampFormat() {
+ return new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method returns long friendly formatted timestamp
+ public static String friendlyTimestamp(Date date) {
+ return DateUtil.format(date, DateUtil.friendlyTimestampFormat());
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method returns long friendly formatted timestamp
+ public static String format8chars(Date date) {
+ return DateUtil.format(date, mFormat8chars);
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method returns long friendly formatted timestamp
+ public static String formatIso8601Day(Date date) {
+ return DateUtil.format(date, mFormatIso8601Day);
+ }
+
+ public static String formatIso8601Day(Timestamp timestamp) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(timestamp.getTime());
+ return DateUtil.format(calendar.getTime(), mFormatIso8601Day);
+ }
+
+ public static String formatTradeEasy(Date date) {
+ return DateUtil.format(date, mFormatTradeEasy);
+ }
+
+ // add by huyanzhi
+ public static String formatTradeEasyProduct(Date date) {
+ return DateUtil.format(date, mFormatTradeEasyProduct);
+ }
+
+ //
+
+ public static String formatFormatTradeEasyMMddyyyy(Date date) {
+ return DateUtil.format(date, mFormatTradeEasyMMddyyyy);
+ }
+
+ public static String formatTradeEasy(Timestamp timestamp) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(timestamp.getTime());
+ return DateUtil.format(calendar.getTime(), mFormatTradeEasy);
+ }
+
+ // -----------------------------------------------------------------------
+ public static String formatRfc822(Date date) {
+ return DateUtil.format(date, mFormatRfc822);
+ }
+
+ public static String formatExpire(Date date) {
+ return DateUtil.format(date, mFormatExpire);
+ }
+
+ // -----------------------------------------------------------------------
+ // This is a hack, but it seems to work
+ public static String formatIso8601(Date date) {
+ if (date == null)
+ return "";
+
+ // Add a colon 2 chars before the end of the string
+ // to make it a valid ISO-8601 date.
+
+ String str = DateUtil.format(date, mFormatIso8601);
+ StringBuffer sb = new StringBuffer();
+ sb.append(str.substring(0, str.length() - 2));
+ sb.append(":");
+ sb.append(str.substring(str.length() - 2));
+ return sb.toString();
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method returns minimal date format
+ public static SimpleDateFormat minimalDateFormat() {
+ return DateUtil.friendlyDateFormat(true);
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method using minimal date format
+ public static String minimalDate(Date date) {
+ return DateUtil.format(date, DateUtil.minimalDateFormat());
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method that returns friendly data format
+ // using full month, day, year digits.
+ public static SimpleDateFormat fullDateFormat() {
+ return DateUtil.friendlyDateFormat(false);
+ }
+
+ // -----------------------------------------------------------------------
+ public static String fullDate(Date date) {
+ return DateUtil.format(date, DateUtil.fullDateFormat());
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Returns a "friendly" date format.
+ *
+ * @param minimalFormat
+ * Should the date format allow single digits.
+ **/
+ public static SimpleDateFormat friendlyDateFormat(boolean minimalFormat) {
+ if (minimalFormat) {
+ return new SimpleDateFormat("d.M.yy");
+ }
+
+ return new SimpleDateFormat("dd.MM.yyyy");
+ }
+
+ // -----------------------------------------------------------------------
+ /**
+ * Format the date using the "friendly" date format.
+ */
+ public static String friendlyDate(Date date, boolean minimalFormat) {
+ return DateUtil.format(date, DateUtil.friendlyDateFormat(minimalFormat));
+ }
+
+ // -----------------------------------------------------------------------
+ // convenience method
+ public static String friendlyDate(Date date) {
+ return DateUtil.format(date, DateUtil.friendlyDateFormat(true));
+ }
+
+ public static Date parseFormatIso8601Date(String date) throws Exception {
+ Date returnDate = null;
+ try {
+ returnDate = mFormatIso8601Day.parse(date);
+ } catch (Exception e) {
+ throw e;
+ }
+ return returnDate;
+ }
+
+ // add by huyanzhi
+ @SuppressWarnings("deprecation")
+ public static String addDate(String date, String type, int into) throws Exception {
+ String Sdate = "";
+ try {
+ GregorianCalendar grc = new GregorianCalendar();
+ grc.setTime(new Date(date));
+ if (type.equals("D")) {
+ grc.add(GregorianCalendar.DATE, into);
+ } else if (type.equals("M")) {
+ grc.add(GregorianCalendar.MONTH, into);
+ } else if (type.equals("Y")) {
+ grc.add(GregorianCalendar.YEAR, into);
+ }
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+ Sdate = new String(formatter.format(grc.getTime()));
+ } catch (Exception e) {
+ throw e;
+ }
+ return Sdate;
+ }
+
+ @SuppressWarnings("deprecation")
+ public static String addDate(String date, String into) throws Exception {
+ String Sdate = "";
+ try {
+ date = date.replaceAll("-", "/");
+ date = date.substring(0, date.length() - 2);
+ GregorianCalendar grc = new GregorianCalendar();
+ grc.setTime(new Date(date));
+ grc.add(GregorianCalendar.DATE, Integer.parseInt(into));
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+ Sdate = new String(formatter.format(grc.getTime()));
+ } catch (Exception e) {
+ throw e;
+ }
+ return Sdate;
+ }
+
+ public static String formatDate(Date date, String pattern) {
+ if (date == null) {
+ return null;
+ }
+ if (pattern == null || pattern.equals("") || pattern.equals("null")) {
+ pattern = "yyyy-MM-dd";
+ }
+ SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+ return sdf.format(date);
+ }
+
+ //
+
+ @SuppressWarnings("deprecation")
+ public static String addValidateDate(String date, String into) throws Exception {
+ String Sdate = "";
+ try {
+ date = date.replaceAll("-", "/");
+ date = date.substring(0, date.length() - 2);
+ GregorianCalendar grc = new GregorianCalendar();
+ grc.setTime(new Date(date));
+ grc.add(GregorianCalendar.DATE, Integer.parseInt(into));
+ Sdate = new String(mFormatExpire.format(grc.getTime()));
+ } catch (Exception e) {
+ throw e;
+ }
+ return Sdate;
+ }
+
+ public static String addDayToStringDate(String formate, String strDate, String days) {
+ String stringDate = null;
+ try {
+ Date date = fromStringToDate(formate, strDate);
+ long now = date.getTime() + (long) Integer.parseInt(days) * DAY_IN_MILLISECOND;
+
+ stringDate = getFomartDate(new Date(now), formate);
+
+ } catch (Exception e) {
+
+ e.printStackTrace();
+ }
+
+ return stringDate;
+ }
+
+ public static Date addDayToStringDate2(String formate, String strDate, String days) {
+ Date date = null;
+ try {
+ date = fromStringToDate(formate, strDate);
+ long now = date.getTime() + (long) Integer.parseInt(days) * DAY_IN_MILLISECOND;
+
+ date = new Date(now);
+ } catch (Exception e) {
+
+ e.printStackTrace();
+ }
+
+ return date;
+ }
+
+ public static Date dateDayAdd(Date date, int days) {
+ long now = date.getTime() + (long) days * DAY_IN_MILLISECOND;
+ return new Date(now);
+ }
+
+ /**
+ *
+ * 瀛楃涓插舰寮忚浆鍖栦负Date绫诲瀷 String绫诲瀷鎸夌収format鏍煎紡杞负Date绫诲瀷
+ **/
+ public static Date fromStringToDate(String format, String dateTime) {
+ Date date = null;
+ try {
+
+ SimpleDateFormat sdf = new SimpleDateFormat(format);
+ date = sdf.parse(dateTime);
+ }catch (Exception e){
+
+ }
+
+ return date;
+ }
+
+ /**
+ *
+ * 瀛楃涓插舰寮忚浆鍖栦负Date绫诲瀷 String绫诲瀷鎸夌収format鏍煎紡杞负Date绫诲瀷
+ **/
+ public static Date fromStringToDate(Date date) throws ParseException {
+ return sdfLongTimePlus.parse(sdfLongTimePlus.format(date));
+ }
+
+ public static void main(String[] args) {
+ try {
+// Date date = getISO8601DateByStr("2024-04-15T07:46:36.014+08:00");
+// Date date1 = getISO8601DateByStr("2024-06-14T08:46:36.014+08:00");
+// System.out.println(DateUtil.afterMinutesDate(-5));
+
+
+// List<String> s = DateUtil.getDayByMonth();
+// System.out.println(getPlusTime2(DateUtil.addMonthToDate(new Date(),-1)));
+ System.out.println(DateUtil.getNowMonth());
+
+// List<Date> list =getThisMonthDateList();
+// for(Date d :list){
+// System.out.println(getPlusTime2(d));
+// }
+// List<Date> list1 =getThisYearMonthList();
+// for(Date d :list1){
+// System.out.println(getPlusTime2(d));
+// }
+
+// Date startTime = DateUtil.StringToDate("2024-05-01 08:00:00" ,"yyyy-MM-dd HH:mm:ss");
+// Date endTime = DateUtil.StringToDate("2024-05-01 17:00:00" ,"yyyy-MM-dd HH:mm:ss");
+// Long intervalTime = 35L;
+//
+//
+// DateUtil.checkDateInterval( startTime.toInstant()
+// .atZone(ZoneId.systemDefault())
+// .toLocalDateTime(), endTime.toInstant()
+// .atZone(ZoneId.systemDefault())
+// .toLocalDateTime(),intervalTime);
+
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ *
+ * <br>
+ * <b>鍔熻兘锛�</b>杩斿洖鏃跺垎绉�:HHmmss<br>
+ * <b>浣滆�咃細</b>www.doumee.com<br>
+ * <b>鏃ユ湡锛�</b> Aug 26, 2013 <br>
+ *
+ * @param date
+ * @return
+ */
+ public static Integer getTimeFormatIntger(Date date) {
+ if (date == null) {
+ return 0;
+ }
+ String strTemp = DateUtil.getFomartDate(date, "yyyyMMddHHmmss");
+ String nowTime = strTemp.substring(8, 14);
+ return Integer.valueOf(nowTime);
+ }
+
+ public static String getNowDayStr(Date date) {
+ if (date == null) {
+ return "";
+ }
+
+ Calendar c = Calendar.getInstance();
+ int i = c.get(Calendar.DAY_OF_WEEK);
+ System.out.println(i);
+ // String strTemp = DateUtil.getFomartDate(date, "yyyyMMddHHmmss");
+ // String nowTime = strTemp.substring(8,14);
+ return "";
+ }
+
+ /**
+ * @param format
+ * 鏃ユ湡鏍煎紡
+ * @return String
+ * @author zhangyong
+ * @return String
+ */
+ public static String toDayToStr(String format) {
+ try {
+ Date now = new Date();
+ return DateToStr(now, format) + " " + getWeekOfDate(now);
+ } catch (Exception e) {
+ System.out.println("Date 杞� String 绫诲瀷澶辫触: " + e);
+ return null;
+ }
+ }
+
+ /**
+ * @param date
+ * @param format
+ * 鏃ユ湡鏍煎紡
+ * @return String
+ * @author zhangyong
+ * @return String
+ */
+ public static String DateToStr(Date date, String format) {
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat(format);
+ return sdf.format(date);
+ } catch (Exception e) {
+ System.out.println("Date 杞� String 绫诲瀷澶辫触: " + e);
+ return null;
+ }
+ }
+
+ /**
+ * @author zhangyong
+ * @return DATE 鍨嬪姞鍏蜂綋鐨勫ぉ鏁�
+ *
+ * @param date
+ * date, int days
+ */
+ public static Date dateAddDays(Date date, int days) {
+ long now = date.getTime() + (long) days * DAY_IN_MILLISECOND;
+ return new Date(now);
+ }
+
+ /**
+ * @return 灏咲ATE 杞崲鎴愬瓧绗︽�ф棩鏈熸牸寮�
+ * @author zhangyong
+ * @param date
+ * date,String fFormatStr eg:yyyy-MM-dd HH:mm:ss
+ */
+ public static String dateTypeToString(Date date, String fFormatStr) {
+ // yyyy-MM-dd HH:mm:ss
+ SimpleDateFormat dateformat = new SimpleDateFormat(fFormatStr);
+ String strDate = dateformat.format(date);
+ return strDate;
+ }
+
+ /**
+ * @param fFormatStr
+ * -MM-dd
+ * @author zhangyong
+ * @鑾峰彇褰撳墠鐨勭郴缁熸椂闂达紝骞舵寜鐓у浐瀹氱殑鏍煎紡鍒濆璇�
+ */
+ public static String getStringOfNowDate(String fFormatStr) {
+ String nowDateString = dateTypeToString(new Date(), fFormatStr);
+ return nowDateString;
+ }
+
+ /**
+ * @ author zhangyong @ 鑾峰彇褰撴湀鐨勭涓�澶╋紝2009-05-01
+ */
+ public static String getStringOfFirstDayInMonth() {
+ Date date = new Date();
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
+ String temp = sdf.format(date);
+ String firstDayInMoth = "";
+ firstDayInMoth = temp + "-01";
+
+ return firstDayInMoth;
+
+ }
+
+ /**
+ * 鑾峰彇褰撳墠鏃ユ湡鏄槦鏈熷嚑<br>
+ *
+ * @param dt
+ * @return 褰撳墠鏃ユ湡鏄槦鏈熷嚑
+ */
+ public static String getWeekOfDate(Date dt) {
+ String[] weekDays = { "鏄熸湡鏃�", "鏄熸湡涓�", "鏄熸湡浜�", "鏄熸湡涓�", "鏄熸湡鍥�", "鏄熸湡浜�", "鏄熸湡鍏�" };
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(dt);
+
+ int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
+ if (w < 0)
+ {
+ w = 0;
+ }
+
+ return weekDays[w];
+ }
+
+ /**
+ * 鑾峰彇鏄熸湡鏁�
+ *
+ * @param dt
+ * @return
+ */
+ public static int getWeekNumOfDate(Date dt) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(dt);
+
+ int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
+ if (w <= 0)
+ w = 7;
+
+ return w;
+ }
+
+ public static Long twoDaysBetween(Date beginDate, Date endDate) throws ParseException {
+ long minute = (endDate.getTime() - beginDate.getTime()) / (60 * 1000);
+ return minute;
+ }
+
+ /**
+ * 鍙栦袱鏈堜互鍓嶇殑1濂�
+ *
+ * @return
+ */
+ public static Date initDateByTwoMonthAgo() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(new Date());
+ calendar.set(Calendar.DAY_OF_MONTH, 1);
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.add(Calendar.MONTH, -2);// 鏈堜唤鍑�1
+ return calendar.getTime();
+ }
+
+ /**
+ * 鏌愭椂闂村鍔犳寚瀹氬ぉ鏁板悗鐨勬棩鏈�
+ *
+ * @return
+ */
+ public static Date addDaysToDate(Date date, int days) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ calendar.add(Calendar.DATE, days);//
+ return calendar.getTime();
+ }
+ public static Date addMonthToDate(Date date, int month) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ calendar.add(Calendar.MONTH, month);//
+ return calendar.getTime();
+ }
+ public static Date addYearToDate(Date date, int year) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ calendar.add(Calendar.YEAR, year);//
+ return calendar.getTime();
+ }
+
+ public static String afterDateToStr(Integer days){
+ Date date = new Date();
+ Long l = date.getTime()+1000*60*60*24*days;
+ date.setTime(l);
+ return DateToStr(date, "yyyyMMdd");
+ }
+
+ public static String afterDateHourToStr(Integer hour){
+ Date date = new Date();
+ Long l = date.getTime()+1000*60*60*hour;
+ date.setTime(l);
+ return DateToStr(date, "yyyyMMdd");
+ }
+
+ public static String beforeDateToStr(Integer days){
+ Date date = new Date();
+ Long l = date.getTime()-1000*60*60*24*days;
+ date.setTime(l);
+ return DateToStr(date, "yyyyMMdd");
+ }
+
+ public static String getLongDate(Date date) {
+ return DateToString(date, "yyyyMMddHHmmss");
+ }
+
+ public static String DateToString(Date date, String dateStyle) {
+ String dateString = null;
+ if (dateStyle != null) {
+ dateString = DateToStringDtl(date, dateStyle);
+ }
+ return dateString;
+ }
+
+ public static String DateToStringDtl(Date date, String parttern) {
+ String dateString = null;
+ if (date != null) {
+ try {
+ dateString = getDateFormat(parttern).format(date);
+ } catch (Exception e) {
+ }
+ }
+ return dateString;
+ }
+
+ /**
+ * 鑾峰彇SimpleDateFormat
+ *
+ * @param parttern 鏃ユ湡鏍煎紡
+ * @return SimpleDateFormat瀵硅薄
+ * @throws RuntimeException 寮傚父锛氶潪娉曟棩鏈熸牸寮�
+ */
+ private static SimpleDateFormat getDateFormat(String parttern) throws RuntimeException {
+ return new SimpleDateFormat(parttern);
+ }
+
+
+ /**
+ * X 鍒嗛挓鍚庢椂闂�
+ * @param minutes
+ * @return
+ */
+ public static Date afterMinutesDate(Integer minutes){
+ Date date = new Date();
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ cal.add(Calendar.MINUTE,minutes);
+ return cal.getTime();
+ }
+
+ /**
+ * X 鍒嗛挓鍚庢椂闂�
+ * @param minutes
+ * @return
+ */
+ public static Date afterMinutesDate(Date date,Integer minutes){
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ cal.add(Calendar.MINUTE,minutes);
+ return cal.getTime();
+ }
+
+ public static Date afterHoursDate(Date date,Integer hours){
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ cal.add(Calendar.HOUR,hours);
+ return cal.getTime();
+ }
+
+
+ /**
+ * LocalDateTime to date
+ * @param now
+ * @return
+ */
+ public static LocalDateTime toDateLocalDateTime(Date now){
+ return LocalDateTime.ofInstant(now.toInstant(),ZoneId.systemDefault());
+ }
+
+
+ /**
+ * LocalDateTime to date
+ * @param localDateTime
+ * @return
+ */
+ public static Date toDate(LocalDateTime localDateTime){
+ Date from = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
+ return from;
+ }
+
+ /**
+ * h鑾峰彇鏈懆鏄熸湡涓�
+ *
+ * @return
+ */
+ public static LocalDateTime getMonday(){
+ LocalDate date = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).with(DayOfWeek.MONDAY).toLocalDate();
+ LocalDateTime dateTime = date.atTime(0, 0, 0);
+ return dateTime;
+ }
+
+ /**
+ * 鑾峰彇鏈懆鏄熸湡澶�
+ *
+ * @return
+ */
+ public static LocalDateTime getSunday(){
+ LocalDate date = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).with(DayOfWeek.SUNDAY).toLocalDate();
+ LocalDateTime dateTime = date.atTime(23, 59, 59);
+ return dateTime;
+ }
+
+ /**
+ * 鑾峰彇鏈堢涓�
+ *
+ * @return
+ */
+ public static LocalDateTime getMonthFirst(){
+ LocalDateTime firstDayOfMonth = LocalDateTime.of(LocalDate.from(LocalDateTime.now().with(TemporalAdjusters.firstDayOfMonth())), LocalTime.MIN);
+ return firstDayOfMonth;
+ }
+
+ /**
+ * 鑾峰彇鏈堟渶鍚庝竴澶�
+ *
+ * @return
+ */
+ public static LocalDateTime getMonthLast(){
+ LocalDateTime lastDayOfMonth = LocalDateTime.of(LocalDate.from(LocalDateTime.now().with(TemporalAdjusters.lastDayOfMonth())), LocalTime.of(23, 59, 59));
+ return lastDayOfMonth;
+ }
+
+ public static Date StringToDate(String date, String parttern) {
+ Date myDate = null;
+ if (date != null) {
+ try {
+ myDate = getDateFormat(parttern).parse(date);
+ } catch (Exception e) {
+ }
+ }
+ return myDate;
+ }
+
+ public static List<String> getDayByMonth(String yearMonth){
+ List<String> data = new ArrayList<>();
+ try {
+ Calendar c = Calendar.getInstance();
+ c.setTime(DateUtil.StringToDate(yearMonth+"-01" ,"yyyy-MM-dd"));
+ // 鑾峰彇鏈湀鐨勬�诲ぉ鏁�
+ int dayCount = c.getActualMaximum(Calendar.DAY_OF_MONTH);
+ // 瀹氫箟鏃堕棿鏍煎紡
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ // 寮�濮嬫棩鏈熶负褰撳墠骞存湀鎷兼帴1鍙�
+ Date startDate = sdf.parse(yearMonth + "-01");
+ // 缁撴潫鏃ユ湡涓哄綋鍓嶅勾鏈堟嫾鎺ヨ鏈堟渶澶уぉ鏁�
+ Date endDate = sdf.parse(yearMonth + "-" + dayCount);
+ // 璁剧疆calendar鐨勫紑濮嬫棩鏈�
+ c.setTime(startDate);
+ // 褰撳墠鏃堕棿灏忎簬绛変簬璁惧畾鐨勭粨鏉熸椂闂�
+ while(c.getTime().compareTo(endDate) <= 0){
+ String time = sdf.format(c.getTime());
+ data.add(time);
+ // 褰撳墠鏃ユ湡鍔�1
+ c.add(Calendar.DATE, 1);
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return data;
+ }
+
+ public static Week getWeek(Date date) {
+ Week week = null;
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ int weekNumber = calendar.get(Calendar.DAY_OF_WEEK) - 1;
+ switch (weekNumber) {
+ case 0:
+ week = Week.SUNDAY;
+ break;
+ case 1:
+ week = Week.MONDAY;
+ break;
+ case 2:
+ week = Week.TUESDAY;
+ break;
+ case 3:
+ week = Week.WEDNESDAY;
+ break;
+ case 4:
+ week = Week.THURSDAY;
+ break;
+ case 5:
+ week = Week.FRIDAY;
+ break;
+ case 6:
+ week = Week.SATURDAY;
+ break;
+ }
+ return week;
+ }
+
+ /**
+ * 鏃堕棿杞箟甯︽椂鍖� 鍏ュ弬鏍煎紡 2022-09-13T00:53:03.000+00:00
+ * @param timeEscape
+ * @return
+ * @throws ParseException
+ */
+ public static String timeEscape(String timeEscape) throws ParseException {
+ SimpleDateFormat startDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.US);
+ SimpleDateFormat startDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String time = startDateFormat1.format(startDateFormat.parse(timeEscape));
+ System.out.println(time);
+ return time;
+ }
+
+
+
+ public static List<LocalDateTime> checkDateInterval(LocalDateTime localStartTime,LocalDateTime localEndTime,Long interval){
+ List<LocalDateTime> segments = new ArrayList<>();
+ LocalDateTime current = localStartTime;
+ while (current.isBefore(localEndTime)) {
+ segments.add(current);
+ current = current.plus(interval, ChronoUnit.MINUTES);
+ }
+ return segments;
+
+ }
+
+ /**
+ * 鑾峰彇X澶╁悗鐨勬棩鏈�
+ * @param date
+ * @param beforDays 鏄庡ぉ -1 鏄ㄥぉ 1
+ * @return
+ */
+ public static String getBeforDay(Date date,Integer beforDays){
+ ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
+ // 杞崲涓簀ava.time.LocalDate,璁$畻x澶╃殑鏃ユ湡
+ LocalDate dateBeforeDay = zonedDateTime.toLocalDate().minusDays(beforDays);
+ return dateBeforeDay.toString();
+ }
+
+
+ /**
+ * 鑾峰彇X澶╁悗鐨勬棩鏈�
+ * @param date
+ * @param beforMonths 涓嬫湀 -1 涓婃湀 1
+ * @return
+ */
+ public static String getBeforMonthStr(Date date,Integer beforMonths){
+ ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
+ // 杞崲涓簀ava.time.LocalDate,璁$畻x澶╃殑鏃ユ湡
+ LocalDate dateBeforeDay = zonedDateTime.toLocalDate().minusMonths(beforMonths);
+ return dateBeforeDay.toString();
+ }
+
+
+ /**
+ * 鑾峰彇X骞村悗鐨勬棩鏈�
+ * @param date
+ * @param beforMonths 涓嬪勾 -1 涓婂勾 1
+ * @return
+ */
+ public static String getBeforYear(Date date,Integer beforMonths){
+ ZonedDateTime zonedDateTime = date.toInstant().atZone(ZoneId.systemDefault());
+ // 杞崲涓簀ava.time.LocalDate,璁$畻x澶╃殑鏃ユ湡
+ LocalDate dateBeforeDay = zonedDateTime.toLocalDate().minusYears(beforMonths);
+ return dateBeforeDay.toString();
+ }
+
+
+
+ // 鑾峰彇鏈懆鐨勫紑濮嬫椂闂�
+ public static Date getBeginDayOfWeek(int addYears) {
+ Date date = new Date();
+ if (date == null) {
+ return null;
+ }
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ cal.set(Calendar.YEAR,getNowYearNum()+addYears);
+ int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
+ if (dayofweek == 1) {
+ dayofweek += 7;
+ }
+ cal.add(Calendar.DATE, 2 - dayofweek);
+ return getDayStartTime(cal.getTime());
+ }
+
+ // 鑾峰彇鏈懆鐨勭粨鏉熸椂闂�
+ public static Date getEndDayOfWeek(int addYears) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(getBeginDayOfWeek(addYears));
+ cal.add(Calendar.DAY_OF_WEEK, 6);
+ Date weekEndSta = cal.getTime();
+ return getDayEndTime(weekEndSta);
+ }
+
+ // 鑾峰彇涓婂懆鐨勫紑濮嬫椂闂�
+ public static Date getBeginDayOfLastWeek() {
+ Date date = new Date();
+ if (date == null) {
+ return null;
+ }
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ cal.set(Calendar.YEAR,getNowYearNum());
+ int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
+ if (dayofweek == 1) {
+ dayofweek += 7;
+ }
+ cal.add(Calendar.DATE, 2 - dayofweek - 7);
+ return getDayStartTime(cal.getTime());
+ }
+
+ // 鑾峰彇涓婂懆鐨勭粨鏉熸椂闂�
+ public static Date getEndDayOfLastWeek() {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(getBeginDayOfLastWeek());
+ cal.add(Calendar.DAY_OF_WEEK, 6);
+ Date weekEndSta = cal.getTime();
+ return getDayEndTime(weekEndSta);
+ }
+
+ // 鑾峰彇鏈湀鐨勫紑濮嬫椂闂�
+ public static Date getBeginDayOfMonth(int addYears) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(getNowYearNum()+addYears, getNowMonthNum() - 1, 1);
+ return getDayStartTime(calendar.getTime());
+ }
+
+ // 鑾峰彇鏈湀鐨勭粨鏉熸椂闂�
+ public static Date getEndDayOfMonth(int addYears) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(getNowYearNum()+addYears, getNowMonthNum() - 1, 1);
+ int day = calendar.getActualMaximum(5);
+ calendar.set(getNowYearNum()+addYears, getNowMonthNum() - 1, day);
+ return getDayEndTime(calendar.getTime());
+ }
+
+ // 鑾峰彇涓婃湀鐨勫紑濮嬫椂闂�
+ public static Date getBeginDayOfLastMonth() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(getNowYearNum(), getNowMonthNum() - 2, 1);
+ return getDayStartTime(calendar.getTime());
+ }
+
+ // 鑾峰彇涓婃湀鐨勭粨鏉熸椂闂�
+ public static Date getEndDayOfLastMonth() {
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(getNowYearNum(), getNowMonthNum() - 2, 1);
+ int day = calendar.getActualMaximum(5);
+ calendar.set(getNowYearNum(), getNowMonthNum() - 2, day);
+ return getDayEndTime(calendar.getTime());
+ }
+
+ // 鑾峰彇鏈勾鐨勫紑濮嬫椂闂�
+ public static Date getBeginDayOfYear(int addYears) {
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.YEAR, getNowYearNum()+addYears);
+ cal.set(Calendar.MONTH, Calendar.JANUARY);
+ cal.set(Calendar.DATE, 1);
+ return getDayStartTime(cal.getTime());
+ }
+ public static Date getBeginDayOfSeason(int addYears) {
+ Integer nowMonth = getNowMonth();
+ int month = Calendar.JANUARY;
+ Integer quarter = (nowMonth - 1) / 3 + 1;//瀛e害
+ if(quarter == 2){
+ month = Calendar.APRIL;
+ }else if(quarter == 3){
+ month = Calendar.JUNE;
+ }else if(quarter == 4){
+ month = Calendar.OCTOBER;
+ }
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.YEAR, getNowYearNum()+addYears);
+ cal.set(Calendar.MONTH, month);
+ cal.set(Calendar.DATE, 1);
+ return getDayStartTime(cal.getTime());
+ }
+
+ // 鑾峰彇鏈勾鐨勭粨鏉熸椂闂�
+ public static Date getEndDayOfYear(int addYears){
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.YEAR, getNowYearNum()+addYears);
+ cal.set(Calendar.MONTH, Calendar.DECEMBER);
+ cal.set(Calendar.DATE, 31);
+ return getDayEndTime(cal.getTime());
+ }
+
+ // 鑾峰彇褰撳ぉ鐨勫紑濮嬫椂闂�
+ public static Date getDayBegin() {
+ Calendar cal = new GregorianCalendar();
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ return cal.getTime();
+ }
+
+ // 鑾峰彇褰撳ぉ鐨勭粨鏉熸椂闂�
+ public static Date getDayEnd() {
+ Calendar cal = new GregorianCalendar();
+ cal.set(Calendar.HOUR_OF_DAY, 23);
+ cal.set(Calendar.MINUTE, 59);
+ cal.set(Calendar.SECOND, 59);
+ return cal.getTime();
+ }
+
+
+ // 鑾峰彇鏌愪釜鏃ユ湡鐨勫紑濮嬫椂闂�
+ public static Timestamp getDayStartTime(Date d) {
+ Calendar calendar = Calendar.getInstance();
+ if (null != d)
+ calendar.setTime(d);
+ calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
+ calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ return new Timestamp(calendar.getTimeInMillis());
+ }
+
+ // 鑾峰彇鏌愪釜鏃ユ湡鐨勭粨鏉熸椂闂�
+ public static Timestamp getDayEndTime(Date d) {
+ Calendar calendar = Calendar.getInstance();
+ if (null != d)
+ calendar.setTime(d);
+ calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
+ calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
+ calendar.set(Calendar.MILLISECOND, 999);
+ return new Timestamp(calendar.getTimeInMillis());
+ }
+
+
+ // 鑾峰彇浠婂勾鏄摢涓�骞�
+ public static Integer getNowYearNum() {
+ Date date = new Date();
+ GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
+ gc.setTime(date);
+ return Integer.valueOf(gc.get(1));
+ }
+
+ // 鑾峰彇鏈湀鏄摢涓�鏈�
+ public static int getNowMonthNum() {
+ Date date = new Date();
+ GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
+ gc.setTime(date);
+ return gc.get(2) + 1;
+ }
+}
\ No newline at end of file
diff --git a/server/services/src/main/java/com/doumee/core/utils/FtpUtil.java b/server/services/src/main/java/com/doumee/core/utils/FtpUtil.java
new file mode 100644
index 0000000..72d0cc8
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/FtpUtil.java
@@ -0,0 +1,768 @@
+package com.doumee.core.utils;
+
+import com.doumee.core.constants.Constants;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.net.PrintCommandListener;
+import org.apache.commons.net.ftp.FTP;
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.net.ftp.FTPReply;
+//import org.apache.http.client.methods.CloseableHttpResponse;
+//import org.apache.http.client.methods.HttpGet;
+//import org.apache.http.impl.client.CloseableHttpClient;
+//import org.apache.http.impl.client.HttpClientBuilder;
+//import org.apache.http.util.EntityUtils;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Date;
+import java.util.UUID;
+
+/** */
+/**
+ * 鏀寔鏂偣缁紶鐨凢TP瀹炵敤绫�
+ *
+ * @author BenZhou http://www.bt285.cn
+ * @version 0.1 瀹炵幇鍩烘湰鏂偣涓婁紶涓嬭浇
+ * @version 0.2 瀹炵幇涓婁紶涓嬭浇杩涘害姹囨姤
+ * @version 0.3 瀹炵幇涓枃鐩綍鍒涘缓鍙婁腑鏂囨枃浠跺垱寤猴紝娣诲姞瀵逛簬涓枃鐨勬敮鎸�
+ */
+@Slf4j
+public class FtpUtil {
+ public FTPClient ftpClient = new FTPClient();
+ public static String hostname;
+ public static int port;
+ public static String username;
+ public static String password;
+
+ public FtpUtil() {
+ // 璁剧疆灏嗚繃绋嬩腑浣跨敤鍒扮殑鍛戒护杈撳嚭鍒版帶鍒跺彴
+ this.ftpClient.addProtocolCommandListener(new PrintCommandListener(
+ new PrintWriter(System.out)));
+ }
+
+ public FtpUtil(String hostname, int port, String username, String password)
+ throws IOException {
+ // 璁剧疆灏嗚繃绋嬩腑浣跨敤鍒扮殑鍛戒护杈撳嚭鍒版帶鍒跺彴
+ FtpUtil.hostname =hostname;
+ FtpUtil.port =port;
+ FtpUtil.username =username;
+ FtpUtil.password =password;
+ connect();
+ }
+ /**
+ * 鍒濆鍖杅tp鏈嶅姟鍣�
+ */
+ public boolean connect() {
+ boolean flag = false;
+ try {
+ System.out.println("connecting...ftp鏈嶅姟鍣�:"+this.hostname+":"+this.port);
+ ftpClient.setRemoteVerificationEnabled(false);
+ ftpClient.connect(hostname, port); //杩炴帴ftp鏈嶅姟鍣�
+ ftpClient.login(username, password); //鐧诲綍ftp鏈嶅姟鍣�
+// if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
+// LOCAL_CHARSET = "UTF-8";
+// }
+ ftpClient.setControlEncoding("GBK");
+ ftpClient.setConnectTimeout(10*60*1000);
+ ftpClient.setDataTimeout(10*60*1000);
+ ftpClient.enterLocalPassiveMode();
+ int replyCode = ftpClient.getReplyCode(); //鏄惁鎴愬姛鐧诲綍鏈嶅姟鍣�
+ if(!FTPReply.isPositiveCompletion(replyCode)){
+ log.error("connect failed...ftp鏈嶅姟鍣�:"+this.hostname+":"+this.port+"杩斿洖鐮侊細"+replyCode);
+ }else {
+ flag = true;
+ log.info("connect successful...ftp鏈嶅姟鍣�:"+this.hostname+":"+this.port+"杩斿洖鐮侊細"+replyCode);
+ }
+ }catch (MalformedURLException e) {
+ e.printStackTrace();
+ log.error("connect exception...ftp鏈嶅姟鍣�:"+this.hostname+":"+this.port+ e.getMessage());
+ }catch (IOException e) {
+ e.printStackTrace();
+ log.error("connect exception...ftp鏈嶅姟鍣�:"+this.hostname+":"+this.port+ e.getMessage());
+ }
+ return flag;
+ }
+
+ /** */
+ /**
+ * 杩炴帴鍒癋TP鏈嶅姟鍣�
+ *
+ * 瀵嗙爜
+ * @return 鏄惁杩炴帴鎴愬姛
+ * @throws IOException
+ */
+ public boolean connect2() throws IOException {
+ ftpClient.connect(hostname, port);
+ ftpClient.setControlEncoding("GBK");
+ if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
+ if (ftpClient.login(username, password)) {
+ return true;
+ }
+ }
+ disconnect();
+ return false;
+ }
+
+ /** */
+ /**
+ * 浠嶧TP鏈嶅姟鍣ㄤ笂涓嬭浇鏂囦欢,鏀寔鏂偣缁紶锛屼笂浼犵櫨鍒嗘瘮姹囨姤
+ *
+ * @param remote
+ * 杩滅▼鏂囦欢璺緞
+ * @param local
+ * 鏈湴鏂囦欢璺緞
+ * @return 涓婁紶鐨勭姸鎬�
+ * @throws IOException
+ */
+ public String download(String remote, String local) throws IOException {
+ // 璁剧疆琚姩妯″紡
+ ftpClient.enterLocalPassiveMode();
+ // 璁剧疆浠ヤ簩杩涘埗鏂瑰紡浼犺緭
+ ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
+
+ String result;
+
+ // 妫�鏌ヨ繙绋嬫枃浠舵槸鍚﹀瓨鍦�
+ FTPFile[] files = ftpClient.listFiles(new String(
+ remote.getBytes("GBK"), "iso-8859-1"));
+ if (files.length != 1) {
+ // System.out.println("杩滅▼鏂囦欢涓嶅瓨鍦�");
+ return "杩滅▼鏂囦欢涓嶅瓨鍦�";
+ }
+
+ long lRemoteSize = files[0].getSize();
+ File f = new File(local);
+ // 鏈湴瀛樺湪鏂囦欢锛岃繘琛屾柇鐐逛笅杞�
+ if (f.exists()) {
+ long localSize = f.length();
+ // 鍒ゆ柇鏈湴鏂囦欢澶у皬鏄惁澶т簬杩滅▼鏂囦欢澶у皬
+ if (localSize >= lRemoteSize) {
+ // System.out.println("鏈湴鏂囦欢澶т簬杩滅▼鏂囦欢锛屼笅杞戒腑姝�");
+ // return "鏈湴鏂囦欢澶т簬杩滅▼鏂囦欢锛屼笅杞戒腑姝�";
+ }
+
+ // 杩涜鏂偣缁紶锛屽苟璁板綍鐘舵��
+ FileOutputStream out = new FileOutputStream(f, true);
+ ftpClient.setRestartOffset(localSize);
+ InputStream in = ftpClient.retrieveFileStream(new String(remote
+ .getBytes("GBK"), "iso-8859-1"));
+ byte[] bytes = new byte[1024];
+ long step = lRemoteSize / 100;
+ long process = localSize / step;
+ int c;
+ while ((c = in.read(bytes)) != -1) {
+ out.write(bytes, 0, c);
+ localSize += c;
+ long nowProcess = localSize / step;
+ if (nowProcess > process) {
+ process = nowProcess;
+ if (process % 10 == 0)
+ System.out.println("涓嬭浇杩涘害锛�" + process);
+ // TODO 鏇存柊鏂囦欢涓嬭浇杩涘害,鍊煎瓨鏀惧湪process鍙橀噺涓�
+ }
+ }
+ in.close();
+ out.close();
+ boolean isDo = ftpClient.completePendingCommand();
+ if (isDo) {
+ result = "300";
+ // result = DownloadStatus.Download_From_Break_Success;
+ } else {
+ result = "400";
+ // result = DownloadStatus.Download_From_Break_Failed;
+ }
+ } else {
+ OutputStream out = new FileOutputStream(f);
+ InputStream in = ftpClient.retrieveFileStream(new String(remote
+ .getBytes("GBK"), "iso-8859-1"));
+ byte[] bytes = new byte[1024];
+ long step = lRemoteSize / 100;
+ long process = 0;
+ long localSize = 0L;
+ int c;
+ while ((c = in.read(bytes)) != -1) {
+ out.write(bytes, 0, c);
+ localSize += c;
+ long nowProcess = localSize / step;
+ if (nowProcess > process) {
+ process = nowProcess;
+ if (process % 10 == 0)
+ System.out.println("涓嬭浇杩涘害锛�" + process);
+ // TODO 鏇存柊鏂囦欢涓嬭浇杩涘害,鍊煎瓨鏀惧湪process鍙橀噺涓�
+ }
+ }
+ in.close();
+ out.close();
+ boolean upNewStatus = ftpClient.completePendingCommand();
+ if (upNewStatus) {
+ result = "500";
+ // result = DownloadStatus.Download_New_Success;
+ } else {
+ // result = DownloadStatus.Download_New_Failed;
+ result = "600";
+ }
+ }
+ return result;
+ }
+
+ /** */
+ /**
+ * 涓婁紶鏂囦欢鍒癋TP鏈嶅姟鍣紝鏀寔鏂偣缁紶
+ *
+ * @param local
+ * 鏈湴鏂囦欢鍚嶇О锛岀粷瀵硅矾寰�
+ * @param remote
+ * 杩滅▼鏂囦欢璺緞锛屼娇鐢�/home/directory1/subdirectory/file.ext鎴栨槸
+ * http://www.guihua.org /subdirectory/file.ext
+ * 鎸夌収Linux涓婄殑璺緞鎸囧畾鏂瑰紡锛屾敮鎸佸绾х洰褰曞祵濂楋紝鏀寔閫掑綊鍒涘缓涓嶅瓨鍦ㄧ殑鐩綍缁撴瀯
+ * @return 涓婁紶缁撴灉
+ * @throws IOException
+ */
+ public String upload(String local, String remote) throws IOException {
+ // 璁剧疆PassiveMode浼犺緭
+ ftpClient.enterLocalPassiveMode();
+
+ // 璁剧疆浠ヤ簩杩涘埗娴佺殑鏂瑰紡浼犺緭
+ ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
+ ftpClient.setControlEncoding("GBK");
+ String result;
+ // 瀵硅繙绋嬬洰褰曠殑澶勭悊
+ String remoteFileName = remote;
+ if (remote.contains(File.separator)) {
+ remoteFileName = remote.substring(remote.lastIndexOf(File.separator) + 1);
+ // 鍒涘缓鏈嶅姟鍣ㄨ繙绋嬬洰褰曠粨鏋勶紝鍒涘缓澶辫触鐩存帴杩斿洖
+ if (StringUtils.equals(CreateDirecroty(remote, ftpClient), "2")) {
+ return "2";
+ }
+ }
+
+ // 妫�鏌ヨ繙绋嬫槸鍚﹀瓨鍦ㄦ枃浠�
+ FTPFile[] files = ftpClient.listFiles(new String(remoteFileName
+ .getBytes("GBK"), "iso-8859-1"));
+ if (files.length == 1) {
+ long remoteSize = files[0].getSize();
+ File f = new File(local);
+ long localSize = f.length();
+ if (remoteSize == localSize) {
+ return "700";
+ // return UploadStatus.File_Exits;
+ } else if (remoteSize > localSize) {
+ return "800";
+ // return UploadStatus.Remote_Bigger_Local;
+ }
+
+ // 灏濊瘯绉诲姩鏂囦欢鍐呰鍙栨寚閽�,瀹炵幇鏂偣缁紶
+ result = uploadFile(remoteFileName, f, ftpClient, remoteSize);
+
+ // 濡傛灉鏂偣缁紶娌℃湁鎴愬姛锛屽垯鍒犻櫎鏈嶅姟鍣ㄤ笂鏂囦欢锛岄噸鏂颁笂浼�
+ if (StringUtils.equals(result, "1")) {
+ if (!ftpClient.deleteFile(remoteFileName)) {
+ return "1";
+ }
+ result = uploadFile(remoteFileName, f, ftpClient, 0);
+ }
+ } else {
+ result = uploadFile(remoteFileName, new File(local), ftpClient, 0);
+ }
+ return result;
+ }
+ public boolean uploadInputstream(InputStream inputStream, String remote) {
+ // 璁剧疆PassiveMode浼犺緭
+ Date d1 = new Date();
+ log.error("涓婁紶鏂囦欢鎴愬姛=============寮�濮�========="+DateUtil.getPlusTime2(d1));
+ try {
+ ftpClient.enterLocalPassiveMode();
+ // 璁剧疆浠ヤ簩杩涘埗娴佺殑鏂瑰紡浼犺緭
+ ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
+ ftpClient.setControlEncoding("GBK");
+ // 瀵硅繙绋嬬洰褰曠殑澶勭悊
+ String remoteFileName = remote;
+ if (remote.contains("/")) {
+ remoteFileName = remote.substring(remote.lastIndexOf("/") + 1);
+ // 鍒涘缓鏈嶅姟鍣ㄨ繙绋嬬洰褰曠粨鏋勶紝鍒涘缓澶辫触鐩存帴杩斿洖
+ if (StringUtils.equals(CreateDirecroty(remote, ftpClient), "2")) {
+ log.error("鍒涘缓ftp鐩綍澶辫触======================="+remote);
+ return false;
+ }
+ }
+ boolean result = ftpClient.storeFile(remoteFileName, inputStream);
+ inputStream.close();
+ ftpClient.logout();
+ if(result){
+ log.info("涓婁紶鏂囦欢鎴愬姛======================"+remote);
+ }else{
+ log.error("涓婁紶鏂囦欢澶辫触======================="+remote);
+ }
+ Date d2= new Date();
+ log.error("涓婁紶鏂囦欢鎴愬姛=============缁撴潫========="+DateUtil.getPlusTime2(d2) +"鑰楁椂姣锛�"+( (d2.getTime()-d1.getTime()) ));
+ return result;
+ }catch (Exception e){
+ e.printStackTrace();
+ log.error("涓婁紶鏂囦欢澶辫触======================="+remote);
+ }
+ return false;
+ }
+
+ public boolean uploadInputstreamBatch(InputStream inputStream, String remote, Boolean close , Integer index ) {
+ // 璁剧疆PassiveMode浼犺緭
+ try {
+ ftpClient.enterLocalPassiveMode();
+ // 璁剧疆浠ヤ簩杩涘埗娴佺殑鏂瑰紡浼犺緭
+ ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
+ ftpClient.setControlEncoding("GBK");
+ // 瀵硅繙绋嬬洰褰曠殑澶勭悊
+ String remoteFileName = remote;
+ if (remote.contains("/")) {
+ remoteFileName = remote.substring(remote.lastIndexOf("/") + 1);
+ // 鍒涘缓鏈嶅姟鍣ㄨ繙绋嬬洰褰曠粨鏋勶紝鍒涘缓澶辫触鐩存帴杩斿洖
+ if (Constants.equalsInteger(index,Constants.ONE) && StringUtils.equals(CreateDirecroty(remote, ftpClient), "2")) {
+ log.error("鍒涘缓ftp鐩綍澶辫触======================="+remote);
+ return false;
+ }
+ }
+ boolean result = ftpClient.storeFile(remoteFileName, inputStream);
+ inputStream.close();
+ if(close){
+ ftpClient.logout();
+ }
+ if(result){
+ log.info("涓婁紶鏂囦欢鎴愬姛======================"+remote);
+ }else{
+ log.error("涓婁紶鏂囦欢澶辫触======================="+remote);
+ }
+ return result;
+ }catch (Exception e){
+ e.printStackTrace();
+ log.error("涓婁紶鏂囦欢澶辫触======================="+remote);
+ }
+ return false;
+ }
+
+ public int getNumFromStr(String str,char searchstr) {
+ int count = 0;
+ char[] charArray = str.toCharArray();
+ for (char param : charArray) {
+ if (param == searchstr) {
+ count++;
+ }
+ }
+ return count;
+ }
+ /** */
+ /**
+ * 涓婁紶鏂囦欢鍒癋TP鏈嶅姟鍣紝鏀寔鏂偣缁紶
+ *
+ * @param localFile
+ * 鏈湴鏂囦欢娴�
+ * @param remote
+ * 杩滅▼鏂囦欢璺緞锛屼娇鐢�/home/directory1/subdirectory/file.ext鎴栨槸
+ * http://www.guihua.org /subdirectory/file.ext
+ * 鎸夌収Linux涓婄殑璺緞鎸囧畾鏂瑰紡锛屾敮鎸佸绾х洰褰曞祵濂楋紝鏀寔閫掑綊鍒涘缓涓嶅瓨鍦ㄧ殑鐩綍缁撴瀯
+ * @return 涓婁紶缁撴灉
+ * @throws IOException
+ */
+ public String uploadFile(File localFile, String remote) throws IOException {
+ // 璁剧疆PassiveMode浼犺緭
+ ftpClient.enterLocalPassiveMode();
+ // 璁剧疆浠ヤ簩杩涘埗娴佺殑鏂瑰紡浼犺緭
+ ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
+ ftpClient.setControlEncoding("GBK");
+ String result;
+ // 瀵硅繙绋嬬洰褰曠殑澶勭悊
+ String remoteFileName = remote ;
+ if (remote.contains("/")) {
+ remoteFileName = remote.substring(remote.lastIndexOf("/") + 1);
+ // 鍒涘缓鏈嶅姟鍣ㄨ繙绋嬬洰褰曠粨鏋勶紝鍒涘缓澶辫触鐩存帴杩斿洖
+ if (StringUtils.equals(CreateDirecroty(remote, ftpClient), "2")) {
+ return "2";
+ }
+ }
+
+ // 妫�鏌ヨ繙绋嬫槸鍚﹀瓨鍦ㄦ枃浠�
+ FTPFile[] files = ftpClient.listFiles(new String(remoteFileName
+ .getBytes("GBK"), "iso-8859-1"));
+ if (files.length == 1) {
+ long remoteSize = files[0].getSize();
+
+ long localSize = localFile.length();
+ if (remoteSize == localSize) {
+ return "700";
+ // return UploadStatus.File_Exits;
+ } else if (remoteSize > localSize) {
+ return "800";
+ // return UploadStatus.Remote_Bigger_Local;
+ }
+
+ // 灏濊瘯绉诲姩鏂囦欢鍐呰鍙栨寚閽�,瀹炵幇鏂偣缁紶
+ result = uploadFile(remoteFileName, localFile, ftpClient,
+ remoteSize);
+
+ // 濡傛灉鏂偣缁紶娌℃湁鎴愬姛锛屽垯鍒犻櫎鏈嶅姟鍣ㄤ笂鏂囦欢锛岄噸鏂颁笂浼�
+ if (StringUtils.equals(result, "1")) {
+ if (!ftpClient.deleteFile(remoteFileName)) {
+ return "1";
+ }
+ result = uploadFile(remoteFileName, localFile, ftpClient, 0);
+ }
+ // if (result == UploadStatus.Upload_From_Break_Failed) {
+ // if (!ftpClient.deleteFile(remoteFileName)) {
+ // return UploadStatus.Delete_Remote_Faild;
+ // }
+ // result = uploadFile(remoteFileName, f, ftpClient, 0);
+ // }
+ } else {
+ result = uploadFile(remoteFileName, localFile, ftpClient, 0);
+ }
+
+ return result;
+ }
+
+ /** */
+ /**
+ * 鏂紑涓庤繙绋嬫湇鍔″櫒鐨勮繛鎺�
+ *
+ * @throws IOException
+ */
+ public void disconnect() throws IOException {
+ if (ftpClient.isConnected()) {
+ ftpClient.disconnect();
+ }
+ }
+
+ /** */
+ /**
+ * 閫掑綊鍒涘缓杩滅▼鏈嶅姟鍣ㄧ洰褰�
+ *
+ * @param remote
+ * 杩滅▼鏈嶅姟鍣ㄦ枃浠剁粷瀵硅矾寰�
+ * @param ftpClient
+ * FTPClient瀵硅薄
+ * @return 鐩綍鍒涘缓鏄惁鎴愬姛
+ * @throws IOException
+ */
+ public String CreateDirecroty(String remote, FTPClient ftpClient)
+ throws IOException {
+ String status = "1";
+ // UploadStatus status = UploadStatus.Create_Directory_Success;
+ String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
+ if (!directory.equalsIgnoreCase("/")
+ && !ftpClient.changeWorkingDirectory(new String(directory
+ .getBytes("GBK"), "iso-8859-1"))) {
+ // 濡傛灉杩滅▼鐩綍涓嶅瓨鍦紝鍒欓�掑綊鍒涘缓杩滅▼鏈嶅姟鍣ㄧ洰褰�
+ int start = 0;
+ int end = 0;
+ if (directory.startsWith("/")) {
+ start = 1;
+ } else {
+ start = 0;
+ }
+ end = directory
+ .indexOf("/", start);
+ while (true) {
+ String subDirectory = new String(remote.substring(start, end)
+ .getBytes("GBK"), "iso-8859-1");
+ if (!ftpClient.changeWorkingDirectory(subDirectory)) {
+ if (ftpClient.makeDirectory(subDirectory)) {
+ ftpClient.changeWorkingDirectory(subDirectory);
+ } else {
+ log.error("鍒涘缓鐩綍澶辫触subDirectory=锛�"+subDirectory);
+ return "2";
+ // return UploadStatus.Create_Directory_Fail;
+ }
+ }
+
+ start = end + 1;
+ end = directory.indexOf("/",
+ start);
+
+ // 妫�鏌ユ墍鏈夌洰褰曟槸鍚﹀垱寤哄畬姣�
+ if (end <= start) {
+ break;
+ }
+ }
+ }
+ return status;
+ }
+
+ /**
+ * 涓婁紶鏂囦欢鍒版湇鍔″櫒,鏂颁笂浼犲拰鏂偣缁紶
+ *
+ * @param remoteFile
+ * 杩滅▼鏂囦欢鍚嶏紝鍦ㄤ笂浼犱箣鍓嶅凡缁忓皢鏈嶅姟鍣ㄥ伐浣滅洰褰曞仛浜嗘敼鍙�
+ * @param localFile
+ * 鏈湴鏂囦欢File鍙ユ焺锛岀粷瀵硅矾寰�
+ * 闇�瑕佹樉绀虹殑澶勭悊杩涘害姝ヨ繘鍊�
+ * @param ftpClient
+ * FTPClient寮曠敤
+ * @return
+ * @throws IOException
+ */
+ public String uploadFile(String remoteFile, File localFile,
+ FTPClient ftpClient, long remoteSize) throws IOException {
+ String status;
+ // 鏄剧ず杩涘害鐨勪笂浼�
+ long step = localFile.length() / 100;
+ step=step ==0?1:step;
+ long process = 0;
+ long localreadbytes = 0L;
+// System.out.println(remoteFile +"-------------------------"+localFile.getPath().toString());
+ RandomAccessFile raf = new RandomAccessFile(localFile, "r");
+ OutputStream out = ftpClient.appendFileStream(new String(remoteFile
+ .getBytes("GBK"), "iso-8859-1"));
+ // 鏂偣缁紶
+ if (remoteSize > 0) {
+ ftpClient.setRestartOffset(remoteSize);
+ process = remoteSize / step;
+ raf.seek(remoteSize);
+ localreadbytes = remoteSize;
+ }
+ byte[] bytes = new byte[1024];
+ int c;
+ while ((c = raf.read(bytes)) != -1) {
+ out.write(bytes, 0, c);
+ localreadbytes += c;
+ if (localreadbytes / step != process) {
+ process = localreadbytes / step;
+ System.out.println("涓婁紶杩涘害:" + process);
+ // TODO 姹囨姤涓婁紶鐘舵��
+ }
+ }
+ out.flush();
+ raf.close();
+ out.close();
+ boolean result = ftpClient.completePendingCommand();
+ if (remoteSize > 0) {
+ status = result ? "0" : "1";
+ // status = result ? UploadStatus.Upload_From_Break_Success
+ // : UploadStatus.Upload_From_Break_Failed;
+ } else {
+ status = result ? "0" : "1";
+ // status = result ? UploadStatus.Upload_New_File_Success
+ // : UploadStatus.Upload_New_File_Failed;
+ }
+ return status;
+ }
+
+ public byte[] getOnlineInputsteam(String urlStr){
+ try {
+ // 鍥剧墖鐨� URL
+ URL url = new URL(urlStr);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.setDoInput(true);
+ connection.connect();
+ // 鑾峰彇杈撳叆娴侊紝鐢ㄤ簬璇诲彇鏁版嵁
+ InputStream inputStream = connection.getInputStream();
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ byte[] buffer = new byte[4096]; // 缂撳啿鍖哄ぇ灏忥紝鍙互鏍规嵁闇�瑕佽皟鏁�
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ outputStream.close();
+ inputStream.close();
+ connection.disconnect();
+
+ // 鑾峰彇瀛楄妭鏁扮粍
+ byte[] imageBytes = outputStream.toByteArray();
+ System.out.println("Image size: " + imageBytes.length + " bytes");
+ return imageBytes;
+ } catch (Exception e) {
+ log.error("鑾峰彇鍥剧墖寮傚父:{}",e.getMessage());
+ }
+ return null;
+ }
+ public boolean uploadOnlineFile(String url,String ftpPath, String fileName) throws Exception
+ {
+ byte[] buf = getOnlineInputsteam(url);
+ if(buf == null){
+ return false;
+ }
+ try
+ {
+ ftpClient.enterLocalPassiveMode();// 寮�鍚鍔ㄦā寮�
+ ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
+ CreateDirecroty( ftpPath,ftpClient);
+ String printWorkingDirectory = ftpClient.printWorkingDirectory();
+ System.out.println("鑾峰彇褰撳墠鐩綍:" + printWorkingDirectory);
+ boolean flag = ftpClient.storeFile(new String(fileName.getBytes("GBK"), "iso-8859-1"), new ByteArrayInputStream(buf));
+ // 閫氳繃鍙戦�� QUIT 鍛戒护娉ㄩ攢 FTP 鏈嶅姟鍣�
+ ftpClient.logout();
+ return flag;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ if (ftpClient.isConnected()){
+ ftpClient.disconnect();
+ }
+
+ }
+ return false;
+ }
+
+ /**
+ * 鍒犻櫎涓�涓枃浠�
+ */
+ public boolean deleteFile(String filename) {
+ boolean flag = true;
+ try {
+
+ flag = ftpClient.deleteFile(filename);
+ if (flag) {
+ System.out.println("鍒犻櫎鏂囦欢鎴愬姛锛�");
+ } else {
+ System.out.println("鍒犻櫎鏂囦欢澶辫触锛�");
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ return flag;
+ }
+
+ public static void main(String[] args) throws Exception {
+ try {
+ FtpUtil ftpUtil = new FtpUtil("175.27.187.84", 21, "ftpuser","doumee168" );
+ ftpUtil.uploadOnlineFile("https://profile-avatar.csdnimg.cn/default.jpg!1", "test"+"/", UUID.randomUUID().toString()+"test.jpg");
+ /*FtpUtil myFtp = new FtpUtil("106.15.54.228", 21, "ftptlg",
+ "tlg168.com");
+ System.out.println(myFtp.upload("D:\\devices.sql", "/1111/devices.sql"));
+
+ // myFtp.ftpClient.makeDirectory(new String("鐢佃鍓�".getBytes("GBK"),
+ // "iso-8859-1"));
+ // myFtp.ftpClient.changeWorkingDirectory(new String("鐢佃鍓�"
+ // .getBytes("GBK"), "iso-8859-1"));
+ // myFtp.ftpClient.makeDirectory(new String("璧拌タ鍙�".getBytes("GBK"),
+ // "iso-8859-1"));
+ // System.out.println(myFtp.upload("http://www.5a520.cn /yw.flv",
+ // "/yw.flv", 5));
+ // System.out.println(myFtp.upload("http://www.5a520.cn /璧拌タ鍙�24.mp4",
+ // "/澶璧拌タ鍙�/鏂版氮缃�/璧拌タ鍙�24.mp4"));
+ *//**
+ * t.connect("pengtu", "61.191.61.226", 2122, "yangnet",
+ * "yanglong@doumee.com"); File file = new File(
+ * "D:\\lib/commons-net-3.3-bin/commons-net-3.3/NOTICE.txt");
+ *
+ *
+ *//*
+
+ System.out.println(myFtp.download("/1/2/NOTICE.txt", "D:\\鍝�.txt"));
+
+ myFtp.deleteFile("/1/2/NOTICE.txt");
+ myFtp.disconnect();
+
+ System.out.println("java鐗堟湰鍙凤細" + System.getProperty("java.version")); // java鐗堟湰鍙�
+ System.out
+ .println("Java鎻愪緵鍟嗗悕绉帮細" + System.getProperty("java.vendor")); // Java鎻愪緵鍟嗗悕绉�
+ System.out.println("Java鎻愪緵鍟嗙綉绔欙細"
+ + System.getProperty("java.vendor.url")); // Java鎻愪緵鍟嗙綉绔�
+ System.out.println("jre鐩綍锛�" + System.getProperty("java.home")); // Java锛屽摝锛屽簲璇ユ槸jre鐩綍
+ System.out.println("Java铏氭嫙鏈鸿鑼冪増鏈彿锛�"
+ + System.getProperty("java.vm.specification.version")); // Java铏氭嫙鏈鸿鑼冪増鏈彿
+ System.out.println("Java铏氭嫙鏈鸿鑼冩彁渚涘晢锛�"
+ + System.getProperty("java.vm.specification.vendor")); // Java铏氭嫙鏈鸿鑼冩彁渚涘晢
+ System.out.println("Java铏氭嫙鏈鸿鑼冨悕绉帮細"
+ + System.getProperty("java.vm.specification.name")); // Java铏氭嫙鏈鸿鑼冨悕绉�
+ System.out.println("Java铏氭嫙鏈虹増鏈彿锛�"
+ + System.getProperty("java.vm.version")); // Java铏氭嫙鏈虹増鏈彿
+ System.out.println("Java铏氭嫙鏈烘彁渚涘晢锛�"
+ + System.getProperty("java.vm.vendor")); // Java铏氭嫙鏈烘彁渚涘晢
+ System.out.println("Java铏氭嫙鏈哄悕绉帮細"
+ + System.getProperty("java.vm.name")); // Java铏氭嫙鏈哄悕绉�
+ System.out.println("Java瑙勮寖鐗堟湰鍙凤細"
+ + System.getProperty("java.specification.version")); // Java瑙勮寖鐗堟湰鍙�
+ System.out.println("Java瑙勮寖鎻愪緵鍟嗭細"
+ + System.getProperty("java.specification.vendor")); // Java瑙勮寖鎻愪緵鍟�
+ System.out.println("Java瑙勮寖鍚嶇О锛�"
+ + System.getProperty("java.specification.name")); // Java瑙勮寖鍚嶇О
+ System.out.println("Java绫荤増鏈彿锛�"
+ + System.getProperty("java.class.version")); // Java绫荤増鏈彿
+ System.out.println("Java绫昏矾寰勶細"
+ + System.getProperty("java.class.path")); // Java绫昏矾寰�
+ System.out.println("Java lib璺緞锛�"
+ + System.getProperty("java.library.path")); // Java lib璺緞
+ System.out.println("Java杈撳叆杈撳嚭涓存椂璺緞锛�"
+ + System.getProperty("java.io.tmpdir")); // Java杈撳叆杈撳嚭涓存椂璺緞
+ System.out
+ .println("Java缂栬瘧鍣細" + System.getProperty("java.compiler")); // Java缂栬瘧鍣�
+ System.out.println("Java鎵ц璺緞锛�"
+ + System.getProperty("java.ext.dirs")); // Java鎵ц璺緞
+ System.out.println("鎿嶄綔绯荤粺鍚嶇О锛�" + System.getProperty("os.name")); // 鎿嶄綔绯荤粺鍚嶇О
+ System.out.println("鎿嶄綔绯荤粺鐨勬灦鏋勶細" + System.getProperty("os.arch")); // 鎿嶄綔绯荤粺鐨勬灦鏋�
+ System.out.println("鎿嶄綔绯荤粺鐗堟湰鍙凤細" + System.getProperty("os.version")); // 鎿嶄綔绯荤粺鐗堟湰鍙�
+ System.out.println("鏂囦欢鍒嗛殧绗︼細" + System.getProperty("file.separator")); // 鏂囦欢鍒嗛殧绗�
+ System.out.println("璺緞鍒嗛殧绗︼細" + System.getProperty("path.separator")); // 璺緞鍒嗛殧绗�
+ System.out.println("鐩寸嚎鍒嗛殧绗︼細" + System.getProperty("line.separator")); // 鐩寸嚎鍒嗛殧绗�
+ System.out.println("鎿嶄綔绯荤粺鐢ㄦ埛鍚嶏細" + System.getProperty("user.name")); // 鐢ㄦ埛鍚�
+ System.out.println("鎿嶄綔绯荤粺鐢ㄦ埛鐨勪富鐩綍锛�" + System.getProperty("user.home")); // 鐢ㄦ埛鐨勪富鐩綍
+ System.out.println("褰撳墠绋嬪簭鎵�鍦ㄧ洰褰曪細" + System.getProperty("user.dir")); // 褰撳墠绋嬪簭鎵�鍦ㄧ洰褰�*/
+
+ } catch (IOException e) {
+ System.out.println("杩炴帴FTP鍑洪敊锛�" + e.getMessage());
+ }
+ }
+
+ /***
+ * @涓婁紶鏂囦欢澶�
+ * @param localDirectory
+ * 褰撳湴鏂囦欢澶�
+ * @param remoteDirectoryPath
+ * Ftp 鏈嶅姟鍣ㄨ矾寰� 浠ョ洰褰旻ile.separator缁撴潫
+ * */
+ public boolean uploadDirectory(String localDirectory,
+ String remoteDirectoryPath) throws Exception {
+ File src = new File(localDirectory);
+ try {
+ remoteDirectoryPath = remoteDirectoryPath + "/";
+ boolean makeDirFlag = this.ftpClient.makeDirectory(remoteDirectoryPath);
+ }catch (IOException e) {
+ e.printStackTrace();
+ log.info(remoteDirectoryPath + "鐩綍鍒涘缓澶辫触");
+ return false;
+ }
+ File[] allFile = src.listFiles();
+ for (int currentFile = 0;currentFile < allFile.length;currentFile++) {
+ File f =allFile[currentFile];
+ String srcName= f.getPath().toString();
+ String tPath = remoteDirectoryPath+f.getName();
+ if (!f.isDirectory()) {
+
+ int dNum = getNumFromStr(tPath,"/".toCharArray()[0]);
+ uploadFile(f, tPath);
+ if(dNum -2>=0){
+ for (int i = 0; i < dNum-1; i++) {
+ this.ftpClient.changeToParentDirectory();
+ }
+ }
+ }else{
+ uploadDirectory(srcName,
+ tPath+"/");
+ }
+ }
+ return true;
+ }
+ /***
+ * @涓婁紶鏂囦欢澶�
+ * @param pathName
+ * 鏂囦欢澶�
+ * */
+ public boolean delDirectory(String pathName ) throws Exception {
+ try {
+ this.ftpClient.changeWorkingDirectory( pathName.substring(0, pathName.lastIndexOf("/")) );
+ ftpClient.removeDirectory(pathName);
+ }catch (IOException e) {
+ e.printStackTrace();
+ log.info(pathName + "鐩綍鍒犻櫎澶辫触");
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/Http.java b/server/services/src/main/java/com/doumee/core/utils/Http.java
new file mode 100644
index 0000000..dfadcdc
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/Http.java
@@ -0,0 +1,239 @@
+package com.doumee.core.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpMethod;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Map;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * Http宸ュ叿绫�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+public class Http {
+
+ /**
+ * 鑾峰彇Http杩炴帴
+ *
+ * @param url 璇锋眰鍦板潃
+ * @return HttpWrap
+ */
+ public HttpWrap build(String url) throws IOException {
+ return this.build(url, "UTF-8");
+ }
+
+ /**
+ * 鑾峰彇Http杩炴帴
+ *
+ * @param url 璇锋眰鍦板潃
+ * @param charset 缂栫爜锛岄粯璁TF-8
+ * @return HttpWrap
+ */
+ public HttpWrap build(String url, String charset) throws IOException {
+ if (url == null) {
+ throw new NullPointerException("url can not be null");
+ }
+ URL urlObj = new URL(url);
+ HttpURLConnection httpURLConnection = (HttpURLConnection) urlObj.openConnection();
+ httpURLConnection.setRequestProperty("ContentType", charset);
+ return new HttpWrap(url, charset, httpURLConnection);
+ }
+
+ @Getter
+ public static class HttpWrap {
+
+ private String url;
+
+ private String charset;
+
+ private HttpURLConnection connection;
+
+ private boolean gzip;
+
+ public HttpWrap (String url, String charset, HttpURLConnection connection) {
+ this.url = url;
+ this.charset = charset;
+ this.connection = connection;
+ }
+
+ /**
+ * 寮�鍚疓ZIP鍘嬬缉
+ */
+ public HttpWrap gzip () {
+ this.gzip = Boolean.TRUE;
+ return this;
+ }
+
+ /**
+ * 璁剧疆璇锋眰灞炴��
+ *
+ * @param key 灞炴��
+ * @param value 灞炴�у��
+ * @return HttpWrap
+ */
+ public HttpWrap setRequestProperty (String key, String value) {
+ connection.setRequestProperty(key, value);
+ return this;
+ }
+
+ /**
+ * 璁剧疆杩炴帴瓒呮椂鏃堕棿
+ *
+ * @param timeout 杩炴帴瓒呮椂鏃堕棿
+ * @return HttpWrap
+ */
+ public HttpWrap setConnectTimeout (int timeout) {
+ connection.setConnectTimeout(timeout);
+ return this;
+ }
+
+ /**
+ * 璁剧疆璇诲彇瓒呮椂鏃堕棿
+ *
+ * @param timeout 璇诲彇瓒呮椂鏃堕棿
+ * @return HttpWrap
+ */
+ public HttpWrap setReadTimeout (int timeout) {
+ connection.setReadTimeout(timeout);
+ return this;
+ }
+
+ /**
+ * 鍙戦�丟ET璇锋眰
+ *
+ * @return HttpResult
+ */
+ public HttpResult get () throws IOException {
+ log.trace("Eva::Util::Http send http request by method GET, url=" + url);
+ connection.setRequestMethod(HttpMethod.GET.toString());
+ return new HttpResult(connection.getInputStream(), charset, gzip);
+ }
+
+ /**
+ * 鍙戦�丳OST璇锋眰
+ *
+ * @return HttpResult
+ */
+ public HttpResult post () throws IOException {
+ log.trace("Eva::Util::Http send http request by method POST, url=" + url);
+ connection.setRequestMethod(HttpMethod.POST.toString());
+ return new HttpResult(connection.getInputStream(), charset, gzip);
+ }
+
+ /**
+ * 鍙戦�丳OST璇锋眰
+ *
+ * @param params 璇锋眰鍙傛暟
+ * @return HttpResult
+ */
+ public HttpResult post (String params) throws IOException {
+ log.trace("Eva::Util::Http send http request by method POST, url=" + url);
+ OutputStreamWriter streamWriter = null;
+ try {
+ connection.setRequestMethod(HttpMethod.POST.toString());
+ if (params != null || "".equals(params.trim())) {
+ connection.setDoInput(Boolean.TRUE);
+ connection.setDoOutput(Boolean.TRUE);
+ streamWriter = new OutputStreamWriter(connection.getOutputStream(), charset);
+ streamWriter.write(params);
+ streamWriter.flush();
+ }
+ return new HttpResult(connection.getInputStream(), charset, gzip);
+ } finally {
+ if (streamWriter != null) {
+ streamWriter.close();
+ }
+ }
+ }
+
+ /**
+ * 鍙戦�丳OST璇锋眰锛岃姹傚弬鏁扮被鍨嬩负JSON
+ *
+ * @param paramsMap 璇锋眰鍙傛暟
+ * @return HttpResult
+ */
+ public HttpResult postJSON(Map<String, Object> paramsMap) throws IOException {
+ setRequestProperty("Content-Type", "application/json");
+ if (paramsMap == null || paramsMap.size() == 0) {
+ return post();
+ }
+ return post(JSON.toJSONString(paramsMap));
+ }
+
+ /**
+ * 鍙戦�丳OST璇锋眰锛岃姹傚弬鏁扮被鍨嬩负JSON
+ *
+ * @param paramJSONObject 璇锋眰鍙傛暟
+ * @return HttpResult
+ */
+ public HttpResult postJSON(JSONObject paramJSONObject) throws IOException {
+ setRequestProperty("Content-Type", "application/json");
+ if (paramJSONObject == null || paramJSONObject.size() == 0) {
+ return post();
+ }
+ return post(paramJSONObject.toJSONString());
+ }
+
+ }
+
+ @Getter
+ @AllArgsConstructor
+ public static class HttpResult {
+
+ private InputStream inputStream;
+
+ private String charset;
+
+ private boolean gzip;
+
+ /**
+ * 杞负瀛楃涓�
+ */
+ public String toStringResult () throws IOException{
+ BufferedReader reader = null;
+ InputStream is = inputStream;
+ try {
+ if (gzip) {
+ is = new GZIPInputStream(inputStream);
+ }
+ reader = new BufferedReader(new InputStreamReader(is, charset));
+ StringBuilder result = new StringBuilder();
+ String line;
+ while((line = reader.readLine()) != null) {
+ result.append(line);
+ }
+ return result.toString();
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+
+ /**
+ * 杞负JSONObject瀵硅薄
+ */
+ public JSONObject toJSONObject () throws IOException {
+ return JSONObject.parseObject(toStringResult());
+ }
+
+ /**
+ * 杞负鐩爣Class瀵硅薄
+ */
+ public <T> T toClass (Class<T> clazz) throws IOException {
+ return JSONObject.parseObject(toStringResult(), clazz);
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/HttpsUtil.java b/server/services/src/main/java/com/doumee/core/utils/HttpsUtil.java
new file mode 100644
index 0000000..e4688de
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/HttpsUtil.java
@@ -0,0 +1,270 @@
+package com.doumee.core.utils;
+
+import javax.net.ssl.*;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+public class HttpsUtil {
+
+ public static String get(String url,boolean ignoreSSL) {
+ return connection(url, "GET", null, null,ignoreSSL);
+ }
+
+ public static String post(String url, String data, String contentType, boolean ignoreSSL) {
+ return connection(url, "POST", data, contentType, ignoreSSL);
+ }
+ public static String postJson(String url, String data) {
+ if(url.startsWith("https://")){
+ return connection(url, "POST", data, "application/json", true);
+ }else{
+ return connectionHttp(url, "POST", data, "application/json");
+ }
+ }
+ public static String uploadTempMedia(String urlString ,String fileUrl){
+ HttpsURLConnection conn= null;
+ try {
+ String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
+ // 鑾峰彇缃戠粶鍥剧墖
+ URL mediaUrl = new URL(fileUrl);
+ HttpURLConnection meidaConn = (HttpURLConnection) mediaUrl.openConnection();
+ meidaConn.setDoOutput(true);
+ meidaConn.setRequestMethod("GET");
+
+ String result = null;
+ URL url=new URL(urlString);
+ conn=(HttpsURLConnection) url.openConnection();
+ conn.setRequestMethod("POST");//浠OST鏂瑰紡鎻愪氦琛ㄥ崟
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+ conn.setUseCaches(false);//POST鏂瑰紡涓嶈兘浣跨敤缂撳瓨
+ //璁剧疆璇锋眰澶翠俊鎭�
+ conn.setRequestProperty("Connection", "Keep-Alive");
+ conn.setRequestProperty("Charset", "UTF-8");
+ //璁剧疆杈圭晫
+ String BOUNDARY="----------"+System.currentTimeMillis();
+ conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
+ //璇锋眰姝f枃淇℃伅
+ //绗竴閮ㄥ垎
+ StringBuilder sb=new StringBuilder();
+ sb.append("--");//蹇呴』澶氫袱鏉¢亾
+ sb.append(BOUNDARY);
+ sb.append("\r\n");
+ sb.append("Content-Disposition: form-data;name=\"media\"; filename=\"" + fileName+"\"\r\n");
+
+ sb.append("Content-Type:application/octet-stream\r\n\r\n");
+ System.out.println("sb:"+sb);
+
+ //鑾峰緱杈撳嚭娴�
+ OutputStream out=new DataOutputStream(conn.getOutputStream());
+ //杈撳嚭琛ㄥご
+ out.write(sb.toString().getBytes("UTF-8"));
+ //鏂囦欢姝f枃閮ㄥ垎
+ //鎶婃枃浠朵互娴佺殑鏂瑰紡 鎺ㄩ�侀亾URL涓�
+ DataInputStream din=new DataInputStream(meidaConn.getInputStream());
+ int bytes=0;
+ byte[] buffer=new byte[1024];
+ while((bytes=din.read(buffer))!=-1){
+ out.write(buffer,0,bytes);
+ }
+ din.close();
+ //缁撳熬閮ㄥ垎
+ byte[] foot=("\r\n--" + BOUNDARY + "--\r\n").getBytes("UTF-8");//瀹氫箟鏁版嵁鏈�鍚庡垎鍓茬嚎
+ out.write(foot);
+ out.flush();
+ out.close();
+ if(HttpsURLConnection.HTTP_OK==conn.getResponseCode()){
+ InputStream is = conn.getInputStream();
+ byte[] b = new byte[4096];
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(b.length);
+ int len;
+ while ((len = is.read(b)) != -1) {
+ baos.write(b, 0, len);
+ }
+ is.close();
+ return baos.toString("utf-8");
+ }
+ return result;
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if(conn != null){
+ conn.disconnect();
+ }
+ }
+ return null;
+
+ }
+ public static String connection(String url,String method,String data,String contentType,boolean ignoreSSL){
+ HttpsURLConnection connection = null;
+ try {
+ URL _url = new URL(url);
+ connection = (HttpsURLConnection) _url.openConnection();
+ connection.setRequestMethod(method);
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+ connection.setUseCaches(false);
+ if(contentType != null){
+ connection.setRequestProperty("Content-Type", contentType);
+ }
+
+ if(ignoreSSL){
+ //淇′换鎵�鏈塻sl璇佷功鍜屼富鏈�
+ TrustManager[] trustManagers = {new HttpsTrustManager()};
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, trustManagers, new SecureRandom());
+ connection.setSSLSocketFactory(context.getSocketFactory());
+ connection.setHostnameVerifier(new HostnameVerifier() {
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
+ });
+ }
+
+
+ connection.connect();
+
+ if(data != null){
+ OutputStream outputStream = connection.getOutputStream();
+ outputStream.write(data.getBytes("utf-8"));
+ outputStream.close();
+ }
+
+ int responseCode = connection.getResponseCode();
+ if (responseCode == HttpsURLConnection.HTTP_OK) {
+ InputStream is = connection.getInputStream();
+ byte[] b = new byte[4096];
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(b.length);
+ int len;
+ while ((len = is.read(b)) != -1) {
+ baos.write(b, 0, len);
+ }
+ is.close();
+ return baos.toString("utf-8");
+ }
+ return connection.getResponseMessage();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if(connection != null){
+ connection.disconnect();
+ }
+ }
+ return null;
+ }
+ public static InputStream connectionInputsteam(String url,String method,String data,String contentType ){
+ HttpURLConnection connection = null;
+ try {
+ URL _url = new URL(url);
+ connection = (HttpURLConnection) _url.openConnection();
+ connection.setDoOutput(true);
+ connection.setRequestMethod("GET");
+ return connection.getInputStream();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ public static String connectionHttp(String url,String method,String data,String contentType ){
+ HttpURLConnection connection = null;
+ try {
+ URL _url = new URL(url);
+ connection = (HttpURLConnection) _url.openConnection();
+ connection.setRequestMethod(method);
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+ connection.setUseCaches(false);
+ if(contentType != null){
+ connection.setRequestProperty("Content-Type", contentType);
+ }
+
+ connection.connect();
+
+ if(data != null){
+ OutputStream outputStream = connection.getOutputStream();
+ outputStream.write(data.getBytes("utf-8"));
+ outputStream.close();
+ }
+
+ int responseCode = connection.getResponseCode();
+ if (responseCode == HttpsURLConnection.HTTP_OK) {
+ InputStream is = connection.getInputStream();
+ byte[] b = new byte[4096];
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(b.length);
+ int len;
+ while ((len = is.read(b)) != -1) {
+ baos.write(b, 0, len);
+ }
+ is.close();
+ return baos.toString("utf-8");
+ }
+ return connection.getResponseMessage();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if(connection != null){
+ connection.disconnect();
+ }
+ }
+ return null;
+ }
+
+
+ public static void main(String[] args) {
+ //灞�閮ㄤ俊浠绘墍鏈夎瘉涔﹀拰涓绘満
+ String result = HttpsUtil.get("https://127.0.0.1:8443/ssl-test/test01.do",true);
+ System.out.println(result);
+
+ //澶栭儴淇′换鎵�鏈夎瘉涔﹀拰涓绘満
+ HttpsTrustManager.allowAllSSL();
+ String response = HttpsUtil.get("https://127.0.0.1:8443/ssl-test/test01.do", false);
+ System.out.println(result);
+
+ }
+}
+
+class HttpsTrustManager implements X509TrustManager {
+
+ private static TrustManager[] trustManagers = {new HttpsTrustManager()};
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static void allowAllSSL() {
+ try {
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, trustManagers, new SecureRandom());
+ HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
+ HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
+ });
+ } catch (NoSuchAlgorithmException | KeyManagementException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/Location.java b/server/services/src/main/java/com/doumee/core/utils/Location.java
new file mode 100644
index 0000000..2f5ad8c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/Location.java
@@ -0,0 +1,72 @@
+package com.doumee.core.utils;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.Serializable;
+import java.nio.charset.Charset;
+
+/**
+ * 鍦板尯宸ュ叿绫�
+ *
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+public class Location {
+
+ // 鍦板尯API
+ private static final String GET_LOCATION_API = "http://whois.pconline.com.cn/ipJson.jsp?json=true&ip=%s";
+
+ /**
+ * 鑾峰彇鍦板尯
+ *
+ * @param ip IP
+ * @return Info
+ */
+ public Info getLocation (String ip) {
+ try {
+ return Utils.Http.build(String.format(GET_LOCATION_API, ip), Charset.forName("GBK").toString())
+ .setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9")
+ .setRequestProperty("Accept-Encoding", "gzip, deflate")
+ .gzip()
+ .get()
+ .toClass(Info.class);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * 鑾峰彇鍦板尯
+ *
+ * @param ip IP
+ * @return String
+ */
+ public String getLocationString (String ip) {
+ Info info = this.getLocation(ip);
+ if (info == null) {
+ return "UNKNOWN";
+ }
+ return info.getAddr();
+ }
+
+ /**
+ * 鍦板尯淇℃伅鍖呰
+ */
+ @Data
+ public static class Info implements Serializable {
+
+ private String pro;
+
+ private String proCode;
+
+ private String city;
+
+ private String cityCode;
+
+ private String addr;
+
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/Monitor.java b/server/services/src/main/java/com/doumee/core/utils/Monitor.java
new file mode 100644
index 0000000..eadf53d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/Monitor.java
@@ -0,0 +1,163 @@
+package com.doumee.core.utils;
+
+import com.doumee.core.utils.monitor.*;
+import com.sun.jna.platform.mac.DiskArbitration;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import oshi.hardware.CentralProcessor;
+import oshi.hardware.GlobalMemory;
+import oshi.hardware.HardwareAbstractionLayer;
+import oshi.software.os.FileSystem;
+import oshi.software.os.OSFileStore;
+import oshi.software.os.OperatingSystem;
+
+import java.io.Serializable;
+import java.lang.management.ManagementFactory;
+import java.lang.management.OperatingSystemMXBean;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鐩戝惉淇℃伅")
+public class Monitor implements Serializable {
+
+ @ApiModelProperty(value = "鎿嶄綔绯荤粺鍚嶇О")
+ private String osName;
+
+ @ApiModelProperty(value = "鎿嶄綔绯荤粺鏋舵瀯")
+ private String osArch;
+
+ @ApiModelProperty(value = "鎿嶄綔绯荤粺鐗堟湰")
+ private String osVersion;
+
+ @ApiModelProperty(value = "鏈嶅姟鍣↖P鍦板潃")
+ private String ip;
+
+ @ApiModelProperty(value = "MAC鍦板潃")
+ private String mac;
+
+ @ApiModelProperty(value = "鏈嶅姟鍣ㄦ椂闂�")
+ private Date currentTime;
+
+ @ApiModelProperty(value = "鍐呭瓨淇℃伅")
+ private Memory memory;
+
+ @ApiModelProperty(value = "CPU淇℃伅")
+ private CPU cpu;
+
+ @ApiModelProperty(value = "纾佺洏鍒楄〃")
+ private List<Disk> disks;
+
+ @ApiModelProperty(value = "JVM淇℃伅")
+ private JVM jvm;
+
+ /**
+ * 鑾峰彇瀹炴椂淇℃伅
+ */
+ public Monitor current() {
+ oshi.SystemInfo systemInfo = new oshi.SystemInfo();
+ HardwareAbstractionLayer hardware = systemInfo.getHardware();
+ systemInfo.getOperatingSystem().getSystemBootTime();
+ // 绯荤粺淇℃伅
+ OperatingSystemMXBean osMXBean = ManagementFactory.getOperatingSystemMXBean();
+ this.setOsName(osMXBean.getName());
+ this.setOsVersion(osMXBean.getVersion());
+ this.setOsArch(osMXBean.getArch());
+ this.setIp(Utils.Server.getIP());
+ this.setMac(Utils.Server.getMAC());
+ this.setCurrentTime(new Date(System.currentTimeMillis()));
+ this.setMemory(hardware.getMemory());
+ this.setCpu(hardware.getProcessor());
+ this.setJvm();
+ this.setDisks(systemInfo.getOperatingSystem());
+ return this;
+ }
+
+ /**
+ * 璁剧疆鍐呭瓨淇℃伅
+ */
+ private void setMemory(GlobalMemory memory) {
+ this.memory = new Memory();
+ this.memory.setSize(this.toM(memory.getTotal()));
+ this.memory.setFreeSpace(this.toM(memory.getAvailable()));
+ }
+
+ /**
+ * 璁剧疆CPU淇℃伅
+ */
+ private void setCpu(CentralProcessor processor) {
+ this.cpu = new CPU();
+ cpu.setLogicalCount(processor.getLogicalProcessorCount());
+ cpu.setPhysicalCount(processor.getPhysicalProcessorCount());
+ long[] prevTicks = processor.getSystemCpuLoadTicks();
+ try {
+ TimeUnit.SECONDS.sleep(1);
+ long[] ticks = processor.getSystemCpuLoadTicks();
+ long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
+ long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
+ long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
+ long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
+ long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
+ long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
+ long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
+ long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
+ long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
+ cpu.setSystemRatio(cSys * 100.0 / totalCpu);
+ cpu.setUserRatio(user * 100.0 / totalCpu);
+ cpu.setUseRatio(100.0 - idle * 100.0 / totalCpu);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 璁剧疆JVM淇℃伅
+ */
+ private void setJvm() {
+ this.jvm = new JVM();
+ Properties props = System.getProperties();
+ jvm.setMemory(new Memory());
+ jvm.getMemory().setSize(this.toM(Runtime.getRuntime().totalMemory()));
+ jvm.getMemory().setFreeSpace(this.toM(Runtime.getRuntime().freeMemory()));
+ jvm.setVersion(props.getProperty("java.version"));
+ jvm.setHome(props.getProperty("java.home"));
+ jvm.setBootTime(new Date(ManagementFactory.getRuntimeMXBean().getStartTime()));
+ }
+
+ /**
+ * 璁剧疆纾佺洏淇℃伅
+ */
+ private void setDisks(OperatingSystem os) {
+ try {
+ this.disks = new LinkedList<>();
+ FileSystem fileSystem = os.getFileSystem();
+ List<OSFileStore> fsArray = fileSystem.getFileStores();
+ for (OSFileStore fileStore : fsArray) {
+ Disk disk = new Disk();
+ disk.setName(fileStore.getName());
+ disk.setDir(fileStore.getMount());
+ disk.setFsType(fileStore.getType());
+ disk.setSize(this.toM(fileStore.getTotalSpace()));
+ disk.setFreeSpace(this.toM(fileStore.getFreeSpace()));
+ this.disks.add(disk);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 杞负鍏�
+ */
+ private double toM(long value) {
+ return value * 1.0 / 1024 / 1024;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/MyBatisPlus.java b/server/services/src/main/java/com/doumee/core/utils/MyBatisPlus.java
new file mode 100644
index 0000000..f1b79cc
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/MyBatisPlus.java
@@ -0,0 +1,36 @@
+package com.doumee.core.utils;
+
+import java.lang.reflect.Field;
+
+/**
+ * Mybatis Plus Wrapper宸ュ叿绫�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public class MyBatisPlus {
+
+ /**
+ * 灏嗙┖杞负null锛岀敤浜巑ybatis plus鏌ヨ鏁版嵁鏃跺皢鍊间负""鐨勫瓧娈佃浆涓簄ull锛岄槻姝㈠皢绌哄瓧绗︿覆浣滀负鏉′欢銆�
+ *
+ * @return T
+ */
+ public <T> T blankToNull(T object) {
+ if (object == null) {
+ return null;
+ }
+ try {
+ Class clazz = object.getClass();
+ Field[] fields = clazz.getDeclaredFields();
+ for (Field field : fields) {
+ field.setAccessible(true);
+ Object value = field.get(object);
+ if ("".equals(value)) {
+ field.set(object, null);
+ }
+ }
+ return object;
+ } catch (Exception e) {
+ throw new RuntimeException("EVA: parse parameter throw an exception", e);
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/PwdCheckUtil.java b/server/services/src/main/java/com/doumee/core/utils/PwdCheckUtil.java
new file mode 100644
index 0000000..e71f277
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/PwdCheckUtil.java
@@ -0,0 +1,78 @@
+package com.doumee.core.utils;
+
+import java.util.regex.Pattern;
+
+/**
+ * Java姝e垯鏍¢獙瀵嗙爜鑷冲皯鍖呭惈锛氬瓧姣嶆暟瀛楃壒娈婄鍙蜂腑鐨�2绉�
+ */
+public class PwdCheckUtil {
+
+ /**
+ * 鍋囧畾璁剧疆瀵嗙爜鏃讹紝瀵嗙爜瑙勫垯涓猴細 瀛楁瘝銆佹暟瀛椼�佺壒娈婄鍙凤紝鑷冲皯鍖归厤2绉�
+ * 鍒欏瘑鐮佸彲鑳藉嚭鐜扮殑鎯呭喌鏈夛細
+ * 1銆佹暟瀛�+鐗规畩绗﹀彿
+ * 2銆佸瓧姣�+鐗规畩绗﹀彿
+ * 3銆佸瓧姣�+鏁板瓧
+ * 4銆佸瓧姣�+鏁板瓧+鐗规畩绗﹀彿
+ * (缁勫悎涓庨『搴忔棤鍏�)
+ * 瑙e喅鎬濊矾锛�
+ * 1銆侀亶鍘嗗瓧绗︿覆鐨勫瓧绗︽暟缁勶紝鏌ョ湅鏄惁鍖呭惈鐩爣鐗规畩瀛楃锛岃嫢鍖呭惈锛屽垯鏍囪瀛楃涓�
+ * 鍖呭惈鐗规畩瀛楃锛屽苟鏇挎崲褰撳墠鐗规畩瀛楃涓�''銆�
+ * 2銆佸垽鏂墿涓嬬殑瀛楃缁勬垚鐨勫瓧绗︿覆锛屾槸鍚﹀尮閰嶄互涓嬫儏鍐�
+ * - 绾瓧姣�
+ * - 绾暟瀛�
+ * - 瀛楁瘝+鏁板瓧
+ * 3銆佸瓧绗︿覆鍖归厤瑙勫垯
+ * 绾瓧姣�+鍖呭惈鐗规畩瀛楃 ---- 鍖归厤閫氳繃
+ * 绾暟瀛�+鍖呭惈鐗规畩瀛楃 ---- 鍖归厤閫氳繃
+ * 瀛楁瘝+鏁板瓧+鍖呭惈涓暟瀛楃 ---- 鍖归厤閫氳繃
+ */
+ //鐗规畩瀛楃
+ public static final String SPEC_CHARACTERS = " !\"#$%&'()*+,-./:;<=>?@\\]\\[^_`{|}~";
+ // 绾瓧姣�
+ public static final String character = "[a-zA-Z]{1,}$";
+ // 绾暟瀛�
+ public static final String numberic = "[0-9]{1,}$";
+ // 瀛楁瘝鍜屾暟瀛�
+ public static final String number_and_character = "((^[a-zA-Z]{1,}[0-9]{1,}[a-zA-Z0-9]*)+)" +
+ "|((^[0-9]{1,}[a-zA-Z]{1,}[a-zA-Z0-9]*)+)$";
+ // 瀛楁瘝鎴栨暟瀛�
+ public static final String number_or_character = "[a-zA-Z0-9]+$";
+ // 瀛楁瘝鏁板瓧涓嬪垝绾�
+ public static final String ncw = "\\w+$";
+
+ public static boolean checkPassword(String targetString) {
+ String opStr = targetString;
+ boolean isLegal = false;
+ boolean hasSpecChar = false;
+ char[] charArray = opStr.toCharArray();
+ for (char c : charArray) {
+ if (SPEC_CHARACTERS.contains(String.valueOf(c))) {
+ hasSpecChar = true;
+ // 鏇挎崲姝ゅ瓧绗︿覆
+ opStr = opStr.replace(c, ' ');
+ }
+ }
+ String excSpecCharStr = opStr.replace(" ", "");
+ boolean isPureNum = Pattern.compile(numberic).matcher(excSpecCharStr).matches();
+ boolean isPureChar = Pattern.compile(character).matcher(excSpecCharStr).matches();
+ boolean isNumAndChar = Pattern.compile(number_and_character).matcher(excSpecCharStr).matches();
+ isLegal = ((isPureNum && hasSpecChar)
+ || (isPureChar && hasSpecChar) || isNumAndChar && hasSpecChar) || isNumAndChar;
+ System.out.println("瀛楃涓诧細" + targetString + ",鏄惁绗﹀悎瑙勫垯锛�" + isLegal);
+ System.out.println("---------------");
+ return isLegal;
+ }
+
+ public static void main(String[] args) {
+ checkPassword("123456a");
+// checkPassword("41234123");
+// checkPassword("#$%^&&*(");
+// checkPassword("fasd$$");
+// checkPassword("41234%%%");
+// checkPassword("fasd41^(324");
+// checkPassword("fa413%^&*");
+// checkPassword("&%fa413%^&*");
+ }
+
+}
\ No newline at end of file
diff --git a/server/services/src/main/java/com/doumee/core/utils/Secure.java b/server/services/src/main/java/com/doumee/core/utils/Secure.java
new file mode 100644
index 0000000..03a1e45
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/Secure.java
@@ -0,0 +1,42 @@
+package com.doumee.core.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.doumee.core.model.ApiResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.DigestUtils;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 瀹夊叏澶勭悊宸ュ叿绫�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+public class Secure {
+
+ /**
+ * 鍔犲瘑瀵嗙爜
+ *
+ * @param password 瀵嗙爜
+ * @param salt 瀵嗙爜鐩�
+ * @return String
+ */
+ public String encryptPassword(String password, String salt) {
+ return this.encryptMD5Password(DigestUtils.md5DigestAsHex(password.getBytes()), salt);
+ }
+
+ /**
+ * 鍔犲瘑瀵嗙爜
+ *
+ * @param md5Password 瀵嗙爜
+ * @param salt 瀵嗙爜鐩�
+ * @return String
+ */
+ public String encryptMD5Password(String md5Password, String salt) {
+ return DigestUtils.md5DigestAsHex((md5Password + salt).getBytes());
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/Server.java b/server/services/src/main/java/com/doumee/core/utils/Server.java
new file mode 100644
index 0000000..7ee8509
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/Server.java
@@ -0,0 +1,92 @@
+package com.doumee.core.utils;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
+
+/**
+ * 鏈嶅姟绔伐鍏风被
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+public class Server {
+
+ /**
+ * 鑾峰彇IP鍦板潃
+ */
+ public String getIP() {
+ String ip = "鑾峰彇澶辫触";
+ InetAddress inetAddress = getInetAddress();
+ if (inetAddress != null) {
+ ip = inetAddress.getHostAddress();
+ }
+ return ip;
+ }
+
+ /**
+ * 鑾峰彇MAC鍦板潃
+ */
+ public String getMAC() {
+ try {
+ InetAddress inetAddress = getInetAddress();
+ if (inetAddress == null) {
+ return "鑾峰彇澶辫触";
+ }
+ byte[] bs = NetworkInterface.getByInetAddress(inetAddress).getHardwareAddress();
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < bs.length; i++) {
+ if (i != 0) {
+ sb.append(":");
+ }
+ // 瀛楄妭杞崲涓烘暣鏁�
+ int temp = bs[i] & 0xff;
+ // 鎶婃棤绗﹀彿鏁存暟鍙傛暟鎵�琛ㄧず鐨勫�艰浆鎹㈡垚浠ュ崄鍏繘鍒惰〃绀虹殑瀛楃涓�
+ String str = Integer.toHexString(temp);
+ if (str.length() == 1) {
+ sb.append("0" + str);
+ } else {
+ sb.append(str);
+ }
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return "鑾峰彇澶辫触";
+ }
+ }
+
+ /**
+ * 鑾峰彇InetAddress瀵硅薄
+ */
+ private InetAddress getInetAddress () {
+ InetAddress inetAddress = null;
+ try {
+ for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
+ NetworkInterface intf = en.nextElement();
+ String name = intf.getName();
+ if (name.contains("docker") || name.contains("lo")) {
+ return inetAddress;
+ }
+ for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
+ InetAddress ia = enumIpAddr.nextElement();
+ if (ia.isLoopbackAddress()) {
+ continue;
+ }
+ String address = ia.getHostAddress();
+ if (address.contains("::") || address.contains("0:0:") || address.contains("fe80")) {
+ continue;
+ }
+ if (!"127.0.0.1".equals(address)) {
+ inetAddress = ia;
+ }
+ }
+ }
+ } catch (SocketException e) {
+ log.error(e.getMessage(), e);
+ }
+ return inetAddress;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/ThreadPool.java b/server/services/src/main/java/com/doumee/core/utils/ThreadPool.java
new file mode 100644
index 0000000..c50ff85
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/ThreadPool.java
@@ -0,0 +1,20 @@
+package com.doumee.core.utils;
+
+import java.util.concurrent.Executors;
+
+/**
+ * 绾跨▼姹犲鐞�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public class ThreadPool {
+
+ /**
+ * 寮�鍚柊绾跨▼骞跺惎鍔�
+ *
+ * @param runnable Runnable
+ */
+ public void start (Runnable runnable) {
+ Executors.defaultThreadFactory().newThread(runnable).start();
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/UserClient.java b/server/services/src/main/java/com/doumee/core/utils/UserClient.java
new file mode 100644
index 0000000..1084c3c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/UserClient.java
@@ -0,0 +1,126 @@
+package com.doumee.core.utils;
+
+import org.apache.commons.lang3.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 璇锋眰宸ュ叿绫�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public class UserClient {
+
+ /**
+ * 鑾峰彇绯荤粺淇℃伅
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @return String
+ */
+ public String getOS(HttpServletRequest request) {
+ String browserDetails = request.getHeader("User-Agent");
+ String userAgent = browserDetails.toLowerCase();
+ String os;
+ if (userAgent.indexOf("windows") >= 0) {
+ os = "Windows";
+ } else if (userAgent.indexOf("mac") >= 0) {
+ os = "Mac";
+ } else if (userAgent.indexOf("x11") >= 0) {
+ os = "Unix";
+ } else if (userAgent.indexOf("android") >= 0) {
+ os = "Android";
+ } else if (userAgent.indexOf("iphone") >= 0) {
+ os = "IPhone";
+ } else {
+ os = "UnKnown, More-Info: " + userAgent;
+ }
+ return os;
+
+ }
+
+ /**
+ * 鑾峰彇瀹㈡埛绔俊鎭�
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @return String
+ */
+ public String getBrowser(HttpServletRequest request) {
+ String browserDetails = request.getHeader("User-Agent");
+ String userAgent = browserDetails;
+ String user = userAgent.toLowerCase();
+
+ String browser = "";
+
+ if (user.contains("edge")) {
+ browser = (userAgent.substring(userAgent.indexOf("Edge")).split(" ")[0]).replace("/", "-");
+ } else if (user.contains("msie")) {
+ String substring = userAgent.substring(userAgent.indexOf("MSIE")).split(";")[0];
+ browser = substring.split(" ")[0].replace("MSIE", "IE") + "-" + substring.split(" ")[1];
+ } else if (user.contains("safari") && user.contains("version")) {
+ browser = (userAgent.substring(userAgent.indexOf("Safari")).split(" ")[0]).split("/")[0] + "-"
+ + (userAgent.substring(userAgent.indexOf("Version")).split(" ")[0]).split("/")[1];
+ } else if (user.contains("opr") || user.contains("opera")) {
+ if (user.contains("opera")) {
+ browser = (userAgent.substring(userAgent.indexOf("Opera")).split(" ")[0]).split("/")[0] + "-"
+ + (userAgent.substring(userAgent.indexOf("Version")).split(" ")[0]).split("/")[1];
+ } else if (user.contains("opr")) {
+ browser = ((userAgent.substring(userAgent.indexOf("OPR")).split(" ")[0]).replace("/", "-"))
+ .replace("OPR", "Opera");
+ }
+
+ } else if (user.contains("chrome")) {
+ browser = (userAgent.substring(userAgent.indexOf("Chrome")).split(" ")[0]).replace("/", "-");
+ } else if ((user.indexOf("mozilla/7.0") > -1) || (user.indexOf("netscape6") != -1)
+ || (user.indexOf("mozilla/4.7") != -1) || (user.indexOf("mozilla/4.78") != -1)
+ || (user.indexOf("mozilla/4.08") != -1) || (user.indexOf("mozilla/3") != -1)) {
+ browser = "Netscape-?";
+
+ } else if (user.contains("firefox")) {
+ browser = (userAgent.substring(userAgent.indexOf("Firefox")).split(" ")[0]).replace("/", "-");
+ } else if (user.contains("rv")) {
+ String IEVersion = (userAgent.substring(userAgent.indexOf("rv")).split(" ")[0]).replace("rv:", "-");
+ browser = "IE" + IEVersion.substring(0, IEVersion.length() - 1);
+ } else {
+ browser = "UnKnown, More-Info: " + userAgent;
+ }
+
+ return browser;
+ }
+
+ /**
+ * 鑾峰彇IP
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @return String
+ */
+ public String getIP(HttpServletRequest request){
+ String ip = request.getHeader("x-forwarded-for");
+ if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
+ ip = request.getHeader("Proxy-Client-IP");
+ }
+ if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
+ ip = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
+ ip = request.getRemoteAddr();
+ }
+ if(!StringUtils.isBlank(ip)) {
+ if(ip.contains(",")) {
+ return ip.split(",")[0].trim();
+ } else {
+ return ip.trim();
+ }
+ }
+ return "-1.-1.-1.-1";
+ }
+
+ /**
+ * 鑾峰彇鐢ㄦ埛鎿嶄綔骞冲彴
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @return String
+ */
+ public String getPlatform (HttpServletRequest request) {
+ return request.getHeader("doumee-platform") == null ? "UNKNOWN" : request.getHeader("doumee-platform");
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/Utils.java b/server/services/src/main/java/com/doumee/core/utils/Utils.java
new file mode 100644
index 0000000..0115c2e
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/Utils.java
@@ -0,0 +1,84 @@
+package com.doumee.core.utils;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * 宸ュ叿鍖�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Component
+public final class Utils {
+
+ /**
+ * Spring涓婁笅鏂�
+ */
+ public static ApplicationContextHelper SpringContext;
+
+ /**
+ * 鍦板尯澶勭悊
+ */
+ public static final Location Location = new Location();
+
+ /**
+ * Http璇锋眰澶勭悊
+ */
+ public static final Http Http = new Http();
+
+ /**
+ * 鐢ㄦ埛瀹㈡埛绔俊鎭�
+ */
+ public static final UserClient User_Client = new UserClient();
+
+ /**
+ * 鏈嶅姟绔俊鎭�
+ */
+ public static final Server Server = new Server();
+
+ /**
+ * 鐩戝惉鍣�
+ */
+ public static final Monitor Monitor = new Monitor();
+
+ /**
+ * MyBatis Plus澶勭悊
+ */
+ public static final MyBatisPlus MP = new MyBatisPlus();
+
+ /**
+ * 瀹夊叏澶勭悊
+ */
+ public static Secure Secure;
+
+ /**
+ * 鏃ユ湡澶勭悊
+ */
+ public static final DateHelper Date = new DateHelper();
+
+ /**
+ * 绾跨▼姹�
+ */
+ public static final ThreadPool ThreadPool = new ThreadPool();
+
+ /**
+ * AES
+ */
+ public static AES AES;
+
+ @Autowired
+ public void setSpringContext(ApplicationContextHelper springContext) {
+ Utils.SpringContext = springContext;
+ }
+
+ @Autowired
+ public void setSecure(Secure secure) {
+ Utils.Secure = secure;
+ }
+
+ @Autowired
+ public void setAES (AES aes) {
+ Utils.AES = aes;
+ }
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/Week.java b/server/services/src/main/java/com/doumee/core/utils/Week.java
new file mode 100644
index 0000000..5a9c5f2
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/Week.java
@@ -0,0 +1,45 @@
+package com.doumee.core.utils;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @Author : Rk
+ * @create 2023/5/6 10:59
+ */
+public enum Week {
+ MONDAY("鏄熸湡涓�", "Monday", "涓�", 1),
+ TUESDAY("鏄熸湡浜�", "Tuesday", "浜�", 2),
+ WEDNESDAY("鏄熸湡涓�", "Wednesday", "涓�", 3),
+ THURSDAY("鏄熸湡鍥�", "Thursday", "鍥�", 4),
+ FRIDAY("鏄熸湡浜�", "Friday", "浜�", 5),
+ SATURDAY("鏄熸湡鍏�", "Saturday", "鍏�", 6),
+ SUNDAY("鏄熸湡鏃�", "Sunday", "鏃�", 7);
+
+ String name_cn;
+ String name_en;
+ String name_enShort;
+ int number;
+
+ Week(String name_cn, String name_en, String name_enShort, int number) {
+ this.name_cn = name_cn;
+ this.name_en = name_en;
+ this.name_enShort = name_enShort;
+ this.number = number;
+ }
+
+ public String getChineseName() {
+ return name_cn;
+ }
+
+ public String getName() {
+ return name_en;
+ }
+
+ public String getShortName() {
+ return name_enShort;
+ }
+
+ public int getNumber() {
+ return number;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/azure/AzureBlobUtil.java b/server/services/src/main/java/com/doumee/core/utils/azure/AzureBlobUtil.java
new file mode 100644
index 0000000..4f1c383
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/azure/AzureBlobUtil.java
@@ -0,0 +1,82 @@
+package com.doumee.core.utils.azure;
+
+import com.azure.core.http.rest.Response;
+import com.azure.storage.blob.BlobClient;
+import com.azure.storage.blob.BlobContainerClient;
+import com.azure.storage.blob.BlobServiceClient;
+import com.azure.storage.blob.BlobServiceClientBuilder;
+import com.azure.storage.blob.models.BlobRequestConditions;
+import com.azure.storage.blob.models.BlockBlobItem;
+import com.azure.storage.blob.options.BlobParallelUploadOptions;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.InputStream;
+
+@Data
+@Slf4j
+public class AzureBlobUtil {
+
+ public String connectionString;
+ public BlobServiceClient blobServiceClient;
+ public String accountName;
+ public String accountKey;
+ public String endpoint;
+ public String container;
+
+ public BlobContainerClient blobContainerClient ;
+
+ public AzureBlobUtil(String accountName, String accountKey, String endpoint, String container){
+ try {
+ this.accountKey = accountKey;
+ this.accountName = accountName;
+ this.endpoint = endpoint;
+ this.container = container;
+ this.connectionString = "DefaultEndpointsProtocol=https;AccountName=" + this.accountName + ";AccountKey=" + this.accountKey + ";EndpointSuffix=" + endpoint;
+ this.blobServiceClient = new BlobServiceClientBuilder().connectionString(connectionString).buildClient();
+ this.blobContainerClient = this.blobServiceClient.getBlobContainerClient(this.container);
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public void initClient( ) {
+ try {
+ this.blobServiceClient = new BlobServiceClientBuilder().connectionString(connectionString).buildClient();
+ this.blobContainerClient = this.blobServiceClient.getBlobContainerClient(this.container);
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ public void uploadFile(String fileName, InputStream data) {
+ try {
+ if(getBlobContainerClient() == null){
+ initClient();
+ }
+ BlobClient client = this.blobContainerClient.getBlobClient(fileName);
+ client.upload(data, data.available(), true);
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ public boolean uploadFileWithResponse(String fileName, InputStream inputStream) {
+ try {
+ if(getBlobContainerClient() == null){
+ initClient();
+ }
+ BlobParallelUploadOptions options = new BlobParallelUploadOptions(inputStream, inputStream.available());
+ options.setRequestConditions(new BlobRequestConditions().setIfNoneMatch("*"));
+ Response<BlockBlobItem> rsp = this.blobContainerClient.getBlobClient(fileName).uploadWithResponse(options, null, null);
+ if(rsp.getStatusCode()==201) {
+ log.info("涓婁紶鎴愬姛锛�........"+fileName);
+ return true;
+ }
+ }catch (Exception e) {
+ e.printStackTrace();
+ log.info("涓婁紶澶辫触锛�........"+e.getMessage());
+ }
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/server/services/src/main/java/com/doumee/core/utils/monitor/CPU.java b/server/services/src/main/java/com/doumee/core/utils/monitor/CPU.java
new file mode 100644
index 0000000..558b25b
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/monitor/CPU.java
@@ -0,0 +1,37 @@
+package com.doumee.core.utils.monitor;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * CPU淇℃伅
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("CPU淇℃伅")
+public class CPU implements Serializable {
+
+ @ApiModelProperty(value = "閫昏緫鏍告暟")
+ private int logicalCount;
+
+ @ApiModelProperty(value = "鐗╃悊鏍告暟")
+ private int physicalCount;
+
+ @ApiModelProperty(value = "鐢ㄦ埛浣跨敤鐜�")
+ private double userRatio;
+
+ @ApiModelProperty(value = "绯荤粺浣跨敤鐜�")
+ private double systemRatio;
+
+ @ApiModelProperty(value = "褰撳墠浣跨敤鐜�")
+ private double useRatio;
+
+ @ApiModelProperty(value = "绌洪棽鐜�")
+ public double getFreeRatio () {
+ return 100.0 - useRatio;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/monitor/Disk.java b/server/services/src/main/java/com/doumee/core/utils/monitor/Disk.java
new file mode 100644
index 0000000..91b06c0
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/monitor/Disk.java
@@ -0,0 +1,42 @@
+package com.doumee.core.utils.monitor;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 纾佺洏淇℃伅
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("纾佺洏淇℃伅")
+public class Disk implements Serializable {
+
+ @ApiModelProperty(value = "纾佺洏鍚嶇О")
+ private String name;
+
+ @ApiModelProperty(value = "鐩樼璺緞")
+ private String dir;
+
+ @ApiModelProperty(value = "鏂囦欢绯荤粺绫诲瀷")
+ private String fsType;
+
+ @ApiModelProperty(value = "鎬诲ぇ灏�")
+ private double size;
+
+ @ApiModelProperty(value = "鍙敤澶у皬")
+ private double freeSpace;
+
+ @ApiModelProperty(value = "鑾峰彇宸蹭娇鐢ㄥぇ灏�")
+ public double getUsedSpace () {
+ return size - freeSpace;
+ }
+
+ @ApiModelProperty(value = "浣跨敤鐜�")
+ public double getUseRatio () {
+ return getUsedSpace() / size * 100;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/monitor/JVM.java b/server/services/src/main/java/com/doumee/core/utils/monitor/JVM.java
new file mode 100644
index 0000000..5fae5f6
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/monitor/JVM.java
@@ -0,0 +1,50 @@
+package com.doumee.core.utils.monitor;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("JVM淇℃伅")
+public class JVM implements Serializable {
+
+ @ApiModelProperty(value = "鐗堟湰")
+ private String version;
+
+ @ApiModelProperty(value = "瀹夎璺緞")
+ private String home;
+
+ @ApiModelProperty(value = "鍚姩鏃堕棿")
+ private Date bootTime;
+
+ @ApiModelProperty(value = "鍐呭瓨淇℃伅")
+ private Memory memory;
+
+ @ApiModelProperty(value = "杩愯鏃堕暱")
+ public String getRuntime () {
+ long ms = (System.currentTimeMillis() - bootTime.getTime())/1000;
+ long months = ms/2592000; // 涓�涓湀鎸�30澶╄绠�
+ long days = ms%2592000/86400;
+ long hours = ms%2592000%86400/3600;
+ long minutes = ms%2592000%86400%3600/60;
+ String runtime = "";
+ if (months > 0) {
+ runtime += months + "涓湀";
+ }
+ if (days > 0 || months > 0) {
+ runtime += days + "澶�";
+ }
+ if (hours > 0 || days > 0 || months > 0) {
+ runtime += hours + "灏忔椂";
+ }
+ runtime += minutes + "鍒嗛挓";
+ return runtime;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/monitor/Memory.java b/server/services/src/main/java/com/doumee/core/utils/monitor/Memory.java
new file mode 100644
index 0000000..2ef73ce
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/monitor/Memory.java
@@ -0,0 +1,32 @@
+package com.doumee.core.utils.monitor;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鍐呭瓨淇℃伅")
+public class Memory implements Serializable {
+
+ @ApiModelProperty(value = "鎬诲唴瀛�")
+ private double size;
+
+ @ApiModelProperty(value = "绌洪棽鍐呭瓨")
+ private double freeSpace;
+
+ @ApiModelProperty(value = "鑾峰彇宸蹭娇鐢ㄥぇ灏�")
+ public double getUsedSpace () {
+ return size - freeSpace;
+ }
+
+ @ApiModelProperty(value = "鑾峰彇浣跨敤鐜�")
+ public double getUseRatio () {
+ return getUsedSpace() / size * 100;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/QywxConstant.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/QywxConstant.java
new file mode 100644
index 0000000..b2bad0f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/QywxConstant.java
@@ -0,0 +1,32 @@
+package com.doumee.core.utils.qiyeweixin;
+
+public class QywxConstant {
+ public final static String MSGCORPSECRET = "WXvaZzwN9A3F-oGTHKY03Rxbl1niz1P_3odjwBdRs8g";//浼佷笟寰俊 娑堟伅鎺ㄩ�丼ECRET
+ public final static String SCHEDULESECRET = "kDucV45wtQaWjRRZoIlvxbBrLp3khHFouJhsDywBe0I";//浼佷笟寰俊 鏃ョ▼SECRET
+ public final static String DOUMIGUANJIA = "1000002";//浼佷笟寰俊 SECRET
+ public final static String PARENTID = "1";//椤剁骇閮ㄩ棬缂栫爜
+ public final static String PASSWORD = "123456";//榛樿瀵嗙爜
+ public final static String CORPID = "wweea8f71b54e3b835";
+ public final static String DMSECRET = "mfmGJpvqj1WNPTwo0Cue42uibhUd5W6_iSWpF39XZQ0";//瀹㈢瀹跺簲鐢� SECRET
+ public final static String CORPSECRET = "8gl5ndGr824OHZ90CkZdcIewUKHoyk13XN4hfxBS_io";
+ public final static String ACCESS_TOKEN = "aOpknXCW7KBBwgGAPuacwfhJRcT1PeIg-IroZicxWamj0JayKJ0rKw2sNXGzpQzK8AMDeDrEJC_kTvPPWTgtefDNLtfsdHS7IpXqBV1P8znLG1EmsYPNgvn78dsQd5bBomLl_qPpOob9hUUsSJJKcEmxXldCNEYVBhKmYnQ4yY8WE8i4xp7aLmm-hRql0AzhzaNhUA7nAzNN5BsgSgbXMA";
+ //鑾峰彇accesstoken,corpid=浼佷笟ID,corpsecret=搴旂敤鐨勫嚟璇佸瘑閽�
+ public final static String[] GET_ACCESS_TOKEN = new String[]{"/cgi-bin/gettoken?corpid=${corpid}&corpsecret=${secret}","鑾峰彇浼佷笟寰俊accesstoken"};
+ //鑾峰彇閮ㄩ棬淇℃伅,閮ㄩ棬id銆傝幏鍙栨寚瀹氶儴闂ㄥ強鍏朵笅鐨勫瓙閮ㄩ棬锛堜互鍙婂強瀛愰儴闂ㄧ殑瀛愰儴闂ㄧ瓑绛夛紝閫掑綊锛夈�� 濡傛灉涓嶅~锛岄粯璁よ幏鍙栧叏閲忕粍缁囨灦鏋�
+ public final static String[] GET_DEPARTMENT_LIST = new String[]{"/cgi-bin/department/list?access_token=${accesstoken}&id=${id}","鑾峰彇閮ㄩ棬淇℃伅"};
+ public final static String[] GET_DEPARTMENT_SIMPLELIST = new String[]{"/cgi-bin/department/simplelist?access_token=${accesstoken}&id=${id}","鑾峰彇閮ㄩ棬淇℃伅"};
+ public final static String[] GET_DEPARTMENT_INFO = new String[]{"/cgi-bin/department/get?access_token=${accesstoken}&id=${id}","鑾峰彇鍗曚釜閮ㄩ棬璇︽儏"};
+ //鑾峰彇閮ㄩ棬鎴愬憳,access_token=璋冪敤鎺ュ彛鍑瘉,department_id=鑾峰彇鐨勯儴闂╥d,fetch_child= 鏄惁閫掑綊鑾峰彇瀛愰儴闂ㄤ笅闈㈢殑鎴愬憳锛�1-閫掑綊鑾峰彇锛�0-鍙幏鍙栨湰閮ㄩ棬
+ public final static String[] GET_DEPARTMENT_SIMPLE_LIST = new String[]{"/cgi-bin/user/simplelist?access_token=${accesstoken}&department_id=${departmentId}","鑾峰彇閮ㄩ棬鎴愬憳"};
+ public final static String[] GET_DEPARTMENT_USER_LIST = new String[]{"/cgi-bin/user/list?access_token=${accesstoken}&department_id=${departmentId}","鑾峰彇閮ㄩ棬鎴愬憳"};
+ public final static String[] GET_MEDIA = new String[]{"/cgi-bin/media/get?access_token=${accesstoken}&media_id=${media_id}","鑾峰彇涓存椂绱犳潗"};
+ public final static String[] UPLOAD_TEMP_MEDIA = new String[]{"/cgi-bin/media/upload?access_token=${accesstoken}&type=${type}","涓婁紶涓存椂绱犳潗"};
+ //鑾峰彇鎴愬憳璇︽儏,access_token=璋冪敤鎺ュ彛鍑瘉,userid=鎴愬憳UserID
+ public final static String[] GET_USER_DETAIL =new String[]{ "/cgi-bin/user/get?access_token=${accesstoken}&userid=${id}","鑾峰彇鎴愬憳璇︽儏"};
+ //鍙戦�佸簲鐢ㄦ秷鎭�,access_token=璋冪敤鎺ュ彛鍑瘉 POST璇锋眰锛�
+ public final static String[] SEND_MSG =new String[]{ "/cgi-bin/message/send?access_token=${accesstoken}","鍙戦�佹帹閫佹秷鎭�"};
+ public final static String[] GET_USER_BY_AUTH_CODE =new String[]{ "/cgi-bin/auth/getuserinfo?access_token=${accesstoken}&code=${code}","鑾峰彇鐢ㄦ埛鐧诲綍韬唤"};
+ public final static String[] GET_JSAPI_TICKET =new String[]{ "/cgi-bin/get_jsapi_ticket?access_token=${accesstoken}","鑾峰彇浼佷笟 jsapi_ticket"};
+
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/QywxUtil.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/QywxUtil.java
new file mode 100644
index 0000000..a501b01
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/QywxUtil.java
@@ -0,0 +1,253 @@
+package com.doumee.core.utils.qiyeweixin;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.TypeReference;
+import com.doumee.biz.system.SystemDictDataBiz;
+import com.doumee.core.utils.HttpsUtil;
+import com.doumee.core.utils.qiyeweixin.model.request.QywxSendMsgRequest;
+import com.doumee.core.utils.qiyeweixin.model.response.*;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+@Component
+@Slf4j
+public class QywxUtil {
+ private static JSONObject json = new JSONObject();
+
+
+
+ private static QywxUtil qyUtil;
+
+ @Value("${qiwei.serviceurl}")
+ private String qiweiUrl;
+
+ @PostConstruct
+ private void init() {
+ qyUtil = this;
+// QywxUtil.qiweiUrl = serviceurl;
+ }
+
+
+ public static String create(Map<String, Object> map, String url, String token) throws IOException {
+ // String token = getToken(QY_Constant.CORPID, QY_Constant.SCHEDULESECRET);
+ String postData = createPostData(map);
+ String response = HttpsUtil.post(url + token, postData, "application/json", false);
+ System.out.println("鑾峰彇鍒扮殑token======>" + token);
+ System.out.println("璇锋眰鏁版嵁======>" + postData);
+ System.out.println("鍙戦�佸井淇$殑鍝嶅簲鏁版嵁======>" + response);
+ return response;
+ }
+
+ private static String createPostData(Map<String, Object> map) {
+ System.out.println("杩涘叆createPostData鏂规硶-------------------------");
+ return JSONObject.toJSONString(map);
+ }
+
+
+ public static String getAccessToken(String corpId, String corpSecret) {
+ String[] interfaceUrl = QywxConstant.GET_ACCESS_TOKEN;
+ String url = interfaceUrl[0].replace("${corpid}",corpId).replace("${secret}",corpSecret);
+ QywxBaseResponse response = sendHttpRequest(url,interfaceUrl[1],"",new TypeReference<QywxBaseResponse<String>>(){});
+ if(response.getErrcode()!=null && response.getErrcode() ==0){
+ return response.getAccess_token();
+ }
+ return null;
+ }
+ public static List<QywxDepartInfoResponse> getDepartmentAll(String token) {
+ String[] interfaceUrl = QywxConstant.GET_DEPARTMENT_LIST;
+ String url = interfaceUrl[0].replace("${accesstoken}",token).replace("${id}","");
+ QywxBaseResponse<List<QywxDepartInfoResponse>> response = sendHttpRequest(url,interfaceUrl[1],"",new TypeReference<QywxBaseResponse<List<QywxDepartInfoResponse>>>(){});
+ if(response.getErrcode()!=null && response.getErrcode() ==0){
+ return response.getData();
+ }
+ return null;
+ }
+ public static QywxDepartInfoResponse getDepartmentInfo(String token,String departid) {
+ String[] interfaceUrl = QywxConstant.GET_DEPARTMENT_INFO;
+ String url = interfaceUrl[0].replace("${accesstoken}",token).replace("${id}",departid);
+ QywxBaseResponse<QywxDepartInfoResponse> response = sendHttpRequest(url,interfaceUrl[1],""
+ ,new TypeReference< QywxBaseResponse<QywxDepartInfoResponse>>(){});
+ if(response.getErrcode()!=null && response.getErrcode() ==0){
+ return response.getData();
+ }
+ return null;
+ }
+ public static QywxSendMsgResponse sendMsg(String token, QywxSendMsgRequest param) {
+ try{
+ String[] interfaceUrl = QywxConstant.SEND_MSG;
+ String url = interfaceUrl[0].replace("${accesstoken}",token);
+ QywxSendMsgResponse response = sendHttpRequestSingle(url,interfaceUrl[1],JSONObject.toJSONString(param)
+ ,new TypeReference<QywxSendMsgResponse>(){});
+ log.error("鎺ㄩ�佹秷鎭粨鏋渰}",JSONObject.toJSONString(response));
+ if(response.getErrcode()!=null && response.getErrcode() ==0){
+ return response;
+ }
+ }catch (Exception e){
+
+ }
+
+ return null;
+ }
+ public static List<QywxUserListResponse> getUserList(String token,String depatId) {
+ try {
+ String[] interfaceUrl = QywxConstant.GET_DEPARTMENT_USER_LIST;
+ String url = interfaceUrl[0].replace("${accesstoken}",token).replace("${departmentId}",depatId);
+ QywxBaseResponse<List<QywxUserListResponse>> response = sendHttpRequest(url,interfaceUrl[1],"",new TypeReference<QywxBaseResponse<List<QywxUserListResponse>>>(){});
+ if(response.getErrcode()!=null && response.getErrcode() ==0){
+ return response.getData();
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+ public static InputStream getMediaInputstream(String token, String media) {
+ try {
+ String[] interfaceUrl = QywxConstant.GET_MEDIA;
+ String url = qyUtil.qiweiUrl+interfaceUrl[0].replace("${accesstoken}",token).replace("${media_id}",media);
+ log.info("浼佷笟寰俊涓存椂绱犳潗鑾峰彇url=========="+url);
+ return HttpsUtil.connectionInputsteam(url,"GET",null,null);
+ }catch (Exception e){
+ e.printStackTrace();
+ log.error("浼佷笟寰俊涓存椂绱犳潗鑾峰彇error=========="+e.getMessage());
+ }
+
+ return null;
+ }
+ public static QywxUserInfoResponse getUserInfo(String token,String id) {
+ String[] interfaceUrl = QywxConstant.GET_USER_DETAIL;
+ String url = interfaceUrl[0].replace("${accesstoken}",token).replace("${id}",id);
+ QywxUserInfoResponse response = sendHttpRequestSingle(url,interfaceUrl[1],""
+ ,new TypeReference<QywxUserInfoResponse>(){});
+ if(response.getErrcode()!=null && response.getErrcode() ==0){
+ return response;
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param token
+ * @param type 濯掍綋鏂囦欢绫诲瀷锛屽垎鍒湁鍥剧墖锛坕mage锛夈�佽闊筹紙voice锛夈�佽棰戯紙video锛夛紝鏅�氭枃浠讹紙file锛�
+ * @return
+ */
+ public static QywxUploadMediaResponse uploadMedia(String token,String type,String imgurl) {
+ String[] interfaceUrl = QywxConstant.UPLOAD_TEMP_MEDIA;
+ String url = interfaceUrl[0].replace("${accesstoken}",token).replace("${type}",type);
+ QywxUploadMediaResponse response = sendHttpRequestMultifile(url,interfaceUrl[1],imgurl
+ ,new TypeReference<QywxUploadMediaResponse>(){});
+ if(response !=null && response.getErrcode()!=null && response.getErrcode() ==0){
+ return response;
+ }
+ return null;
+ }
+ public static QywxBaseResponse<String> getUserInfoByCode(String token,String code) {
+ String[] interfaceUrl = QywxConstant.GET_USER_BY_AUTH_CODE;
+ String url = interfaceUrl[0].replace("${accesstoken}",token).replace("${code}",code);
+ QywxBaseResponse<String> response = sendHttpRequest(url,interfaceUrl[1],""
+ ,new TypeReference<QywxBaseResponse<String>>(){});
+ if(response.getErrcode()!=null && response.getErrcode() ==0){
+ return response;
+ }
+ return null;
+ }
+
+
+ public static String getJsApiTicket(String token) {
+ String[] interfaceUrl = QywxConstant.GET_JSAPI_TICKET;
+ String url = interfaceUrl[0].replace("${accesstoken}",token);
+ QywxBaseResponse<String> response = sendHttpRequest(url,interfaceUrl[1],""
+ ,new TypeReference<QywxBaseResponse<String>>(){});
+ if(response.getErrcode()!=null && response.getErrcode() ==0){
+ return response.getTicket();
+ }
+ return null;
+ }
+
+
+ /**
+ * 鍙戣捣wms鎺ュ彛璇锋眰
+ * @param url
+ * @param name
+ * @param param
+ * @param typeReference
+ * @return
+ * @param <T>
+ */
+ public static <T> QywxBaseResponse<T> sendHttpRequest(String url, String name, String param, TypeReference<QywxBaseResponse<T>> typeReference){
+ log.info("銆�"+name+"銆�================寮�濮�===="+url+"\nparam==========================:"+ JSONObject.toJSONString(param));
+ if ( StringUtils.isNotBlank(url)) {
+ String res = null;
+ try {
+ Map<String,String> headers = new HashMap<>();
+ res = HttpsUtil.postJson(qyUtil.qiweiUrl+url,param);
+ QywxBaseResponse result = JSONObject.parseObject(res, typeReference.getType());
+ logResult(result,name);
+ return result;
+ }catch (Exception e){
+ e.printStackTrace();
+ log.error("銆�"+name+"銆�================澶辫触===="+ JSONObject.toJSONString(param));
+ }
+ }
+ return null;
+ }
+ public static <T extends QywxBaseSingleResponse> T sendHttpRequestMultifile(String url, String name, String imgUrl , TypeReference<T> typeReference){
+ log.info("銆�"+name+"銆�================寮�濮�===="+ imgUrl);
+ if ( StringUtils.isNotBlank(url)) {
+ String res = null;
+ try {
+ res = HttpsUtil.uploadTempMedia (qyUtil.qiweiUrl+url,imgUrl);
+ log.info("浠庝紒寰帴鍙�:{}----涓婁紶涓存椂绱犳潗缁撴灉:{}",url,res);
+ JSONObject jsonObject = JSONObject.parseObject(res);
+ T result = JSONObject.parseObject(res, typeReference.getType());
+ return result;
+ }catch (Exception e){
+ e.printStackTrace();
+ log.error("銆�"+name+"銆�================澶辫触===="+ imgUrl);
+ }
+ }
+ return null;
+ }
+ public static <T extends QywxBaseSingleResponse> T sendHttpRequestSingle(String url, String name, String param, TypeReference<T> typeReference){
+ log.info("銆�"+name+"銆�================寮�濮�===="+ JSONObject.toJSONString(param));
+ if ( StringUtils.isNotBlank(url)) {
+ String res = null;
+ try {
+ Map<String,String> headers = new HashMap<>();
+ res = HttpsUtil.postJson(qyUtil.qiweiUrl+url,param);
+ T result = JSONObject.parseObject(res, typeReference.getType());
+// logResult(result,name);
+ return result;
+ }catch (Exception e){
+ e.printStackTrace();
+ log.error("銆�"+name+"銆�================澶辫触===="+ JSONObject.toJSONString(param));
+ }
+ }
+ return null;
+ }
+ private static void logResult(QywxBaseResponse res,String name) {
+ if( res.getErrcode() !=null && res.getErrcode().equals(0)){
+ log.info("銆愪紒涓氬井淇℃帴鍙o細"+name+"銆�================鎴愬姛====\n"+ JSONObject.toJSONString(res));
+ }else{
+ log.error("銆愪紒涓氬井淇℃帴鍙o細"+name+"銆�================澶辫触====锛歕n"+ JSONObject.toJSONString(res));
+ }
+ }
+}
+
+
+
+
+
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxBaseRequest.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxBaseRequest.java
new file mode 100644
index 0000000..a689d33
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxBaseRequest.java
@@ -0,0 +1,20 @@
+package com.doumee.core.utils.qiyeweixin.model.request;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("wms璇锋眰鍏叡鍙傛暟")
+public class QywxBaseRequest<T> {
+
+ @ApiModelProperty(value = "data" )
+ private List<T> data;
+ private List<Integer> jobIdList;
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxSendMsgRequest.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxSendMsgRequest.java
new file mode 100644
index 0000000..05e9597
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxSendMsgRequest.java
@@ -0,0 +1,32 @@
+package com.doumee.core.utils.qiyeweixin.model.request;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊鏂囦欢鍗$墖娑堟伅璇锋眰鍙傛暟")
+public class QywxSendMsgRequest {
+ @ApiModelProperty(value = "鎴愬憳ID鍒楄〃锛堟秷鎭帴鏀惰�咃紝澶氫釜鎺ユ敹鑰呯敤鈥榺鈥欏垎闅旓紝鏈�澶氭敮鎸�1000涓級銆傜壒娈婃儏鍐碉細鎸囧畾涓篅all锛屽垯鍚戝叧娉ㄨ浼佷笟搴旂敤鐨勫叏閮ㄦ垚鍛樺彂閫�")
+ private String touser;//
+ @ApiModelProperty(value = "閮ㄩ棬ID鍒楄〃锛屽涓帴鏀惰�呯敤鈥榺鈥欏垎闅旓紝鏈�澶氭敮鎸�100涓�傚綋touser涓篅all鏃跺拷鐣ユ湰鍙傛暟 ")
+ private String toparty;//
+ @ApiModelProperty(value = "鏍囩ID鍒楄〃锛屽涓帴鏀惰�呯敤鈥榺鈥欏垎闅旓紝鏈�澶氭敮鎸�100涓�傚綋touser涓篅all鏃跺拷鐣ユ湰鍙傛暟")
+ private String totag;//
+ @ApiModelProperty(value = "娑堟伅绫诲瀷锛屾鏃跺浐瀹氫负锛歵extcard")
+ private String msgtype;//
+ @ApiModelProperty(value = "浼佷笟搴旂敤鐨刬d锛屾暣鍨嬨�備紒涓氬唴閮ㄥ紑鍙戯紝鍙湪搴旂敤鐨勮缃〉闈㈡煡鐪嬶紱绗笁鏂规湇鍔″晢锛屽彲閫氳繃鎺ュ彛 鑾峰彇浼佷笟鎺堟潈淇℃伅 鑾峰彇璇ュ弬鏁板��")
+ private String agentid;//
+ @ApiModelProperty(value = "鏂囨湰鍗$墖娑堟伅瀵硅薄")
+ private QywxTextCardMsgRequest textcard;//
+ @ApiModelProperty(value = "琛ㄧず鏄惁寮�鍚痠d杞瘧锛�0琛ㄧず鍚︼紝1琛ㄧず鏄紝榛樿0")
+ private String enable_id_trans;//
+ @ApiModelProperty(value = "琛ㄧず鏄惁寮�鍚噸澶嶆秷鎭鏌ワ紝0琛ㄧず鍚︼紝1琛ㄧず鏄紝榛樿0")
+ private String enable_duplicate_check;//
+ @ApiModelProperty(value = "琛ㄧず鏄惁閲嶅娑堟伅妫�鏌ョ殑鏃堕棿闂撮殧锛岄粯璁�1800s锛屾渶澶т笉瓒呰繃4灏忔椂")
+ private String duplicate_check_interval;//
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxTextCardMsgRequest.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxTextCardMsgRequest.java
new file mode 100644
index 0000000..8171fd9
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/request/QywxTextCardMsgRequest.java
@@ -0,0 +1,22 @@
+package com.doumee.core.utils.qiyeweixin.model.request;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊鏂囦欢鍗$墖娑堟伅璇锋眰鍙傛暟")
+public class QywxTextCardMsgRequest {
+ @ApiModelProperty(value = "鏍囬锛屼笉瓒呰繃128涓瓧绗︼紝瓒呰繃浼氳嚜鍔ㄦ埅鏂紙鏀寔id杞瘧锛�")
+ private String title;//
+ @ApiModelProperty(value = "鎻忚堪锛屼笉瓒呰繃512涓瓧绗︼紝瓒呰繃浼氳嚜鍔ㄦ埅鏂紙鏀寔id杞瘧锛�")
+ private String description;//
+ @ApiModelProperty(value = "鐐瑰嚮鍚庤烦杞殑閾炬帴銆傛渶闀�2048瀛楄妭锛岃纭繚鍖呭惈浜嗗崗璁ご(http/https)")
+ private String url;//
+ @ApiModelProperty(value = "鎸夐挳鏂囧瓧銆� 榛樿涓衡�滆鎯呪�濓紝 涓嶈秴杩�4涓枃瀛楋紝瓒呰繃鑷姩鎴柇銆�")
+ private String btntxt;//
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxBaseResponse.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxBaseResponse.java
new file mode 100644
index 0000000..f0e02e8
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxBaseResponse.java
@@ -0,0 +1,34 @@
+package com.doumee.core.utils.qiyeweixin.model.response;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊鎺ュ彛澶勭悊杩斿洖鍙傛暟")
+public class QywxBaseResponse<T> {
+ public static final String CODE_SUCCESS = "1";
+ @ApiModelProperty(value = "杩斿洖鍙傛暟" )
+ @JSONField(name="records",alternateNames = {"department","userlist","userid"})
+ private T data;
+ @ApiModelProperty(value = "鍑洪敊杩斿洖鐮侊紝涓�0琛ㄧず鎴愬姛锛岄潪0琛ㄧず璋冪敤澶辫触")
+ private Integer errcode;
+
+ @ApiModelProperty(value = "杩斿洖鐮佹彁绀鸿")
+ private String errmsg;
+ @ApiModelProperty(value = "鑾峰彇鍒扮殑鍑瘉锛屾渶闀夸负512瀛楄妭")
+ private String access_token;
+ @ApiModelProperty(value = "鑾峰彇鍒扮殑鍑瘉锛屾渶闀夸负512瀛楄妭")
+ private String ticket;
+
+ @ApiModelProperty(value = "鍑瘉鐨勬湁鏁堟椂闂�")
+ private Long expires_in;
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxBaseSingleResponse.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxBaseSingleResponse.java
new file mode 100644
index 0000000..1b71cd7
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxBaseSingleResponse.java
@@ -0,0 +1,21 @@
+package com.doumee.core.utils.qiyeweixin.model.response;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊鎺ュ彛澶勭悊杩斿洖鍙傛暟(鐙珛绫诲瀷锛�")
+public class QywxBaseSingleResponse {
+ @ApiModelProperty(value = "鍑洪敊杩斿洖鐮侊紝涓�0琛ㄧず鎴愬姛锛岄潪0琛ㄧず璋冪敤澶辫触")
+ private Integer errcode;
+
+ @ApiModelProperty(value = "杩斿洖鐮佹彁绀鸿")
+ private String errmsg;
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxDepartInfoResponse.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxDepartInfoResponse.java
new file mode 100644
index 0000000..345c235
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxDepartInfoResponse.java
@@ -0,0 +1,29 @@
+package com.doumee.core.utils.qiyeweixin.model.response;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊閮ㄩ棬鍒楄〃杩斿洖鍙傛暟")
+public class QywxDepartInfoResponse {
+ @ApiModelProperty(value = "鍒涘缓鐨勯儴闂╥d")
+ private String id;
+ @ApiModelProperty(value = "閮ㄩ棬鍚嶇О锛屼唬寮�鍙戣嚜寤哄簲鐢ㄩ渶瑕佺鐞嗗憳鎺堟潈鎵嶈繑鍥烇紱姝ゅ瓧娈典粠2019骞�12鏈�30鏃ヨ捣锛屽鏂板垱寤虹涓夋柟搴旂敤涓嶅啀杩斿洖锛�2020骞�6鏈�30鏃ヨ捣锛屽鎵�鏈夊巻鍙茬涓夋柟搴旂敤涓嶅啀杩斿洖name锛岃繑鍥炵殑name瀛楁浣跨敤id浠f浛锛屽悗缁涓夋柟浠呴�氳褰曞簲鐢ㄥ彲鑾峰彇锛屾湭杩斿洖鍚嶇О鐨勬儏鍐甸渶瑕侀�氳繃閫氳褰曞睍绀虹粍浠舵潵灞曠ず閮ㄩ棬鍚嶇О")
+ private String name;
+ @ApiModelProperty(value = "鑻辨枃鍚嶇О锛屾瀛楁浠�2019骞�12鏈�30鏃ヨ捣锛屽鏂板垱寤虹涓夋柟搴旂敤涓嶅啀杩斿洖锛�2020骞�6鏈�30鏃ヨ捣锛屽鎵�鏈夊巻鍙茬涓夋柟搴旂敤涓嶅啀杩斿洖璇ュ瓧娈�")
+ private String name_en;
+ @ApiModelProperty(value = "閮ㄩ棬璐熻矗浜虹殑UserID锛涚涓夋柟浠呴�氳褰曞簲鐢ㄥ彲鑾峰彇")
+ private List<String> department_leader;
+ @ApiModelProperty(value = "鐖堕儴闂╥d銆傛牴閮ㄩ棬涓�1")
+ private String parentid;
+ @ApiModelProperty(value = "鍦ㄧ埗閮ㄩ棬涓殑娆″簭鍊笺�俹rder鍊煎ぇ鐨勬帓搴忛潬鍓嶃�傚�艰寖鍥存槸[0, 2^32)")
+ private String order;
+
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxSendMsgResponse.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxSendMsgResponse.java
new file mode 100644
index 0000000..ac450fe
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxSendMsgResponse.java
@@ -0,0 +1,28 @@
+package com.doumee.core.utils.qiyeweixin.model.response;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊鐢ㄦ埛璇︽儏杩斿洖鍙傛暟")
+public class QywxSendMsgResponse extends QywxBaseSingleResponse {
+ @ApiModelProperty(value = "涓嶅悎娉曠殑userid锛屼笉鍖哄垎澶у皬鍐欙紝缁熶竴杞负灏忓啓")
+ private String invaliduser;
+ @ApiModelProperty(value = "涓嶅悎娉曠殑partyid")
+ private String invalidparty;
+ @ApiModelProperty(value = "涓嶅悎娉曠殑鏍囩id")
+ private String invalidtag;
+ @ApiModelProperty(value = "娌℃湁鍩虹鎺ュ彛璁稿彲")
+ private String unlicenseduser;
+ @ApiModelProperty(value = "娑堟伅id锛岀敤浜庢挙鍥炲簲鐢ㄦ秷鎭�")
+ private String msgid;
+ @ApiModelProperty(value = "浠呮秷鎭被鍨嬩负鈥滄寜閽氦浜掑瀷鈥濓紝鈥滄姇绁ㄩ�夋嫨鍨嬧�濆拰鈥滃椤归�夋嫨鍨嬧�濈殑妯℃澘鍗$墖娑堟伅杩斿洖锛屽簲鐢ㄥ彲浣跨敤response_code璋冪敤鏇存柊妯$増鍗$墖娑堟伅鎺ュ彛锛�72灏忔椂鍐呮湁鏁堬紝涓斿彧鑳戒娇鐢ㄤ竴娆�")
+ private String response_code;
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUploadMediaResponse.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUploadMediaResponse.java
new file mode 100644
index 0000000..42d01fb
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUploadMediaResponse.java
@@ -0,0 +1,22 @@
+package com.doumee.core.utils.qiyeweixin.model.response;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊涓婁紶绱犳潗杩斿洖鍙傛暟")
+public class QywxUploadMediaResponse extends QywxBaseSingleResponse {
+ @ApiModelProperty(value = "濯掍綋鏂囦欢绫诲瀷锛屽垎鍒湁鍥剧墖锛坕mage锛夈�佽闊筹紙voice锛夈�佽棰戯紙video锛夛紝鏅�氭枃浠�(file)")
+ private String type;//
+ @ApiModelProperty(value = "濯掍綋鏂囦欢涓婁紶鍚庤幏鍙栫殑鍞竴鏍囪瘑锛�3澶╁唴鏈夋晥")
+ private String media_id ;//
+ @ApiModelProperty(value = "濯掍綋鏂囦欢涓婁紶鏃堕棿鎴�")
+ private String created_at;//
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserAttrInfoResponse.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserAttrInfoResponse.java
new file mode 100644
index 0000000..eb88955
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserAttrInfoResponse.java
@@ -0,0 +1,25 @@
+package com.doumee.core.utils.qiyeweixin.model.response;
+
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊鐢ㄦ埛鎵╁睍瀛楁杩斿洖鍙傛暟")
+public class QywxUserAttrInfoResponse {
+ @ApiModelProperty(value = "鎴愬憳UserID銆傚搴旂鐞嗙鐨勮处鍙�")
+ private String type;//: 0,
+ @ApiModelProperty(value = "鏂囨湰鍚嶇О")
+ private String name;//: 0,
+ @ApiModelProperty(value = "鏂囨湰鍊�")
+ private String value;//: 0,
+ @ApiModelProperty(value = "鏂囨湰")
+ private QywxUserAttrValResponse text;
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserAttrValResponse.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserAttrValResponse.java
new file mode 100644
index 0000000..666465d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserAttrValResponse.java
@@ -0,0 +1,16 @@
+package com.doumee.core.utils.qiyeweixin.model.response;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊鐢ㄦ埛鎵╁睍瀛楁value杩斿洖鍙傛暟")
+public class QywxUserAttrValResponse {
+ @ApiModelProperty(value = "value")
+ private String value;//: 0,
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserExtAttrResponse.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserExtAttrResponse.java
new file mode 100644
index 0000000..b232926
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserExtAttrResponse.java
@@ -0,0 +1,18 @@
+package com.doumee.core.utils.qiyeweixin.model.response;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊鐢ㄦ埛鎵╁睍瀛楁杩斿洖鍙傛暟")
+public class QywxUserExtAttrResponse {
+ @ApiModelProperty(value = "鎵╁睍瀛楁闆嗗悎")
+ private List<QywxUserAttrInfoResponse> attrs;
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserInfoResponse.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserInfoResponse.java
new file mode 100644
index 0000000..45fe549
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserInfoResponse.java
@@ -0,0 +1,54 @@
+package com.doumee.core.utils.qiyeweixin.model.response;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊鐢ㄦ埛璇︽儏杩斿洖鍙傛暟")
+public class QywxUserInfoResponse extends QywxBaseSingleResponse {
+ @ApiModelProperty(value = "鎴愬憳UserID銆傚搴旂鐞嗙鐨勮处鍙�")
+ private String userid;
+ @ApiModelProperty(value = "鎴愬憳鍚嶇О锛屼唬寮�鍙戣嚜寤哄簲鐢ㄩ渶瑕佺鐞嗗憳鎺堟潈鎵嶈繑鍥烇紱姝ゅ瓧娈典粠2019骞�12鏈�30鏃ヨ捣锛屽鏂板垱寤虹涓夋柟搴旂敤涓嶅啀杩斿洖鐪熷疄name锛屼娇鐢╱serid浠f浛name锛�2020骞�6鏈�30鏃ヨ捣锛屽鎵�鏈夊巻鍙茬涓夋柟搴旂敤涓嶅啀杩斿洖鐪熷疄name锛屼娇鐢╱serid浠f浛name锛屽悗缁涓夋柟浠呴�氳褰曞簲鐢ㄥ彲鑾峰彇锛屾湭杩斿洖鍚嶇О鐨勬儏鍐甸渶瑕侀�氳繃閫氳褰曞睍绀虹粍浠舵潵灞曠ず鍚嶅瓧")
+ private String name;
+ @ApiModelProperty(value = "鎴愬憳鎵�灞為儴闂ㄥ垪琛ㄣ�傚垪琛ㄩ」涓洪儴闂↖D锛�32浣嶆暣鍨�")
+ private List<String> department;
+ @ApiModelProperty(value = "閮ㄩ棬鍐呯殑鎺掑簭鍊硷紝榛樿涓�0")
+ private List<String> order;
+ @ApiModelProperty(value = "鍏ㄥ眬鍞竴銆傚浜庡悓涓�涓湇鍔″晢锛屼笉鍚屽簲鐢ㄨ幏鍙栧埌浼佷笟鍐呭悓涓�涓垚鍛樼殑open_userid鏄浉鍚岀殑锛屾渶澶�64涓瓧鑺傘�備粎绗笁鏂瑰簲鐢ㄥ彲鑾峰彇")
+ private String open_userid;
+ @ApiModelProperty(value = "鎵嬫満鍙风爜")
+ private String mobile;
+ @ApiModelProperty(value = "鑱屽姟淇℃伅")
+ private String position;
+ @ApiModelProperty(value = "鎬у埆銆�0琛ㄧず鏈畾涔夛紝1琛ㄧず鐢锋�э紝2琛ㄧず濂虫�с��")
+ private Integer gender;
+ @ApiModelProperty(value = "婵�娲荤姸鎬�: 1=宸叉縺娲伙紝2=宸茬鐢紝4=鏈縺娲伙紝5=閫�鍑轰紒涓氥��")
+ private Integer status;
+ @ApiModelProperty(value = "閭")
+ private String email;
+ @ApiModelProperty(value = "鍛樺伐涓汉浜岀淮鐮侊紝鎵弿鍙坊鍔犱负澶栭儴鑱旂郴浜�(娉ㄦ剰杩斿洖鐨勬槸涓�涓猽rl锛屽彲鍦ㄦ祻瑙堝櫒涓婃墦寮�璇rl浠ュ睍绀轰簩缁寸爜)")
+ private String qr_code;
+ @ApiModelProperty(value = "浼佷笟閭")
+ private String biz_mail;
+ @ApiModelProperty(value = "琛ㄧず鍦ㄦ墍鍦ㄧ殑閮ㄩ棬鍐呮槸鍚︿负閮ㄩ棬璐熻矗浜恒��0-鍚︼紱1-鏄�傛槸涓�涓垪琛紝鏁伴噺蹇呴』涓巇epartment涓�鑷淬��")
+ private List<String> is_leader_in_dept;
+ @ApiModelProperty(value = "鐩村睘涓婄骇UserID")
+ private List<String> direct_leader;
+ @ApiModelProperty(value = "鍍弖rl")
+ private String avatar;
+ @ApiModelProperty(value = "澶村儚缂╃暐鍥緐rl")
+ private String thumb_avatar;
+ @ApiModelProperty(value = "搴ф満")
+ private String telephone;
+ @ApiModelProperty(value = "鍒悕")
+ private String alias;
+ @ApiModelProperty(value = "鎵╁睍灞炴��")
+ private QywxUserExtAttrResponse extattr;
+}
diff --git a/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserListResponse.java b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserListResponse.java
new file mode 100644
index 0000000..34ed301
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/utils/qiyeweixin/model/response/QywxUserListResponse.java
@@ -0,0 +1,54 @@
+package com.doumee.core.utils.qiyeweixin.model.response;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/23 14:03
+ */
+@Data
+@ApiModel("浼佷笟寰俊鐢ㄦ埛鍒楄〃杩斿洖鍙傛暟")
+public class QywxUserListResponse {
+ @ApiModelProperty(value = "鎴愬憳UserID銆傚搴旂鐞嗙鐨勮处鍙�")
+ private String userid;
+ @ApiModelProperty(value = "鎴愬憳鍚嶇О锛屼唬寮�鍙戣嚜寤哄簲鐢ㄩ渶瑕佺鐞嗗憳鎺堟潈鎵嶈繑鍥烇紱姝ゅ瓧娈典粠2019骞�12鏈�30鏃ヨ捣锛屽鏂板垱寤虹涓夋柟搴旂敤涓嶅啀杩斿洖鐪熷疄name锛屼娇鐢╱serid浠f浛name锛�2020骞�6鏈�30鏃ヨ捣锛屽鎵�鏈夊巻鍙茬涓夋柟搴旂敤涓嶅啀杩斿洖鐪熷疄name锛屼娇鐢╱serid浠f浛name锛屽悗缁涓夋柟浠呴�氳褰曞簲鐢ㄥ彲鑾峰彇锛屾湭杩斿洖鍚嶇О鐨勬儏鍐甸渶瑕侀�氳繃閫氳褰曞睍绀虹粍浠舵潵灞曠ず鍚嶅瓧")
+ private String name;
+ @ApiModelProperty(value = "鎴愬憳鎵�灞為儴闂ㄥ垪琛ㄣ�傚垪琛ㄩ」涓洪儴闂↖D锛�32浣嶆暣鍨�")
+ private List<String> department;
+ @ApiModelProperty(value = "閮ㄩ棬鍐呯殑鎺掑簭鍊硷紝榛樿涓�0")
+ private List<String> order;
+ @ApiModelProperty(value = "鍏ㄥ眬鍞竴銆傚浜庡悓涓�涓湇鍔″晢锛屼笉鍚屽簲鐢ㄨ幏鍙栧埌浼佷笟鍐呭悓涓�涓垚鍛樼殑open_userid鏄浉鍚岀殑锛屾渶澶�64涓瓧鑺傘�備粎绗笁鏂瑰簲鐢ㄥ彲鑾峰彇")
+ private String open_userid;
+ @ApiModelProperty(value = "鎵嬫満鍙风爜")
+ private String mobile;
+ @ApiModelProperty(value = "鑱屽姟淇℃伅")
+ private String position;
+ @ApiModelProperty(value = "鎬у埆銆�0琛ㄧず鏈畾涔夛紝1琛ㄧず鐢锋�э紝2琛ㄧず濂虫�с��")
+ private Integer gender;
+ @ApiModelProperty(value = "婵�娲荤姸鎬�: 1=宸叉縺娲伙紝2=宸茬鐢紝4=鏈縺娲伙紝5=閫�鍑轰紒涓氥��")
+ private Integer status;
+ @ApiModelProperty(value = "閭")
+ private String email;
+ @ApiModelProperty(value = "鍛樺伐涓汉浜岀淮鐮侊紝鎵弿鍙坊鍔犱负澶栭儴鑱旂郴浜�(娉ㄦ剰杩斿洖鐨勬槸涓�涓猽rl锛屽彲鍦ㄦ祻瑙堝櫒涓婃墦寮�璇rl浠ュ睍绀轰簩缁寸爜)")
+ private String qr_code;
+ @ApiModelProperty(value = "浼佷笟閭")
+ private String biz_mail;
+ @ApiModelProperty(value = "琛ㄧず鍦ㄦ墍鍦ㄧ殑閮ㄩ棬鍐呮槸鍚︿负閮ㄩ棬璐熻矗浜恒��0-鍚︼紱1-鏄�傛槸涓�涓垪琛紝鏁伴噺蹇呴』涓巇epartment涓�鑷淬��")
+ private List<Integer> is_leader_in_dept;
+ @ApiModelProperty(value = "鐩村睘涓婄骇UserID")
+ private List<String> direct_leader;
+ @ApiModelProperty(value = "鍍弖rl")
+ private String avatar;
+ @ApiModelProperty(value = "澶村儚缂╃暐鍥緐rl")
+ private String thumb_avatar;
+ @ApiModelProperty(value = "搴ф満")
+ private String telephone;
+ @ApiModelProperty(value = "鍒悕")
+ private String alias;
+ @ApiModelProperty(value = "鎵╁睍灞炴��")
+ private QywxUserExtAttrResponse extattr;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/CategoryMapper.java b/server/services/src/main/java/com/doumee/dao/business/CategoryMapper.java
new file mode 100644
index 0000000..324b66b
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/CategoryMapper.java
@@ -0,0 +1,12 @@
+package com.doumee.dao.business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.business.model.Category;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface CategoryMapper extends BaseMapper<Category> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/IdentityInfoMapper.java b/server/services/src/main/java/com/doumee/dao/business/IdentityInfoMapper.java
new file mode 100644
index 0000000..35c6efe
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/IdentityInfoMapper.java
@@ -0,0 +1,12 @@
+package com.doumee.dao.business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.business.model.IdentityInfo;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface IdentityInfoMapper extends BaseMapper<IdentityInfo> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/MemberMapper.java b/server/services/src/main/java/com/doumee/dao/business/MemberMapper.java
new file mode 100644
index 0000000..9438b6c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/MemberMapper.java
@@ -0,0 +1,12 @@
+package com.doumee.dao.business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.business.model.Member;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface MemberMapper extends BaseMapper<Member> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/MemberRevenueMapper.java b/server/services/src/main/java/com/doumee/dao/business/MemberRevenueMapper.java
new file mode 100644
index 0000000..68db80e
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/MemberRevenueMapper.java
@@ -0,0 +1,12 @@
+package com.doumee.dao.business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.business.model.MemberRevenue;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface MemberRevenueMapper extends BaseMapper<MemberRevenue> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/MultifileMapper.java b/server/services/src/main/java/com/doumee/dao/business/MultifileMapper.java
new file mode 100644
index 0000000..6f67762
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/MultifileMapper.java
@@ -0,0 +1,12 @@
+package com.doumee.dao.business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.business.model.Multifile;
+
+/**
+ * @author 姹熻箘韫�
+ * @since 2025/04/02 17:49
+ */
+public interface MultifileMapper extends BaseMapper<Multifile> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/OrderLogMapper.java b/server/services/src/main/java/com/doumee/dao/business/OrderLogMapper.java
new file mode 100644
index 0000000..f228021
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/OrderLogMapper.java
@@ -0,0 +1,12 @@
+package com.doumee.dao.business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.business.model.OrderLog;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface OrderLogMapper extends BaseMapper<OrderLog> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/OrdersMapper.java b/server/services/src/main/java/com/doumee/dao/business/OrdersMapper.java
new file mode 100644
index 0000000..cc67a58
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/OrdersMapper.java
@@ -0,0 +1,12 @@
+package com.doumee.dao.business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.business.model.Orders;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface OrdersMapper extends BaseMapper<Orders> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/ReceiveWeightMapper.java b/server/services/src/main/java/com/doumee/dao/business/ReceiveWeightMapper.java
new file mode 100644
index 0000000..0ad8daf
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/ReceiveWeightMapper.java
@@ -0,0 +1,12 @@
+package com.doumee.dao.business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.business.model.ReceiveWeight;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface ReceiveWeightMapper extends BaseMapper<ReceiveWeight> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/WithdrawalOrdersMapper.java b/server/services/src/main/java/com/doumee/dao/business/WithdrawalOrdersMapper.java
new file mode 100644
index 0000000..b3df52e
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/WithdrawalOrdersMapper.java
@@ -0,0 +1,12 @@
+package com.doumee.dao.business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.business.model.WithdrawalOrders;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface WithdrawalOrdersMapper extends BaseMapper<WithdrawalOrders> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/Category.java b/server/services/src/main/java/com/doumee/dao/business/model/Category.java
new file mode 100644
index 0000000..7141788
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/model/Category.java
@@ -0,0 +1,77 @@
+package com.doumee.dao.business.model;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+
+/**
+ * 鍒嗙被淇℃伅琛�
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Data
+@ApiModel("鍒嗙被淇℃伅琛�")
+@TableName("`category`")
+public class Category {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @ExcelColumn(name="涓婚敭")
+ private Integer id;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�", example = "1")
+ @ExcelColumn(name="鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�")
+ private Byte deleted;
+
+ @ApiModelProperty(value = "鐘舵��:0=鍚敤锛�1=绂佺敤锛�", example = "1")
+ @ExcelColumn(name="鐘舵��:0=鍚敤锛�1=绂佺敤锛�")
+ private Integer status;
+
+ @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鍒涘缓浜虹紪鐮�")
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ @ExcelColumn(name="鍒涘缓鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鏇存柊浜虹紪鐮�")
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ @ExcelColumn(name="鏇存柊鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "澶囨敞")
+ @ExcelColumn(name="澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "鍗曚綅鍚嶇О")
+ @ExcelColumn(name="鍗曚綅鍚嶇О")
+ private String name;
+
+ @ApiModelProperty(value = "绫诲瀷:0=鍝佺閰嶇疆锛�1=杞﹁締绫诲瀷閰嶇疆锛�2=椁愭爣閰嶇疆锛�3=鎵嬬画璐归厤缃紱", example = "1")
+ @ExcelColumn(name="绫诲瀷:0=鍝佺閰嶇疆锛�1=杞﹁締绫诲瀷閰嶇疆锛�2=椁愭爣閰嶇疆锛�3=鎵嬬画璐归厤缃紱")
+ private Byte type;
+
+ @ApiModelProperty(value = "鍐呭锛堣溅杈嗚鏍笺�侀鏍囥�佹墜缁垂姣斾緥锛�")
+ @ExcelColumn(name="鍐呭锛堣溅杈嗚鏍笺�侀鏍囥�佹墜缁垂姣斾緥锛�")
+ private String detail;
+
+ @ApiModelProperty(value = "鍥炬爣锛堣溅杈嗙被鍨嬩娇鐢級")
+ @ExcelColumn(name="鍥炬爣锛堣溅杈嗙被鍨嬩娇鐢級")
+ private String icon;
+
+ @ApiModelProperty(value = "鏄惁鍥哄畾杞﹁締锛堣溅杈嗙被鍨嬩娇鐢級:0=鍚︼紱1=鏄紱", example = "1")
+ @ExcelColumn(name="鏄惁鍥哄畾杞﹁締锛堣溅杈嗙被鍨嬩娇鐢級:0=鍚︼紱1=鏄紱")
+ private Integer isFixed;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/IdentityInfo.java b/server/services/src/main/java/com/doumee/dao/business/model/IdentityInfo.java
new file mode 100644
index 0000000..824f8e2
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/model/IdentityInfo.java
@@ -0,0 +1,131 @@
+package com.doumee.dao.business.model;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+import java.math.BigDecimal;
+
+/**
+ * 浼氬憳韬唤璁よ瘉淇℃伅琛�
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Data
+@ApiModel("浼氬憳韬唤璁よ瘉淇℃伅琛�")
+@TableName("`identity_info`")
+public class IdentityInfo {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @ExcelColumn(name="涓婚敭")
+ private Integer id;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�", example = "1")
+ @ExcelColumn(name="鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�")
+ private Byte deleted;
+
+ @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鍒涘缓浜虹紪鐮�")
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ @ExcelColumn(name="鍒涘缓鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鏇存柊浜虹紪鐮�")
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ @ExcelColumn(name="鏇存柊鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "澶囨敞")
+ @ExcelColumn(name="澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "绫诲瀷:0=鐢ㄥ伐韬唤锛�1=璐ц繍韬唤锛�2=渚涢韬唤锛�", example = "1")
+ @ExcelColumn(name="绫诲瀷:0=鐢ㄥ伐韬唤锛�1=璐ц繍韬唤锛�2=渚涢韬唤锛�")
+ private Integer type;
+
+ @ApiModelProperty(value = "浼氬憳閫愭笎", example = "1")
+ @ExcelColumn(name="浼氬憳閫愭笎")
+ private Integer memberId;
+
+ @ApiModelProperty(value = "璁よ瘉绫诲瀷:0=涓汉锛�1=浼佷笟", example = "1")
+ @ExcelColumn(name="璁よ瘉绫诲瀷:0=涓汉锛�1=浼佷笟")
+ private Integer authType;
+
+ @ApiModelProperty(value = "鑱旂郴浜�")
+ @ExcelColumn(name="鑱旂郴浜�")
+ private String linkName;
+
+ @ApiModelProperty(value = "鑱旂郴鏂瑰紡")
+ @ExcelColumn(name="鑱旂郴鏂瑰紡")
+ private String telephone;
+
+ @ApiModelProperty(value = "鎺ュ崟浣嶇疆")
+ @ExcelColumn(name="鎺ュ崟浣嶇疆")
+ private String location;
+
+ @ApiModelProperty(value = "鍗曚綅鍚嶇О")
+ @ExcelColumn(name="鍗曚綅鍚嶇О")
+ private String companyName;
+
+ @ApiModelProperty(value = "绾害", example = "1")
+ @ExcelColumn(name="绾害")
+ private BigDecimal lat;
+
+ @ApiModelProperty(value = "缁忓害", example = "1")
+ @ExcelColumn(name="缁忓害")
+ private BigDecimal lgt;
+
+ @ApiModelProperty(value = "韬唤璇佷汉鍍忛潰")
+ @ExcelColumn(name="韬唤璇佷汉鍍忛潰")
+ private String identityFront;
+
+ @ApiModelProperty(value = "韬唤璇佸浗寰介潰")
+ @ExcelColumn(name="韬唤璇佸浗寰介潰")
+ private String identityBack;
+
+ @ApiModelProperty(value = "钀ヤ笟鎵х収锛堜紒涓氱被浣跨敤锛�")
+ @ExcelColumn(name="钀ヤ笟鎵х収锛堜紒涓氱被浣跨敤锛�")
+ private String businessLicense;
+
+ @ApiModelProperty(value = "鍏朵粬璁よ瘉璧勬枡锛堜紒涓氱被浣跨敤锛�")
+ @ExcelColumn(name="鍏朵粬璁よ瘉璧勬枡锛堜紒涓氱被浣跨敤锛�")
+ private String otherFile;
+
+ @ApiModelProperty(value = "閬撹矾杩愯緭缁忛獙璁稿彲璇侊紙浼佷笟绫昏揣杩愯韩浠戒娇鐢級")
+ @ExcelColumn(name="閬撹矾杩愯緭缁忛獙璁稿彲璇侊紙浼佷笟绫昏揣杩愯韩浠戒娇鐢級")
+ private String transportFile;
+
+ @ApiModelProperty(value = "椋熷搧缁忚惀璁稿彲璇侊紙浼佷笟绫讳緵椁愯韩浠戒娇鐢級")
+ @ExcelColumn(name="椋熷搧缁忚惀璁稿彲璇侊紙浼佷笟绫讳緵椁愯韩浠戒娇鐢級")
+ private String foodBusinessFile;
+
+ @ApiModelProperty(value = "浠庝笟浜哄憳鍋ュ悍璇�")
+ @ExcelColumn(name="浠庝笟浜哄憳鍋ュ悍璇�")
+ private String healthFile;
+
+ @ApiModelProperty(value = "璁よ瘉瀹℃壒鐘舵��:1=鐢宠涓紱2=宸查�氳繃锛�3=鏈�氳繃锛�", example = "1")
+ @ExcelColumn(name="璁よ瘉瀹℃壒鐘舵��:1=鐢宠涓紱2=宸查�氳繃锛�3=鏈�氳繃锛�")
+ private Integer auditStatus;
+
+ @ApiModelProperty(value = "璁よ瘉瀹℃壒鏃堕棿")
+ @ExcelColumn(name="璁よ瘉瀹℃壒鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date auditTime;
+
+ @ApiModelProperty(value = "璁よ瘉瀹℃壒澶囨敞")
+ @ExcelColumn(name="璁よ瘉瀹℃壒澶囨敞")
+ private String auditRemark;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/Member.java b/server/services/src/main/java/com/doumee/dao/business/model/Member.java
new file mode 100644
index 0000000..a753400
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/model/Member.java
@@ -0,0 +1,147 @@
+package com.doumee.dao.business.model;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+import java.math.BigDecimal;
+
+/**
+ * 浼氬憳淇℃伅琛�
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Data
+@ApiModel("浼氬憳淇℃伅琛�")
+@TableName("`member`")
+public class Member {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @ExcelColumn(name="涓婚敭")
+ private Integer id;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�", example = "1")
+ @ExcelColumn(name="鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�")
+ private Byte deleted;
+
+ @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鍒涘缓浜虹紪鐮�")
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ @ExcelColumn(name="鍒涘缓鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鏇存柊浜虹紪鐮�")
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ @ExcelColumn(name="鏇存柊鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "澶囨敞")
+ @ExcelColumn(name="澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "澶村儚")
+ @ExcelColumn(name="澶村儚")
+ private String coverImage;
+
+ @ApiModelProperty(value = "openid")
+ @ExcelColumn(name="openid")
+ private String openid;
+
+ @ApiModelProperty(value = "鏄电О")
+ @ExcelColumn(name="鏄电О")
+ private String nickName;
+
+ @ApiModelProperty(value = "鑱旂郴鐢佃瘽")
+ @ExcelColumn(name="鑱旂郴鐢佃瘽")
+ private String telephone;
+
+ @ApiModelProperty(value = "濮撳悕")
+ @ExcelColumn(name="濮撳悕")
+ private String name;
+
+ @ApiModelProperty(value = "鐢ㄥ伐韬唤:0=鏈敵璇凤紱1=鐢宠涓紱2=宸查�氳繃锛�3=鏈�氳繃锛�", example = "1")
+ @ExcelColumn(name="鐢ㄥ伐韬唤:0=鏈敵璇凤紱1=鐢宠涓紱2=宸查�氳繃锛�3=鏈�氳繃锛�")
+ private Integer workerIdentity;
+
+ @ApiModelProperty(value = "璐ц繍韬唤:0=鏈敵璇凤紱1=鐢宠涓紱2=宸查�氳繃锛�3=鏈�氳繃锛�", example = "1")
+ @ExcelColumn(name="璐ц繍韬唤:0=鏈敵璇凤紱1=鐢宠涓紱2=宸查�氳繃锛�3=鏈�氳繃锛�")
+ private Integer driverIdentity;
+
+ @ApiModelProperty(value = "渚涢寰堢矇:0=鏈敵璇凤紱1=鐢宠涓紱2=宸查�氳繃锛�3=鏈�氳繃锛�", example = "1")
+ @ExcelColumn(name="渚涢寰堢矇:0=鏈敵璇凤紱1=鐢宠涓紱2=宸查�氳繃锛�3=鏈�氳繃锛�")
+ private Integer chefIdentity;
+
+ @ApiModelProperty(value = "褰撳墠浣欓(鍗曚綅:鍒�)", example = "1")
+ @ExcelColumn(name="褰撳墠浣欓(鍗曚綅:鍒�)")
+ private Long amount;
+
+ @ApiModelProperty(value = "鍘嗗彶鎬婚噾棰�(鍗曚綅:鍒�)", example = "1")
+ @ExcelColumn(name="鍘嗗彶鎬婚噾棰�(鍗曚綅:鍒�)")
+ private Long totalAmount;
+
+ @ApiModelProperty(value = "鐘舵��", example = "1")
+ @ExcelColumn(name="鐘舵��")
+ private Integer status;
+
+ @ApiModelProperty(value = "鏈�鍚庣櫥褰曟椂闂�")
+ @ExcelColumn(name="鏈�鍚庣櫥褰曟椂闂�")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date loginTime;
+
+ @ApiModelProperty(value = "鎬荤櫥褰曟鏁�", example = "1")
+ @ExcelColumn(name="鎬荤櫥褰曟鏁�")
+ private Long loginTimes;
+
+ @ApiModelProperty(value = "鎬绘帴鍗曢噺", example = "1")
+ @ExcelColumn(name="鎬绘帴鍗曢噺")
+ private Long reciveNum;
+
+ @ApiModelProperty(value = "鎬诲彂鍗曢噺", example = "1")
+ @ExcelColumn(name="鎬诲彂鍗曢噺")
+ private Long publishNum;
+
+ @ApiModelProperty(value = "璇勫垎", example = "1")
+ @ExcelColumn(name="璇勫垎")
+ private BigDecimal score;
+
+ @ApiModelProperty(value = "瀹氫綅鍦板潃")
+ @ExcelColumn(name="瀹氫綅鍦板潃")
+ private String localtion;
+
+ @ApiModelProperty(value = "绾害", example = "1")
+ @ExcelColumn(name="绾害")
+ private BigDecimal lat;
+
+ @ApiModelProperty(value = "缁忓害", example = "1")
+ @ExcelColumn(name="缁忓害")
+ private BigDecimal lgt;
+
+ @ApiModelProperty(value = "鐪佷唤")
+ @ExcelColumn(name="鐪佷唤")
+ private String province;
+
+ @ApiModelProperty(value = "鍩庡競")
+ @ExcelColumn(name="鍩庡競")
+ private String city;
+
+ @ApiModelProperty(value = "鍖哄幙")
+ @ExcelColumn(name="鍖哄幙")
+ private String area;
+
+ @ApiModelProperty(value = "鏄惁鎺ュ彈鑷姩娲惧崟:0=鍚︼紱1=鏄紱", example = "1")
+ @ExcelColumn(name="鏄惁鎺ュ彈鑷姩娲惧崟:0=鍚︼紱1=鏄紱")
+ private Integer autoReciveStatus;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/MemberRevenue.java b/server/services/src/main/java/com/doumee/dao/business/model/MemberRevenue.java
new file mode 100644
index 0000000..de8488d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/model/MemberRevenue.java
@@ -0,0 +1,90 @@
+package com.doumee.dao.business.model;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+import java.math.BigDecimal;
+
+/**
+ * 浼氬憳鏀舵敮璁板綍
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Data
+@ApiModel("浼氬憳鏀舵敮璁板綍")
+@TableName("`member_revenue`")
+public class MemberRevenue {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @ExcelColumn(name="涓婚敭")
+ private Integer id;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�", example = "1")
+ @ExcelColumn(name="鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�")
+ private Byte deleted;
+
+ @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鍒涘缓浜虹紪鐮�")
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ @ExcelColumn(name="鍒涘缓鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鏇存柊浜虹紪鐮�")
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ @ExcelColumn(name="鏇存柊鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "澶囨敞")
+ @ExcelColumn(name="澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "浼氬憳涓婚敭", example = "1")
+ @ExcelColumn(name="浼氬憳涓婚敭")
+ private Integer memberId;
+
+ @ApiModelProperty(value = "鍙樺姩绫诲瀷:0=鐢ㄥ伐鍗曟敹鍏ワ紱1=璐ц繍鍗曟敹鍏ワ紱2=渚涢鍗曟敹鍏ワ紱3=鎻愮幇鐢宠锛�", example = "1")
+ @ExcelColumn(name="鍙樺姩绫诲瀷:0=鐢ㄥ伐鍗曟敹鍏ワ紱1=璐ц繍鍗曟敹鍏ワ紱2=渚涢鍗曟敹鍏ワ紱3=鎻愮幇鐢宠锛�")
+ private Integer type;
+
+ @ApiModelProperty(value = "鏀舵敮绫诲瀷:1=鏀跺叆锛�-1=鏀嚭锛�", example = "1")
+ @ExcelColumn(name="鏀舵敮绫诲瀷:1=鏀跺叆锛�-1=鏀嚭锛�")
+ private Integer optType;
+
+ @ApiModelProperty(value = "鍙樺姩閲戦", example = "1")
+ @ExcelColumn(name="鍙樺姩閲戦")
+ private BigDecimal amount;
+
+ @ApiModelProperty(value = "鍙樺姩鍓嶉噾棰�", example = "1")
+ @ExcelColumn(name="鍙樺姩鍓嶉噾棰�")
+ private BigDecimal beforeAmount;
+
+ @ApiModelProperty(value = "鍙樺姩鍚庨噾棰�", example = "1")
+ @ExcelColumn(name="鍙樺姩鍚庨噾棰�")
+ private BigDecimal afterAmount;
+
+ @ApiModelProperty(value = "涓氬姟璁板綍涓婚敭", example = "1")
+ @ExcelColumn(name="涓氬姟璁板綍涓婚敭")
+ private Integer objId;
+
+ @ApiModelProperty(value = "涓氬姟绫诲瀷:0=璁㈠崟涓氬姟锛�1=鎻愮幇涓氬姟锛�", example = "1")
+ @ExcelColumn(name="涓氬姟绫诲瀷:0=璁㈠崟涓氬姟锛�1=鎻愮幇涓氬姟锛�")
+ private Integer objType;
+
+ @ApiModelProperty(value = "涓氬姟鐘舵��:0=鎴愬姛锛�1=澶辫触锛�2=澶勭悊涓紱", example = "1")
+ @ExcelColumn(name="涓氬姟鐘舵��:0=鎴愬姛锛�1=澶辫触锛�2=澶勭悊涓紱")
+ private Integer status;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/Multifile.java b/server/services/src/main/java/com/doumee/dao/business/model/Multifile.java
new file mode 100644
index 0000000..c5e23a1
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/model/Multifile.java
@@ -0,0 +1,77 @@
+package com.doumee.dao.business.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 闄勪欢涓婁紶淇℃伅琛�
+ * @author 姹熻箘韫�
+ * @since 2025/04/02 17:49
+ */
+@Data
+@ApiModel("闄勪欢涓婁紶淇℃伅琛�")
+@TableName("`multifile`")
+public class Multifile {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ private Integer id;
+
+ @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
+ private Integer creator;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+
+ private Date createDate;
+
+ @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
+ private Integer editor;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+
+ private Date editDate;
+
+ @ApiModelProperty(value = "鏄惁鍒犻櫎0鍚� 1鏄�", example = "1")
+ private Integer isdeleted;
+
+ @ApiModelProperty(value = "鏂囦欢鍚�")
+ private String name;
+
+ @ApiModelProperty(value = "澶囨敞")
+ private String info;
+
+ @ApiModelProperty(value = "鍏宠仈瀵硅薄缂栫爜", example = "1")
+ private Integer objId;
+
+ @ApiModelProperty(value = "绫诲瀷0鍥剧墖 1瑙嗛 2鍏朵粬", example = "1")
+ private Integer type;
+
+// @ApiModelProperty(value = "鍏宠仈瀵硅薄绫诲瀷 0SHE涓婃姤 1璺岀粖婊戜笂鎶� 2璺岀粖婊戝鐞� 3璺岀粖婊戝垎閰嶇墿涓氫富绠� 4璺岀粖婊戝垎閰嶅鐞嗕汉 5DCA椋庨櫓涓婃姤 6DCA椋庨櫓澶勭悊 7DCA宸ュ崟鍥剧墖", example = "1")
+// @ExcelExportColumn(name="鍏宠仈瀵硅薄绫诲瀷 0SHE涓婃姤 1璺岀粖婊戜笂鎶� 2璺岀粖婊戝鐞� 3璺岀粖婊戝垎閰嶇墿涓氫富绠� 4璺岀粖婊戝垎閰嶅鐞嗕汉 5DCA椋庨櫓涓婃姤 6DCA椋庨櫓澶勭悊 7DCA宸ュ崟鍥剧墖")
+ @ApiModelProperty(value = "鍏宠仈瀵硅薄绫诲瀷 0宸ュ崟涓婃姤 1宸ュ崟澶勭悊 2宸ュ崟杞氦", example = "1")
+ private Integer objType;
+
+ @ApiModelProperty(value = "鏂囦欢鍦板潃")
+ private String fileurl;
+
+ @ApiModelProperty(value = "鎺掑簭鐮�", example = "1")
+ private Integer sortnum;
+
+ @ApiModelProperty(value = "浼佷笟缂栫爜(鍏宠仈company琛級", example = "1")
+ private Integer companyId;
+
+ @ApiModelProperty(value = "鏂囦欢鍦板潃")
+ @TableField(exist = false)
+ private String fileurlFull;
+
+
+ @ApiModelProperty(value = "鍐呯綉鏂囦欢鍦板潃")
+ @TableField(exist = false)
+ private String localFileurlFull;
+
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/OrderLog.java b/server/services/src/main/java/com/doumee/dao/business/model/OrderLog.java
new file mode 100644
index 0000000..5584ea2
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/model/OrderLog.java
@@ -0,0 +1,85 @@
+package com.doumee.dao.business.model;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+
+/**
+ * 璁㈠崟鎿嶄綔鏃ュ織
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Data
+@ApiModel("璁㈠崟鎿嶄綔鏃ュ織")
+@TableName("`order_log`")
+public class OrderLog {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @ExcelColumn(name="涓婚敭")
+ private Integer id;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�", example = "1")
+ @ExcelColumn(name="鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�")
+ private Byte deleted;
+
+ @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鍒涘缓浜虹紪鐮�")
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ @ExcelColumn(name="鍒涘缓鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鏇存柊浜虹紪鐮�")
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ @ExcelColumn(name="鏇存柊鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "澶囨敞")
+ @ExcelColumn(name="澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "璁㈠崟涓婚敭锛坥rders锛�", example = "1")
+ @ExcelColumn(name="璁㈠崟涓婚敭锛坥rders锛�")
+ private Integer orderId;
+
+ @ApiModelProperty(value = "鏍囬")
+ @ExcelColumn(name="鏍囬")
+ private String title;
+
+ @ApiModelProperty(value = "鏃ュ織鍐呭")
+ @ExcelColumn(name="鏃ュ織鍐呭")
+ private String logInfo;
+
+ @ApiModelProperty(value = "鎿嶄綔绫诲瀷", example = "1")
+ @ExcelColumn(name="鎿嶄綔绫诲瀷")
+ private Integer objType;
+
+ @ApiModelProperty(value = "鎿嶄綔浜�", example = "1")
+ @ExcelColumn(name="鎿嶄綔浜�")
+ private Integer memberId;
+
+ @ApiModelProperty(value = "鎿嶄綔鍓嶆暟鎹�")
+ @ExcelColumn(name="鎿嶄綔鍓嶆暟鎹�")
+ private String beforeInfo;
+
+ @ApiModelProperty(value = "鎿嶄綔鍚庢暟鎹�")
+ @ExcelColumn(name="鎿嶄綔鍚庢暟鎹�")
+ private String afterInfo;
+
+ @ApiModelProperty(value = "璁㈠崟鐘舵��:0=寰呮帴鍗曪紱1=宸叉帴鍗曪紱2=杩涜涓紱3=宸插畬鎴愶紱99=宸插彇娑堬紱", example = "1")
+ @ExcelColumn(name="璁㈠崟鐘舵��:0=寰呮帴鍗曪紱1=宸叉帴鍗曪紱2=杩涜涓紱3=宸插畬鎴愶紱99=宸插彇娑堬紱")
+ private Integer orderStatus;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/Orders.java b/server/services/src/main/java/com/doumee/dao/business/model/Orders.java
new file mode 100644
index 0000000..fd7fd2a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/model/Orders.java
@@ -0,0 +1,245 @@
+package com.doumee.dao.business.model;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+import java.math.BigDecimal;
+
+/**
+ * 璁㈠崟淇℃伅璁板綍
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Data
+@ApiModel("璁㈠崟淇℃伅璁板綍")
+@TableName("`orders`")
+public class Orders {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @ExcelColumn(name="涓婚敭")
+ private Integer id;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�", example = "1")
+ @ExcelColumn(name="鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�")
+ private Byte deleted;
+
+ @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鍒涘缓浜虹紪鐮�")
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ @ExcelColumn(name="鍒涘缓鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鏇存柊浜虹紪鐮�")
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ @ExcelColumn(name="鏇存柊鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "澶囨敞")
+ @ExcelColumn(name="澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "鍙戝崟鏂�", example = "1")
+ @ExcelColumn(name="鍙戝崟鏂�")
+ private Integer releaseMemberId;
+
+ @ApiModelProperty(value = "绫诲瀷:0=鐢ㄥ伐锛�1=杩愯揣锛�2=璁㈤", example = "1")
+ @ExcelColumn(name="绫诲瀷:0=鐢ㄥ伐锛�1=杩愯揣锛�2=璁㈤")
+ private Integer type;
+
+ @ApiModelProperty(value = "寮�濮嬫椂闂� yyyy-MM-dd")
+ @ExcelColumn(name="寮�濮嬫椂闂� yyyy-MM-dd")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date startDate;
+
+ @ApiModelProperty(value = "缁撴潫鏃堕棿 yyyy-MM-dd")
+ @ExcelColumn(name="缁撴潫鏃堕棿 yyyy-MM-dd")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date endDate;
+
+ @ApiModelProperty(value = "鍦扮偣淇℃伅/鐢ㄨ溅璧风偣/鐢ㄩ鍦扮偣")
+ @ExcelColumn(name="鍦扮偣淇℃伅/鐢ㄨ溅璧风偣/鐢ㄩ鍦扮偣")
+ private String location;
+
+ @ApiModelProperty(value = "鍦扮偣鎻忚堪")
+ @ExcelColumn(name="鍦扮偣鎻忚堪")
+ private String locationRemark;
+
+ @ApiModelProperty(value = "缁忓害", example = "1")
+ @ExcelColumn(name="缁忓害")
+ private BigDecimal lat;
+
+ @ApiModelProperty(value = "鐪佷唤")
+ @ExcelColumn(name="鐪佷唤")
+ private String province;
+
+ @ApiModelProperty(value = "鍩庡競")
+ @ExcelColumn(name="鍩庡競")
+ private String city;
+
+ @ApiModelProperty(value = "鍖哄幙")
+ @ExcelColumn(name="鍖哄幙")
+ private String area;
+
+ @ApiModelProperty(value = "绾害", example = "1")
+ @ExcelColumn(name="绾害")
+ private BigDecimal lgt;
+
+ @ApiModelProperty(value = "闇�姹傜被鍨嬶紙杩愯揣/鐢ㄥ伐)锛氬叧鑱� category", example = "1")
+ @ExcelColumn(name="闇�姹傜被鍨嬶紙杩愯揣/鐢ㄥ伐)锛氬叧鑱� category")
+ private Integer categoryId;
+
+ @ApiModelProperty(value = "鐢ㄥ伐绫诲瀷:0=閲囨憳宸ワ紱1=鍒嗘嫞宸ワ紱2=鍖呰宸ワ紱锛堢敤宸ヨ鍗曪級", example = "1")
+ @ExcelColumn(name="鐢ㄥ伐绫诲瀷:0=閲囨憳宸ワ紱1=鍒嗘嫞宸ワ紱2=鍖呰宸ワ紱锛堢敤宸ヨ鍗曪級")
+ private Integer workType;
+
+ @ApiModelProperty(value = "璁′环鏁伴噺1(澶╂暟/鐢ㄨ溅娆℃暟)", example = "1")
+ @ExcelColumn(name="璁′环鏁伴噺1(澶╂暟/鐢ㄨ溅娆℃暟)")
+ private Integer priceNum1;
+
+ @ApiModelProperty(value = "璁′环鏁伴噺2(鐢ㄥ伐鏁伴噺/閲囨憳鏁伴噺/鐢ㄨ溅鏁伴噺/)", example = "1")
+ @ExcelColumn(name="璁′环鏁伴噺2(鐢ㄥ伐鏁伴噺/閲囨憳鏁伴噺/鐢ㄨ溅鏁伴噺/)")
+ private Integer priceNum2;
+
+ @ApiModelProperty(value = "闇�姹傝ˉ鍏�")
+ @ExcelColumn(name="闇�姹傝ˉ鍏�")
+ private String supplement;
+
+ @ApiModelProperty(value = "璐圭敤鏍囧噯", example = "1")
+ @ExcelColumn(name="璐圭敤鏍囧噯")
+ private Long price;
+
+ @ApiModelProperty(value = "棰勪及璐圭敤", example = "1")
+ @ExcelColumn(name="棰勪及璐圭敤")
+ private Long estimatedAccount;
+
+ @ApiModelProperty(value = "瀹為檯鏀粯璐圭敤", example = "1")
+ @ExcelColumn(name="瀹為檯鏀粯璐圭敤")
+ private Long payAccount;
+
+ @ApiModelProperty(value = "瀹炴敹璐圭敤", example = "1")
+ @ExcelColumn(name="瀹炴敹璐圭敤")
+ private Long reviceAccount;
+
+ @ApiModelProperty(value = "璐圭敤璇存槑")
+ @ExcelColumn(name="璐圭敤璇存槑")
+ private String priceRemark;
+
+ @ApiModelProperty(value = "鐢ㄨ溅绫诲瀷(杩愯揣浣跨敤):0=澶╋紱1=娆�", example = "1")
+ @ExcelColumn(name="鐢ㄨ溅绫诲瀷(杩愯揣浣跨敤):0=澶╋紱1=娆�")
+ private Integer carType;
+
+ @ApiModelProperty(value = "杩愯緭鍝佺(杩愯揣浣跨敤) 鍏宠仈category琛�", example = "1")
+ @ExcelColumn(name="杩愯緭鍝佺(杩愯揣浣跨敤) 鍏宠仈category琛�")
+ private Integer transportTypeId;
+
+ @ApiModelProperty(value = "杩愯緭閲嶉噺/鏁伴噺", example = "1")
+ @ExcelColumn(name="杩愯緭閲嶉噺/鏁伴噺")
+ private Integer transportNum;
+
+ @ApiModelProperty(value = "杩愯緭鍗曚綅(涓�/鏂�)")
+ @ExcelColumn(name="杩愯緭鍗曚綅(涓�/鏂�)")
+ private String transportUnit;
+
+ @ApiModelProperty(value = "鐢ㄨ溅缁堢偣鍦板潃")
+ @ExcelColumn(name="鐢ㄨ溅缁堢偣鍦板潃")
+ private String locationEnd;
+
+ @ApiModelProperty(value = "鐢ㄨ溅缁堢偣缁忓害")
+ @ExcelColumn(name="鐢ㄨ溅缁堢偣缁忓害")
+ private String latEnd;
+
+ @ApiModelProperty(value = "鐢ㄨ溅缁堢偣绾害")
+ @ExcelColumn(name="鐢ㄨ溅缁堢偣绾害")
+ private String lgtEnd;
+
+ @ApiModelProperty(value = "閫旂粡鐐�/椁愭爣淇℃伅")
+ @ExcelColumn(name="閫旂粡鐐�/椁愭爣淇℃伅")
+ private String wayInfo;
+
+ @ApiModelProperty(value = "璁㈠崟缂栧彿")
+ @ExcelColumn(name="璁㈠崟缂栧彿")
+ private String code;
+
+ @ApiModelProperty(value = "璁㈠崟鐘舵��:0=寰呮帴鍗曪紱1=宸叉帴鍗曪紱2=杩涜涓紱3=宸插畬鎴愶紱99=宸插彇娑堬紱", example = "1")
+ @ExcelColumn(name="璁㈠崟鐘舵��:0=寰呮帴鍗曪紱1=宸叉帴鍗曪紱2=杩涜涓紱3=宸插畬鎴愶紱99=宸插彇娑堬紱")
+ private Integer status;
+
+ @ApiModelProperty(value = "鎺ュ崟鏃堕棿")
+ @ExcelColumn(name="鎺ュ崟鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date acceptTime;
+
+ @ApiModelProperty(value = "鎺ュ崟浜�", example = "1")
+ @ExcelColumn(name="鎺ュ崟浜�")
+ private Integer acceptMemberId;
+
+ @ApiModelProperty(value = "鎺ュ崟绫诲瀷:0=鎵嬪姩鎺ュ崟锛�1=绯荤粺娲惧崟锛�", example = "1")
+ @ExcelColumn(name="鎺ュ崟绫诲瀷:0=鎵嬪姩鎺ュ崟锛�1=绯荤粺娲惧崟锛�")
+ private Integer acceptType;
+
+ @ApiModelProperty(value = "寮�濮嬩綔涓氭椂闂�")
+ @ExcelColumn(name="寮�濮嬩綔涓氭椂闂�")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date workStartTime;
+
+ @ApiModelProperty(value = "瀹屾垚鏃堕棿")
+ @ExcelColumn(name="瀹屾垚鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date finishTime;
+
+ @ApiModelProperty(value = "骞冲彴鎻愭垚姣斾緥", example = "1")
+ @ExcelColumn(name="骞冲彴鎻愭垚姣斾緥")
+ private BigDecimal platformRata;
+
+ @ApiModelProperty(value = "寰俊骞冲彴浜ゆ槗璁㈠崟鍙�")
+ @ExcelColumn(name="寰俊骞冲彴浜ゆ槗璁㈠崟鍙�")
+ private String wxExternalNo;
+
+ @ApiModelProperty(value = "鏄惁璇勪环:0=鍚︼紱1=鏄�", example = "1")
+ @ExcelColumn(name="鏄惁璇勪环:0=鍚︼紱1=鏄�")
+ private Integer commentStatus;
+
+ @ApiModelProperty(value = "璇勪环鍐呭")
+ @ExcelColumn(name="璇勪环鍐呭")
+ private String commentInfo;
+
+ @ApiModelProperty(value = "璇勪环鏄熺骇1-5", example = "1")
+ @ExcelColumn(name="璇勪环鏄熺骇1-5")
+ private Integer commentLevel;
+
+ @ApiModelProperty(value = "璇勪环鏃堕棿")
+ @ExcelColumn(name="璇勪环鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date commentTime;
+
+ @ApiModelProperty(value = "璇勪环绫诲瀷:0=鎵嬪姩璇勪环锛�1=绯荤粺鑷姩璇勪环锛�", example = "1")
+ @ExcelColumn(name="璇勪环绫诲瀷:0=鎵嬪姩璇勪环锛�1=绯荤粺鑷姩璇勪环锛�")
+ private Integer commentType;
+
+ @ApiModelProperty(value = "鍙栨秷鏃堕棿")
+ @ExcelColumn(name="鍙栨秷鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date cancelTime;
+
+ @ApiModelProperty(value = "鏄惁宸蹭慨鏀�:0=鍚︼紱1=鏄紱", example = "1")
+ @ExcelColumn(name="鏄惁宸蹭慨鏀�:0=鍚︼紱1=鏄紱")
+ private Integer isUpdate;
+
+ @ApiModelProperty(value = "鎺ュ崟鏂归粦鍚嶅崟member:id 澶氫釜浠�,鍒嗗壊")
+ @ExcelColumn(name="鎺ュ崟鏂归粦鍚嶅崟member:id 澶氫釜浠�,鍒嗗壊")
+ private String blackRecive;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/ReceiveWeight.java b/server/services/src/main/java/com/doumee/dao/business/model/ReceiveWeight.java
new file mode 100644
index 0000000..d515456
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/model/ReceiveWeight.java
@@ -0,0 +1,77 @@
+package com.doumee.dao.business.model;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+
+/**
+ * 鎺ュ崟鏉冮噸閰嶇疆琛�
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Data
+@ApiModel("鎺ュ崟鏉冮噸閰嶇疆琛�")
+@TableName("`receive_weight`")
+public class ReceiveWeight {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @ExcelColumn(name="涓婚敭")
+ private Integer id;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�", example = "1")
+ @ExcelColumn(name="鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�")
+ private Byte deleted;
+
+ @ApiModelProperty(value = "鐘舵��:0=鍚敤锛�1=绂佺敤锛�", example = "1")
+ @ExcelColumn(name="鐘舵��:0=鍚敤锛�1=绂佺敤锛�")
+ private Integer status;
+
+ @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鍒涘缓浜虹紪鐮�")
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ @ExcelColumn(name="鍒涘缓鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鏇存柊浜虹紪鐮�")
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ @ExcelColumn(name="鏇存柊鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "澶囨敞")
+ @ExcelColumn(name="澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "鏈�澶ф帴鍗曢噺", example = "1")
+ @ExcelColumn(name="鏈�澶ф帴鍗曢噺")
+ private Integer receiveMax;
+
+ @ApiModelProperty(value = "鏈�灏忔帴鍗曢噺", example = "1")
+ @ExcelColumn(name="鏈�灏忔帴鍗曢噺")
+ private Integer receiveMin;
+
+ @ApiModelProperty(value = "浼樺厛绾�", example = "1")
+ @ExcelColumn(name="浼樺厛绾�")
+ private Integer level;
+
+ @ApiModelProperty(value = "璁㈠崟鏌ョ湅寤惰繜鏃堕棿", example = "1")
+ @ExcelColumn(name="璁㈠崟鏌ョ湅寤惰繜鏃堕棿")
+ private Integer delayTime;
+
+ @ApiModelProperty(value = "鎺掑簭鐮�", example = "1")
+ @ExcelColumn(name="鎺掑簭鐮�")
+ private Integer sortnum;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/WithdrawalOrders.java b/server/services/src/main/java/com/doumee/dao/business/model/WithdrawalOrders.java
new file mode 100644
index 0000000..49e5003
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/model/WithdrawalOrders.java
@@ -0,0 +1,78 @@
+package com.doumee.dao.business.model;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+
+/**
+ * 鎻愮幇鐢宠璁板綍
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Data
+@ApiModel("鎻愮幇鐢宠璁板綍")
+@TableName("`withdrawal_orders`")
+public class WithdrawalOrders {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @ExcelColumn(name="涓婚敭")
+ private Integer id;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�", example = "1")
+ @ExcelColumn(name="鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�")
+ private Byte deleted;
+
+ @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鍒涘缓浜虹紪鐮�")
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ @ExcelColumn(name="鍒涘缓鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
+ @ExcelColumn(name="鏇存柊浜虹紪鐮�")
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ @ExcelColumn(name="鏇存柊鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "澶囨敞")
+ @ExcelColumn(name="澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "浼氬憳涓婚敭", example = "1")
+ @ExcelColumn(name="浼氬憳涓婚敭")
+ private Integer memberId;
+
+ @ApiModelProperty(value = "鎻愮幇閲戦(鍗曚綅:鍒�)", example = "1")
+ @ExcelColumn(name="鎻愮幇閲戦(鍗曚綅:鍒�)")
+ private Long amount;
+
+ @ApiModelProperty(value = "寰俊骞冲彴浜ゆ槗璁㈠崟鍙�")
+ @ExcelColumn(name="寰俊骞冲彴浜ゆ槗璁㈠崟鍙�")
+ private String wxExternalNo;
+
+ @ApiModelProperty(value = "鐘舵��:0=鎻愮幇鐢宠涓�:1=鎻愮幇鎴愬姛锛�2=鎻愮幇澶辫触锛�", example = "1")
+ @ExcelColumn(name="鐘舵��:0=鎻愮幇鐢宠涓�:1=鎻愮幇鎴愬姛锛�2=鎻愮幇澶辫触锛�")
+ private Integer status;
+
+ @ApiModelProperty(value = "鎻愮幇瀹屾垚鏃堕棿")
+ @ExcelColumn(name="鎻愮幇瀹屾垚鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date doneTime;
+
+ @ApiModelProperty(value = "瀹屾垚澶囨敞")
+ @ExcelColumn(name="瀹屾垚澶囨敞")
+ private String doneInfo;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/common/dto/UpdateSortDTO.java b/server/services/src/main/java/com/doumee/dao/common/dto/UpdateSortDTO.java
new file mode 100644
index 0000000..4c67e9d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/common/dto/UpdateSortDTO.java
@@ -0,0 +1,26 @@
+package com.doumee.dao.common.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鎺掑簭鍙傛暟")
+public class UpdateSortDTO implements Serializable {
+
+ @ApiModelProperty(value = "ID")
+ @NotNull(message = "ID涓嶈兘涓虹┖")
+ private Integer id;
+
+ @ApiModelProperty(value = "鎺掑簭鏂瑰悜锛宼op鍚戜笂锛宐ottom鍚戜笅")
+ @NotBlank(message = "鎺掑簭鏂瑰悜涓嶈兘涓虹┖")
+ private String direction;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemDictDataMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemDictDataMapper.java
new file mode 100644
index 0000000..332622a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemDictDataMapper.java
@@ -0,0 +1,20 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.dto.QuerySystemDictDataDTO;
+import com.doumee.dao.system.model.SystemDictData;
+import com.doumee.dao.system.vo.SystemDictDataListVO;
+
+import java.util.List;
+
+public interface SystemDictDataMapper extends BaseMapper<SystemDictData> {
+
+ /**
+ * 鏌ヨ瀛楀吀鏁版嵁绠$悊鍒楄〃
+ *
+ * @param dto 璇﹁QuerySystemDictDataDTO
+ * @return List<SystemDictDataListVO>
+ */
+ List<SystemDictDataListVO> selectManageList(QuerySystemDictDataDTO dto);
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemDictMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemDictMapper.java
new file mode 100644
index 0000000..c15e072
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemDictMapper.java
@@ -0,0 +1,21 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.dto.QuerySystemDictDTO;
+import com.doumee.dao.system.model.SystemDict;
+import com.doumee.dao.system.vo.SystemDictListVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface SystemDictMapper extends BaseMapper<SystemDict> {
+
+ /**
+ * 鏌ヨ瀛楀吀绠$悊鍒楄〃
+ *
+ * @param dto 璇﹁QuerySystemDictDTO
+ * @param orderByClause 鎺掑簭璇彞
+ * @return List<SystemDictListVO>
+ */
+ List<SystemDictListVO> selectManageList(@Param("dto") QuerySystemDictDTO dto, @Param("orderByClause") String orderByClause);
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemJobListMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemJobListMapper.java
new file mode 100644
index 0000000..7aee620
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemJobListMapper.java
@@ -0,0 +1,19 @@
+package com.doumee.dao.system;
+
+import com.doumee.dao.system.model.SystemJob;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.vo.SystemJobListVO;
+import com.doumee.dao.system.dto.QuerySystemJobListDTO;
+
+import java.util.List;
+
+public interface SystemJobListMapper extends BaseMapper<SystemJob> {
+
+ /**
+ * 鏌ヨ浠诲姟绠$悊鍒楄〃
+ *
+ * @param dto 璇﹁QuerySystemJobListDTO
+ * @return List<SystemJobListVO>
+ */
+ List<SystemJobListVO> selectList(QuerySystemJobListDTO dto);
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemJobLogMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemJobLogMapper.java
new file mode 100644
index 0000000..0181ef5
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemJobLogMapper.java
@@ -0,0 +1,7 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.model.SystemJobLog;
+
+public interface SystemJobLogMapper extends BaseMapper<SystemJobLog> {
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemJobMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemJobMapper.java
new file mode 100644
index 0000000..1a20379
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemJobMapper.java
@@ -0,0 +1,7 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.model.SystemJob;
+
+public interface SystemJobMapper extends BaseMapper<SystemJob> {
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemJobSnippetMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemJobSnippetMapper.java
new file mode 100644
index 0000000..27f13be
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemJobSnippetMapper.java
@@ -0,0 +1,7 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.model.SystemJobSnippet;
+
+public interface SystemJobSnippetMapper extends BaseMapper<SystemJobSnippet> {
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemLoginLogMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemLoginLogMapper.java
new file mode 100644
index 0000000..c4d6d2d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemLoginLogMapper.java
@@ -0,0 +1,8 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.model.SystemLoginLog;
+
+public interface SystemLoginLogMapper extends BaseMapper<SystemLoginLog> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemMenuMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemMenuMapper.java
new file mode 100644
index 0000000..15afd3c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemMenuMapper.java
@@ -0,0 +1,34 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.model.SystemMenu;
+import com.doumee.dao.system.vo.SystemMenuListVO;
+
+import java.util.List;
+
+public interface SystemMenuMapper extends BaseMapper<SystemMenu> {
+
+ /**
+ * 鏌ヨ鑿滃崟绠$悊鍒楄〃
+ *
+ * @return List<SystemMenuListVO>
+ */
+ List<SystemMenuListVO> selectManageList();
+
+ /**
+ * 鏍规嵁鐢ㄦ埛ID鏌ヨ
+ *
+ * @param userId 鐢ㄦ埛ID
+ * @return List<SystemMenu>
+ */
+ List<SystemMenu> selectByUserId(Integer userId);
+
+ /**
+ * 鏍规嵁瑙掕壊ID鏌ヨ
+ *
+ * @param roleId 瑙掕壊ID
+ * @return List<SystemMenu>
+ */
+ List<SystemMenu> selectByRoleId(Integer roleId);
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemPermissionMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemPermissionMapper.java
new file mode 100644
index 0000000..8866214
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemPermissionMapper.java
@@ -0,0 +1,36 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.dto.QuerySystemPermissionDTO;
+import com.doumee.dao.system.model.SystemPermission;
+import com.doumee.dao.system.vo.SystemPermissionListVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface SystemPermissionMapper extends BaseMapper<SystemPermission> {
+
+ /**
+ * 鏍规嵁鐢ㄦ埛ID鏌ヨ
+ *
+ * @param userId 鐢ㄦ埛ID
+ * @return List<SystemPermission>
+ */
+ List<SystemPermission> selectByUserId(Integer userId);
+
+ /**
+ * 鏍规嵁瑙掕壊ID鏌ヨ
+ *
+ * @param roleId 瑙掕壊ID
+ * @return List<SystemPermission>
+ */
+ List<SystemPermission> selectByRoleId(Integer roleId);
+
+ /**
+ * 鏌ヨ鏉冮檺绠$悊鍒楄〃
+ *
+ * @return List<SystemPermissionListVO>
+ */
+ List<SystemPermissionListVO> selectManageList();
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemRoleMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemRoleMapper.java
new file mode 100644
index 0000000..510f33e
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemRoleMapper.java
@@ -0,0 +1,30 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.dto.QuerySystemRoleDTO;
+import com.doumee.dao.system.model.SystemRole;
+import com.doumee.dao.system.vo.SystemRoleListVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface SystemRoleMapper extends BaseMapper<SystemRole> {
+
+ /**
+ * 鏌ヨ瑙掕壊绠$悊鍒楄〃
+ *
+ * @param dto 璇﹁QuerySystemRoleDTO
+ * @param orderByClause 鎺掑簭SQL
+ * @return List<SystemRoleListVO>
+ */
+ List<SystemRoleListVO> selectManageList(@Param("dto") QuerySystemRoleDTO dto, @Param("orderByClause") String orderByClause);
+
+ /**
+ * 鏍规嵁鐢ㄦ埛ID鏌ヨ
+ *
+ * @param userId 鐢ㄦ埛ID
+ * @return List<SystemRole>
+ */
+ List<SystemRole> selectByUserId(Integer userId);
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemRoleMenuMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemRoleMenuMapper.java
new file mode 100644
index 0000000..73d151f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemRoleMenuMapper.java
@@ -0,0 +1,8 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.model.SystemRoleMenu;
+
+public interface SystemRoleMenuMapper extends BaseMapper<SystemRoleMenu> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemRolePermissionMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemRolePermissionMapper.java
new file mode 100644
index 0000000..8c524c3
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemRolePermissionMapper.java
@@ -0,0 +1,8 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.model.SystemRolePermission;
+
+public interface SystemRolePermissionMapper extends BaseMapper<SystemRolePermission> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemTraceLogMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemTraceLogMapper.java
new file mode 100644
index 0000000..5e1fb6c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemTraceLogMapper.java
@@ -0,0 +1,8 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.model.SystemTraceLog;
+
+public interface SystemTraceLogMapper extends BaseMapper<SystemTraceLog> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemUserMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemUserMapper.java
new file mode 100644
index 0000000..fdda884
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemUserMapper.java
@@ -0,0 +1,22 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.dto.QuerySystemUserDTO;
+import com.doumee.dao.system.model.SystemUser;
+import com.doumee.dao.system.vo.SystemUserListVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface SystemUserMapper extends BaseMapper<SystemUser> {
+
+ /**
+ * 鏌ヨ鐢ㄦ埛绠$悊鍒楄〃
+ *
+ * @param dto 璇﹁QuerySystemUserDTO
+ * @param orderByClause 鎺掑簭SQL
+ * @return List<SystemUserListVO>
+ */
+ List<SystemUserListVO> selectManageList(@Param("dto") QuerySystemUserDTO dto, @Param("orderByClause") String orderByClause);
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/SystemUserRoleMapper.java b/server/services/src/main/java/com/doumee/dao/system/SystemUserRoleMapper.java
new file mode 100644
index 0000000..7950303
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/SystemUserRoleMapper.java
@@ -0,0 +1,8 @@
+package com.doumee.dao.system;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.system.model.SystemUserRole;
+
+public interface SystemUserRoleMapper extends BaseMapper<SystemUserRole> {
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/CreateRoleMenuDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/CreateRoleMenuDTO.java
new file mode 100644
index 0000000..1540c10
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/CreateRoleMenuDTO.java
@@ -0,0 +1,29 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鍒涘缓瑙掕壊鑿滃崟鍙傛暟")
+public class CreateRoleMenuDTO implements Serializable {
+
+ @ApiModelProperty(value = "瑙掕壊ID", example = "1")
+ @NotNull(message = "瑙掕壊ID涓嶈兘涓虹┖")
+ private Integer roleId;
+
+ @ApiModelProperty(value = "鑿滃崟ID闆�")
+ @NotNull(message = "鑿滃崟ID闆嗕笉鑳戒负绌�")
+ private List<Integer> menuIds;
+
+ @ApiModelProperty(value = "鍒涘缓浜篒D", hidden = true)
+ private Integer createUser;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/CreateRolePermissionDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/CreateRolePermissionDTO.java
new file mode 100644
index 0000000..39760c5
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/CreateRolePermissionDTO.java
@@ -0,0 +1,29 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鍒涘缓瑙掕壊鏉冮檺鍙傛暟")
+public class CreateRolePermissionDTO implements Serializable {
+
+ @ApiModelProperty(value = "瑙掕壊ID")
+ @NotNull(message = "瑙掕壊ID涓嶈兘涓虹┖")
+ private Integer roleId;
+
+ @ApiModelProperty(value = "鏉冮檺ID闆�")
+ @NotNull(message = "鏉冮檺ID闆嗕笉鑳戒负绌�")
+ private List<Integer> permissionIds;
+
+ @ApiModelProperty(value = "鍒涘缓浜�", hidden = true)
+ private Integer createUser;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/CreateSystemUserDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/CreateSystemUserDTO.java
new file mode 100644
index 0000000..2f907fc
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/CreateSystemUserDTO.java
@@ -0,0 +1,17 @@
+package com.doumee.dao.system.dto;
+
+import com.doumee.dao.system.model.SystemUser;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鍒涘缓鐢ㄦ埛鍙傛暟")
+public class CreateSystemUserDTO extends SystemUser {
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/CreateUserRoleDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/CreateUserRoleDTO.java
new file mode 100644
index 0000000..3075cb4
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/CreateUserRoleDTO.java
@@ -0,0 +1,29 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鍒涘缓鐢ㄦ埛瑙掕壊鍙傛暟")
+public class CreateUserRoleDTO implements Serializable {
+
+ @ApiModelProperty(value = "鐢ㄦ埛ID")
+ @NotNull(message = "鐢ㄦ埛ID涓嶈兘涓虹┖")
+ private Integer userId;
+
+ @ApiModelProperty(value = "瑙掕壊ID闆�")
+ @NotNull(message = "瑙掕壊ID闆嗕笉鑳戒负绌�")
+ private List<Integer> roleIds;
+
+ @ApiModelProperty(value = "鍒涘缓浜�", hidden = true)
+ private Integer createUser;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/DeleteSystemPermissionDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/DeleteSystemPermissionDTO.java
new file mode 100644
index 0000000..512c323
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/DeleteSystemPermissionDTO.java
@@ -0,0 +1,20 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鍒犻櫎鏉冮檺鍙傛暟")
+public class DeleteSystemPermissionDTO {
+
+ @ApiModelProperty("鏉冮檺ID")
+ private Integer id;
+
+ @ApiModelProperty("妯″潡鍓嶇紑")
+ private String modulePrefix;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/LoginDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/LoginDTO.java
new file mode 100644
index 0000000..79c341e
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/LoginDTO.java
@@ -0,0 +1,33 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鐧诲綍鍙傛暟")
+public class LoginDTO implements Serializable {
+
+ @NotBlank(message = "鐢ㄦ埛鍚嶄笉鑳戒负绌�")
+ @ApiModelProperty(value = "鐢ㄦ埛鍚�")
+ private String username;
+
+ @NotBlank(message = "瀵嗙爜涓嶈兘涓虹┖")
+ @ApiModelProperty(value = "瀵嗙爜")
+ private String password;
+
+ @NotBlank(message = "楠岃瘉鐮佷笉鑳戒负绌�")
+ @ApiModelProperty(value = "楠岃瘉鐮�")
+ private String code;
+
+ @NotBlank(message = "楠岃瘉鐮乁UID涓嶈兘涓虹┖")
+ @ApiModelProperty(value = "楠岃瘉鐮乁UID")
+ private String uuid;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/QueryJobDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/QueryJobDTO.java
new file mode 100644
index 0000000..eb62c95
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/QueryJobDTO.java
@@ -0,0 +1,18 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瀹氭椂浠诲姟鍒楄〃鏌ヨ鍙傛暟")
+public class QueryJobDTO {
+
+ @ApiModelProperty(value = "JOB鍚嶇О")
+ private String jobName;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemDictDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemDictDTO.java
new file mode 100644
index 0000000..c0613c8
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemDictDTO.java
@@ -0,0 +1,22 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鏌ヨ瀛楀吀鍒楄〃鍙傛暟")
+public class QuerySystemDictDTO implements Serializable {
+
+ @ApiModelProperty(value = "瀛楀吀缂栫爜")
+ private String code;
+
+ @ApiModelProperty(value = "瀛楀吀鍚嶇О")
+ private String name;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemDictDataDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemDictDataDTO.java
new file mode 100644
index 0000000..0cdded7
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemDictDataDTO.java
@@ -0,0 +1,19 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鏌ヨ瀛楀吀鏁版嵁鍒楄〃鍙傛暟")
+public class QuerySystemDictDataDTO implements Serializable {
+
+ @ApiModelProperty(value = "瀛楀吀ID")
+ private Integer dictId;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemJobListDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemJobListDTO.java
new file mode 100644
index 0000000..2d4c936
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemJobListDTO.java
@@ -0,0 +1,18 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瀹氭椂浠诲姟鍒楄〃鏌ヨ鍙傛暟")
+public class QuerySystemJobListDTO {
+
+ @ApiModelProperty(value = "JOB鍚嶇О")
+ private String jobName;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemJobLogDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemJobLogDTO.java
new file mode 100644
index 0000000..22ffea2
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemJobLogDTO.java
@@ -0,0 +1,39 @@
+package com.doumee.dao.system.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@ApiModel("绯荤粺瀹氭椂浠诲姟鏃ュ織")
+public class QuerySystemJobLogDTO {
+
+ @ApiModelProperty(value = "瀹氭椂浠诲姟ID", example = "1")
+ private Integer jobId;
+
+ @ApiModelProperty(value = "鍒嗙墖缂栫爜")
+ private String snippetCode;
+
+ @ApiModelProperty(value = "鍒嗗彂缁�")
+ private String jobDistributeGroup;
+
+ @ApiModelProperty(value = "涓氬姟鏃堕棿")
+
+ private Date businessTime;
+
+ @ApiModelProperty(value = "鎵ц浠诲姟鐨勬湇鍔″櫒IP")
+ private String serverIp;
+
+ @ApiModelProperty(value = "瑙﹀彂绫诲瀷锛孲YSTEM-绯荤粺瀹氭椂瑙﹀彂锛孧ANUAL-鎵嬪姩瑙﹀彂")
+ private String triggerType;
+
+ @ApiModelProperty(value = "鐘舵�侊紙0鎵ц澶辫触锛�1鎵ц鎴愬姛锛�2璺宠繃锛�-1鎵ц涓級", example = "1")
+ private Byte status;
+
+ @ApiModelProperty(value = "鏃ュ織鍒涘缓鏃堕棿")
+
+ private Date createTime;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemLoginLogDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemLoginLogDTO.java
new file mode 100644
index 0000000..9814aae
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemLoginLogDTO.java
@@ -0,0 +1,22 @@
+package com.doumee.dao.system.dto;
+
+import com.doumee.dao.system.model.SystemLoginLog;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 鏌ヨ鐧诲綍鏃ュ織鍙傛暟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+public class QuerySystemLoginLogDTO extends SystemLoginLog {
+
+ @ApiModelProperty("鐧诲綍寮�濮嬫椂闂�")
+ private Date startTime;
+
+ @ApiModelProperty("鐧诲綍缁撴潫鏃堕棿")
+ private Date endTime;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemPermissionDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemPermissionDTO.java
new file mode 100644
index 0000000..b3f5951
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemPermissionDTO.java
@@ -0,0 +1,23 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鏌ヨ绯荤粺鏉冮檺鍙傛暟")
+public class QuerySystemPermissionDTO implements Serializable {
+
+ @ApiModelProperty(value = "鏉冮檺缂栫爜")
+ private String code;
+
+ @ApiModelProperty(value = "鏉冮檺鍚嶇О")
+ private String name;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemRoleDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemRoleDTO.java
new file mode 100644
index 0000000..c60b70a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemRoleDTO.java
@@ -0,0 +1,22 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鏌ヨ绯荤粺瑙掕壊鍙傛暟")
+public class QuerySystemRoleDTO implements Serializable {
+
+ @ApiModelProperty(value = "瑙掕壊缂栫爜")
+ private String code;
+
+ @ApiModelProperty(value = "瑙掕壊鍚嶇О")
+ private String name;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemTraceLogDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemTraceLogDTO.java
new file mode 100644
index 0000000..1849567
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemTraceLogDTO.java
@@ -0,0 +1,24 @@
+package com.doumee.dao.system.dto;
+
+import com.doumee.dao.system.model.SystemTraceLog;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 璺熻釜鏃ュ織鏌ヨ
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鏌ヨ璺熻釜鏃ュ織鍙傛暟")
+public class QuerySystemTraceLogDTO extends SystemTraceLog {
+
+ @ApiModelProperty("鎿嶄綔寮�濮嬫椂闂�")
+ private Date startTime;
+
+ @ApiModelProperty("鎿嶄綔缁撴潫鏃堕棿")
+ private Date endTime;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemUserDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemUserDTO.java
new file mode 100644
index 0000000..0109055
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/QuerySystemUserDTO.java
@@ -0,0 +1,38 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鏌ヨ绯荤粺鐢ㄦ埛鍙傛暟")
+public class QuerySystemUserDTO implements Serializable {
+
+ @ApiModelProperty(value = "鐢ㄤ簬鏌ヨ瀛愰儴闂ㄧ殑閮ㄩ棬ID")
+ private Integer rootDeptId;
+
+ @ApiModelProperty(value = "绮惧噯鍖归厤鐨勯儴闂↖D")
+ private Integer strictDeptId;
+
+ @ApiModelProperty(value = "閮ㄩ棬ID闆�", hidden = true)
+ private List<Integer> departmentIds;
+
+ @ApiModelProperty(value = "宀椾綅ID")
+ private Integer positionId;
+
+ @ApiModelProperty(value = "鐢ㄦ埛鍚�")
+ private String username;
+
+ @ApiModelProperty(value = "濮撳悕")
+ private String realname;
+
+ @ApiModelProperty(value = "鎵嬫満鍙风爜")
+ private String mobile;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/ResetSystemUserPwdDTO.java b/server/services/src/main/java/com/doumee/dao/system/dto/ResetSystemUserPwdDTO.java
new file mode 100644
index 0000000..9339737
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/ResetSystemUserPwdDTO.java
@@ -0,0 +1,29 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("閲嶇疆鐢ㄦ埛瀵嗙爜鍙傛暟瀵硅薄")
+public class ResetSystemUserPwdDTO implements Serializable {
+
+ @ApiModelProperty(value = "鐢ㄦ埛ID")
+ @NotNull(message = "鐢ㄦ埛ID涓嶈兘涓虹┖")
+ private Integer id;
+
+ @ApiModelProperty(value = "鏂板瘑鐮�")
+ @NotBlank(message = "鏂板瘑鐮佷笉鑳戒负绌�")
+ private String password;
+
+ @ApiModelProperty(value = "鎿嶄綔浜�", hidden = true)
+ private Integer operaUserId;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/dto/UpdatePwdDto.java b/server/services/src/main/java/com/doumee/dao/system/dto/UpdatePwdDto.java
new file mode 100644
index 0000000..5ae3e38
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/dto/UpdatePwdDto.java
@@ -0,0 +1,29 @@
+package com.doumee.dao.system.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("淇敼瀵嗙爜鍙傛暟")
+public class UpdatePwdDto implements Serializable {
+
+ @ApiModelProperty(value = "鐢ㄦ埛ID", hidden = true)
+ private Integer userId;
+
+ @NotBlank(message = "鍘熷瀵嗙爜涓嶈兘涓虹┖")
+ @ApiModelProperty(value = "鍘熷瀵嗙爜")
+ private String oldPwd;
+
+ @NotBlank(message = "鏂板瘑鐮佷笉鑳戒负绌�")
+ @ApiModelProperty(value = "鏂板瘑鐮�")
+ private String newPwd;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemDict.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemDict.java
new file mode 100644
index 0000000..b42797d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemDict.java
@@ -0,0 +1,55 @@
+package com.doumee.dao.system.model;
+
+import com.doumee.core.constants.Constants;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 瀛楀吀
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瀛楀吀")
+public class SystemDict implements Serializable {
+
+ @TableId(type = IdType.AUTO)
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {Constants.OperaType.Update.class})
+ private Integer id;
+
+ @ApiModelProperty(value = "瀛楀吀缂栫爜")
+ @NotBlank(message = "瀛楀吀缂栫爜涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String code;
+
+ @ApiModelProperty(value = "瀛楀吀鍚嶇О")
+ @NotBlank(message = "瀛楀吀鍚嶇О涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String name;
+
+ @ApiModelProperty(value = "澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "鍒涘缓浜�", example = "1", hidden = true)
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鏇存柊浜�", example = "1", hidden = true)
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "鏄惁鍒犻櫎", hidden = true)
+ private Boolean deleted;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemDictData.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemDictData.java
new file mode 100644
index 0000000..80a7813
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemDictData.java
@@ -0,0 +1,66 @@
+package com.doumee.dao.system.model;
+
+import com.doumee.core.constants.Constants;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 瀛楀吀鏁版嵁
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瀛楀吀鏁版嵁")
+public class SystemDictData implements Serializable {
+
+ @TableId(type = IdType.AUTO)
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {Constants.OperaType.Update.class})
+ private Integer id;
+
+ @ApiModelProperty(value = "鎵�灞炲瓧鍏�", example = "1")
+ @NotNull(message = "鎵�灞炲瓧鍏镐笉鑳戒负绌�", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private Integer dictId;
+
+ @ApiModelProperty(value = "鏁版嵁鍊�")
+ @NotBlank(message = "鏁版嵁鍊间笉鑳戒负绌�", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String code;
+ @ApiModelProperty(value = "澶囨敞")
+ @NotBlank(message = "澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "鏁版嵁鏍囩")
+ @NotBlank(message = "鏁版嵁鏍囩涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String label;
+
+ @ApiModelProperty(value = "鎺掑簭", example = "1")
+ private Integer sort;
+
+ @ApiModelProperty(value = "鏄惁绂佺敤")
+ @NotNull(message = "鏄惁绂佺敤涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private Boolean disabled;
+
+ @ApiModelProperty(value = "鍒涘缓浜�", example = "1", hidden = true)
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鏇存柊浜�", example = "1", hidden = true)
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "鏄惁鍒犻櫎", hidden = true)
+ private Boolean deleted;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemJob.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemJob.java
new file mode 100644
index 0000000..db35aa0
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemJob.java
@@ -0,0 +1,96 @@
+package com.doumee.dao.system.model;
+
+import com.doumee.core.constants.Constants;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * 绯荤粺瀹氭椂浠诲姟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("绯荤粺瀹氭椂浠诲姟")
+@TableName("`SYSTEM_JOB`")
+public class SystemJob {
+
+ @TableId(type = IdType.AUTO)
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {Constants.OperaType.Update.class, Constants.OperaType.UpdateStatus.class})
+ private Integer id;
+
+ @ApiModelProperty(value = "JOB鍚嶇О")
+ @NotBlank(message = "浠诲姟鍚嶇О涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String jobName;
+
+ @ApiModelProperty(value = "JOB鎻忚堪")
+ private String jobDescription;
+
+ @ApiModelProperty(value = "浠诲姟澶勭悊鍣ㄧ被")
+ @NotBlank(message = "浠诲姟澶勭悊鍣ㄧ被涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class, Constants.OperaType.UpdateStatus.class})
+ private String handler;
+
+ @ApiModelProperty(value = "鏁版嵁鍒嗗彂澶勭悊鍣�")
+ private String distributeHandler;
+
+ @ApiModelProperty(value = "鍒嗗彂鏁伴檺鍒�", example = "1")
+ private Integer distributeLimit;
+
+ @ApiModelProperty(value = "鏄惁绂佺敤骞跺彂鎵ц")
+ @NotNull(message = "鏄惁绂佺敤骞跺彂鎵ц涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private Boolean disallowConcurrent;
+
+ @ApiModelProperty(value = "鏄惁绂佺敤")
+ private Boolean disabled;
+
+ @ApiModelProperty(value = "鏄惁寮傛鎵ц")
+ @NotNull(message = "鏄惁寮傛鎵ц涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private Boolean withAsync;
+
+ @ApiModelProperty(value = "鏄惁璁板綍鏃ュ織")
+ @NotNull(message = "鏄惁璁板綍鏃ュ織涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private Boolean withLog;
+
+ @ApiModelProperty(value = "CRON琛ㄨ揪寮�")
+ @NotNull(message = "CRON琛ㄨ揪寮忎笉鑳戒负绌�", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String cronExpression;
+
+ @ApiModelProperty(value = "鏈嶅姟鍣ㄧ櫧鍚嶅崟")
+ private String allowServerIps;
+
+ @ApiModelProperty(value = "鐘舵�侊紙0鍑嗗锛�1杩愯涓級", example = "1")
+ private Integer status;
+
+ @ApiModelProperty(value = "閿佺紪鍙�", example = "1")
+ private Integer lockNumber;
+
+ @ApiModelProperty(value = "棰勮涓嬩竴娆℃墽琛屾椂闂�")
+ private Date nextFireTime;
+
+ @ApiModelProperty(value = "鍒涘缓浜�", example = "1")
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊浜�", example = "1")
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "鏄惁鍒犻櫎")
+ private Boolean deleted;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemJobLog.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemJobLog.java
new file mode 100644
index 0000000..1e255f1
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemJobLog.java
@@ -0,0 +1,79 @@
+package com.doumee.dao.system.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.util.Date;
+
+/**
+ * 绯荤粺瀹氭椂浠诲姟鏃ュ織
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("绯荤粺瀹氭椂浠诲姟鏃ュ織")
+@TableName("`SYSTEM_JOB_LOG`")
+public class SystemJobLog {
+
+ @TableId(type = IdType.AUTO)
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ private Integer id;
+
+ @ApiModelProperty(value = "瀹氭椂浠诲姟ID", example = "1")
+ private Integer jobId;
+
+ @ApiModelProperty(value = "浠诲姟鍚嶇О")
+ private String jobName;
+
+ @ApiModelProperty(value = "鍒嗗彂缁�")
+ private String jobDistributeGroup;
+
+ @ApiModelProperty(value = "鍒嗙墖ID", example = "1")
+ private Integer snippetId;
+
+ @ApiModelProperty(value = "鍒嗙墖缂栫爜")
+ private String snippetCode;
+
+ @ApiModelProperty(value = "涓氬姟鏃堕棿")
+ private Date businessTime;
+
+ @ApiModelProperty(value = "鎵ц寮�濮嬫椂闂�")
+ private Date runTimeStart;
+
+ @ApiModelProperty(value = "鎵ц缁撴潫鏃堕棿")
+ private Date runTimeEnd;
+
+ @ApiModelProperty(value = "鑰楁椂", example = "1")
+ private Integer runSpendTime;
+
+ @ApiModelProperty(value = "鎵ц鍙傛暟")
+ private String parameters;
+
+ @ApiModelProperty(value = "澶勭悊鎬绘暟", example = "1")
+ private Integer handleTotalSize;
+
+ @ApiModelProperty(value = "澶勭悊鎴愬姛鏁�", example = "1")
+ private Integer handleSuccessSize;
+
+ @ApiModelProperty(value = "鎵ц浠诲姟鐨勬湇鍔″櫒IP")
+ private String serverIp;
+
+ @ApiModelProperty(value = "鐘舵�侊紙0鎵ц澶辫触锛�1鎵ц鎴愬姛锛�2璺宠繃锛�-1鎵ц涓級", example = "1")
+ private Integer status;
+
+ @ApiModelProperty(value = "浠诲姟鎵ц涓婁笅鏂�")
+ private String context;
+
+ @ApiModelProperty(value = "瑙﹀彂绫诲瀷锛孲YSTEM-绯荤粺瀹氭椂瑙﹀彂锛孧ANUAL-鎵嬪姩瑙﹀彂")
+ private String triggerType;
+
+ @ApiModelProperty(value = "澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "鏃ュ織鍒涘缓鏃堕棿")
+ private Date createTime;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemJobSnippet.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemJobSnippet.java
new file mode 100644
index 0000000..dc73d5c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemJobSnippet.java
@@ -0,0 +1,74 @@
+package com.doumee.dao.system.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+
+/**
+ * 瀹氭椂浠诲姟鐗囨
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瀹氭椂浠诲姟鐗囨")
+@TableName("`SYSTEM_JOB_SNIPPET`")
+public class SystemJobSnippet {
+
+ @TableId(type = IdType.AUTO)
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ private Integer id;
+
+ @ApiModelProperty(value = "瀹氭椂浠诲姟ID", example = "1")
+ private Integer jobId;
+
+ @ApiModelProperty(value = "JOB鍚嶇О")
+ private String jobName;
+
+ @ApiModelProperty(value = "鍒嗗彂缁�")
+ private String jobDistributeGroup;
+
+ @ApiModelProperty(value = "浠诲姟鎵ц涓氬姟鏃堕棿")
+ private Date jobBusinessTime;
+
+ @ApiModelProperty(value = "鍒嗙墖澶勭悊鍣ㄧ被")
+ private String handler;
+
+ @ApiModelProperty(value = "鏁版嵁鍒嗗彂澶勭悊鍣�")
+ private String distributeHandler;
+
+ @ApiModelProperty(value = "鍒嗗彂鏁伴檺鍒�", example = "1")
+ private Integer distributeLimit;
+
+ @ApiModelProperty(value = "鍒嗙墖绱㈠紩")
+ private Integer snippetIndex;
+
+ @ApiModelProperty(value = "鍒嗙墖缂栧彿")
+ private String snippetCode;
+
+ @ApiModelProperty(value = "鍒嗙墖鏁版嵁")
+ private String snippetData;
+
+ @ApiModelProperty(value = "鍒嗙墖鏁版嵁鏁伴噺", example = "1")
+ private Integer snippetDataSize;
+
+ @ApiModelProperty(value = "鏄惁璁板綍鏃ュ織")
+ private Boolean withLog;
+
+ @ApiModelProperty(value = "鏈嶅姟鍣ㄧ櫧鍚嶅崟")
+ private String allowServerIps;
+
+ @ApiModelProperty(value = "鍒嗙墖鐘舵�侊紙0鍑嗗锛�1杩愯涓紝2宸插畬鎴愶級", example = "1")
+ private Integer status;
+
+ @ApiModelProperty(value = "閿佺紪鍙�", example = "1")
+ private Integer lockNumber;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemLoginLog.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemLoginLog.java
new file mode 100644
index 0000000..fa83b30
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemLoginLog.java
@@ -0,0 +1,60 @@
+package com.doumee.dao.system.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 鐧诲綍鏃ュ織
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鐧诲綍鏃ュ織")
+public class SystemLoginLog {
+
+ @TableId(type = IdType.AUTO)
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ private Integer id;
+
+ @ApiModelProperty(value = "鐧诲綍鐢ㄦ埛ID", example = "1")
+ private Integer userId;
+
+ @ApiModelProperty(value = "鐧诲綍鐢ㄦ埛鍚�")
+ private String loginUsername;
+
+ @ApiModelProperty(value = "鐧诲綍IP")
+ private String ip;
+
+ @ApiModelProperty(value = "鐧诲綍鍦板潃")
+ private String location;
+
+ @ApiModelProperty(value = "瀹㈡埛绔�")
+ private String clientInfo;
+
+ @ApiModelProperty(value = "鎿嶄綔绯荤粺")
+ private String osInfo;
+
+ @ApiModelProperty(value = "鐧诲綍骞冲彴")
+ private String platform;
+
+ @ApiModelProperty(value = "绯荤粺鐗堟湰")
+ private String systemVersion;
+
+ @ApiModelProperty(value = "鏈嶅姟鍣↖P")
+ private String serverIp;
+
+ @ApiModelProperty(value = "鏄惁鐧诲綍鎴愬姛")
+ private Boolean success;
+
+ @ApiModelProperty(value = "澶辫触鍘熷洜")
+ private String reason;
+
+ @ApiModelProperty(value = "鐧诲綍鏃堕棿")
+ private Date loginTime;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemMenu.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemMenu.java
new file mode 100644
index 0000000..ac78b1b
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemMenu.java
@@ -0,0 +1,73 @@
+package com.doumee.dao.system.model;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.doumee.core.constants.Constants;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 绯荤粺鑿滃崟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("绯荤粺鑿滃崟")
+public class SystemMenu implements Serializable {
+
+ @TableId(type = IdType.AUTO)
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {Constants.OperaType.Update.class, Constants.OperaType.UpdateStatus.class})
+ private Integer id;
+
+ @ApiModelProperty(value = "涓婁竴绾ц彍鍗�", example = "1")
+ @TableField(updateStrategy = FieldStrategy.IGNORED)
+ private Integer parentId;
+
+ @ApiModelProperty(value = "鑿滃崟鍚嶇О")
+ @NotBlank(message = "鑿滃崟鍚嶇О涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String name;
+
+ @ApiModelProperty(value = "鑿滃崟璁块棶璺緞")
+ private String path;
+
+ @ApiModelProperty(value = "澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "鍥炬爣")
+ private String icon;
+
+ @ApiModelProperty(value = "鏄惁绂佺敤")
+ @NotNull(message = "鏄惁绂佺敤涓嶈兘涓虹┖", groups = Constants.OperaType.UpdateStatus.class)
+ private Boolean disabled;
+
+ @ApiModelProperty(value = "鎺掑簭", example = "1")
+ private Integer sort;
+
+ @ApiModelProperty(value = "鏄惁涓哄浐瀹氳彍鍗�", hidden = true)
+ private Boolean fixed;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "鍒涘缓鑰匢D", example = "1", hidden = true)
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鏇存柊鑰匢D", example = "1", hidden = true)
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄�", hidden = true)
+ private Boolean deleted;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemPermission.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemPermission.java
new file mode 100644
index 0000000..7eee52a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemPermission.java
@@ -0,0 +1,61 @@
+package com.doumee.dao.system.model;
+
+import com.doumee.core.constants.Constants;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 绯荤粺鏉冮檺
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("绯荤粺鏉冮檺")
+public class SystemPermission implements Serializable {
+
+ @TableId(type = IdType.AUTO)
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {Constants.OperaType.Update.class})
+ private Integer id;
+
+ @ApiModelProperty(value = "鏉冮檺缂栫爜")
+ @NotBlank(message = "鏉冮檺缂栫爜涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class,Constants.OperaType.Update.class})
+ private String code;
+
+ @ApiModelProperty(value = "鏉冮檺鍚嶇О")
+ @NotBlank(message = "鏉冮檺鍚嶇О涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class,Constants.OperaType.Update.class})
+ private String name;
+
+ @ApiModelProperty(value = "妯″潡")
+ private String module;
+
+ @ApiModelProperty(value = "鏉冮檺澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "鏄惁涓哄浐瀹氭潈闄�", hidden = true)
+ private Boolean fixed;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "鍒涘缓鑰匢D", example = "1", hidden = true)
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鏇存柊鑰匢D", example = "1", hidden = true)
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄�", hidden = true)
+ private Boolean deleted;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemRole.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemRole.java
new file mode 100644
index 0000000..9e5a316
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemRole.java
@@ -0,0 +1,58 @@
+package com.doumee.dao.system.model;
+
+import com.doumee.core.constants.Constants;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 绯荤粺瑙掕壊
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("绯荤粺瑙掕壊")
+public class SystemRole implements Serializable {
+
+ @TableId(type = IdType.AUTO)
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {Constants.OperaType.Update.class})
+ private Integer id;
+
+ @ApiModelProperty(value = "瑙掕壊缂栫爜")
+ @NotBlank(message = "瑙掕壊缂栫爜涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String code;
+
+ @ApiModelProperty(value = "瑙掕壊鍚嶇О")
+ @NotBlank(message = "瑙掕壊鍚嶇О涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String name;
+
+ @ApiModelProperty(value = "瑙掕壊澶囨敞")
+ private String remark;
+
+ @ApiModelProperty(value = "鏄惁涓哄浐瀹氳鑹�", hidden = true)
+ private Boolean fixed;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "鍒涘缓鑰匢D", example = "1", hidden = true)
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鏇存柊鑰匢D", example = "1", hidden = true)
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄�", hidden = true)
+ private Boolean deleted;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemRoleMenu.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemRoleMenu.java
new file mode 100644
index 0000000..3f01353
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemRoleMenu.java
@@ -0,0 +1,46 @@
+package com.doumee.dao.system.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 瑙掕壊鑿滃崟鍏宠仈
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瑙掕壊鑿滃崟鍏宠仈")
+public class SystemRoleMenu implements Serializable {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @TableId(type = IdType.AUTO)
+ private Integer id;
+
+ @ApiModelProperty(value = "瑙掕壊ID", example = "1")
+ private Integer roleId;
+
+ @ApiModelProperty(value = "鑿滃崟ID", example = "1")
+ private Integer menuId;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "鍒涘缓浜�", example = "1", hidden = true)
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鏇存柊浜�", example = "1", hidden = true)
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄�", hidden = true)
+ private Boolean deleted;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemRolePermission.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemRolePermission.java
new file mode 100644
index 0000000..5408e3a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemRolePermission.java
@@ -0,0 +1,46 @@
+package com.doumee.dao.system.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 瑙掕壊鏉冮檺鍏宠仈
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瑙掕壊鏉冮檺鍏宠仈")
+public class SystemRolePermission implements Serializable {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @TableId(type = IdType.AUTO)
+ private Integer id;
+
+ @ApiModelProperty(value = "瑙掕壊ID", example = "1")
+ private Integer roleId;
+
+ @ApiModelProperty(value = "鏉冮檺ID", example = "1")
+ private Integer permissionId;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "鍒涘缓浜�", example = "1", hidden = true)
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鏇存柊浜�", example = "1", hidden = true)
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄�", hidden = true)
+ private Boolean deleted;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemTraceLog.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemTraceLog.java
new file mode 100644
index 0000000..2213746
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemTraceLog.java
@@ -0,0 +1,94 @@
+package com.doumee.dao.system.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 璺熻釜鏃ュ織
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("璺熻釜鏃ュ織")
+public class SystemTraceLog implements Serializable {
+
+ @TableId(type = IdType.AUTO)
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ private Integer id;
+
+ @ApiModelProperty(value = "鐢ㄦ埛", example = "1")
+ private Integer userId;
+
+ @ApiModelProperty(value = "鍥哄寲鐢ㄦ埛鍚�")
+ private String username;
+
+ @ApiModelProperty(value = "鍥哄寲鐢ㄦ埛濮撳悕")
+ private String userRealname;
+
+ @ApiModelProperty(value = "鍥哄寲鐢ㄦ埛瑙掕壊")
+ private String userRoles;
+
+ @ApiModelProperty(value = "鍥哄寲鐢ㄦ埛鏉冮檺")
+ private String userPermissions;
+
+ @ApiModelProperty(value = "鎿嶄綔妯″潡")
+ private String operaModule;
+
+ @ApiModelProperty(value = "鎿嶄綔绫诲瀷")
+ private String operaType;
+
+ @ApiModelProperty(value = "鎿嶄綔澶囨敞")
+ private String operaRemark;
+
+ @ApiModelProperty(value = "鎿嶄綔寮�濮嬫椂闂�")
+ private Date operaTime;
+
+ @ApiModelProperty(value = "鑰楁椂", example = "1")
+ private Integer operaSpendTime;
+
+ @ApiModelProperty(value = "璇锋眰鏂瑰紡")
+ private String requestMethod;
+
+ @ApiModelProperty(value = "璇锋眰鍦板潃")
+ private String requestUri;
+
+ @ApiModelProperty(value = "璇锋眰鍙傛暟")
+ private String requestParams;
+
+ @ApiModelProperty(value = "璇锋眰缁撴灉")
+ private String requestResult;
+
+ @ApiModelProperty(value = "鐘舵�侊紙0鎿嶄綔澶辫触锛�1鎿嶄綔鎴愬姛锛�-1鏈緱鍒板鐞嗭級", example = "1")
+ private Integer status;
+
+ @ApiModelProperty(value = "寮傚父绛夌骇")
+ private Integer exceptionLevel;
+
+ @ApiModelProperty(value = "寮傚父淇℃伅")
+ private String exceptionStack;
+
+ @ApiModelProperty(value = "IP")
+ private String ip;
+
+ @ApiModelProperty(value = "鏈嶅姟鍣↖P")
+ private String serverIp;
+
+ @ApiModelProperty(value = "鎺ュ彛鐗堟湰")
+ private String systemVersion;
+
+ @ApiModelProperty(value = "鎿嶄綔骞冲彴")
+ private String platform;
+
+ @ApiModelProperty(value = "瀹㈡埛绔俊鎭�")
+ private String clientInfo;
+
+ @ApiModelProperty(value = "绯荤粺淇℃伅")
+ private String osInfo;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemUser.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemUser.java
new file mode 100644
index 0000000..3157800
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemUser.java
@@ -0,0 +1,88 @@
+package com.doumee.dao.system.model;
+
+import com.doumee.core.constants.Constants;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 绯荤粺鐢ㄦ埛
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("绯荤粺鐢ㄦ埛")
+public class SystemUser implements Serializable {
+
+ @TableId(type = IdType.AUTO)
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @NotNull(message = "涓婚敭涓嶈兘涓虹┖", groups = {Constants.OperaType.Update.class})
+ private Integer id;
+
+ @ApiModelProperty(value = "鐢ㄦ埛鍚�")
+ @NotBlank(message = "鐢ㄦ埛鍚嶄笉鑳戒负绌�", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String username;
+
+ @ApiModelProperty(value = "濮撳悕")
+ @NotBlank(message = "濮撳悕涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String realname;
+
+ @ApiModelProperty(value = "宸ュ彿")
+ private String empNo;
+
+ @ApiModelProperty(value = "鐢熸棩")
+ @JsonFormat(pattern = "yyyy-MM-dd")
+ private Date birthday;
+
+ @ApiModelProperty(value = "鎬у埆")
+ @NotBlank(message = "鎬у埆涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String sex;
+
+ @ApiModelProperty(value = "閭")
+ @Email(message = "閭鏍煎紡涓嶆纭�", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String email;
+
+ @ApiModelProperty(value = "鎵嬫満鍙风爜")
+ @Pattern(message = "鎵嬫満鍙风爜鏍煎紡涓嶆纭�", regexp = "^\\d*$", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String mobile;
+
+ @ApiModelProperty(value = "澶村儚")
+ @NotBlank(message = "澶村儚涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class, Constants.OperaType.Update.class})
+ private String avatar;
+
+ @ApiModelProperty(value = "瀵嗙爜")
+ @NotBlank(message = "鍒濆瀵嗙爜涓嶈兘涓虹┖", groups = {Constants.OperaType.Create.class})
+ private String password;
+
+ @ApiModelProperty(value = "鐩�")
+ private String salt;
+
+ @ApiModelProperty(value = "鏄惁涓哄浐瀹氱敤鎴�", hidden = true)
+ private Boolean fixed;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "鍒涘缓浜�", example = "1", hidden = true)
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鏇存柊浜�", example = "1", hidden = true)
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄�", hidden = true)
+ private Boolean deleted;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/model/SystemUserRole.java b/server/services/src/main/java/com/doumee/dao/system/model/SystemUserRole.java
new file mode 100644
index 0000000..339b40c
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/model/SystemUserRole.java
@@ -0,0 +1,46 @@
+package com.doumee.dao.system.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 鐢ㄦ埛瑙掕壊鍏宠仈
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鐢ㄦ埛瑙掕壊鍏宠仈")
+public class SystemUserRole implements Serializable {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ @TableId(type = IdType.AUTO)
+ private Integer id;
+
+ @ApiModelProperty(value = "鐢ㄦ埛ID", example = "1")
+ private Integer userId;
+
+ @ApiModelProperty(value = "瑙掕壊ID", example = "1")
+ private Integer roleId;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "鍒涘缓浜�", example = "1", hidden = true)
+ private Integer createUser;
+
+ @ApiModelProperty(value = "鏇存柊浜�", example = "1", hidden = true)
+ private Integer updateUser;
+
+ @ApiModelProperty(value = "鏄惁宸插垹闄�", hidden = true)
+ private Boolean deleted;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/vo/SystemDictDataListVO.java b/server/services/src/main/java/com/doumee/dao/system/vo/SystemDictDataListVO.java
new file mode 100644
index 0000000..f37a9fa
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/vo/SystemDictDataListVO.java
@@ -0,0 +1,22 @@
+package com.doumee.dao.system.vo;
+
+import com.doumee.dao.system.model.SystemDictData;
+import com.doumee.dao.system.model.SystemUser;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瀛楀吀鏁版嵁鍒楄〃瑙嗗浘瀵硅薄")
+public class SystemDictDataListVO extends SystemDictData {
+
+ @ApiModelProperty(value = "鍒涘缓浜轰俊鎭�")
+ private SystemUser createUserInfo;
+
+ @ApiModelProperty(value = "鏇存柊浜轰俊鎭�")
+ private SystemUser updateUserInfo;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/vo/SystemDictListVO.java b/server/services/src/main/java/com/doumee/dao/system/vo/SystemDictListVO.java
new file mode 100644
index 0000000..7aaa2da
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/vo/SystemDictListVO.java
@@ -0,0 +1,22 @@
+package com.doumee.dao.system.vo;
+
+import com.doumee.dao.system.model.SystemDict;
+import com.doumee.dao.system.model.SystemUser;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瀛楀吀鍒楄〃瑙嗗浘瀵硅薄")
+public class SystemDictListVO extends SystemDict {
+
+ @ApiModelProperty(value = "鍒涘缓浜轰俊鎭�")
+ private SystemUser createUserInfo;
+
+ @ApiModelProperty(value = "鏇存柊浜轰俊鎭�")
+ private SystemUser updateUserInfo;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/vo/SystemJobListVO.java b/server/services/src/main/java/com/doumee/dao/system/vo/SystemJobListVO.java
new file mode 100644
index 0000000..5d0a124
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/vo/SystemJobListVO.java
@@ -0,0 +1,69 @@
+package com.doumee.dao.system.vo;
+
+import com.doumee.dao.system.model.SystemUser;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("瀹氭椂浠诲姟鍒楄〃鍒楄〃瀵硅薄")
+public class SystemJobListVO {
+
+ @ApiModelProperty(value = "涓婚敭", example = "1")
+ private Integer id;
+
+ @ApiModelProperty(value = "JOB鍚嶇О")
+ private String jobName;
+
+ @ApiModelProperty(value = "JOB鎻忚堪")
+ private String jobDescription;
+
+ @ApiModelProperty(value = "浠诲姟澶勭悊鍣ㄧ被")
+ private String handler;
+
+ @ApiModelProperty(value = "鏁版嵁鍒嗗彂澶勭悊鍣�")
+ private String distributeHandler;
+
+ @ApiModelProperty(value = "鍒嗗彂鏁伴檺鍒�", example = "1")
+ private Integer distributeLimit;
+
+ @ApiModelProperty(value = "鏄惁绂佺敤骞跺彂鎵ц")
+ private Boolean disallowConcurrent;
+
+ @ApiModelProperty(value = "鏄惁绂佺敤")
+ private Boolean disabled;
+
+ @ApiModelProperty(value = "鏄惁寮傛鎵ц")
+ private Boolean withAsync;
+
+ @ApiModelProperty(value = "鏄惁璁板綍鏃ュ織")
+ private Boolean withLog;
+
+ @ApiModelProperty(value = "CRON琛ㄨ揪寮�")
+ private String cronExpression;
+
+ @ApiModelProperty(value = "鍏佽鎵ц璇ヤ换鍔$殑鏈嶅姟IP锛屽涓狪P浣跨敤鑻辨枃閫楀彿闅斿紑")
+ private String allowServerIps;
+
+ @ApiModelProperty(value = "鐘舵�侊紙0鍑嗗锛�1杩愯涓級", example = "1")
+ private Byte status;
+
+ @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+ private Date createTime;
+
+ @ApiModelProperty(value = "鏇存柊鏃堕棿")
+ private Date updateTime;
+
+ @ApiModelProperty(value = "绯荤粺鐢ㄦ埛淇℃伅")
+ private SystemUser createUserInfo;
+
+ @ApiModelProperty(value = "绯荤粺鐢ㄦ埛淇℃伅")
+ private SystemUser updateUserInfo;
+
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/vo/SystemMenuListVO.java b/server/services/src/main/java/com/doumee/dao/system/vo/SystemMenuListVO.java
new file mode 100644
index 0000000..cbd9a4f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/vo/SystemMenuListVO.java
@@ -0,0 +1,30 @@
+package com.doumee.dao.system.vo;
+
+import com.doumee.dao.system.model.SystemMenu;
+import com.doumee.dao.system.model.SystemUser;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鑿滃崟鍒楄〃瑙嗗浘瀵硅薄")
+public class SystemMenuListVO extends SystemMenu {
+
+ @ApiModelProperty(value = "瀛愯彍鍗曞垪琛�")
+ private List<SystemMenuListVO> children;
+
+ @ApiModelProperty(value = "鏄惁鍖呭惈瀛愯彍鍗�")
+ private Boolean hasChildren;
+
+ @ApiModelProperty(value = "鍒涘缓浜轰俊鎭�")
+ private SystemUser createUserInfo;
+
+ @ApiModelProperty(value = "鏇存柊浜轰俊鎭�")
+ private SystemUser updateUserInfo;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/vo/SystemMenuNodeVO.java b/server/services/src/main/java/com/doumee/dao/system/vo/SystemMenuNodeVO.java
new file mode 100644
index 0000000..1c8af1f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/vo/SystemMenuNodeVO.java
@@ -0,0 +1,35 @@
+package com.doumee.dao.system.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("鑿滃崟鑺傜偣瑙嗗浘瀵硅薄")
+public class SystemMenuNodeVO implements Serializable {
+
+ @ApiModelProperty(value = "鑿滃崟ID")
+ private Integer id;
+
+ @ApiModelProperty(value = "鑿滃崟鍚嶇О")
+ private String label;
+
+ @ApiModelProperty(value = "鑿滃崟鍞竴鏍囪瘑锛堝墠绔笓鐢級")
+ private String index;
+
+ @ApiModelProperty(value = "鍥炬爣")
+ private String icon;
+
+ @ApiModelProperty(value = "鑿滃崟鍦板潃")
+ private String url;
+
+ @ApiModelProperty(value = "瀛愯彍鍗�")
+ private List<SystemMenuNodeVO> children;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/vo/SystemPermissionListVO.java b/server/services/src/main/java/com/doumee/dao/system/vo/SystemPermissionListVO.java
new file mode 100644
index 0000000..bde8ccb
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/vo/SystemPermissionListVO.java
@@ -0,0 +1,36 @@
+package com.doumee.dao.system.vo;
+
+import com.doumee.dao.system.model.SystemPermission;
+import com.doumee.dao.system.model.SystemUser;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("绯荤粺鏉冮檺鍒楄〃瑙嗗浘瀵硅薄")
+public class SystemPermissionListVO extends SystemPermission {
+
+ @ApiModelProperty(value = "绫诲瀷锛宮odule妯″潡锛宲ermission鏉冮檺")
+ private String type;
+
+ @ApiModelProperty(value = "妯″潡璺緞")
+ private String modulePath;
+
+ @ApiModelProperty(value = "灞傜骇")
+ private Integer level;
+
+ @ApiModelProperty(value = "瀛愭潈闄愬垪琛�")
+ private List<SystemPermissionListVO> children;
+
+ @ApiModelProperty(value = "鍒涘缓浜轰俊鎭�")
+ private SystemUser createUserInfo;
+
+ @ApiModelProperty(value = "鏇存柊浜轰俊鎭�")
+ private SystemUser updateUserInfo;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/vo/SystemRoleListVO.java b/server/services/src/main/java/com/doumee/dao/system/vo/SystemRoleListVO.java
new file mode 100644
index 0000000..7033d46
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/vo/SystemRoleListVO.java
@@ -0,0 +1,32 @@
+package com.doumee.dao.system.vo;
+
+import com.doumee.dao.system.model.SystemMenu;
+import com.doumee.dao.system.model.SystemPermission;
+import com.doumee.dao.system.model.SystemRole;
+import com.doumee.dao.system.model.SystemUser;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("绯荤粺瑙掕壊鍒楄〃瑙嗗浘瀵硅薄")
+public class SystemRoleListVO extends SystemRole {
+
+ @ApiModelProperty(value = "瑙掕壊鎷ユ湁鐨勬潈闄愬垪琛�")
+ private List<SystemPermission> permissions;
+
+ @ApiModelProperty(value = "瑙掕壊鎷ユ湁鐨勮彍鍗曞垪琛�")
+ private List<SystemMenu> menus;
+
+ @ApiModelProperty(value = "鍒涘缓浜轰俊鎭�")
+ private SystemUser createUserInfo;
+
+ @ApiModelProperty(value = "鏇存柊浜轰俊鎭�")
+ private SystemUser updateUserInfo;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/system/vo/SystemUserListVO.java b/server/services/src/main/java/com/doumee/dao/system/vo/SystemUserListVO.java
new file mode 100644
index 0000000..2d45172
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/system/vo/SystemUserListVO.java
@@ -0,0 +1,28 @@
+package com.doumee.dao.system.vo;
+
+import com.doumee.dao.system.model.SystemRole;
+import com.doumee.dao.system.model.SystemUser;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("绯荤粺鐢ㄦ埛鍒楄〃瑙嗗浘瀵硅薄")
+public class SystemUserListVO extends SystemUser {
+
+ @ApiModelProperty(value = "瑙掕壊")
+ private List<SystemRole> roles;
+
+ @ApiModelProperty(value = "鍒涘缓浜轰俊鎭�")
+ private SystemUser createUserInfo;
+
+ @ApiModelProperty(value = "鏇存柊浜轰俊鎭�")
+ private SystemUser updateUserInfo;
+
+}
diff --git a/server/services/src/main/java/com/doumee/job/CommonTestJob.java b/server/services/src/main/java/com/doumee/job/CommonTestJob.java
new file mode 100644
index 0000000..859efef
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/job/CommonTestJob.java
@@ -0,0 +1,29 @@
+package com.doumee.job;
+
+import com.doumee.core.job.BaseJob;
+import com.doumee.core.job.JobContext;
+import com.doumee.core.job.JobParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * 鏅�氱殑瀹氭椂浠诲姟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component("commonTestJob")
+public class CommonTestJob extends BaseJob {
+
+ @Override
+ public JobContext execute(JobParam param) {
+ JobContext jobContext = new JobContext();
+ try {
+ jobContext.setContext("鏆傚仠20000姣");
+ Thread.sleep(20000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return jobContext;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/job/DistributableTestJob.java b/server/services/src/main/java/com/doumee/job/DistributableTestJob.java
new file mode 100644
index 0000000..3414b64
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/job/DistributableTestJob.java
@@ -0,0 +1,36 @@
+package com.doumee.job;
+
+import com.alibaba.fastjson.JSON;
+import com.doumee.core.job.BaseJob;
+import com.doumee.core.job.JobContext;
+import com.doumee.core.job.JobParam;
+import com.doumee.dao.system.model.SystemPermission;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 鑷姩鍒嗗彂鐨勫畾鏃朵换鍔�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component("distributableTestJob")
+public class DistributableTestJob extends BaseJob {
+
+ @Override
+ public JobContext execute(JobParam param) {
+ JobContext jobContext = new JobContext();
+ List<SystemPermission> permissions = param.getRuntimeData(SystemPermission.class);
+ StringBuilder context = new StringBuilder();
+ for (SystemPermission permission : permissions) {
+ context.append(JSON.toJSONString(permission));
+ context.append("\n");
+ }
+ jobContext.setHandleSuccessSize(permissions.size());
+ jobContext.setHandleTotalSize(permissions.size());
+ jobContext.setContext(context.toString());
+ return jobContext;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/job/DistributableTestJobDistributer.java b/server/services/src/main/java/com/doumee/job/DistributableTestJobDistributer.java
new file mode 100644
index 0000000..03f5a23
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/job/DistributableTestJobDistributer.java
@@ -0,0 +1,27 @@
+package com.doumee.job;
+
+import com.doumee.core.job.BaseDistributer;
+import com.doumee.core.job.JobParam;
+import com.doumee.dao.system.model.SystemPermission;
+import com.doumee.service.system.SystemPermissionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * DistributableTestJob鐨勫垎鍙戝櫒
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Component("distributableTestJobDistributer")
+public class DistributableTestJobDistributer extends BaseDistributer<SystemPermission> {
+
+ @Autowired
+ private SystemPermissionService systemPermissionService;
+
+ @Override
+ public List<SystemPermission> getBusinessData(JobParam jobParam) {
+ return systemPermissionService.findList(new SystemPermission());
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/CategoryService.java b/server/services/src/main/java/com/doumee/service/business/CategoryService.java
new file mode 100644
index 0000000..d5cd0d7
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/CategoryService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.business;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.Category;
+import java.util.List;
+
+/**
+ * 鍒嗙被淇℃伅琛⊿ervice瀹氫箟
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface CategoryService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param category 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(Category category);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param category 瀹炰綋瀵硅薄
+ */
+ void delete(Category category);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param category 瀹炰綋瀵硅薄
+ */
+ void updateById(Category category);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param categorys 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<Category> categorys);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return Category
+ */
+ Category findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param category 瀹炰綋瀵硅薄
+ * @return Category
+ */
+ Category findOne(Category category);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param category 瀹炰綋瀵硅薄
+ * @return List<Category>
+ */
+ List<Category> findList(Category category);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉瀵硅薄
+ * @return PageData<Category>
+ */
+ PageData<Category> findPage(PageWrap<Category> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param category 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(Category category);
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/IdentityInfoService.java b/server/services/src/main/java/com/doumee/service/business/IdentityInfoService.java
new file mode 100644
index 0000000..1e0bbbc
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/IdentityInfoService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.business;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.IdentityInfo;
+import java.util.List;
+
+/**
+ * 浼氬憳韬唤璁よ瘉淇℃伅琛⊿ervice瀹氫箟
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface IdentityInfoService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param identityInfo 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(IdentityInfo identityInfo);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param identityInfo 瀹炰綋瀵硅薄
+ */
+ void delete(IdentityInfo identityInfo);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param identityInfo 瀹炰綋瀵硅薄
+ */
+ void updateById(IdentityInfo identityInfo);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param identityInfos 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<IdentityInfo> identityInfos);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return IdentityInfo
+ */
+ IdentityInfo findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param identityInfo 瀹炰綋瀵硅薄
+ * @return IdentityInfo
+ */
+ IdentityInfo findOne(IdentityInfo identityInfo);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param identityInfo 瀹炰綋瀵硅薄
+ * @return List<IdentityInfo>
+ */
+ List<IdentityInfo> findList(IdentityInfo identityInfo);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉瀵硅薄
+ * @return PageData<IdentityInfo>
+ */
+ PageData<IdentityInfo> findPage(PageWrap<IdentityInfo> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param identityInfo 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(IdentityInfo identityInfo);
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/MemberRevenueService.java b/server/services/src/main/java/com/doumee/service/business/MemberRevenueService.java
new file mode 100644
index 0000000..d6cb0f7
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/MemberRevenueService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.business;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.MemberRevenue;
+import java.util.List;
+
+/**
+ * 浼氬憳鏀舵敮璁板綍Service瀹氫箟
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface MemberRevenueService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param memberRevenue 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(MemberRevenue memberRevenue);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param memberRevenue 瀹炰綋瀵硅薄
+ */
+ void delete(MemberRevenue memberRevenue);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param memberRevenue 瀹炰綋瀵硅薄
+ */
+ void updateById(MemberRevenue memberRevenue);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param memberRevenues 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<MemberRevenue> memberRevenues);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return MemberRevenue
+ */
+ MemberRevenue findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param memberRevenue 瀹炰綋瀵硅薄
+ * @return MemberRevenue
+ */
+ MemberRevenue findOne(MemberRevenue memberRevenue);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param memberRevenue 瀹炰綋瀵硅薄
+ * @return List<MemberRevenue>
+ */
+ List<MemberRevenue> findList(MemberRevenue memberRevenue);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉瀵硅薄
+ * @return PageData<MemberRevenue>
+ */
+ PageData<MemberRevenue> findPage(PageWrap<MemberRevenue> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param memberRevenue 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(MemberRevenue memberRevenue);
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/MemberService.java b/server/services/src/main/java/com/doumee/service/business/MemberService.java
new file mode 100644
index 0000000..c7080a2
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/MemberService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.business;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.Member;
+import java.util.List;
+
+/**
+ * 浼氬憳淇℃伅琛⊿ervice瀹氫箟
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface MemberService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param member 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(Member member);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param member 瀹炰綋瀵硅薄
+ */
+ void delete(Member member);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param member 瀹炰綋瀵硅薄
+ */
+ void updateById(Member member);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param members 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<Member> members);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return Member
+ */
+ Member findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param member 瀹炰綋瀵硅薄
+ * @return Member
+ */
+ Member findOne(Member member);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param member 瀹炰綋瀵硅薄
+ * @return List<Member>
+ */
+ List<Member> findList(Member member);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉瀵硅薄
+ * @return PageData<Member>
+ */
+ PageData<Member> findPage(PageWrap<Member> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param member 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(Member member);
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/MultifileService.java b/server/services/src/main/java/com/doumee/service/business/MultifileService.java
new file mode 100644
index 0000000..764f1eb
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/MultifileService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.business;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.Multifile;
+import java.util.List;
+
+/**
+ * 闄勪欢涓婁紶淇℃伅琛⊿ervice瀹氫箟
+ * @author 姹熻箘韫�
+ * @since 2025/04/02 17:49
+ */
+public interface MultifileService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param multifile 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(Multifile multifile);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param multifile 瀹炰綋瀵硅薄
+ */
+ void delete(Multifile multifile);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param multifile 瀹炰綋瀵硅薄
+ */
+ void updateById(Multifile multifile);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param multifiles 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<Multifile> multifiles);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return Multifile
+ */
+ Multifile findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param multifile 瀹炰綋瀵硅薄
+ * @return Multifile
+ */
+ Multifile findOne(Multifile multifile);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param multifile 瀹炰綋瀵硅薄
+ * @return List<Multifile>
+ */
+ List<Multifile> findList(Multifile multifile);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉瀵硅薄
+ * @return PageData<Multifile>
+ */
+ PageData<Multifile> findPage(PageWrap<Multifile> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param multifile 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(Multifile multifile);
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/OrderLogService.java b/server/services/src/main/java/com/doumee/service/business/OrderLogService.java
new file mode 100644
index 0000000..0cf42ee
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/OrderLogService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.business;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.OrderLog;
+import java.util.List;
+
+/**
+ * 璁㈠崟鎿嶄綔鏃ュ織Service瀹氫箟
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface OrderLogService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param orderLog 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(OrderLog orderLog);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param orderLog 瀹炰綋瀵硅薄
+ */
+ void delete(OrderLog orderLog);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param orderLog 瀹炰綋瀵硅薄
+ */
+ void updateById(OrderLog orderLog);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param orderLogs 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<OrderLog> orderLogs);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return OrderLog
+ */
+ OrderLog findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param orderLog 瀹炰綋瀵硅薄
+ * @return OrderLog
+ */
+ OrderLog findOne(OrderLog orderLog);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param orderLog 瀹炰綋瀵硅薄
+ * @return List<OrderLog>
+ */
+ List<OrderLog> findList(OrderLog orderLog);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉瀵硅薄
+ * @return PageData<OrderLog>
+ */
+ PageData<OrderLog> findPage(PageWrap<OrderLog> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param orderLog 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(OrderLog orderLog);
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/OrdersService.java b/server/services/src/main/java/com/doumee/service/business/OrdersService.java
new file mode 100644
index 0000000..9aac0f9
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/OrdersService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.business;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.Orders;
+import java.util.List;
+
+/**
+ * 璁㈠崟淇℃伅璁板綍Service瀹氫箟
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface OrdersService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param orders 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(Orders orders);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param orders 瀹炰綋瀵硅薄
+ */
+ void delete(Orders orders);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param orders 瀹炰綋瀵硅薄
+ */
+ void updateById(Orders orders);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param orderss 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<Orders> orderss);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return Orders
+ */
+ Orders findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param orders 瀹炰綋瀵硅薄
+ * @return Orders
+ */
+ Orders findOne(Orders orders);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param orders 瀹炰綋瀵硅薄
+ * @return List<Orders>
+ */
+ List<Orders> findList(Orders orders);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉瀵硅薄
+ * @return PageData<Orders>
+ */
+ PageData<Orders> findPage(PageWrap<Orders> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param orders 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(Orders orders);
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/ReceiveWeightService.java b/server/services/src/main/java/com/doumee/service/business/ReceiveWeightService.java
new file mode 100644
index 0000000..6101430
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/ReceiveWeightService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.business;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.ReceiveWeight;
+import java.util.List;
+
+/**
+ * 鎺ュ崟鏉冮噸閰嶇疆琛⊿ervice瀹氫箟
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface ReceiveWeightService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param receiveWeight 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(ReceiveWeight receiveWeight);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param receiveWeight 瀹炰綋瀵硅薄
+ */
+ void delete(ReceiveWeight receiveWeight);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param receiveWeight 瀹炰綋瀵硅薄
+ */
+ void updateById(ReceiveWeight receiveWeight);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param receiveWeights 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<ReceiveWeight> receiveWeights);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return ReceiveWeight
+ */
+ ReceiveWeight findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param receiveWeight 瀹炰綋瀵硅薄
+ * @return ReceiveWeight
+ */
+ ReceiveWeight findOne(ReceiveWeight receiveWeight);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param receiveWeight 瀹炰綋瀵硅薄
+ * @return List<ReceiveWeight>
+ */
+ List<ReceiveWeight> findList(ReceiveWeight receiveWeight);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉瀵硅薄
+ * @return PageData<ReceiveWeight>
+ */
+ PageData<ReceiveWeight> findPage(PageWrap<ReceiveWeight> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param receiveWeight 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(ReceiveWeight receiveWeight);
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/WithdrawalOrdersService.java b/server/services/src/main/java/com/doumee/service/business/WithdrawalOrdersService.java
new file mode 100644
index 0000000..ed032a9
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/WithdrawalOrdersService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.business;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.business.model.WithdrawalOrders;
+import java.util.List;
+
+/**
+ * 鎻愮幇鐢宠璁板綍Service瀹氫箟
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+public interface WithdrawalOrdersService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param withdrawalOrders 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(WithdrawalOrders withdrawalOrders);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param withdrawalOrders 瀹炰綋瀵硅薄
+ */
+ void delete(WithdrawalOrders withdrawalOrders);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param withdrawalOrders 瀹炰綋瀵硅薄
+ */
+ void updateById(WithdrawalOrders withdrawalOrders);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param withdrawalOrderss 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<WithdrawalOrders> withdrawalOrderss);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return WithdrawalOrders
+ */
+ WithdrawalOrders findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param withdrawalOrders 瀹炰綋瀵硅薄
+ * @return WithdrawalOrders
+ */
+ WithdrawalOrders findOne(WithdrawalOrders withdrawalOrders);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param withdrawalOrders 瀹炰綋瀵硅薄
+ * @return List<WithdrawalOrders>
+ */
+ List<WithdrawalOrders> findList(WithdrawalOrders withdrawalOrders);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉瀵硅薄
+ * @return PageData<WithdrawalOrders>
+ */
+ PageData<WithdrawalOrders> findPage(PageWrap<WithdrawalOrders> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param withdrawalOrders 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(WithdrawalOrders withdrawalOrders);
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java
new file mode 100644
index 0000000..478f86a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java
@@ -0,0 +1,148 @@
+package com.doumee.service.business.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.business.CategoryMapper;
+import com.doumee.dao.business.model.Category;
+import com.doumee.service.business.CategoryService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 鍒嗙被淇℃伅琛⊿ervice瀹炵幇
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Service
+public class CategoryServiceImpl implements CategoryService {
+
+ @Autowired
+ private CategoryMapper categoryMapper;
+
+ @Override
+ public Integer create(Category category) {
+ categoryMapper.insert(category);
+ return category.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ categoryMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(Category category) {
+ UpdateWrapper<Category> deleteWrapper = new UpdateWrapper<>(category);
+ categoryMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ categoryMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(Category category) {
+ categoryMapper.updateById(category);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<Category> categorys) {
+ if (CollectionUtils.isEmpty(categorys)) {
+ return;
+ }
+ for (Category category: categorys) {
+ this.updateById(category);
+ }
+ }
+
+ @Override
+ public Category findById(Integer id) {
+ return categoryMapper.selectById(id);
+ }
+
+ @Override
+ public Category findOne(Category category) {
+ QueryWrapper<Category> wrapper = new QueryWrapper<>(category);
+ return categoryMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<Category> findList(Category category) {
+ QueryWrapper<Category> wrapper = new QueryWrapper<>(category);
+ return categoryMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<Category> findPage(PageWrap<Category> pageWrap) {
+ IPage<Category> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
+ Utils.MP.blankToNull(pageWrap.getModel());
+ if (pageWrap.getModel().getId() != null) {
+ queryWrapper.lambda().eq(Category::getId, pageWrap.getModel().getId());
+ }
+ if (pageWrap.getModel().getDeleted() != null) {
+ queryWrapper.lambda().eq(Category::getDeleted, pageWrap.getModel().getDeleted());
+ }
+ if (pageWrap.getModel().getStatus() != null) {
+ queryWrapper.lambda().eq(Category::getStatus, pageWrap.getModel().getStatus());
+ }
+ if (pageWrap.getModel().getCreateUser() != null) {
+ queryWrapper.lambda().eq(Category::getCreateUser, pageWrap.getModel().getCreateUser());
+ }
+ if (pageWrap.getModel().getCreateTime() != null) {
+ queryWrapper.lambda().ge(Category::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()));
+ queryWrapper.lambda().le(Category::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()));
+ }
+ if (pageWrap.getModel().getUpdateUser() != null) {
+ queryWrapper.lambda().eq(Category::getUpdateUser, pageWrap.getModel().getUpdateUser());
+ }
+ if (pageWrap.getModel().getUpdateTime() != null) {
+ queryWrapper.lambda().ge(Category::getUpdateTime, Utils.Date.getStart(pageWrap.getModel().getUpdateTime()));
+ queryWrapper.lambda().le(Category::getUpdateTime, Utils.Date.getEnd(pageWrap.getModel().getUpdateTime()));
+ }
+ if (pageWrap.getModel().getRemark() != null) {
+ queryWrapper.lambda().eq(Category::getRemark, pageWrap.getModel().getRemark());
+ }
+ if (pageWrap.getModel().getName() != null) {
+ queryWrapper.lambda().eq(Category::getName, pageWrap.getModel().getName());
+ }
+ if (pageWrap.getModel().getType() != null) {
+ queryWrapper.lambda().eq(Category::getType, pageWrap.getModel().getType());
+ }
+ if (pageWrap.getModel().getDetail() != null) {
+ queryWrapper.lambda().eq(Category::getDetail, pageWrap.getModel().getDetail());
+ }
+ if (pageWrap.getModel().getIcon() != null) {
+ queryWrapper.lambda().eq(Category::getIcon, pageWrap.getModel().getIcon());
+ }
+ if (pageWrap.getModel().getIsFixed() != null) {
+ queryWrapper.lambda().eq(Category::getIsFixed, pageWrap.getModel().getIsFixed());
+ }
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(categoryMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(Category category) {
+ QueryWrapper<Category> wrapper = new QueryWrapper<>(category);
+ return categoryMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/IdentityInfoServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/IdentityInfoServiceImpl.java
new file mode 100644
index 0000000..c017ad6
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/impl/IdentityInfoServiceImpl.java
@@ -0,0 +1,188 @@
+package com.doumee.service.business.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.business.IdentityInfoMapper;
+import com.doumee.dao.business.model.IdentityInfo;
+import com.doumee.service.business.IdentityInfoService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 浼氬憳韬唤璁よ瘉淇℃伅琛⊿ervice瀹炵幇
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Service
+public class IdentityInfoServiceImpl implements IdentityInfoService {
+
+ @Autowired
+ private IdentityInfoMapper identityInfoMapper;
+
+ @Override
+ public Integer create(IdentityInfo identityInfo) {
+ identityInfoMapper.insert(identityInfo);
+ return identityInfo.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ identityInfoMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(IdentityInfo identityInfo) {
+ UpdateWrapper<IdentityInfo> deleteWrapper = new UpdateWrapper<>(identityInfo);
+ identityInfoMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ identityInfoMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(IdentityInfo identityInfo) {
+ identityInfoMapper.updateById(identityInfo);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<IdentityInfo> identityInfos) {
+ if (CollectionUtils.isEmpty(identityInfos)) {
+ return;
+ }
+ for (IdentityInfo identityInfo: identityInfos) {
+ this.updateById(identityInfo);
+ }
+ }
+
+ @Override
+ public IdentityInfo findById(Integer id) {
+ return identityInfoMapper.selectById(id);
+ }
+
+ @Override
+ public IdentityInfo findOne(IdentityInfo identityInfo) {
+ QueryWrapper<IdentityInfo> wrapper = new QueryWrapper<>(identityInfo);
+ return identityInfoMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<IdentityInfo> findList(IdentityInfo identityInfo) {
+ QueryWrapper<IdentityInfo> wrapper = new QueryWrapper<>(identityInfo);
+ return identityInfoMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<IdentityInfo> findPage(PageWrap<IdentityInfo> pageWrap) {
+ IPage<IdentityInfo> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<IdentityInfo> queryWrapper = new QueryWrapper<>();
+ Utils.MP.blankToNull(pageWrap.getModel());
+ if (pageWrap.getModel().getId() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getId, pageWrap.getModel().getId());
+ }
+ if (pageWrap.getModel().getDeleted() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getDeleted, pageWrap.getModel().getDeleted());
+ }
+ if (pageWrap.getModel().getCreateUser() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getCreateUser, pageWrap.getModel().getCreateUser());
+ }
+ if (pageWrap.getModel().getCreateTime() != null) {
+ queryWrapper.lambda().ge(IdentityInfo::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()));
+ queryWrapper.lambda().le(IdentityInfo::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()));
+ }
+ if (pageWrap.getModel().getUpdateUser() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getUpdateUser, pageWrap.getModel().getUpdateUser());
+ }
+ if (pageWrap.getModel().getUpdateTime() != null) {
+ queryWrapper.lambda().ge(IdentityInfo::getUpdateTime, Utils.Date.getStart(pageWrap.getModel().getUpdateTime()));
+ queryWrapper.lambda().le(IdentityInfo::getUpdateTime, Utils.Date.getEnd(pageWrap.getModel().getUpdateTime()));
+ }
+ if (pageWrap.getModel().getRemark() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getRemark, pageWrap.getModel().getRemark());
+ }
+ if (pageWrap.getModel().getType() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getType, pageWrap.getModel().getType());
+ }
+ if (pageWrap.getModel().getMemberId() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getMemberId, pageWrap.getModel().getMemberId());
+ }
+ if (pageWrap.getModel().getAuthType() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getAuthType, pageWrap.getModel().getAuthType());
+ }
+ if (pageWrap.getModel().getLinkName() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getLinkName, pageWrap.getModel().getLinkName());
+ }
+ if (pageWrap.getModel().getTelephone() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getTelephone, pageWrap.getModel().getTelephone());
+ }
+ if (pageWrap.getModel().getLocation() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getLocation, pageWrap.getModel().getLocation());
+ }
+ if (pageWrap.getModel().getCompanyName() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getCompanyName, pageWrap.getModel().getCompanyName());
+ }
+ if (pageWrap.getModel().getLat() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getLat, pageWrap.getModel().getLat());
+ }
+ if (pageWrap.getModel().getLgt() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getLgt, pageWrap.getModel().getLgt());
+ }
+ if (pageWrap.getModel().getIdentityFront() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getIdentityFront, pageWrap.getModel().getIdentityFront());
+ }
+ if (pageWrap.getModel().getIdentityBack() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getIdentityBack, pageWrap.getModel().getIdentityBack());
+ }
+ if (pageWrap.getModel().getBusinessLicense() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getBusinessLicense, pageWrap.getModel().getBusinessLicense());
+ }
+ if (pageWrap.getModel().getOtherFile() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getOtherFile, pageWrap.getModel().getOtherFile());
+ }
+ if (pageWrap.getModel().getTransportFile() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getTransportFile, pageWrap.getModel().getTransportFile());
+ }
+ if (pageWrap.getModel().getFoodBusinessFile() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getFoodBusinessFile, pageWrap.getModel().getFoodBusinessFile());
+ }
+ if (pageWrap.getModel().getHealthFile() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getHealthFile, pageWrap.getModel().getHealthFile());
+ }
+ if (pageWrap.getModel().getAuditStatus() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getAuditStatus, pageWrap.getModel().getAuditStatus());
+ }
+ if (pageWrap.getModel().getAuditTime() != null) {
+ queryWrapper.lambda().ge(IdentityInfo::getAuditTime, Utils.Date.getStart(pageWrap.getModel().getAuditTime()));
+ queryWrapper.lambda().le(IdentityInfo::getAuditTime, Utils.Date.getEnd(pageWrap.getModel().getAuditTime()));
+ }
+ if (pageWrap.getModel().getAuditRemark() != null) {
+ queryWrapper.lambda().eq(IdentityInfo::getAuditRemark, pageWrap.getModel().getAuditRemark());
+ }
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(identityInfoMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(IdentityInfo identityInfo) {
+ QueryWrapper<IdentityInfo> wrapper = new QueryWrapper<>(identityInfo);
+ return identityInfoMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/MemberRevenueServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/MemberRevenueServiceImpl.java
new file mode 100644
index 0000000..adc8a7d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/impl/MemberRevenueServiceImpl.java
@@ -0,0 +1,157 @@
+package com.doumee.service.business.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.business.MemberRevenueMapper;
+import com.doumee.dao.business.model.MemberRevenue;
+import com.doumee.service.business.MemberRevenueService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 浼氬憳鏀舵敮璁板綍Service瀹炵幇
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Service
+public class MemberRevenueServiceImpl implements MemberRevenueService {
+
+ @Autowired
+ private MemberRevenueMapper memberRevenueMapper;
+
+ @Override
+ public Integer create(MemberRevenue memberRevenue) {
+ memberRevenueMapper.insert(memberRevenue);
+ return memberRevenue.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ memberRevenueMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(MemberRevenue memberRevenue) {
+ UpdateWrapper<MemberRevenue> deleteWrapper = new UpdateWrapper<>(memberRevenue);
+ memberRevenueMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ memberRevenueMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(MemberRevenue memberRevenue) {
+ memberRevenueMapper.updateById(memberRevenue);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<MemberRevenue> memberRevenues) {
+ if (CollectionUtils.isEmpty(memberRevenues)) {
+ return;
+ }
+ for (MemberRevenue memberRevenue: memberRevenues) {
+ this.updateById(memberRevenue);
+ }
+ }
+
+ @Override
+ public MemberRevenue findById(Integer id) {
+ return memberRevenueMapper.selectById(id);
+ }
+
+ @Override
+ public MemberRevenue findOne(MemberRevenue memberRevenue) {
+ QueryWrapper<MemberRevenue> wrapper = new QueryWrapper<>(memberRevenue);
+ return memberRevenueMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<MemberRevenue> findList(MemberRevenue memberRevenue) {
+ QueryWrapper<MemberRevenue> wrapper = new QueryWrapper<>(memberRevenue);
+ return memberRevenueMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<MemberRevenue> findPage(PageWrap<MemberRevenue> pageWrap) {
+ IPage<MemberRevenue> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<MemberRevenue> queryWrapper = new QueryWrapper<>();
+ Utils.MP.blankToNull(pageWrap.getModel());
+ if (pageWrap.getModel().getId() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getId, pageWrap.getModel().getId());
+ }
+ if (pageWrap.getModel().getDeleted() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getDeleted, pageWrap.getModel().getDeleted());
+ }
+ if (pageWrap.getModel().getCreateUser() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getCreateUser, pageWrap.getModel().getCreateUser());
+ }
+ if (pageWrap.getModel().getCreateTime() != null) {
+ queryWrapper.lambda().ge(MemberRevenue::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()));
+ queryWrapper.lambda().le(MemberRevenue::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()));
+ }
+ if (pageWrap.getModel().getUpdateUser() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getUpdateUser, pageWrap.getModel().getUpdateUser());
+ }
+ if (pageWrap.getModel().getUpdateTime() != null) {
+ queryWrapper.lambda().ge(MemberRevenue::getUpdateTime, Utils.Date.getStart(pageWrap.getModel().getUpdateTime()));
+ queryWrapper.lambda().le(MemberRevenue::getUpdateTime, Utils.Date.getEnd(pageWrap.getModel().getUpdateTime()));
+ }
+ if (pageWrap.getModel().getRemark() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getRemark, pageWrap.getModel().getRemark());
+ }
+ if (pageWrap.getModel().getMemberId() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getMemberId, pageWrap.getModel().getMemberId());
+ }
+ if (pageWrap.getModel().getType() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getType, pageWrap.getModel().getType());
+ }
+ if (pageWrap.getModel().getOptType() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getOptType, pageWrap.getModel().getOptType());
+ }
+ if (pageWrap.getModel().getAmount() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getAmount, pageWrap.getModel().getAmount());
+ }
+ if (pageWrap.getModel().getBeforeAmount() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getBeforeAmount, pageWrap.getModel().getBeforeAmount());
+ }
+ if (pageWrap.getModel().getAfterAmount() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getAfterAmount, pageWrap.getModel().getAfterAmount());
+ }
+ if (pageWrap.getModel().getObjId() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getObjId, pageWrap.getModel().getObjId());
+ }
+ if (pageWrap.getModel().getObjType() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getObjType, pageWrap.getModel().getObjType());
+ }
+ if (pageWrap.getModel().getStatus() != null) {
+ queryWrapper.lambda().eq(MemberRevenue::getStatus, pageWrap.getModel().getStatus());
+ }
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(memberRevenueMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(MemberRevenue memberRevenue) {
+ QueryWrapper<MemberRevenue> wrapper = new QueryWrapper<>(memberRevenue);
+ return memberRevenueMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
new file mode 100644
index 0000000..8defece
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
@@ -0,0 +1,200 @@
+package com.doumee.service.business.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.business.MemberMapper;
+import com.doumee.dao.business.model.Member;
+import com.doumee.service.business.MemberService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 浼氬憳淇℃伅琛⊿ervice瀹炵幇
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Service
+public class MemberServiceImpl implements MemberService {
+
+ @Autowired
+ private MemberMapper memberMapper;
+
+ @Override
+ public Integer create(Member member) {
+ memberMapper.insert(member);
+ return member.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ memberMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(Member member) {
+ UpdateWrapper<Member> deleteWrapper = new UpdateWrapper<>(member);
+ memberMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ memberMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(Member member) {
+ memberMapper.updateById(member);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<Member> members) {
+ if (CollectionUtils.isEmpty(members)) {
+ return;
+ }
+ for (Member member: members) {
+ this.updateById(member);
+ }
+ }
+
+ @Override
+ public Member findById(Integer id) {
+ return memberMapper.selectById(id);
+ }
+
+ @Override
+ public Member findOne(Member member) {
+ QueryWrapper<Member> wrapper = new QueryWrapper<>(member);
+ return memberMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<Member> findList(Member member) {
+ QueryWrapper<Member> wrapper = new QueryWrapper<>(member);
+ return memberMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<Member> findPage(PageWrap<Member> pageWrap) {
+ IPage<Member> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
+ Utils.MP.blankToNull(pageWrap.getModel());
+ if (pageWrap.getModel().getId() != null) {
+ queryWrapper.lambda().eq(Member::getId, pageWrap.getModel().getId());
+ }
+ if (pageWrap.getModel().getDeleted() != null) {
+ queryWrapper.lambda().eq(Member::getDeleted, pageWrap.getModel().getDeleted());
+ }
+ if (pageWrap.getModel().getCreateUser() != null) {
+ queryWrapper.lambda().eq(Member::getCreateUser, pageWrap.getModel().getCreateUser());
+ }
+ if (pageWrap.getModel().getCreateTime() != null) {
+ queryWrapper.lambda().ge(Member::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()));
+ queryWrapper.lambda().le(Member::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()));
+ }
+ if (pageWrap.getModel().getUpdateUser() != null) {
+ queryWrapper.lambda().eq(Member::getUpdateUser, pageWrap.getModel().getUpdateUser());
+ }
+ if (pageWrap.getModel().getUpdateTime() != null) {
+ queryWrapper.lambda().ge(Member::getUpdateTime, Utils.Date.getStart(pageWrap.getModel().getUpdateTime()));
+ queryWrapper.lambda().le(Member::getUpdateTime, Utils.Date.getEnd(pageWrap.getModel().getUpdateTime()));
+ }
+ if (pageWrap.getModel().getRemark() != null) {
+ queryWrapper.lambda().eq(Member::getRemark, pageWrap.getModel().getRemark());
+ }
+ if (pageWrap.getModel().getCoverImage() != null) {
+ queryWrapper.lambda().eq(Member::getCoverImage, pageWrap.getModel().getCoverImage());
+ }
+ if (pageWrap.getModel().getOpenid() != null) {
+ queryWrapper.lambda().eq(Member::getOpenid, pageWrap.getModel().getOpenid());
+ }
+ if (pageWrap.getModel().getNickName() != null) {
+ queryWrapper.lambda().eq(Member::getNickName, pageWrap.getModel().getNickName());
+ }
+ if (pageWrap.getModel().getTelephone() != null) {
+ queryWrapper.lambda().eq(Member::getTelephone, pageWrap.getModel().getTelephone());
+ }
+ if (pageWrap.getModel().getName() != null) {
+ queryWrapper.lambda().eq(Member::getName, pageWrap.getModel().getName());
+ }
+ if (pageWrap.getModel().getWorkerIdentity() != null) {
+ queryWrapper.lambda().eq(Member::getWorkerIdentity, pageWrap.getModel().getWorkerIdentity());
+ }
+ if (pageWrap.getModel().getDriverIdentity() != null) {
+ queryWrapper.lambda().eq(Member::getDriverIdentity, pageWrap.getModel().getDriverIdentity());
+ }
+ if (pageWrap.getModel().getChefIdentity() != null) {
+ queryWrapper.lambda().eq(Member::getChefIdentity, pageWrap.getModel().getChefIdentity());
+ }
+ if (pageWrap.getModel().getAmount() != null) {
+ queryWrapper.lambda().eq(Member::getAmount, pageWrap.getModel().getAmount());
+ }
+ if (pageWrap.getModel().getTotalAmount() != null) {
+ queryWrapper.lambda().eq(Member::getTotalAmount, pageWrap.getModel().getTotalAmount());
+ }
+ if (pageWrap.getModel().getStatus() != null) {
+ queryWrapper.lambda().eq(Member::getStatus, pageWrap.getModel().getStatus());
+ }
+ if (pageWrap.getModel().getLoginTime() != null) {
+ queryWrapper.lambda().ge(Member::getLoginTime, Utils.Date.getStart(pageWrap.getModel().getLoginTime()));
+ queryWrapper.lambda().le(Member::getLoginTime, Utils.Date.getEnd(pageWrap.getModel().getLoginTime()));
+ }
+ if (pageWrap.getModel().getLoginTimes() != null) {
+ queryWrapper.lambda().eq(Member::getLoginTimes, pageWrap.getModel().getLoginTimes());
+ }
+ if (pageWrap.getModel().getReciveNum() != null) {
+ queryWrapper.lambda().eq(Member::getReciveNum, pageWrap.getModel().getReciveNum());
+ }
+ if (pageWrap.getModel().getPublishNum() != null) {
+ queryWrapper.lambda().eq(Member::getPublishNum, pageWrap.getModel().getPublishNum());
+ }
+ if (pageWrap.getModel().getScore() != null) {
+ queryWrapper.lambda().eq(Member::getScore, pageWrap.getModel().getScore());
+ }
+ if (pageWrap.getModel().getLocaltion() != null) {
+ queryWrapper.lambda().eq(Member::getLocaltion, pageWrap.getModel().getLocaltion());
+ }
+ if (pageWrap.getModel().getLat() != null) {
+ queryWrapper.lambda().eq(Member::getLat, pageWrap.getModel().getLat());
+ }
+ if (pageWrap.getModel().getLgt() != null) {
+ queryWrapper.lambda().eq(Member::getLgt, pageWrap.getModel().getLgt());
+ }
+ if (pageWrap.getModel().getProvince() != null) {
+ queryWrapper.lambda().eq(Member::getProvince, pageWrap.getModel().getProvince());
+ }
+ if (pageWrap.getModel().getCity() != null) {
+ queryWrapper.lambda().eq(Member::getCity, pageWrap.getModel().getCity());
+ }
+ if (pageWrap.getModel().getArea() != null) {
+ queryWrapper.lambda().eq(Member::getArea, pageWrap.getModel().getArea());
+ }
+ if (pageWrap.getModel().getAutoReciveStatus() != null) {
+ queryWrapper.lambda().eq(Member::getAutoReciveStatus, pageWrap.getModel().getAutoReciveStatus());
+ }
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(memberMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(Member member) {
+ QueryWrapper<Member> wrapper = new QueryWrapper<>(member);
+ return memberMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/MultifileServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/MultifileServiceImpl.java
new file mode 100644
index 0000000..5f0d231
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/impl/MultifileServiceImpl.java
@@ -0,0 +1,125 @@
+package com.doumee.service.business.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.business.MultifileMapper;
+import com.doumee.dao.business.model.Multifile;
+import com.doumee.service.business.MultifileService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 闄勪欢涓婁紶淇℃伅琛⊿ervice瀹炵幇
+ * @author 姹熻箘韫�
+ * @since 2025/04/02 17:49
+ */
+@Service
+public class MultifileServiceImpl implements MultifileService {
+
+ @Autowired
+ private MultifileMapper multifileMapper;
+
+ @Override
+ public Integer create(Multifile multifile) {
+ multifileMapper.insert(multifile);
+ return multifile.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ multifileMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(Multifile multifile) {
+ UpdateWrapper<Multifile> deleteWrapper = new UpdateWrapper<>(multifile);
+ multifileMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ multifileMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(Multifile multifile) {
+ multifileMapper.updateById(multifile);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<Multifile> multifiles) {
+ if (CollectionUtils.isEmpty(multifiles)) {
+ return;
+ }
+ for (Multifile multifile: multifiles) {
+ this.updateById(multifile);
+ }
+ }
+
+ @Override
+ public Multifile findById(Integer id) {
+ return multifileMapper.selectById(id);
+ }
+
+ @Override
+ public Multifile findOne(Multifile multifile) {
+ QueryWrapper<Multifile> wrapper = new QueryWrapper<>(multifile);
+ return multifileMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<Multifile> findList(Multifile multifile) {
+ QueryWrapper<Multifile> wrapper = new QueryWrapper<>(multifile);
+ return multifileMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<Multifile> findPage(PageWrap<Multifile> pageWrap) {
+ IPage<Multifile> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<Multifile> queryWrapper = new QueryWrapper<>();
+ Utils.MP.blankToNull(pageWrap.getModel());
+ queryWrapper.lambda()
+ .eq(pageWrap.getModel().getId() != null, Multifile::getId, pageWrap.getModel().getId())
+ .eq(pageWrap.getModel().getCreator() != null, Multifile::getCreator, pageWrap.getModel().getCreator())
+ .ge(pageWrap.getModel().getCreateDate() != null, Multifile::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()))
+ .le(pageWrap.getModel().getCreateDate() != null, Multifile::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()))
+ .eq(pageWrap.getModel().getEditor() != null, Multifile::getEditor, pageWrap.getModel().getEditor())
+ .ge(pageWrap.getModel().getEditDate() != null, Multifile::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()))
+ .le(pageWrap.getModel().getEditDate() != null, Multifile::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()))
+ .eq(pageWrap.getModel().getIsdeleted() != null, Multifile::getIsdeleted, pageWrap.getModel().getIsdeleted())
+ .eq(pageWrap.getModel().getName() != null, Multifile::getName, pageWrap.getModel().getName())
+ .eq(pageWrap.getModel().getInfo() != null, Multifile::getInfo, pageWrap.getModel().getInfo())
+ .eq(pageWrap.getModel().getObjId() != null, Multifile::getObjId, pageWrap.getModel().getObjId())
+ .eq(pageWrap.getModel().getType() != null, Multifile::getType, pageWrap.getModel().getType())
+ .eq(pageWrap.getModel().getObjType() != null, Multifile::getObjType, pageWrap.getModel().getObjType())
+ .eq(pageWrap.getModel().getFileurl() != null, Multifile::getFileurl, pageWrap.getModel().getFileurl())
+ .eq(pageWrap.getModel().getSortnum() != null, Multifile::getSortnum, pageWrap.getModel().getSortnum())
+ .eq(pageWrap.getModel().getCompanyId() != null, Multifile::getCompanyId, pageWrap.getModel().getCompanyId())
+ ;
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(multifileMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(Multifile multifile) {
+ QueryWrapper<Multifile> wrapper = new QueryWrapper<>(multifile);
+ return multifileMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/OrderLogServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/OrderLogServiceImpl.java
new file mode 100644
index 0000000..945b237
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/impl/OrderLogServiceImpl.java
@@ -0,0 +1,154 @@
+package com.doumee.service.business.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.business.OrderLogMapper;
+import com.doumee.dao.business.model.OrderLog;
+import com.doumee.service.business.OrderLogService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 璁㈠崟鎿嶄綔鏃ュ織Service瀹炵幇
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Service
+public class OrderLogServiceImpl implements OrderLogService {
+
+ @Autowired
+ private OrderLogMapper orderLogMapper;
+
+ @Override
+ public Integer create(OrderLog orderLog) {
+ orderLogMapper.insert(orderLog);
+ return orderLog.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ orderLogMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(OrderLog orderLog) {
+ UpdateWrapper<OrderLog> deleteWrapper = new UpdateWrapper<>(orderLog);
+ orderLogMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ orderLogMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(OrderLog orderLog) {
+ orderLogMapper.updateById(orderLog);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<OrderLog> orderLogs) {
+ if (CollectionUtils.isEmpty(orderLogs)) {
+ return;
+ }
+ for (OrderLog orderLog: orderLogs) {
+ this.updateById(orderLog);
+ }
+ }
+
+ @Override
+ public OrderLog findById(Integer id) {
+ return orderLogMapper.selectById(id);
+ }
+
+ @Override
+ public OrderLog findOne(OrderLog orderLog) {
+ QueryWrapper<OrderLog> wrapper = new QueryWrapper<>(orderLog);
+ return orderLogMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<OrderLog> findList(OrderLog orderLog) {
+ QueryWrapper<OrderLog> wrapper = new QueryWrapper<>(orderLog);
+ return orderLogMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<OrderLog> findPage(PageWrap<OrderLog> pageWrap) {
+ IPage<OrderLog> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<OrderLog> queryWrapper = new QueryWrapper<>();
+ Utils.MP.blankToNull(pageWrap.getModel());
+ if (pageWrap.getModel().getId() != null) {
+ queryWrapper.lambda().eq(OrderLog::getId, pageWrap.getModel().getId());
+ }
+ if (pageWrap.getModel().getDeleted() != null) {
+ queryWrapper.lambda().eq(OrderLog::getDeleted, pageWrap.getModel().getDeleted());
+ }
+ if (pageWrap.getModel().getCreateUser() != null) {
+ queryWrapper.lambda().eq(OrderLog::getCreateUser, pageWrap.getModel().getCreateUser());
+ }
+ if (pageWrap.getModel().getCreateTime() != null) {
+ queryWrapper.lambda().ge(OrderLog::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()));
+ queryWrapper.lambda().le(OrderLog::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()));
+ }
+ if (pageWrap.getModel().getUpdateUser() != null) {
+ queryWrapper.lambda().eq(OrderLog::getUpdateUser, pageWrap.getModel().getUpdateUser());
+ }
+ if (pageWrap.getModel().getUpdateTime() != null) {
+ queryWrapper.lambda().ge(OrderLog::getUpdateTime, Utils.Date.getStart(pageWrap.getModel().getUpdateTime()));
+ queryWrapper.lambda().le(OrderLog::getUpdateTime, Utils.Date.getEnd(pageWrap.getModel().getUpdateTime()));
+ }
+ if (pageWrap.getModel().getRemark() != null) {
+ queryWrapper.lambda().eq(OrderLog::getRemark, pageWrap.getModel().getRemark());
+ }
+ if (pageWrap.getModel().getOrderId() != null) {
+ queryWrapper.lambda().eq(OrderLog::getOrderId, pageWrap.getModel().getOrderId());
+ }
+ if (pageWrap.getModel().getTitle() != null) {
+ queryWrapper.lambda().eq(OrderLog::getTitle, pageWrap.getModel().getTitle());
+ }
+ if (pageWrap.getModel().getLogInfo() != null) {
+ queryWrapper.lambda().eq(OrderLog::getLogInfo, pageWrap.getModel().getLogInfo());
+ }
+ if (pageWrap.getModel().getObjType() != null) {
+ queryWrapper.lambda().eq(OrderLog::getObjType, pageWrap.getModel().getObjType());
+ }
+ if (pageWrap.getModel().getMemberId() != null) {
+ queryWrapper.lambda().eq(OrderLog::getMemberId, pageWrap.getModel().getMemberId());
+ }
+ if (pageWrap.getModel().getBeforeInfo() != null) {
+ queryWrapper.lambda().eq(OrderLog::getBeforeInfo, pageWrap.getModel().getBeforeInfo());
+ }
+ if (pageWrap.getModel().getAfterInfo() != null) {
+ queryWrapper.lambda().eq(OrderLog::getAfterInfo, pageWrap.getModel().getAfterInfo());
+ }
+ if (pageWrap.getModel().getOrderStatus() != null) {
+ queryWrapper.lambda().eq(OrderLog::getOrderStatus, pageWrap.getModel().getOrderStatus());
+ }
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(orderLogMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(OrderLog orderLog) {
+ QueryWrapper<OrderLog> wrapper = new QueryWrapper<>(orderLog);
+ return orderLogMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java
new file mode 100644
index 0000000..36a4040
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/impl/OrdersServiceImpl.java
@@ -0,0 +1,275 @@
+package com.doumee.service.business.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.business.OrdersMapper;
+import com.doumee.dao.business.model.Orders;
+import com.doumee.service.business.OrdersService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 璁㈠崟淇℃伅璁板綍Service瀹炵幇
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Service
+public class OrdersServiceImpl implements OrdersService {
+
+ @Autowired
+ private OrdersMapper ordersMapper;
+
+ @Override
+ public Integer create(Orders orders) {
+ ordersMapper.insert(orders);
+ return orders.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ ordersMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(Orders orders) {
+ UpdateWrapper<Orders> deleteWrapper = new UpdateWrapper<>(orders);
+ ordersMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ ordersMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(Orders orders) {
+ ordersMapper.updateById(orders);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<Orders> orderss) {
+ if (CollectionUtils.isEmpty(orderss)) {
+ return;
+ }
+ for (Orders orders: orderss) {
+ this.updateById(orders);
+ }
+ }
+
+ @Override
+ public Orders findById(Integer id) {
+ return ordersMapper.selectById(id);
+ }
+
+ @Override
+ public Orders findOne(Orders orders) {
+ QueryWrapper<Orders> wrapper = new QueryWrapper<>(orders);
+ return ordersMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<Orders> findList(Orders orders) {
+ QueryWrapper<Orders> wrapper = new QueryWrapper<>(orders);
+ return ordersMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<Orders> findPage(PageWrap<Orders> pageWrap) {
+ IPage<Orders> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
+ Utils.MP.blankToNull(pageWrap.getModel());
+ if (pageWrap.getModel().getId() != null) {
+ queryWrapper.lambda().eq(Orders::getId, pageWrap.getModel().getId());
+ }
+ if (pageWrap.getModel().getDeleted() != null) {
+ queryWrapper.lambda().eq(Orders::getDeleted, pageWrap.getModel().getDeleted());
+ }
+ if (pageWrap.getModel().getCreateUser() != null) {
+ queryWrapper.lambda().eq(Orders::getCreateUser, pageWrap.getModel().getCreateUser());
+ }
+ if (pageWrap.getModel().getCreateTime() != null) {
+ queryWrapper.lambda().ge(Orders::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()));
+ queryWrapper.lambda().le(Orders::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()));
+ }
+ if (pageWrap.getModel().getUpdateUser() != null) {
+ queryWrapper.lambda().eq(Orders::getUpdateUser, pageWrap.getModel().getUpdateUser());
+ }
+ if (pageWrap.getModel().getUpdateTime() != null) {
+ queryWrapper.lambda().ge(Orders::getUpdateTime, Utils.Date.getStart(pageWrap.getModel().getUpdateTime()));
+ queryWrapper.lambda().le(Orders::getUpdateTime, Utils.Date.getEnd(pageWrap.getModel().getUpdateTime()));
+ }
+ if (pageWrap.getModel().getRemark() != null) {
+ queryWrapper.lambda().eq(Orders::getRemark, pageWrap.getModel().getRemark());
+ }
+ if (pageWrap.getModel().getReleaseMemberId() != null) {
+ queryWrapper.lambda().eq(Orders::getReleaseMemberId, pageWrap.getModel().getReleaseMemberId());
+ }
+ if (pageWrap.getModel().getType() != null) {
+ queryWrapper.lambda().eq(Orders::getType, pageWrap.getModel().getType());
+ }
+ if (pageWrap.getModel().getStartDate() != null) {
+ queryWrapper.lambda().ge(Orders::getStartDate, Utils.Date.getStart(pageWrap.getModel().getStartDate()));
+ queryWrapper.lambda().le(Orders::getStartDate, Utils.Date.getEnd(pageWrap.getModel().getStartDate()));
+ }
+ if (pageWrap.getModel().getEndDate() != null) {
+ queryWrapper.lambda().ge(Orders::getEndDate, Utils.Date.getStart(pageWrap.getModel().getEndDate()));
+ queryWrapper.lambda().le(Orders::getEndDate, Utils.Date.getEnd(pageWrap.getModel().getEndDate()));
+ }
+ if (pageWrap.getModel().getLocation() != null) {
+ queryWrapper.lambda().eq(Orders::getLocation, pageWrap.getModel().getLocation());
+ }
+ if (pageWrap.getModel().getLocationRemark() != null) {
+ queryWrapper.lambda().eq(Orders::getLocationRemark, pageWrap.getModel().getLocationRemark());
+ }
+ if (pageWrap.getModel().getLat() != null) {
+ queryWrapper.lambda().eq(Orders::getLat, pageWrap.getModel().getLat());
+ }
+ if (pageWrap.getModel().getProvince() != null) {
+ queryWrapper.lambda().eq(Orders::getProvince, pageWrap.getModel().getProvince());
+ }
+ if (pageWrap.getModel().getCity() != null) {
+ queryWrapper.lambda().eq(Orders::getCity, pageWrap.getModel().getCity());
+ }
+ if (pageWrap.getModel().getArea() != null) {
+ queryWrapper.lambda().eq(Orders::getArea, pageWrap.getModel().getArea());
+ }
+ if (pageWrap.getModel().getLgt() != null) {
+ queryWrapper.lambda().eq(Orders::getLgt, pageWrap.getModel().getLgt());
+ }
+ if (pageWrap.getModel().getCategoryId() != null) {
+ queryWrapper.lambda().eq(Orders::getCategoryId, pageWrap.getModel().getCategoryId());
+ }
+ if (pageWrap.getModel().getWorkType() != null) {
+ queryWrapper.lambda().eq(Orders::getWorkType, pageWrap.getModel().getWorkType());
+ }
+ if (pageWrap.getModel().getPriceNum1() != null) {
+ queryWrapper.lambda().eq(Orders::getPriceNum1, pageWrap.getModel().getPriceNum1());
+ }
+ if (pageWrap.getModel().getPriceNum2() != null) {
+ queryWrapper.lambda().eq(Orders::getPriceNum2, pageWrap.getModel().getPriceNum2());
+ }
+ if (pageWrap.getModel().getSupplement() != null) {
+ queryWrapper.lambda().eq(Orders::getSupplement, pageWrap.getModel().getSupplement());
+ }
+ if (pageWrap.getModel().getPrice() != null) {
+ queryWrapper.lambda().eq(Orders::getPrice, pageWrap.getModel().getPrice());
+ }
+ if (pageWrap.getModel().getEstimatedAccount() != null) {
+ queryWrapper.lambda().eq(Orders::getEstimatedAccount, pageWrap.getModel().getEstimatedAccount());
+ }
+ if (pageWrap.getModel().getPayAccount() != null) {
+ queryWrapper.lambda().eq(Orders::getPayAccount, pageWrap.getModel().getPayAccount());
+ }
+ if (pageWrap.getModel().getReviceAccount() != null) {
+ queryWrapper.lambda().eq(Orders::getReviceAccount, pageWrap.getModel().getReviceAccount());
+ }
+ if (pageWrap.getModel().getPriceRemark() != null) {
+ queryWrapper.lambda().eq(Orders::getPriceRemark, pageWrap.getModel().getPriceRemark());
+ }
+ if (pageWrap.getModel().getCarType() != null) {
+ queryWrapper.lambda().eq(Orders::getCarType, pageWrap.getModel().getCarType());
+ }
+ if (pageWrap.getModel().getTransportTypeId() != null) {
+ queryWrapper.lambda().eq(Orders::getTransportTypeId, pageWrap.getModel().getTransportTypeId());
+ }
+ if (pageWrap.getModel().getTransportNum() != null) {
+ queryWrapper.lambda().eq(Orders::getTransportNum, pageWrap.getModel().getTransportNum());
+ }
+ if (pageWrap.getModel().getTransportUnit() != null) {
+ queryWrapper.lambda().eq(Orders::getTransportUnit, pageWrap.getModel().getTransportUnit());
+ }
+ if (pageWrap.getModel().getLocationEnd() != null) {
+ queryWrapper.lambda().eq(Orders::getLocationEnd, pageWrap.getModel().getLocationEnd());
+ }
+ if (pageWrap.getModel().getLatEnd() != null) {
+ queryWrapper.lambda().eq(Orders::getLatEnd, pageWrap.getModel().getLatEnd());
+ }
+ if (pageWrap.getModel().getLgtEnd() != null) {
+ queryWrapper.lambda().eq(Orders::getLgtEnd, pageWrap.getModel().getLgtEnd());
+ }
+ if (pageWrap.getModel().getWayInfo() != null) {
+ queryWrapper.lambda().eq(Orders::getWayInfo, pageWrap.getModel().getWayInfo());
+ }
+ if (pageWrap.getModel().getCode() != null) {
+ queryWrapper.lambda().eq(Orders::getCode, pageWrap.getModel().getCode());
+ }
+ if (pageWrap.getModel().getStatus() != null) {
+ queryWrapper.lambda().eq(Orders::getStatus, pageWrap.getModel().getStatus());
+ }
+ if (pageWrap.getModel().getAcceptTime() != null) {
+ queryWrapper.lambda().ge(Orders::getAcceptTime, Utils.Date.getStart(pageWrap.getModel().getAcceptTime()));
+ queryWrapper.lambda().le(Orders::getAcceptTime, Utils.Date.getEnd(pageWrap.getModel().getAcceptTime()));
+ }
+ if (pageWrap.getModel().getAcceptMemberId() != null) {
+ queryWrapper.lambda().eq(Orders::getAcceptMemberId, pageWrap.getModel().getAcceptMemberId());
+ }
+ if (pageWrap.getModel().getAcceptType() != null) {
+ queryWrapper.lambda().eq(Orders::getAcceptType, pageWrap.getModel().getAcceptType());
+ }
+ if (pageWrap.getModel().getWorkStartTime() != null) {
+ queryWrapper.lambda().ge(Orders::getWorkStartTime, Utils.Date.getStart(pageWrap.getModel().getWorkStartTime()));
+ queryWrapper.lambda().le(Orders::getWorkStartTime, Utils.Date.getEnd(pageWrap.getModel().getWorkStartTime()));
+ }
+ if (pageWrap.getModel().getFinishTime() != null) {
+ queryWrapper.lambda().ge(Orders::getFinishTime, Utils.Date.getStart(pageWrap.getModel().getFinishTime()));
+ queryWrapper.lambda().le(Orders::getFinishTime, Utils.Date.getEnd(pageWrap.getModel().getFinishTime()));
+ }
+ if (pageWrap.getModel().getPlatformRata() != null) {
+ queryWrapper.lambda().eq(Orders::getPlatformRata, pageWrap.getModel().getPlatformRata());
+ }
+ if (pageWrap.getModel().getWxExternalNo() != null) {
+ queryWrapper.lambda().eq(Orders::getWxExternalNo, pageWrap.getModel().getWxExternalNo());
+ }
+ if (pageWrap.getModel().getCommentStatus() != null) {
+ queryWrapper.lambda().eq(Orders::getCommentStatus, pageWrap.getModel().getCommentStatus());
+ }
+ if (pageWrap.getModel().getCommentInfo() != null) {
+ queryWrapper.lambda().eq(Orders::getCommentInfo, pageWrap.getModel().getCommentInfo());
+ }
+ if (pageWrap.getModel().getCommentLevel() != null) {
+ queryWrapper.lambda().eq(Orders::getCommentLevel, pageWrap.getModel().getCommentLevel());
+ }
+ if (pageWrap.getModel().getCommentTime() != null) {
+ queryWrapper.lambda().ge(Orders::getCommentTime, Utils.Date.getStart(pageWrap.getModel().getCommentTime()));
+ queryWrapper.lambda().le(Orders::getCommentTime, Utils.Date.getEnd(pageWrap.getModel().getCommentTime()));
+ }
+ if (pageWrap.getModel().getCommentType() != null) {
+ queryWrapper.lambda().eq(Orders::getCommentType, pageWrap.getModel().getCommentType());
+ }
+ if (pageWrap.getModel().getCancelTime() != null) {
+ queryWrapper.lambda().ge(Orders::getCancelTime, Utils.Date.getStart(pageWrap.getModel().getCancelTime()));
+ queryWrapper.lambda().le(Orders::getCancelTime, Utils.Date.getEnd(pageWrap.getModel().getCancelTime()));
+ }
+ if (pageWrap.getModel().getIsUpdate() != null) {
+ queryWrapper.lambda().eq(Orders::getIsUpdate, pageWrap.getModel().getIsUpdate());
+ }
+ if (pageWrap.getModel().getBlackRecive() != null) {
+ queryWrapper.lambda().eq(Orders::getBlackRecive, pageWrap.getModel().getBlackRecive());
+ }
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(ordersMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(Orders orders) {
+ QueryWrapper<Orders> wrapper = new QueryWrapper<>(orders);
+ return ordersMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/ReceiveWeightServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/ReceiveWeightServiceImpl.java
new file mode 100644
index 0000000..14fd298
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/impl/ReceiveWeightServiceImpl.java
@@ -0,0 +1,148 @@
+package com.doumee.service.business.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.business.ReceiveWeightMapper;
+import com.doumee.dao.business.model.ReceiveWeight;
+import com.doumee.service.business.ReceiveWeightService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 鎺ュ崟鏉冮噸閰嶇疆琛⊿ervice瀹炵幇
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Service
+public class ReceiveWeightServiceImpl implements ReceiveWeightService {
+
+ @Autowired
+ private ReceiveWeightMapper receiveWeightMapper;
+
+ @Override
+ public Integer create(ReceiveWeight receiveWeight) {
+ receiveWeightMapper.insert(receiveWeight);
+ return receiveWeight.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ receiveWeightMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(ReceiveWeight receiveWeight) {
+ UpdateWrapper<ReceiveWeight> deleteWrapper = new UpdateWrapper<>(receiveWeight);
+ receiveWeightMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ receiveWeightMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(ReceiveWeight receiveWeight) {
+ receiveWeightMapper.updateById(receiveWeight);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<ReceiveWeight> receiveWeights) {
+ if (CollectionUtils.isEmpty(receiveWeights)) {
+ return;
+ }
+ for (ReceiveWeight receiveWeight: receiveWeights) {
+ this.updateById(receiveWeight);
+ }
+ }
+
+ @Override
+ public ReceiveWeight findById(Integer id) {
+ return receiveWeightMapper.selectById(id);
+ }
+
+ @Override
+ public ReceiveWeight findOne(ReceiveWeight receiveWeight) {
+ QueryWrapper<ReceiveWeight> wrapper = new QueryWrapper<>(receiveWeight);
+ return receiveWeightMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<ReceiveWeight> findList(ReceiveWeight receiveWeight) {
+ QueryWrapper<ReceiveWeight> wrapper = new QueryWrapper<>(receiveWeight);
+ return receiveWeightMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<ReceiveWeight> findPage(PageWrap<ReceiveWeight> pageWrap) {
+ IPage<ReceiveWeight> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<ReceiveWeight> queryWrapper = new QueryWrapper<>();
+ Utils.MP.blankToNull(pageWrap.getModel());
+ if (pageWrap.getModel().getId() != null) {
+ queryWrapper.lambda().eq(ReceiveWeight::getId, pageWrap.getModel().getId());
+ }
+ if (pageWrap.getModel().getDeleted() != null) {
+ queryWrapper.lambda().eq(ReceiveWeight::getDeleted, pageWrap.getModel().getDeleted());
+ }
+ if (pageWrap.getModel().getStatus() != null) {
+ queryWrapper.lambda().eq(ReceiveWeight::getStatus, pageWrap.getModel().getStatus());
+ }
+ if (pageWrap.getModel().getCreateUser() != null) {
+ queryWrapper.lambda().eq(ReceiveWeight::getCreateUser, pageWrap.getModel().getCreateUser());
+ }
+ if (pageWrap.getModel().getCreateTime() != null) {
+ queryWrapper.lambda().ge(ReceiveWeight::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()));
+ queryWrapper.lambda().le(ReceiveWeight::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()));
+ }
+ if (pageWrap.getModel().getUpdateUser() != null) {
+ queryWrapper.lambda().eq(ReceiveWeight::getUpdateUser, pageWrap.getModel().getUpdateUser());
+ }
+ if (pageWrap.getModel().getUpdateTime() != null) {
+ queryWrapper.lambda().ge(ReceiveWeight::getUpdateTime, Utils.Date.getStart(pageWrap.getModel().getUpdateTime()));
+ queryWrapper.lambda().le(ReceiveWeight::getUpdateTime, Utils.Date.getEnd(pageWrap.getModel().getUpdateTime()));
+ }
+ if (pageWrap.getModel().getRemark() != null) {
+ queryWrapper.lambda().eq(ReceiveWeight::getRemark, pageWrap.getModel().getRemark());
+ }
+ if (pageWrap.getModel().getReceiveMax() != null) {
+ queryWrapper.lambda().eq(ReceiveWeight::getReceiveMax, pageWrap.getModel().getReceiveMax());
+ }
+ if (pageWrap.getModel().getReceiveMin() != null) {
+ queryWrapper.lambda().eq(ReceiveWeight::getReceiveMin, pageWrap.getModel().getReceiveMin());
+ }
+ if (pageWrap.getModel().getLevel() != null) {
+ queryWrapper.lambda().eq(ReceiveWeight::getLevel, pageWrap.getModel().getLevel());
+ }
+ if (pageWrap.getModel().getDelayTime() != null) {
+ queryWrapper.lambda().eq(ReceiveWeight::getDelayTime, pageWrap.getModel().getDelayTime());
+ }
+ if (pageWrap.getModel().getSortnum() != null) {
+ queryWrapper.lambda().eq(ReceiveWeight::getSortnum, pageWrap.getModel().getSortnum());
+ }
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(receiveWeightMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(ReceiveWeight receiveWeight) {
+ QueryWrapper<ReceiveWeight> wrapper = new QueryWrapper<>(receiveWeight);
+ return receiveWeightMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/WithdrawalOrdersServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/WithdrawalOrdersServiceImpl.java
new file mode 100644
index 0000000..03b55af
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/business/impl/WithdrawalOrdersServiceImpl.java
@@ -0,0 +1,149 @@
+package com.doumee.service.business.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.business.WithdrawalOrdersMapper;
+import com.doumee.dao.business.model.WithdrawalOrders;
+import com.doumee.service.business.WithdrawalOrdersService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 鎻愮幇鐢宠璁板綍Service瀹炵幇
+ * @author 姹熻箘韫�
+ * @date 2025/07/09 12:00
+ */
+@Service
+public class WithdrawalOrdersServiceImpl implements WithdrawalOrdersService {
+
+ @Autowired
+ private WithdrawalOrdersMapper withdrawalOrdersMapper;
+
+ @Override
+ public Integer create(WithdrawalOrders withdrawalOrders) {
+ withdrawalOrdersMapper.insert(withdrawalOrders);
+ return withdrawalOrders.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ withdrawalOrdersMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(WithdrawalOrders withdrawalOrders) {
+ UpdateWrapper<WithdrawalOrders> deleteWrapper = new UpdateWrapper<>(withdrawalOrders);
+ withdrawalOrdersMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ withdrawalOrdersMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(WithdrawalOrders withdrawalOrders) {
+ withdrawalOrdersMapper.updateById(withdrawalOrders);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<WithdrawalOrders> withdrawalOrderss) {
+ if (CollectionUtils.isEmpty(withdrawalOrderss)) {
+ return;
+ }
+ for (WithdrawalOrders withdrawalOrders: withdrawalOrderss) {
+ this.updateById(withdrawalOrders);
+ }
+ }
+
+ @Override
+ public WithdrawalOrders findById(Integer id) {
+ return withdrawalOrdersMapper.selectById(id);
+ }
+
+ @Override
+ public WithdrawalOrders findOne(WithdrawalOrders withdrawalOrders) {
+ QueryWrapper<WithdrawalOrders> wrapper = new QueryWrapper<>(withdrawalOrders);
+ return withdrawalOrdersMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<WithdrawalOrders> findList(WithdrawalOrders withdrawalOrders) {
+ QueryWrapper<WithdrawalOrders> wrapper = new QueryWrapper<>(withdrawalOrders);
+ return withdrawalOrdersMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<WithdrawalOrders> findPage(PageWrap<WithdrawalOrders> pageWrap) {
+ IPage<WithdrawalOrders> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<WithdrawalOrders> queryWrapper = new QueryWrapper<>();
+ Utils.MP.blankToNull(pageWrap.getModel());
+ if (pageWrap.getModel().getId() != null) {
+ queryWrapper.lambda().eq(WithdrawalOrders::getId, pageWrap.getModel().getId());
+ }
+ if (pageWrap.getModel().getDeleted() != null) {
+ queryWrapper.lambda().eq(WithdrawalOrders::getDeleted, pageWrap.getModel().getDeleted());
+ }
+ if (pageWrap.getModel().getCreateUser() != null) {
+ queryWrapper.lambda().eq(WithdrawalOrders::getCreateUser, pageWrap.getModel().getCreateUser());
+ }
+ if (pageWrap.getModel().getCreateTime() != null) {
+ queryWrapper.lambda().ge(WithdrawalOrders::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()));
+ queryWrapper.lambda().le(WithdrawalOrders::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()));
+ }
+ if (pageWrap.getModel().getUpdateUser() != null) {
+ queryWrapper.lambda().eq(WithdrawalOrders::getUpdateUser, pageWrap.getModel().getUpdateUser());
+ }
+ if (pageWrap.getModel().getUpdateTime() != null) {
+ queryWrapper.lambda().ge(WithdrawalOrders::getUpdateTime, Utils.Date.getStart(pageWrap.getModel().getUpdateTime()));
+ queryWrapper.lambda().le(WithdrawalOrders::getUpdateTime, Utils.Date.getEnd(pageWrap.getModel().getUpdateTime()));
+ }
+ if (pageWrap.getModel().getRemark() != null) {
+ queryWrapper.lambda().eq(WithdrawalOrders::getRemark, pageWrap.getModel().getRemark());
+ }
+ if (pageWrap.getModel().getMemberId() != null) {
+ queryWrapper.lambda().eq(WithdrawalOrders::getMemberId, pageWrap.getModel().getMemberId());
+ }
+ if (pageWrap.getModel().getAmount() != null) {
+ queryWrapper.lambda().eq(WithdrawalOrders::getAmount, pageWrap.getModel().getAmount());
+ }
+ if (pageWrap.getModel().getWxExternalNo() != null) {
+ queryWrapper.lambda().eq(WithdrawalOrders::getWxExternalNo, pageWrap.getModel().getWxExternalNo());
+ }
+ if (pageWrap.getModel().getStatus() != null) {
+ queryWrapper.lambda().eq(WithdrawalOrders::getStatus, pageWrap.getModel().getStatus());
+ }
+ if (pageWrap.getModel().getDoneTime() != null) {
+ queryWrapper.lambda().ge(WithdrawalOrders::getDoneTime, Utils.Date.getStart(pageWrap.getModel().getDoneTime()));
+ queryWrapper.lambda().le(WithdrawalOrders::getDoneTime, Utils.Date.getEnd(pageWrap.getModel().getDoneTime()));
+ }
+ if (pageWrap.getModel().getDoneInfo() != null) {
+ queryWrapper.lambda().eq(WithdrawalOrders::getDoneInfo, pageWrap.getModel().getDoneInfo());
+ }
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(withdrawalOrdersMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(WithdrawalOrders withdrawalOrders) {
+ QueryWrapper<WithdrawalOrders> wrapper = new QueryWrapper<>(withdrawalOrders);
+ return withdrawalOrdersMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/common/CacheProxy.java b/server/services/src/main/java/com/doumee/service/common/CacheProxy.java
new file mode 100644
index 0000000..44fe0a9
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/common/CacheProxy.java
@@ -0,0 +1,165 @@
+package com.doumee.service.common;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.cache.CacheException;
+import org.apache.shiro.util.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 缂撳瓨浠g悊绫伙紝渚夸簬缂撳瓨鍙樻洿
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@Component
+public class CacheProxy<K,V> {
+
+ @Autowired
+ private RedisTemplate<K, V> redisTemplate;
+
+ /**
+ * 鑾峰彇缂撳瓨鍊�
+ *
+ * @param key 缂撳瓨閿�
+ * @return V
+ */
+ public V get(K key) throws CacheException {
+ log.trace("CacheProxy: get, key = [" + key + "]");
+ if (key == null) {
+ return null;
+ }
+ return redisTemplate.opsForValue().get(key);
+ }
+
+ /**
+ * 鑾峰彇缂撳瓨鍊�
+ *
+ * @param key 缂撳瓨閿�
+ * @param value 缂撳瓨鍊�
+ * @return V
+ */
+ public V put(K key, V value) throws CacheException {
+ log.trace("CacheProxy: put, key = [" + key + "]");
+ if (key == null) {
+ log.warn("CacheProxy: put, key can not be null");
+ }
+ redisTemplate.opsForValue().set(key, value);
+ return value;
+ }
+
+ /**
+ * 鎸囧畾杩囨湡鏃堕暱
+ *
+ * @param key 缂撳瓨閿�
+ * @param value 缂撳瓨鍊�
+ * @param expire 杩囨湡鏃堕棿(s)
+ * @return V
+ */
+ public V put(K key, V value, int expire) throws CacheException {
+ this.put(key, value, expire * 1000L);
+ return value;
+ }
+
+ /**
+ * 鎸囧畾杩囨湡鏃堕暱
+ *
+ * @param key 缂撳瓨閿�
+ * @param value 缂撳瓨鍊�
+ * @param expire 杩囨湡鏃堕棿(ms)
+ * @return V
+ */
+ public V put(K key, V value, long expire) throws CacheException {
+ log.trace("CacheProxy: put, key = [" + key + "]");
+ if (key == null) {
+ log.warn("CacheProxy: put, key can not be null");
+ }
+ redisTemplate.opsForValue().set(key, value, expire, TimeUnit.MILLISECONDS);
+ return value;
+ }
+
+ /**
+ * 娓呯悊缂撳瓨
+ */
+ public void clear() throws CacheException {
+ log.trace("CacheProxy: clear");
+ Set<K> keys = this.keys();
+ redisTemplate.delete(keys);
+ }
+
+ /**
+ * 鑾峰彇缂撳瓨鏁�
+ *
+ * @return int
+ */
+ public int size() {
+ log.trace("CacheProxy: size");
+ return this.keys().size();
+ }
+
+ /**
+ * 鑾峰彇缂撳瓨key
+ *
+ * @return Set<K>
+ */
+ public Set<K> keys() {
+ log.trace("CacheProxy: keys");
+ Set<K> keys = redisTemplate.keys(null);
+ if (CollectionUtils.isEmpty(keys)) {
+ return Collections.emptySet();
+ }
+ return keys;
+ }
+
+ /**
+ * 鑾峰彇缂撳瓨key
+ *
+ * @param keyPattern 缂撳瓨閿鍒�
+ * @return Set<K>
+ */
+ public Set<K> keys(String keyPattern) {
+ log.trace("CacheProxy: keys, keyPattern = [" + keyPattern + "]");
+ if (keyPattern == null || "".equals(keyPattern) || "*".equals(keyPattern)) {
+ return keys();
+ }
+ return redisTemplate.keys((K)keyPattern);
+ }
+
+ /**
+ * 鑾峰彇鎵�鏈夌紦瀛樺��
+ *
+ * @return Collection<V>
+ */
+ public Collection<V> values() {
+ log.trace("CacheProxy: values");
+ Collection<V> values = new ArrayList<>();
+ Set<K> keys = this.keys();
+ if (CollectionUtils.isEmpty(keys)) {
+ return values;
+ }
+ for (K k : keys) {
+ values.add(redisTemplate.opsForValue().get(k));
+ }
+ return values;
+ }
+
+ /**
+ * 鑾峰彇鎵�鏈夌紦瀛樺��
+ *
+ * @param key 缂撳瓨閿�
+ * @return Collection<V>
+ */
+ public V remove(K key) throws CacheException {
+ log.trace("CacheProxy: remove, key = [" + key + "]");
+ if (key == null) {
+ return null;
+ }
+ V value = this.get(key);
+ redisTemplate.delete(key);
+ return value;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/common/CaptchaService.java b/server/services/src/main/java/com/doumee/service/common/CaptchaService.java
new file mode 100644
index 0000000..2b00c71
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/common/CaptchaService.java
@@ -0,0 +1,149 @@
+package com.doumee.service.common;
+
+import com.doumee.core.config.ProjectConfig;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.constants.ResponseStatus;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Base64;
+import java.util.Random;
+import java.util.UUID;
+
+/**
+ * 鍥剧墖楠岃瘉鐮�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class CaptchaService {
+
+ @Value("${cache.captcha.expire}")
+ private int expire;
+
+ @Autowired
+ private ProjectConfig projectConfig;
+
+ // 楠岃瘉鐮佸瓧绗﹂泦
+ private static final char[] CODES = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J',
+ 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'a', 'b', 'c', 'd', 'e', 'f', 'h', 'j',
+ 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', '3', '4', '5', '6', '7', '8' };
+
+ // 楠岃瘉鐮佸浘鐗囧搴�
+ private static final Integer WIDTH = 90;
+
+ // 楠岃瘉鐮佸浘鐗囬珮搴�
+ private static final Integer HEIGHT = 30;
+
+ @Autowired
+ private CacheProxy<String, String> cacheProxy;
+
+ /**
+ * 鐢熸垚楠岃瘉鐮佸浘鐗�
+ */
+ public Captcha genCaptcha () {
+ // 瀹氫箟鍥惧儚buffer
+ BufferedImage buffImg = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
+ Graphics gd = buffImg.getGraphics();
+ // 鍒涘缓涓�涓殢鏈烘暟鐢熸垚鍣ㄧ被
+ Random random = new Random();
+ // 灏嗗浘鍍忓~鍏呬负鐧借壊
+ gd.setColor(Color.decode("#FFFFFF"));
+ gd.fillRect(0, 0, WIDTH, HEIGHT);
+ // 鍒涘缓瀛椾綋锛屽瓧浣撶殑澶у皬搴旇鏍规嵁鍥剧墖鐨勯珮搴︽潵瀹氥��
+ Font font = new Font("Dialog", 1, 23);
+ // 璁剧疆瀛椾綋
+ gd.setFont(font);
+ // 鐢昏竟妗�
+ // gd.setColor(Color.decode("#E6BA09"));
+ gd.drawRect(0, 0, WIDTH, HEIGHT);
+ // 闅忔満浜х敓40鏉″共鎵扮嚎锛屼娇鍥捐薄涓殑璁よ瘉鐮佷笉鏄撹鍏跺畠绋嬪簭鎺㈡祴鍒般��
+ gd.setColor(Color.decode("#990000"));
+ for (int i = 0; i < 30; i++) {
+ int x = random.nextInt(WIDTH);
+ int y = random.nextInt(HEIGHT);
+ int xl = random.nextInt(12);
+ int yl = random.nextInt(12);
+ gd.drawLine(x, y, x + xl, y + yl);
+ }
+ // randomCode鐢ㄤ簬淇濆瓨闅忔満浜х敓鐨勯獙璇佺爜锛屼互渚跨敤鎴风櫥褰曞悗杩涜楠岃瘉銆�
+ StringBuffer randomCode = new StringBuffer();
+ int red, green, blue;
+ // 闅忔満浜х敓codeCount鏁板瓧鐨勯獙璇佺爜銆�
+ for (int i = 0; i < 4; i++) {
+ // 寰楀埌闅忔満浜х敓鐨勯獙璇佺爜鏁板瓧銆�
+ String code = String.valueOf(CODES[random.nextInt(CODES.length)]);
+ // 浜х敓闅忔満鐨勯鑹插垎閲忔潵鏋勯�犻鑹插�硷紝杩欐牱杈撳嚭鐨勬瘡浣嶆暟瀛楃殑棰滆壊鍊奸兘灏嗕笉鍚屻��
+ red = random.nextInt(255);
+ green = random.nextInt(255);
+ blue = random.nextInt(255);
+
+ // 鐢ㄩ殢鏈轰骇鐢熺殑棰滆壊灏嗛獙璇佺爜缁樺埗鍒板浘鍍忎腑銆�
+ gd.setColor(new Color(red, green, blue));
+ gd.drawString(code, (i + 1) * 15, 24);
+
+ // 灏嗕骇鐢熺殑鍥涗釜闅忔満鏁扮粍鍚堝湪涓�璧枫��
+ randomCode.append(code);
+ }
+ // 瀛樺叆缂撳瓨
+ Captcha captcha = new Captcha(randomCode.toString(), buffImg);
+ cacheProxy.put(captcha.getUuid(), captcha.getText(), expire);
+ return captcha;
+ }
+
+ /**
+ * 鏍¢獙楠岃瘉鐮�
+ *
+ * @param uuid 楠岃瘉鐮乁UID
+ * @param code 楠岃瘉鐮佸��
+ */
+ public void check(String uuid, String code) {
+ // 娴嬭瘯妯″紡涓嬩笉鏍¢獙
+ if (projectConfig.isTestingMode()) {
+ return;
+ }
+ String cacheCode = cacheProxy.get(uuid);
+ if (cacheCode == null) {
+ throw new BusinessException(ResponseStatus.VERIFICATION_CODE_INCORRECT);
+ }
+ cacheProxy.remove(cacheCode);
+ if (!code.equalsIgnoreCase(cacheCode)) {
+ throw new BusinessException(ResponseStatus.VERIFICATION_CODE_INCORRECT);
+ }
+ }
+
+ @Data
+ @ApiModel("楠岃瘉鐮佸璞�")
+ public static class Captcha {
+ @ApiModelProperty(value = "楠岃瘉鐮乁UID")
+ private String uuid;
+ @JsonIgnore
+ @ApiModelProperty(value = "楠岃瘉鐮�", hidden = true)
+ private String text;
+ @ApiModelProperty(value = "楠岃瘉鐮丅ase64")
+ private String image;
+ Captcha (String text, BufferedImage image) {
+ this.uuid = UUID.randomUUID().toString();
+ this.text = text;
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ try {
+ ImageIO.write(image, "png", stream);
+ } catch (IOException e) {
+ throw new RuntimeException("EVA: build captcha throw an exception", e);
+ }
+ this.image = "data:image/png;base64," + Base64.getEncoder().encodeToString(stream.toByteArray());
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/common/EmailService.java b/server/services/src/main/java/com/doumee/service/common/EmailService.java
new file mode 100644
index 0000000..e511c37
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/common/EmailService.java
@@ -0,0 +1,79 @@
+package com.doumee.service.common;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.stereotype.Service;
+
+import javax.mail.internet.MimeMessage;
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class EmailService {
+ @Autowired
+ private JavaMailSender javaMailSender;//娉ㄥ叆JavaMailSender
+ @Value("${spring.mail.username}")
+ private String fromEmail;
+ public boolean sendEmailWithLocalFiles(String toEmail, String title, String content, List<Map<String,Object>> fileList) {
+ try {
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+ context.refresh();
+ MimeMessage message = javaMailSender.createMimeMessage();
+ MimeMessageHelper helper = new MimeMessageHelper(message, true);
+ helper.setTo(toEmail);
+ helper.setFrom(fromEmail);
+ helper.setSubject(title);
+ helper.setText(content);
+ if(fileList!=null){
+ for (Map<String,Object> f : fileList){
+ // 璁剧疆闄勪欢
+ helper.addAttachment((String) f.get("name"),new FileSystemResource((File) f.get("file")));
+ }
+ }
+ javaMailSender.send(message);
+ System.out.println("閭欢鍙戦�佹垚鍔燂紒");
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ public boolean sendEmailWithImages(String toEmail, String title, Map<String,String> contentForm, List<String> imgList) {
+ try {
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+ context.refresh();
+ MimeMessage message = javaMailSender.createMimeMessage();
+ MimeMessageHelper helper = new MimeMessageHelper(message, true);
+ helper.setTo(toEmail);
+ helper.setFrom(fromEmail);
+ helper.setSubject(title);
+ String content = "<html><body>";
+ if(contentForm!=null){
+ for (Map.Entry<String, String> f : contentForm.entrySet()) {
+ // 璁剧疆闄勪欢
+ content += "<div style='display:block;'>"+f.getKey()+"锛�"+f.getValue()+"</p>";
+ }
+ }
+ if(imgList!=null){
+ content += "<div style='display:block;'> ";
+ for (String f : imgList){
+ // 璁剧疆闄勪欢
+ content += "<a href='"+f+"' target='blank'><img style='width:200px;margin:5px' src='"+f+"'/></a>";
+ }
+ }
+ content += "</div></body><html>";
+ helper.setText(content,true);
+ javaMailSender.send(message);
+ System.out.println("閭欢鍙戦�佹垚鍔燂紒");
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ }
diff --git a/server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java b/server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java
new file mode 100644
index 0000000..7fda776
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java
@@ -0,0 +1,20 @@
+package com.doumee.service.common.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("涓嬭浇鏈湴鏂囦欢鍙傛暟")
+public class DownloadLocalFileDTO {
+
+ @ApiModelProperty("鏂囦欢鍏ㄨ矾寰�")
+ private String path;
+
+ @ApiModelProperty("涓嬭浇鍚庣殑鏂囦欢鍚嶇О")
+ private String name;
+}
diff --git "a/server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java\0501\051" "b/server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java\0501\051"
new file mode 100644
index 0000000..7fda776
--- /dev/null
+++ "b/server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java\0501\051"
@@ -0,0 +1,20 @@
+package com.doumee.service.common.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("涓嬭浇鏈湴鏂囦欢鍙傛暟")
+public class DownloadLocalFileDTO {
+
+ @ApiModelProperty("鏂囦欢鍏ㄨ矾寰�")
+ private String path;
+
+ @ApiModelProperty("涓嬭浇鍚庣殑鏂囦欢鍚嶇О")
+ private String name;
+}
diff --git "a/server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java\0502\051" "b/server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java\0502\051"
new file mode 100644
index 0000000..7fda776
--- /dev/null
+++ "b/server/services/src/main/java/com/doumee/service/common/dto/DownloadLocalFileDTO.java\0502\051"
@@ -0,0 +1,20 @@
+package com.doumee.service.common.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Data
+@ApiModel("涓嬭浇鏈湴鏂囦欢鍙傛暟")
+public class DownloadLocalFileDTO {
+
+ @ApiModelProperty("鏂囦欢鍏ㄨ矾寰�")
+ private String path;
+
+ @ApiModelProperty("涓嬭浇鍚庣殑鏂囦欢鍚嶇О")
+ private String name;
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemDictDataService.java b/server/services/src/main/java/com/doumee/service/system/SystemDictDataService.java
new file mode 100644
index 0000000..60b7446
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemDictDataService.java
@@ -0,0 +1,101 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.QuerySystemDictDataDTO;
+import com.doumee.dao.system.model.SystemDictData;
+import com.doumee.dao.system.vo.SystemDictDataListVO;
+
+import java.util.List;
+
+/**
+ * 瀛楀吀鏁版嵁Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemDictDataService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemDictData 瀛楀吀鏁版嵁
+ * @return Integer
+ */
+ Integer create(SystemDictData systemDictData);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemDictData 瀛楀吀鏁版嵁
+ */
+ void updateById(SystemDictData systemDictData);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemDictDatas 瀛楀吀鏁版嵁鍒楄〃
+ */
+ void updateByIdInBatch(List<SystemDictData> systemDictDatas);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemDictData
+ */
+ SystemDictData findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemDictData 鏌ヨ鏉′欢
+ * @return SystemDictData
+ */
+ SystemDictData findOne(SystemDictData systemDictData);
+ List<SystemDictData> findList(Integer dicId, List<String> codes);
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemDictData 鏌ヨ鏉′欢
+ * @return List<SystemDictData>
+ */
+ List<SystemDictData> findList(SystemDictData systemDictData);
+
+ /**
+ * 鏍规嵁瀛楀吀缂栫爜鏌ヨ
+ *
+ * @param dictCode 瀛楀吀缂栫爜
+ * @return List<SystemDictData>
+ */
+ List<SystemDictData> findByDictCode(String dictCode);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉鍙傛暟
+ * @return PageData<SystemDictDataListVO>
+ */
+ PageData<SystemDictDataListVO> findPage(PageWrap<QuerySystemDictDataDTO> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemDictData 缁熻鏉′欢
+ * @return long
+ */
+ long count(SystemDictData systemDictData);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemDictService.java b/server/services/src/main/java/com/doumee/service/system/SystemDictService.java
new file mode 100644
index 0000000..e8091a9
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemDictService.java
@@ -0,0 +1,93 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.QuerySystemDictDTO;
+import com.doumee.dao.system.model.SystemDict;
+import com.doumee.dao.system.vo.SystemDictListVO;
+
+import java.util.List;
+
+/**
+ * 瀛楀吀Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemDictService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemDict 瀛楀吀
+ * @return Integer
+ */
+ Integer create(SystemDict systemDict);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemDict 瀛楀吀
+ */
+ void updateById(SystemDict systemDict);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemDicts 瀛楀吀鍒楄〃
+ */
+ void updateByIdInBatch(List<SystemDict> systemDicts);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemDict
+ */
+ SystemDict findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemDict 鏉′欢鍙傛暟
+ * @return SystemDict
+ */
+ SystemDict findOne(SystemDict systemDict);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemDict 鏉′欢鍙傛暟
+ * @return List<SystemDict>
+ */
+ List<SystemDict> findList(SystemDict systemDict);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉鍙傛暟
+ * @return PageData<SystemDictListVO>
+ */
+ PageData<SystemDictListVO> findPage(PageWrap<QuerySystemDictDTO> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemDict 缁熻鍙傛暟
+ * @return long
+ */
+ long count(SystemDict systemDict);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemJobListService.java b/server/services/src/main/java/com/doumee/service/system/SystemJobListService.java
new file mode 100644
index 0000000..6a2725d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemJobListService.java
@@ -0,0 +1,23 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.vo.SystemJobListVO;
+import com.doumee.dao.system.dto.QuerySystemJobListDTO;
+
+/**
+ * 瀹氭椂浠诲姟鍒楄〃Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemJobListService {
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉鍙傛暟
+ * @return PageData<SystemJobListVO>
+ */
+ PageData<SystemJobListVO> findPage(PageWrap<QuerySystemJobListDTO> pageWrap);
+
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemJobLogService.java b/server/services/src/main/java/com/doumee/service/system/SystemJobLogService.java
new file mode 100644
index 0000000..b61ce7b
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemJobLogService.java
@@ -0,0 +1,98 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.QuerySystemJobLogDTO;
+import com.doumee.dao.system.model.SystemJobLog;
+import java.util.List;
+
+/**
+ * 绯荤粺瀹氭椂浠诲姟鏃ュ織Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemJobLogService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemJobLog 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(SystemJobLog systemJobLog);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param systemJobLog 瀹炰綋瀵硅薄
+ */
+ void delete(SystemJobLog systemJobLog);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemJobLog 瀹炰綋瀵硅薄
+ */
+ void updateById(SystemJobLog systemJobLog);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemJobLogs 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<SystemJobLog> systemJobLogs);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemJobLog
+ */
+ SystemJobLog findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemJobLog 瀹炰綋瀵硅薄
+ * @return SystemJobLog
+ */
+ SystemJobLog findOne(SystemJobLog systemJobLog);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemJobLog 瀹炰綋瀵硅薄
+ * @return List<SystemJobLog>
+ */
+ List<SystemJobLog> findList(SystemJobLog systemJobLog);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉瀵硅薄
+ * @return PageData<SystemJobLog>
+ */
+ PageData<SystemJobLog> findPage(PageWrap<QuerySystemJobLogDTO> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemJobLog 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(SystemJobLog systemJobLog);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemJobService.java b/server/services/src/main/java/com/doumee/service/system/SystemJobService.java
new file mode 100644
index 0000000..fe1d606
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemJobService.java
@@ -0,0 +1,87 @@
+package com.doumee.service.system;
+
+import com.doumee.dao.system.model.SystemJob;
+import java.util.List;
+
+/**
+ * 绯荤粺瀹氭椂浠诲姟Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemJobService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemJob 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(SystemJob systemJob);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param systemJob 瀹炰綋瀵硅薄
+ */
+ void delete(SystemJob systemJob);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemJob 瀹炰綋瀵硅薄
+ */
+ void updateById(SystemJob systemJob);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemJobs 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<SystemJob> systemJobs);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemJob
+ */
+ SystemJob findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemJob 瀹炰綋瀵硅薄
+ * @return SystemJob
+ */
+ SystemJob findOne(SystemJob systemJob);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemJob 瀹炰綋瀵硅薄
+ * @return List<SystemJob>
+ */
+ List<SystemJob> findList(SystemJob systemJob);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemJob 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(SystemJob systemJob);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemJobSnippetService.java b/server/services/src/main/java/com/doumee/service/system/SystemJobSnippetService.java
new file mode 100644
index 0000000..c3b1a59
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemJobSnippetService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.model.SystemJobSnippet;
+import java.util.List;
+
+/**
+ * 瀹氭椂浠诲姟鐗囨Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemJobSnippetService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemJobSnippet 瀹炰綋瀵硅薄
+ * @return Integer
+ */
+ Integer create(SystemJobSnippet systemJobSnippet);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param systemJobSnippet 瀹炰綋瀵硅薄
+ */
+ void delete(SystemJobSnippet systemJobSnippet);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭闆�
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemJobSnippet 瀹炰綋瀵硅薄
+ */
+ void updateById(SystemJobSnippet systemJobSnippet);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemJobSnippets 瀹炰綋闆�
+ */
+ void updateByIdInBatch(List<SystemJobSnippet> systemJobSnippets);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemJobSnippet
+ */
+ SystemJobSnippet findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemJobSnippet 瀹炰綋瀵硅薄
+ * @return SystemJobSnippet
+ */
+ SystemJobSnippet findOne(SystemJobSnippet systemJobSnippet);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemJobSnippet 瀹炰綋瀵硅薄
+ * @return List<SystemJobSnippet>
+ */
+ List<SystemJobSnippet> findList(SystemJobSnippet systemJobSnippet);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉瀵硅薄
+ * @return PageData<SystemJobSnippet>
+ */
+ PageData<SystemJobSnippet> findPage(PageWrap<SystemJobSnippet> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemJobSnippet 瀹炰綋瀵硅薄
+ * @return long
+ */
+ long count(SystemJobSnippet systemJobSnippet);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemLoginLogService.java b/server/services/src/main/java/com/doumee/service/system/SystemLoginLogService.java
new file mode 100644
index 0000000..3634d9f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemLoginLogService.java
@@ -0,0 +1,98 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.QuerySystemLoginLogDTO;
+import com.doumee.dao.system.model.SystemLoginLog;
+import java.util.List;
+
+/**
+ * 鐧诲綍鏃ュ織Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemLoginLogService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemLoginLog 瀹炰綋
+ * @return Integer
+ */
+ Integer create(SystemLoginLog systemLoginLog);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param systemLoginLog 鍒犻櫎鏉′欢
+ */
+ void delete(SystemLoginLog systemLoginLog);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 娉ㄨВ鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemLoginLog 瀹炰綋
+ */
+ void updateById(SystemLoginLog systemLoginLog);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemLoginLogs 瀹炰綋鍒楄〃
+ */
+ void updateByIdInBatch(List<SystemLoginLog> systemLoginLogs);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemLoginLog
+ */
+ SystemLoginLog findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemLoginLog 鏌ヨ鏉′欢
+ * @return SystemLoginLog
+ */
+ SystemLoginLog findOne(SystemLoginLog systemLoginLog);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemLoginLog 鏌ヨ鏉′欢
+ * @return List<SystemLoginLog>
+ */
+ List<SystemLoginLog> findList(SystemLoginLog systemLoginLog);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉鍙傛暟
+ * @return PageData<SystemLoginLog>
+ */
+ PageData<SystemLoginLog> findPage(PageWrap<QuerySystemLoginLogDTO> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemLoginLog 缁熻鏉′欢
+ * @return long
+ */
+ long count(SystemLoginLog systemLoginLog);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemLoginService.java b/server/services/src/main/java/com/doumee/service/system/SystemLoginService.java
new file mode 100644
index 0000000..57572c6
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemLoginService.java
@@ -0,0 +1,22 @@
+package com.doumee.service.system;
+
+import com.doumee.dao.system.dto.LoginDTO;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 绯荤粺鐧诲綍
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemLoginService {
+
+ /**
+ * 瀵嗙爜鐧诲綍
+ *
+ * @param dto 璇﹁LoginDTO
+ * @param request 璇锋眰瀵硅薄
+ * @return String
+ */
+ String loginByPassword (LoginDTO dto, HttpServletRequest request);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemMenuService.java b/server/services/src/main/java/com/doumee/service/system/SystemMenuService.java
new file mode 100644
index 0000000..d8afc8e
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemMenuService.java
@@ -0,0 +1,120 @@
+package com.doumee.service.system;
+
+import com.doumee.dao.system.model.SystemMenu;
+import com.doumee.dao.system.vo.SystemMenuListVO;
+
+import java.util.List;
+
+/**
+ * 绯荤粺鑿滃崟Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemMenuService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemMenu 瀹炰綋
+ * @return Integer
+ */
+ Integer create(SystemMenu systemMenu);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemMenu 瀹炰綋
+ */
+ void updateById(SystemMenu systemMenu);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemMenus 瀹炰綋
+ */
+ void updateByIdInBatch(List<SystemMenu> systemMenus);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemMenu
+ */
+ SystemMenu findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemMenu 鏌ヨ鏉′欢
+ * @return SystemMenu
+ */
+ SystemMenu findOne(SystemMenu systemMenu);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemMenu 鏌ヨ鏉′欢
+ * @return List<SystemMenu>
+ */
+ List<SystemMenu> findList(SystemMenu systemMenu);
+
+ /**
+ * 鏌ヨ鍒楄〃
+ *
+ * @return List<SystemMenuListVO>
+ */
+ List<SystemMenuListVO> findList();
+
+ /**
+ * 鏌ヨ涓�绾ц彍鍗曞垪琛�
+ *
+ * @return List<SystemMenu>
+ */
+ List<SystemMenu> findRootList();
+
+ /**
+ * 鏌ヨ鐢ㄦ埛ID鏌ヨ
+ *
+ * @param userId 鐢ㄦ埛ID
+ * @return List<SystemMenu>
+ */
+ List<SystemMenu> findByUserId(Integer userId);
+
+ /**
+ * 鏍规嵁瑙掕壊ID鏌ヨ
+ *
+ * @param roleId 瑙掕壊ID
+ * @return List<SystemMenu>
+ */
+ List<SystemMenu> findByRoleId(Integer roleId);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemMenu 缁熻鍙傛暟
+ * @return long
+ */
+ long count(SystemMenu systemMenu);
+
+ /**
+ * 鏌ヨ瀛愯彍鍗�
+ *
+ * @param menuId 鑿滃崟ID
+ * @return List<Integer>
+ */
+ List<Integer> findChildren(Integer menuId);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemPermissionService.java b/server/services/src/main/java/com/doumee/service/system/SystemPermissionService.java
new file mode 100644
index 0000000..2649ec1
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemPermissionService.java
@@ -0,0 +1,120 @@
+package com.doumee.service.system;
+
+import com.doumee.dao.system.dto.DeleteSystemPermissionDTO;
+import com.doumee.dao.system.model.SystemPermission;
+import com.doumee.dao.system.vo.SystemPermissionListVO;
+
+import java.util.List;
+
+/**
+ * 绯荤粺鏉冮檺Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemPermissionService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemPermission 瀹炰綋
+ * @return Integer
+ */
+ Integer create(SystemPermission systemPermission);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param dto 鍒犻櫎鏉′欢
+ */
+ void delete (DeleteSystemPermissionDTO dto);
+
+ /**
+ * 鎵归噺鍒犻櫎
+ *
+ * @param dtos 鍒犻櫎鏉′欢鍒楄〃
+ */
+ void deleteInBatch(List<DeleteSystemPermissionDTO> dtos);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemPermission 瀹炰綋
+ */
+ void updateById(SystemPermission systemPermission);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemPermissions 瀹炰綋鍒楄〃
+ */
+ void updateByIdInBatch(List<SystemPermission> systemPermissions);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemPermission
+ */
+ SystemPermission findById(Integer id);
+
+ /**
+ * 鏍规嵁鐢ㄦ埛ID鏌ヨ
+ *
+ * @param userId 鐢ㄦ埛ID
+ * @return List<SystemPermission>
+ */
+ List<SystemPermission> findByUserId(Integer userId);
+
+ /**
+ * 鏍规嵁瑙掕壊ID鏌ヨ
+ *
+ * @param roleId 瑙掕壊ID
+ * @return List<SystemPermission>
+ */
+ List<SystemPermission> findByRoleId(Integer roleId);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemPermission 鏌ヨ鏉′欢
+ * @return SystemPermission
+ */
+ SystemPermission findOne(SystemPermission systemPermission);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemPermission 鏌ヨ鏉′欢
+ * @return List<SystemPermission>
+ */
+ List<SystemPermission> findList(SystemPermission systemPermission);
+
+ /**
+ * 鏌ヨ绠$悊鍒楄〃
+ *
+ * @return List<SystemPermissionListVO>
+ */
+ List<SystemPermissionListVO> findTree();
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemPermission 缁熻鏉′欢
+ * @return long
+ */
+ long count(SystemPermission systemPermission);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemRoleMenuService.java b/server/services/src/main/java/com/doumee/service/system/SystemRoleMenuService.java
new file mode 100644
index 0000000..4dcc627
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemRoleMenuService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.model.SystemRoleMenu;
+import java.util.List;
+
+/**
+ * 瑙掕壊鑿滃崟鍏宠仈Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemRoleMenuService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemRoleMenu 瀹炰綋
+ * @return Integer
+ */
+ Integer create(SystemRoleMenu systemRoleMenu);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param systemRoleMenu 鍒犻櫎鏉′欢
+ */
+ void delete(SystemRoleMenu systemRoleMenu);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemRoleMenu 涓讳綋
+ */
+ void updateById(SystemRoleMenu systemRoleMenu);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemRoleMenus 涓讳綋鍒楄〃
+ */
+ void updateByIdInBatch(List<SystemRoleMenu> systemRoleMenus);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemRoleMenu
+ */
+ SystemRoleMenu findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemRoleMenu 鏌ヨ鏉′欢
+ * @return SystemRoleMenu
+ */
+ SystemRoleMenu findOne(SystemRoleMenu systemRoleMenu);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemRoleMenu 鏌ヨ鏉′欢
+ * @return List<SystemRoleMenu>
+ */
+ List<SystemRoleMenu> findList(SystemRoleMenu systemRoleMenu);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉鍙傛暟
+ * @return PageData<SystemRoleMenu>
+ */
+ PageData<SystemRoleMenu> findPage(PageWrap<SystemRoleMenu> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemRoleMenu 缁熻鏉′欢
+ * @return long
+ */
+ long count(SystemRoleMenu systemRoleMenu);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemRolePermissionService.java b/server/services/src/main/java/com/doumee/service/system/SystemRolePermissionService.java
new file mode 100644
index 0000000..3e7a152
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemRolePermissionService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.model.SystemRolePermission;
+import java.util.List;
+
+/**
+ * 瑙掕壊鏉冮檺鍏宠仈Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemRolePermissionService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemRolePermission 瀹炰綋
+ * @return Integer
+ */
+ Integer create(SystemRolePermission systemRolePermission);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param systemRolePermission 鍒犻櫎鏉′欢
+ */
+ void delete(SystemRolePermission systemRolePermission);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemRolePermission 瀹炰綋
+ */
+ void updateById(SystemRolePermission systemRolePermission);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemRolePermissions 瀹炰綋鍒楄〃
+ */
+ void updateByIdInBatch(List<SystemRolePermission> systemRolePermissions);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemRolePermission
+ */
+ SystemRolePermission findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemRolePermission 鏌ヨ鏉′欢
+ * @return SystemRolePermission
+ */
+ SystemRolePermission findOne(SystemRolePermission systemRolePermission);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemRolePermission 鏌ヨ鏉′欢
+ * @return List<SystemRolePermission>
+ */
+ List<SystemRolePermission> findList(SystemRolePermission systemRolePermission);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉鍙傛暟
+ * @return PageData<SystemRolePermission>
+ */
+ PageData<SystemRolePermission> findPage(PageWrap<SystemRolePermission> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemRolePermission 缁熻鍙傛暟
+ * @return long
+ */
+ long count(SystemRolePermission systemRolePermission);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemRoleService.java b/server/services/src/main/java/com/doumee/service/system/SystemRoleService.java
new file mode 100644
index 0000000..e3510e3
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemRoleService.java
@@ -0,0 +1,101 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.QuerySystemRoleDTO;
+import com.doumee.dao.system.model.SystemRole;
+import com.doumee.dao.system.vo.SystemRoleListVO;
+
+import java.util.List;
+
+/**
+ * 绯荤粺瑙掕壊Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemRoleService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemRole 瀹炰綋
+ * @return Integer
+ */
+ Integer create(SystemRole systemRole);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemRole 瀹炰綋
+ */
+ void updateById(SystemRole systemRole);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemRoles 瀹炰綋鍒楄〃
+ */
+ void updateByIdInBatch(List<SystemRole> systemRoles);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemRole
+ */
+ SystemRole findById(Integer id);
+
+ /**
+ * 鏍规嵁鐢ㄦ埛ID鏌ヨ
+ *
+ * @param userId 鐢ㄦ埛ID
+ * @return List<SystemRole>
+ */
+ List<SystemRole> findByUserId(Integer userId);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemRole 鏌ヨ鏉′欢
+ * @return SystemRole
+ */
+ SystemRole findOne(SystemRole systemRole);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemRole 鏌ヨ鏉′欢
+ * @return List<SystemRole>
+ */
+ List<SystemRole> findList(SystemRole systemRole);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉鍙傛暟
+ * @return PageData<SystemRoleListVO>
+ */
+ PageData<SystemRoleListVO> findPage(PageWrap<QuerySystemRoleDTO> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemRole 缁熻鍙傛暟
+ * @return long
+ */
+ long count(SystemRole systemRole);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemTraceLogService.java b/server/services/src/main/java/com/doumee/service/system/SystemTraceLogService.java
new file mode 100644
index 0000000..463aada
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemTraceLogService.java
@@ -0,0 +1,91 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.QuerySystemTraceLogDTO;
+import com.doumee.dao.system.model.SystemTraceLog;
+import java.util.List;
+
+/**
+ * 璺熻釜鏃ュ織Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemTraceLogService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemTraceLog 瀹炰綋
+ * @return Integer
+ */
+ Integer create(SystemTraceLog systemTraceLog);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemTraceLog 瀹炰綋
+ */
+ void updateById(SystemTraceLog systemTraceLog);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemTraceLogs 瀹炰綋鍒楄〃
+ */
+ void updateByIdInBatch(List<SystemTraceLog> systemTraceLogs);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemTraceLog
+ */
+ SystemTraceLog findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemTraceLog 鏌ヨ鏉′欢
+ * @return SystemTraceLog
+ */
+ SystemTraceLog findOne(SystemTraceLog systemTraceLog);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemTraceLog 鏌ヨ鏉′欢
+ * @return List<SystemTraceLog>
+ */
+ List<SystemTraceLog> findList(SystemTraceLog systemTraceLog);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉鍙傛暟
+ * @return PageData<SystemTraceLog>
+ */
+ PageData<SystemTraceLog> findPage(PageWrap<QuerySystemTraceLogDTO> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemTraceLog 缁熻鍙傛暟
+ * @return long
+ */
+ long count(SystemTraceLog systemTraceLog);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemUserRoleService.java b/server/services/src/main/java/com/doumee/service/system/SystemUserRoleService.java
new file mode 100644
index 0000000..ad47e20
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemUserRoleService.java
@@ -0,0 +1,97 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.model.SystemUserRole;
+import java.util.List;
+
+/**
+ * 鐢ㄦ埛瑙掕壊鍏宠仈Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemUserRoleService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemUserRole 瀹炰綋
+ * @return Integer
+ */
+ Integer create(SystemUserRole systemUserRole);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鍒犻櫎
+ *
+ * @param systemUserRole 鍒犻櫎鏉′欢
+ */
+ void delete(SystemUserRole systemUserRole);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemUserRole 瀹炰綋
+ */
+ void updateById(SystemUserRole systemUserRole);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemUserRoles 瀹炰綋鍒楄〃
+ */
+ void updateByIdInBatch(List<SystemUserRole> systemUserRoles);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemUserRole
+ */
+ SystemUserRole findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemUserRole 鏌ヨ鏉′欢
+ * @return SystemUserRole
+ */
+ SystemUserRole findOne(SystemUserRole systemUserRole);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemUserRole 鏌ヨ鏉′欢
+ * @return List<SystemUserRole>
+ */
+ List<SystemUserRole> findList(SystemUserRole systemUserRole);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉鍙傛暟
+ * @return PageData<SystemUserRole>
+ */
+ PageData<SystemUserRole> findPage(PageWrap<SystemUserRole> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemUserRole 缁熻鍙傛暟
+ * @return long
+ */
+ long count(SystemUserRole systemUserRole);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/SystemUserService.java b/server/services/src/main/java/com/doumee/service/system/SystemUserService.java
new file mode 100644
index 0000000..a8a6043
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/SystemUserService.java
@@ -0,0 +1,93 @@
+package com.doumee.service.system;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.QuerySystemUserDTO;
+import com.doumee.dao.system.model.SystemUser;
+import com.doumee.dao.system.vo.SystemUserListVO;
+
+import java.util.List;
+
+/**
+ * 绯荤粺鐢ㄦ埛Service瀹氫箟
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+public interface SystemUserService {
+
+ /**
+ * 鍒涘缓
+ *
+ * @param systemUser 瀹炰綋
+ * @return Integer
+ */
+ Integer create(SystemUser systemUser);
+
+ /**
+ * 涓婚敭鍒犻櫎
+ *
+ * @param id 涓婚敭
+ */
+ void deleteById(Integer id);
+
+ /**
+ * 鎵归噺涓婚敭鍒犻櫎
+ *
+ * @param ids 涓婚敭鍒楄〃
+ */
+ void deleteByIdInBatch(List<Integer> ids);
+
+ /**
+ * 涓婚敭鏇存柊
+ *
+ * @param systemUser 瀹炰綋
+ */
+ void updateById(SystemUser systemUser);
+
+ /**
+ * 鎵归噺涓婚敭鏇存柊
+ *
+ * @param systemUsers 瀹炰綋鍒楄〃
+ */
+ void updateByIdInBatch(List<SystemUser> systemUsers);
+
+ /**
+ * 涓婚敭鏌ヨ
+ *
+ * @param id 涓婚敭
+ * @return SystemUser
+ */
+ SystemUser findById(Integer id);
+
+ /**
+ * 鏉′欢鏌ヨ鍗曟潯璁板綍
+ *
+ * @param systemUser 鏌ヨ鏉′欢
+ * @return SystemUser
+ */
+ SystemUser findOne(SystemUser systemUser);
+
+ /**
+ * 鏉′欢鏌ヨ
+ *
+ * @param systemUser 鏌ヨ鏉′欢
+ * @return List<SystemUser>
+ */
+ List<SystemUser> findList(SystemUser systemUser);
+
+ /**
+ * 鍒嗛〉鏌ヨ
+ *
+ * @param pageWrap 鍒嗛〉鍙傛暟
+ * @return PageData<SystemUserListVO>
+ */
+ PageData<SystemUserListVO> findPage(PageWrap<QuerySystemUserDTO> pageWrap);
+
+ /**
+ * 鏉′欢缁熻
+ *
+ * @param systemUser 缁熻鍙傛暟
+ * @return long
+ */
+ long count(SystemUser systemUser);
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemDictDataServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemDictDataServiceImpl.java
new file mode 100644
index 0000000..255eb9d
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemDictDataServiceImpl.java
@@ -0,0 +1,131 @@
+package com.doumee.service.system.impl;
+
+import com.doumee.dao.system.model.SystemDict;
+import com.doumee.dao.system.model.SystemMenu;
+import com.doumee.service.system.SystemDictService;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.SystemDictDataMapper;
+import com.doumee.dao.system.dto.QuerySystemDictDataDTO;
+import com.doumee.dao.system.model.SystemDictData;
+import com.doumee.dao.system.vo.SystemDictDataListVO;
+import com.doumee.service.system.SystemDictDataService;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+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.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 瀛楀吀鏁版嵁Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemDictDataServiceImpl implements SystemDictDataService {
+
+ @Autowired
+ private SystemDictDataMapper systemDictDataMapper;
+
+ @Autowired
+ private SystemDictService systemDictService;
+
+ @Override
+ public Integer create(SystemDictData systemDictData) {
+ systemDictDataMapper.insert(systemDictData);
+ return systemDictData.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemDictData systemDictData = new SystemDictData();
+ systemDictData.setId(id);
+ systemDictData.setDeleted(Boolean.TRUE);
+ this.updateById(systemDictData);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) return;
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ public void updateById(SystemDictData systemDictData) {
+ systemDictDataMapper.updateById(systemDictData);
+ }
+
+ @Override
+ @Transactional
+ public void updateByIdInBatch(List<SystemDictData> systemDictDatas) {
+ if (CollectionUtils.isEmpty(systemDictDatas)) return;
+ for (SystemDictData systemDictData: systemDictDatas) {
+ this.updateById(systemDictData);
+ }
+ }
+
+ @Override
+ public SystemDictData findById(Integer id) {
+ return systemDictDataMapper.selectById(id);
+ }
+
+ @Override
+ public SystemDictData findOne(SystemDictData systemDictData) {
+ Wrapper<SystemDictData> wrapper = new QueryWrapper<>(systemDictData);
+ return systemDictDataMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemDictData> findList(SystemDictData systemDictData) {
+ QueryWrapper<SystemDictData> wrapper = new QueryWrapper<>(systemDictData);
+ wrapper.lambda().orderByAsc(SystemDictData::getSort);
+ return systemDictDataMapper.selectList(wrapper);
+ }
+
+ @Override
+ public List<SystemDictData> findList(Integer dicId,List<String> codes) {
+ QueryWrapper<SystemDictData> wrapper = new QueryWrapper<>();
+ wrapper.lambda()
+ .eq(Objects.nonNull(dicId),SystemDictData::getDictId,dicId)
+ .in(SystemDictData::getLabel,codes);
+ return systemDictDataMapper.selectList(wrapper);
+ }
+
+ @Override
+ public List<SystemDictData> findByDictCode(String dictCode) {
+ SystemDict queryDto = new SystemDict();
+ queryDto.setCode(dictCode);
+ queryDto.setDeleted(Boolean.FALSE);
+ SystemDict systemDict = systemDictService.findOne(queryDto);
+ if (systemDict == null) {
+ return Collections.emptyList();
+ }
+ SystemDictData queryDictDataDto = new SystemDictData();
+ queryDictDataDto.setDictId(systemDict.getId());
+ queryDictDataDto.setDisabled(Boolean.FALSE);
+ queryDictDataDto.setDeleted(Boolean.FALSE);
+ return this.findList(queryDictDataDto);
+ }
+
+ @Override
+ public PageData<SystemDictDataListVO> findPage(PageWrap<QuerySystemDictDataDTO> pageWrap) {
+ PageHelper.startPage(pageWrap.getPage(), pageWrap.getCapacity());
+ return PageData.from(new PageInfo<>(systemDictDataMapper.selectManageList(pageWrap.getModel())));
+ }
+
+ @Override
+ public long count(SystemDictData systemDictData) {
+ Wrapper<SystemDictData> wrapper = new QueryWrapper<>(systemDictData);
+ return systemDictDataMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemDictServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemDictServiceImpl.java
new file mode 100644
index 0000000..d0e044f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemDictServiceImpl.java
@@ -0,0 +1,97 @@
+package com.doumee.service.system.impl;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.SystemDictMapper;
+import com.doumee.dao.system.dto.QuerySystemDictDTO;
+import com.doumee.dao.system.model.SystemDict;
+import com.doumee.dao.system.vo.SystemDictListVO;
+import com.doumee.service.system.SystemDictService;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+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;
+
+/**
+ * 瀛楀吀Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemDictServiceImpl implements SystemDictService {
+
+ @Autowired
+ private SystemDictMapper systemDictMapper;
+
+ @Override
+ public Integer create(SystemDict systemDict) {
+ systemDictMapper.insert(systemDict);
+ return systemDict.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemDict systemDict = new SystemDict();
+ systemDict.setId(id);
+ systemDict.setDeleted(Boolean.TRUE);
+ this.updateById(systemDict);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) return;
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ public void updateById(SystemDict systemDict) {
+ systemDictMapper.updateById(systemDict);
+ }
+
+ @Override
+ @Transactional
+ public void updateByIdInBatch(List<SystemDict> systemDicts) {
+ if (CollectionUtils.isEmpty(systemDicts)) return;
+ for (SystemDict systemDict: systemDicts) {
+ this.updateById(systemDict);
+ }
+ }
+
+ @Override
+ public SystemDict findById(Integer id) {
+ return systemDictMapper.selectById(id);
+ }
+
+ @Override
+ public SystemDict findOne(SystemDict systemDict) {
+ Wrapper<SystemDict> wrapper = new QueryWrapper<>(systemDict);
+ return systemDictMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemDict> findList(SystemDict systemDict) {
+ Wrapper<SystemDict> wrapper = new QueryWrapper<>(systemDict);
+ return systemDictMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<SystemDictListVO> findPage(PageWrap<QuerySystemDictDTO> pageWrap) {
+ PageHelper.startPage(pageWrap.getPage(), pageWrap.getCapacity());
+ return PageData.from(new PageInfo<>(systemDictMapper.selectManageList(pageWrap.getModel(), pageWrap.getOrderByClause())));
+ }
+
+ @Override
+ public long count(SystemDict systemDict) {
+ Wrapper<SystemDict> wrapper = new QueryWrapper<>(systemDict);
+ return systemDictMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemJobListServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemJobListServiceImpl.java
new file mode 100644
index 0000000..79e6b7b
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemJobListServiceImpl.java
@@ -0,0 +1,33 @@
+package com.doumee.service.system.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.dto.QuerySystemJobListDTO;
+import com.doumee.dao.system.vo.SystemJobListVO;
+import com.doumee.service.system.SystemJobListService;
+import com.doumee.dao.system.SystemJobListMapper;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 瀹氭椂浠诲姟鍒楄〃Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemJobListServiceImpl implements SystemJobListService {
+
+ @Autowired
+ private SystemJobListMapper systemJobListMapper;
+
+ @Override
+ public PageData<SystemJobListVO> findPage(PageWrap<QuerySystemJobListDTO> pageWrap) {
+ PageHelper.startPage(pageWrap.getPage(), pageWrap.getCapacity());
+ List<SystemJobListVO> result = systemJobListMapper.selectList(pageWrap.getModel());
+ return PageData.from(new PageInfo<>(result));
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemJobLogServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemJobLogServiceImpl.java
new file mode 100644
index 0000000..a711265
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemJobLogServiceImpl.java
@@ -0,0 +1,119 @@
+package com.doumee.service.system.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.SystemJobLogMapper;
+import com.doumee.dao.system.dto.QuerySystemJobLogDTO;
+import com.doumee.dao.system.model.SystemJobLog;
+import com.doumee.service.system.SystemJobLogService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 绯荤粺瀹氭椂浠诲姟鏃ュ織Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemJobLogServiceImpl implements SystemJobLogService {
+
+ @Autowired
+ private SystemJobLogMapper systemJobLogMapper;
+
+ @Override
+ public Integer create(SystemJobLog systemJobLog) {
+ systemJobLogMapper.insert(systemJobLog);
+ return systemJobLog.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ systemJobLogMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(SystemJobLog systemJobLog) {
+ UpdateWrapper<SystemJobLog> deleteWrapper = new UpdateWrapper<>(systemJobLog);
+ systemJobLogMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ systemJobLogMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(SystemJobLog systemJobLog) {
+ systemJobLogMapper.updateById(systemJobLog);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<SystemJobLog> systemJobLogs) {
+ if (CollectionUtils.isEmpty(systemJobLogs)) {
+ return;
+ }
+ for (SystemJobLog systemJobLog: systemJobLogs) {
+ this.updateById(systemJobLog);
+ }
+ }
+
+ @Override
+ public SystemJobLog findById(Integer id) {
+ return systemJobLogMapper.selectById(id);
+ }
+
+ @Override
+ public SystemJobLog findOne(SystemJobLog systemJobLog) {
+ QueryWrapper<SystemJobLog> wrapper = new QueryWrapper<>(systemJobLog);
+ return systemJobLogMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemJobLog> findList(SystemJobLog systemJobLog) {
+ QueryWrapper<SystemJobLog> wrapper = new QueryWrapper<>(systemJobLog);
+ return systemJobLogMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<SystemJobLog> findPage(PageWrap<QuerySystemJobLogDTO> pageWrap) {
+ IPage<SystemJobLog> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<SystemJobLog> queryWrapper = new QueryWrapper<>();
+ Utils.MP.blankToNull(pageWrap.getModel());
+ queryWrapper.lambda()
+ .eq(pageWrap.getModel().getJobId() != null, SystemJobLog::getJobId, pageWrap.getModel().getJobId())
+ .eq(pageWrap.getModel().getSnippetCode() != null, SystemJobLog::getSnippetCode, pageWrap.getModel().getSnippetCode())
+ .eq(pageWrap.getModel().getJobDistributeGroup() != null, SystemJobLog::getJobDistributeGroup, pageWrap.getModel().getJobDistributeGroup())
+ .ge(pageWrap.getModel().getBusinessTime() != null, SystemJobLog::getBusinessTime, Utils.Date.getStart(pageWrap.getModel().getBusinessTime()))
+ .le(pageWrap.getModel().getBusinessTime() != null, SystemJobLog::getBusinessTime, Utils.Date.getEnd(pageWrap.getModel().getBusinessTime()))
+ .eq(pageWrap.getModel().getServerIp() != null, SystemJobLog::getServerIp, pageWrap.getModel().getServerIp())
+ .eq(pageWrap.getModel().getTriggerType() != null, SystemJobLog::getTriggerType, pageWrap.getModel().getTriggerType())
+ .eq(pageWrap.getModel().getStatus() != null, SystemJobLog::getStatus, pageWrap.getModel().getStatus())
+ .ge(pageWrap.getModel().getCreateTime() != null, SystemJobLog::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()))
+ .le(pageWrap.getModel().getCreateTime() != null, SystemJobLog::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()));
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(systemJobLogMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(SystemJobLog systemJobLog) {
+ QueryWrapper<SystemJobLog> wrapper = new QueryWrapper<>(systemJobLog);
+ return systemJobLogMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemJobServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemJobServiceImpl.java
new file mode 100644
index 0000000..757c4fa
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemJobServiceImpl.java
@@ -0,0 +1,87 @@
+package com.doumee.service.system.impl;
+
+import com.doumee.dao.system.SystemJobMapper;
+import com.doumee.dao.system.model.SystemJob;
+import com.doumee.service.system.SystemJobService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 绯荤粺瀹氭椂浠诲姟Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemJobServiceImpl implements SystemJobService {
+
+ @Autowired
+ private SystemJobMapper systemJobMapper;
+
+ @Override
+ public Integer create(SystemJob systemJob) {
+ systemJobMapper.insert(systemJob);
+ return systemJob.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ systemJobMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(SystemJob systemJob) {
+ UpdateWrapper<SystemJob> deleteWrapper = new UpdateWrapper<>(systemJob);
+ systemJobMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ systemJobMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(SystemJob systemJob) {
+ systemJobMapper.updateById(systemJob);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<SystemJob> systemJobs) {
+ if (CollectionUtils.isEmpty(systemJobs)) {
+ return;
+ }
+ for (SystemJob systemJob: systemJobs) {
+ this.updateById(systemJob);
+ }
+ }
+
+ @Override
+ public SystemJob findById(Integer id) {
+ return systemJobMapper.selectById(id);
+ }
+
+ @Override
+ public SystemJob findOne(SystemJob systemJob) {
+ QueryWrapper<SystemJob> wrapper = new QueryWrapper<>(systemJob);
+ return systemJobMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemJob> findList(SystemJob systemJob) {
+ QueryWrapper<SystemJob> wrapper = new QueryWrapper<>(systemJob);
+ return systemJobMapper.selectList(wrapper);
+ }
+
+ @Override
+ public long count(SystemJob systemJob) {
+ QueryWrapper<SystemJob> wrapper = new QueryWrapper<>(systemJob);
+ return systemJobMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemJobSnippetServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemJobSnippetServiceImpl.java
new file mode 100644
index 0000000..147b498
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemJobSnippetServiceImpl.java
@@ -0,0 +1,112 @@
+package com.doumee.service.system.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.SystemJobSnippetMapper;
+import com.doumee.dao.system.model.SystemJobSnippet;
+import com.doumee.service.system.SystemJobSnippetService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 瀹氭椂浠诲姟鐗囨Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemJobSnippetServiceImpl implements SystemJobSnippetService {
+
+ @Autowired
+ private SystemJobSnippetMapper systemJobSnippetMapper;
+
+ @Override
+ public Integer create(SystemJobSnippet systemJobSnippet) {
+ systemJobSnippetMapper.insert(systemJobSnippet);
+ return systemJobSnippet.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ systemJobSnippetMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(SystemJobSnippet systemJobSnippet) {
+ UpdateWrapper<SystemJobSnippet> deleteWrapper = new UpdateWrapper<>(systemJobSnippet);
+ systemJobSnippetMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) {
+ return;
+ }
+ systemJobSnippetMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(SystemJobSnippet systemJobSnippet) {
+ systemJobSnippetMapper.updateById(systemJobSnippet);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<SystemJobSnippet> systemJobSnippets) {
+ if (CollectionUtils.isEmpty(systemJobSnippets)) {
+ return;
+ }
+ for (SystemJobSnippet systemJobSnippet: systemJobSnippets) {
+ this.updateById(systemJobSnippet);
+ }
+ }
+
+ @Override
+ public SystemJobSnippet findById(Integer id) {
+ return systemJobSnippetMapper.selectById(id);
+ }
+
+ @Override
+ public SystemJobSnippet findOne(SystemJobSnippet systemJobSnippet) {
+ QueryWrapper<SystemJobSnippet> wrapper = new QueryWrapper<>(systemJobSnippet);
+ return systemJobSnippetMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemJobSnippet> findList(SystemJobSnippet systemJobSnippet) {
+ QueryWrapper<SystemJobSnippet> wrapper = new QueryWrapper<>(systemJobSnippet);
+ return systemJobSnippetMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<SystemJobSnippet> findPage(PageWrap<SystemJobSnippet> pageWrap) {
+ IPage<SystemJobSnippet> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<SystemJobSnippet> queryWrapper = new QueryWrapper<>();
+ Utils.MP.blankToNull(pageWrap.getModel());
+ queryWrapper.lambda()
+ .eq(pageWrap.getModel().getJobId() != null, SystemJobSnippet::getJobId, pageWrap.getModel().getJobId())
+ .eq(pageWrap.getModel().getSnippetCode() != null, SystemJobSnippet::getSnippetCode, pageWrap.getModel().getSnippetCode())
+ .eq(pageWrap.getModel().getJobDistributeGroup() != null, SystemJobSnippet::getJobDistributeGroup, pageWrap.getModel().getJobDistributeGroup());
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(systemJobSnippetMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(SystemJobSnippet systemJobSnippet) {
+ QueryWrapper<SystemJobSnippet> wrapper = new QueryWrapper<>(systemJobSnippet);
+ return systemJobSnippetMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemLoginLogServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemLoginLogServiceImpl.java
new file mode 100644
index 0000000..65c7fda
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemLoginLogServiceImpl.java
@@ -0,0 +1,132 @@
+package com.doumee.service.system.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.SystemLoginLogMapper;
+import com.doumee.dao.system.dto.QuerySystemLoginLogDTO;
+import com.doumee.dao.system.model.SystemLoginLog;
+import com.doumee.dao.system.model.SystemTraceLog;
+import com.doumee.service.system.SystemLoginLogService;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 鐧诲綍鏃ュ織Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemLoginLogServiceImpl implements SystemLoginLogService {
+
+ @Autowired
+ private SystemLoginLogMapper systemLoginLogMapper;
+
+ @Override
+ public Integer create(SystemLoginLog systemLoginLog) {
+ systemLoginLogMapper.insert(systemLoginLog);
+ return systemLoginLog.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ systemLoginLogMapper.deleteById(id);
+ }
+
+ @Override
+ public void delete(SystemLoginLog systemLoginLog) {
+ UpdateWrapper<SystemLoginLog> deleteWrapper = new UpdateWrapper<>(systemLoginLog);
+ systemLoginLogMapper.delete(deleteWrapper);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) return;
+ systemLoginLogMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(SystemLoginLog systemLoginLog) {
+ systemLoginLogMapper.updateById(systemLoginLog);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<SystemLoginLog> systemLoginLogs) {
+ if (CollectionUtils.isEmpty(systemLoginLogs)) return;
+ for (SystemLoginLog systemLoginLog: systemLoginLogs) {
+ this.updateById(systemLoginLog);
+ }
+ }
+
+ @Override
+ public SystemLoginLog findById(Integer id) {
+ return systemLoginLogMapper.selectById(id);
+ }
+
+ @Override
+ public SystemLoginLog findOne(SystemLoginLog systemLoginLog) {
+ Wrapper<SystemLoginLog> wrapper = new QueryWrapper<>(systemLoginLog);
+ return systemLoginLogMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemLoginLog> findList(SystemLoginLog systemLoginLog) {
+ Wrapper<SystemLoginLog> wrapper = new QueryWrapper<>(systemLoginLog);
+ return systemLoginLogMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<SystemLoginLog> findPage(PageWrap<QuerySystemLoginLogDTO> pageWrap) {
+ IPage<SystemLoginLog> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<SystemLoginLog> queryWrapper = new QueryWrapper<>();
+
+ // 鐧诲綍鐢ㄦ埛鍚�
+ if (StringUtils.isNotBlank(pageWrap.getModel().getLoginUsername())) {
+ queryWrapper.lambda().like(SystemLoginLog::getLoginUsername, pageWrap.getModel().getLoginUsername());
+ }
+ // 鐧诲綍IP
+ if (StringUtils.isNotBlank(pageWrap.getModel().getIp())) {
+ queryWrapper.lambda().eq(SystemLoginLog::getIp, pageWrap.getModel().getIp());
+ }
+ // 鏈嶅姟鍣↖P
+ if (StringUtils.isNotBlank(pageWrap.getModel().getServerIp())) {
+ queryWrapper.lambda().eq(SystemLoginLog::getServerIp, pageWrap.getModel().getServerIp());
+ }
+ // 鐧诲綍鐘舵��
+ if (pageWrap.getModel().getSuccess() != null) {
+ queryWrapper.lambda().eq(SystemLoginLog::getSuccess, pageWrap.getModel().getSuccess());
+ }
+ // 鐧诲綍寮�濮嬫椂闂�
+ if (pageWrap.getModel().getStartTime() != null) {
+ queryWrapper.lambda().ge(SystemLoginLog::getLoginTime, pageWrap.getModel().getStartTime());
+ }
+ // 鐧诲綍缁撴潫鏃堕棿
+ if (pageWrap.getModel().getStartTime() != null) {
+ queryWrapper.lambda().lt(SystemLoginLog::getLoginTime, pageWrap.getModel().getEndTime());
+ }
+ // 瀛楁鎺掑簭
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase("DESC")) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(systemLoginLogMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(SystemLoginLog systemLoginLog) {
+ Wrapper<SystemLoginLog> wrapper = new QueryWrapper<>(systemLoginLog);
+ return systemLoginLogMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java
new file mode 100644
index 0000000..ba21070
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java
@@ -0,0 +1,76 @@
+package com.doumee.service.system.impl;
+
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.model.LoginUserInfo;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.dto.LoginDTO;
+import com.doumee.dao.system.model.SystemLoginLog;
+import com.doumee.service.common.CaptchaService;
+import com.doumee.service.system.SystemLoginLogService;
+import com.doumee.service.system.SystemLoginService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.subject.Subject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+
+@Slf4j
+@Service
+public class SystemLoginServiceImpl implements SystemLoginService {
+
+ @Value("${project.version}")
+ private String systemVersion;
+
+ @Autowired
+ private CaptchaService captchaService;
+
+ @Autowired
+ private SystemLoginLogService systemLoginLogService;
+
+ @Override
+ public String loginByPassword(LoginDTO dto, HttpServletRequest request) {
+ SystemLoginLog loginLog = new SystemLoginLog();
+ loginLog.setLoginUsername(dto.getUsername());
+ loginLog.setLoginTime(new Date());
+ loginLog.setSystemVersion(systemVersion);
+ loginLog.setIp(Utils.User_Client.getIP(request));
+// loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
+ loginLog.setPlatform(Utils.User_Client.getPlatform(request));
+ loginLog.setClientInfo(Utils.User_Client.getBrowser(request));
+ loginLog.setOsInfo(Utils.User_Client.getOS(request));
+ loginLog.setServerIp(Utils.Server.getIP());
+ // 鏍¢獙楠岃瘉鐮�
+ try {
+ captchaService.check(dto.getUuid(), dto.getCode());
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ loginLog.setReason(e.getMessage().length() > 200 ? (e.getMessage().substring(0, 190) + "...") : e.getMessage());
+ loginLog.setSuccess(Boolean.FALSE);
+ systemLoginLogService.create(loginLog);
+ throw e;
+ }
+ // 鏍¢獙鐢ㄦ埛鍚嶅拰瀵嗙爜
+ Subject subject = SecurityUtils.getSubject();
+ UsernamePasswordToken token = new UsernamePasswordToken(dto.getUsername(), dto.getPassword());
+ try {
+ subject.login(token);
+ loginLog.setUserId(((LoginUserInfo)subject.getPrincipal()).getId());
+ loginLog.setSuccess(Boolean.TRUE);
+ systemLoginLogService.create(loginLog);
+ return (String)subject.getSession().getId();
+ } catch (AuthenticationException e) {
+ log.error(ResponseStatus.ACCOUNT_INCORRECT.getMessage(), e);
+ loginLog.setReason(e.getMessage().length() > 200 ? (e.getMessage().substring(0, 190) + "...") : e.getMessage());
+ loginLog.setSuccess(Boolean.FALSE);
+ systemLoginLogService.create(loginLog);
+ throw new BusinessException(ResponseStatus.ACCOUNT_INCORRECT);
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemMenuServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemMenuServiceImpl.java
new file mode 100644
index 0000000..5261033
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemMenuServiceImpl.java
@@ -0,0 +1,140 @@
+package com.doumee.service.system.impl;
+
+import com.doumee.dao.system.SystemMenuMapper;
+import com.doumee.dao.system.model.SystemMenu;
+import com.doumee.dao.system.vo.SystemMenuListVO;
+import com.doumee.service.system.SystemMenuService;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+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.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 绯荤粺鑿滃崟Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemMenuServiceImpl implements SystemMenuService {
+
+ @Autowired
+ private SystemMenuMapper systemMenuMapper;
+
+ @Override
+ public Integer create(SystemMenu systemMenu) {
+ systemMenuMapper.insert(systemMenu);
+ return systemMenu.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemMenu systemMenu = new SystemMenu();
+ systemMenu.setId(id);
+ systemMenu.setDeleted(Boolean.TRUE);
+ this.updateById(systemMenu);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) return;
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ public void updateById(SystemMenu systemMenu) {
+ systemMenuMapper.updateById(systemMenu);
+ }
+
+ @Override
+ @Transactional
+ public void updateByIdInBatch(List<SystemMenu> systemMenus) {
+ if (CollectionUtils.isEmpty(systemMenus)) return;
+ for (SystemMenu systemMenu: systemMenus) {
+ this.updateById(systemMenu);
+ }
+ }
+
+ @Override
+ public SystemMenu findById(Integer id) {
+ return systemMenuMapper.selectById(id);
+ }
+
+ @Override
+ public SystemMenu findOne(SystemMenu systemMenu) {
+ Wrapper<SystemMenu> wrapper = new QueryWrapper<>(systemMenu);
+ return systemMenuMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemMenu> findList(SystemMenu systemMenu) {
+ QueryWrapper<SystemMenu> wrapper = new QueryWrapper<>(systemMenu);
+ wrapper.lambda().orderByAsc(SystemMenu::getSort);
+ return systemMenuMapper.selectList(wrapper);
+ }
+
+ @Override
+ public List<SystemMenuListVO> findList() {
+ return systemMenuMapper.selectManageList();
+ }
+
+ @Override
+ public List<SystemMenu> findRootList() {
+ QueryWrapper<SystemMenu> queryWrapper = new QueryWrapper<>();
+ queryWrapper.lambda()
+ .isNull(SystemMenu::getParentId)
+ .eq(SystemMenu::getDeleted, Boolean.FALSE)
+ .orderByAsc(SystemMenu::getSort);
+ return systemMenuMapper.selectList(queryWrapper);
+ }
+
+ @Override
+ public List<SystemMenu> findByUserId(Integer userId) {
+ return systemMenuMapper.selectByUserId(userId);
+ }
+
+ @Override
+ public List<SystemMenu> findByRoleId(Integer roleId) {
+ return systemMenuMapper.selectByRoleId(roleId);
+ }
+
+ @Override
+ public long count(SystemMenu systemMenu) {
+ Wrapper<SystemMenu> wrapper = new QueryWrapper<>(systemMenu);
+ return systemMenuMapper.selectCount(wrapper);
+ }
+
+ @Override
+ public List<Integer> findChildren(Integer menuId) {
+ List<Integer> pool = new ArrayList<>();
+ this.fillChildren(pool, Arrays.asList(menuId));
+ return pool;
+ }
+
+ /**
+ * 鑾峰彇瀛愰儴闂↖D
+ * @author dm
+ * @date 2025/03/31 16:44
+ */
+ private void fillChildren(List<Integer> pool, List<Integer> parentIds) {
+ QueryWrapper<SystemMenu> queryWrapper = new QueryWrapper<>();
+ queryWrapper.lambda()
+ .eq(SystemMenu::getDeleted, Boolean.FALSE)
+ .in(SystemMenu::getParentId, parentIds);
+ List<SystemMenu> departments = systemMenuMapper.selectList(queryWrapper);
+ List<Integer> ids = departments.stream().map(SystemMenu::getId).collect(Collectors.toList());
+ if (ids.size() > 0) {
+ pool.addAll(ids);
+ this.fillChildren(pool, ids);
+ }
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemPermissionServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemPermissionServiceImpl.java
new file mode 100644
index 0000000..91b4755
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemPermissionServiceImpl.java
@@ -0,0 +1,189 @@
+package com.doumee.service.system.impl;
+
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.doumee.dao.system.SystemPermissionMapper;
+import com.doumee.dao.system.dto.DeleteSystemPermissionDTO;
+import com.doumee.dao.system.model.SystemPermission;
+import com.doumee.dao.system.vo.SystemPermissionListVO;
+import com.doumee.service.system.SystemPermissionService;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
+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.ArrayList;
+import java.util.List;
+
+/**
+ * 绯荤粺鏉冮檺Service瀹炵幇
+ *
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemPermissionServiceImpl implements SystemPermissionService {
+
+ @Autowired
+ private SystemPermissionMapper systemPermissionMapper;
+
+ @Override
+ public Integer create(SystemPermission systemPermission) {
+ systemPermissionMapper.insert(systemPermission);
+ return systemPermission.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemPermission systemPermission = new SystemPermission();
+ systemPermission.setId(id);
+ systemPermission.setDeleted(Boolean.TRUE);
+ this.updateById(systemPermission);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) return;
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ public void delete(DeleteSystemPermissionDTO dto) {
+ UpdateWrapper<SystemPermission> deleteWrapper = new UpdateWrapper<>();
+ deleteWrapper.lambda()
+ .set(SystemPermission::getDeleted, Boolean.TRUE)
+ .eq(dto.getId() != null, SystemPermission::getId, dto.getId())
+ .likeLeft(dto.getModulePrefix() != null, SystemPermission::getModule, dto.getModulePrefix());
+ systemPermissionMapper.update(null, deleteWrapper);
+ }
+
+ @Override
+ public void deleteInBatch(List<DeleteSystemPermissionDTO> dtos) {
+ if (CollectionUtils.isEmpty(dtos)) {
+ return;
+ }
+ for (DeleteSystemPermissionDTO dto : dtos) {
+ this.delete(dto);
+ }
+ }
+
+ @Override
+ public void updateById(SystemPermission systemPermission) {
+ systemPermissionMapper.updateById(systemPermission);
+ }
+
+ @Override
+ @Transactional
+ public void updateByIdInBatch(List<SystemPermission> systemPermissions) {
+ if (CollectionUtils.isEmpty(systemPermissions)) return;
+ for (SystemPermission systemPermission : systemPermissions) {
+ this.updateById(systemPermission);
+ }
+ }
+
+ @Override
+ public SystemPermission findById(Integer id) {
+ return systemPermissionMapper.selectById(id);
+ }
+
+ @Override
+ public List<SystemPermission> findByUserId(Integer userId) {
+ return systemPermissionMapper.selectByUserId(userId);
+ }
+
+ @Override
+ public List<SystemPermission> findByRoleId(Integer roleId) {
+ return systemPermissionMapper.selectByRoleId(roleId);
+ }
+
+ @Override
+ public SystemPermission findOne(SystemPermission systemPermission) {
+ Wrapper<SystemPermission> wrapper = new QueryWrapper<>(systemPermission);
+ return systemPermissionMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemPermission> findList(SystemPermission systemPermission) {
+ Wrapper<SystemPermission> wrapper = new QueryWrapper<>(systemPermission);
+ return systemPermissionMapper.selectList(wrapper);
+ }
+
+ @Override
+ public List<SystemPermissionListVO> findTree() {
+ List<SystemPermissionListVO> permissionList = systemPermissionMapper.selectManageList();
+ List<SystemPermissionListVO> tree = new ArrayList<>();
+ for (SystemPermissionListVO permission : permissionList) {
+ // 娌℃湁妯″潡鐨勬潈闄愰粯璁ゅ綊灞炰负"鍏跺畠"妯″潡
+ if (StringUtils.isBlank(permission.getModule())) {
+ permission.setModule("鍏跺畠");
+ }
+ // 鍒嗚В妯″潡
+ String[] modulePaths = permission.getModule().split("/");
+ SystemPermissionListVO target = null;
+ SystemPermissionListVO parent = null;
+ List<String> paths = new ArrayList<>();
+ for (String path : modulePaths) {
+ paths.add(path);
+ // 鏌ユ壘妯″潡
+ target = this.getTargetNode(tree, paths);
+ // 濡傛灉妯″潡涓嶅瓨鍦紝鍒欐坊鍔犱竴涓瓙妯″潡
+ if (target == null) {
+ target = new SystemPermissionListVO();
+ target.setId(Integer.valueOf(RandomStringUtils.randomNumeric(6)) * -1);
+ target.setLevel(paths.size() - 1);
+ target.setType("module");
+ target.setName(path);
+ target.setModulePath(StringUtils.join(paths, "/"));
+ target.setChildren(new ArrayList<>());
+ if (parent != null) {
+ parent.getChildren().add(target);
+ } else {
+ tree.add(target);
+ }
+ }
+ parent = target;
+ }
+ // 灏嗘潈闄愭坊鍔犺繘妯″潡涓�
+ if (target != null) {
+ target.getChildren().add(permission);
+ }
+ }
+ return tree;
+ }
+
+ @Override
+ public long count(SystemPermission systemPermission) {
+ Wrapper<SystemPermission> wrapper = new QueryWrapper<>(systemPermission);
+ return systemPermissionMapper.selectCount(wrapper);
+ }
+
+ /**
+ * 鏌ユ壘鐩爣鑺傜偣
+ * @param tree 鑺傜偣鏍�
+ * @param paths 妯″潡璺緞
+ * @return
+ */
+ private SystemPermissionListVO getTargetNode(List<SystemPermissionListVO> tree, List<String> paths) {
+ List<SystemPermissionListVO> list = tree;
+ List<SystemPermissionListVO> nodeStack = new ArrayList<>();
+ for (String path : paths) {
+ if (list == null) {
+ break;
+ }
+ for (SystemPermissionListVO permission : list) {
+ if (path.equals(permission.getName()) && "module".equals(permission.getType())) {
+ nodeStack.add(permission);
+ list = permission.getChildren();
+ break;
+ }
+ }
+ }
+ return nodeStack.size() == paths.size() ? nodeStack.get(nodeStack.size() - 1) : null;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemRoleMenuServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemRoleMenuServiceImpl.java
new file mode 100644
index 0000000..b680326
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemRoleMenuServiceImpl.java
@@ -0,0 +1,113 @@
+package com.doumee.service.system.impl;
+
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.SystemRoleMenuMapper;
+import com.doumee.dao.system.model.SystemRoleMenu;
+import com.doumee.service.system.SystemRoleMenuService;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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;
+
+/**
+ * 瑙掕壊鑿滃崟鍏宠仈Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemRoleMenuServiceImpl implements SystemRoleMenuService {
+
+ @Autowired
+ private SystemRoleMenuMapper systemRoleMenuMapper;
+
+ @Override
+ public Integer create(SystemRoleMenu systemRoleMenu) {
+ systemRoleMenuMapper.insert(systemRoleMenu);
+ return systemRoleMenu.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemRoleMenu systemRoleMenu = new SystemRoleMenu();
+ systemRoleMenu.setId(id);
+ systemRoleMenu.setDeleted(Boolean.TRUE);
+ this.updateById(systemRoleMenu);
+ }
+
+ @Override
+ public void delete(SystemRoleMenu systemRoleMenu) {
+ SystemRoleMenu newRoleMenu = new SystemRoleMenu();
+ newRoleMenu.setDeleted(Boolean.TRUE);
+ UpdateWrapper<SystemRoleMenu> updateWrapper = new UpdateWrapper<>(systemRoleMenu);
+ systemRoleMenuMapper.update(newRoleMenu, updateWrapper);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) return;
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ public void updateById(SystemRoleMenu systemRoleMenu) {
+ systemRoleMenuMapper.updateById(systemRoleMenu);
+ }
+
+ @Override
+ @Transactional
+ public void updateByIdInBatch(List<SystemRoleMenu> systemRoleMenus) {
+ if (CollectionUtils.isEmpty(systemRoleMenus)) return;
+ for (SystemRoleMenu systemRoleMenu: systemRoleMenus) {
+ this.updateById(systemRoleMenu);
+ }
+ }
+
+ @Override
+ public SystemRoleMenu findById(Integer id) {
+ return systemRoleMenuMapper.selectById(id);
+ }
+
+ @Override
+ public SystemRoleMenu findOne(SystemRoleMenu systemRoleMenu) {
+ Wrapper<SystemRoleMenu> wrapper = new QueryWrapper<>(systemRoleMenu);
+ return systemRoleMenuMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemRoleMenu> findList(SystemRoleMenu systemRoleMenu) {
+ Wrapper<SystemRoleMenu> wrapper = new QueryWrapper<>(systemRoleMenu);
+ return systemRoleMenuMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<SystemRoleMenu> findPage(PageWrap<SystemRoleMenu> pageWrap) {
+ IPage<SystemRoleMenu> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<SystemRoleMenu> queryWrapper = new QueryWrapper<>(Utils.MP.blankToNull(pageWrap.getModel()));
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase("DESC")) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(systemRoleMenuMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(SystemRoleMenu systemRoleMenu) {
+ Wrapper<SystemRoleMenu> wrapper = new QueryWrapper<>(systemRoleMenu);
+ return systemRoleMenuMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemRolePermissionServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemRolePermissionServiceImpl.java
new file mode 100644
index 0000000..eaf02bc
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemRolePermissionServiceImpl.java
@@ -0,0 +1,113 @@
+package com.doumee.service.system.impl;
+
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.SystemRolePermissionMapper;
+import com.doumee.dao.system.model.SystemRolePermission;
+import com.doumee.service.system.SystemRolePermissionService;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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;
+
+/**
+ * 瑙掕壊鏉冮檺鍏宠仈Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemRolePermissionServiceImpl implements SystemRolePermissionService {
+
+ @Autowired
+ private SystemRolePermissionMapper systemRolePermissionMapper;
+
+ @Override
+ public Integer create(SystemRolePermission systemRolePermission) {
+ systemRolePermissionMapper.insert(systemRolePermission);
+ return systemRolePermission.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemRolePermission systemRolePermission = new SystemRolePermission();
+ systemRolePermission.setId(id);
+ systemRolePermission.setDeleted(Boolean.TRUE);
+ this.updateById(systemRolePermission);
+ }
+
+ @Override
+ public void delete(SystemRolePermission systemRolePermission) {
+ SystemRolePermission newPermission = new SystemRolePermission();
+ newPermission.setDeleted(Boolean.TRUE);
+ UpdateWrapper<SystemRolePermission> updateWrapper = new UpdateWrapper<>(systemRolePermission);
+ systemRolePermissionMapper.update(newPermission, updateWrapper);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) return;
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ public void updateById(SystemRolePermission systemRolePermission) {
+ systemRolePermissionMapper.updateById(systemRolePermission);
+ }
+
+ @Override
+ @Transactional
+ public void updateByIdInBatch(List<SystemRolePermission> systemRolePermissions) {
+ if (CollectionUtils.isEmpty(systemRolePermissions)) return;
+ for (SystemRolePermission systemRolePermission: systemRolePermissions) {
+ this.updateById(systemRolePermission);
+ }
+ }
+
+ @Override
+ public SystemRolePermission findById(Integer id) {
+ return systemRolePermissionMapper.selectById(id);
+ }
+
+ @Override
+ public SystemRolePermission findOne(SystemRolePermission systemRolePermission) {
+ Wrapper<SystemRolePermission> wrapper = new QueryWrapper<>(systemRolePermission);
+ return systemRolePermissionMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemRolePermission> findList(SystemRolePermission systemRolePermission) {
+ Wrapper<SystemRolePermission> wrapper = new QueryWrapper<>(systemRolePermission);
+ return systemRolePermissionMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<SystemRolePermission> findPage(PageWrap<SystemRolePermission> pageWrap) {
+ IPage<SystemRolePermission> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<SystemRolePermission> queryWrapper = new QueryWrapper<>(Utils.MP.blankToNull(pageWrap.getModel()));
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase("DESC")) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(systemRolePermissionMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(SystemRolePermission systemRolePermission) {
+ Wrapper<SystemRolePermission> wrapper = new QueryWrapper<>(systemRolePermission);
+ return systemRolePermissionMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemRoleServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemRoleServiceImpl.java
new file mode 100644
index 0000000..80b2517
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemRoleServiceImpl.java
@@ -0,0 +1,115 @@
+package com.doumee.service.system.impl;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.SystemRoleMapper;
+import com.doumee.dao.system.dto.QuerySystemRoleDTO;
+import com.doumee.dao.system.model.SystemRole;
+import com.doumee.dao.system.vo.SystemRoleListVO;
+import com.doumee.service.system.SystemMenuService;
+import com.doumee.service.system.SystemPermissionService;
+import com.doumee.service.system.SystemRoleService;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+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;
+
+/**
+ * 绯荤粺瑙掕壊Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemRoleServiceImpl implements SystemRoleService {
+
+ @Autowired
+ private SystemRoleMapper systemRoleMapper;
+
+ @Autowired
+ private SystemMenuService systemMenuService;
+
+ @Autowired
+ private SystemPermissionService systemPermissionService;
+
+ @Override
+ public Integer create(SystemRole systemRole) {
+ systemRoleMapper.insert(systemRole);
+ return systemRole.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemRole systemRole = new SystemRole();
+ systemRole.setId(id);
+ systemRole.setDeleted(Boolean.TRUE);
+ this.updateById(systemRole);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) return;
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ public void updateById(SystemRole systemRole) {
+ systemRoleMapper.updateById(systemRole);
+ }
+
+ @Override
+ @Transactional
+ public void updateByIdInBatch(List<SystemRole> systemRoles) {
+ if (CollectionUtils.isEmpty(systemRoles)) return;
+ for (SystemRole systemRole: systemRoles) {
+ this.updateById(systemRole);
+ }
+ }
+
+ @Override
+ public SystemRole findById(Integer id) {
+ return systemRoleMapper.selectById(id);
+ }
+
+ @Override
+ public List<SystemRole> findByUserId(Integer userId) {
+ return systemRoleMapper.selectByUserId(userId);
+ }
+
+ @Override
+ public SystemRole findOne(SystemRole systemRole) {
+ Wrapper<SystemRole> wrapper = new QueryWrapper<>(systemRole);
+ return systemRoleMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemRole> findList(SystemRole systemRole) {
+ Wrapper<SystemRole> wrapper = new QueryWrapper<>(systemRole);
+ return systemRoleMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<SystemRoleListVO> findPage(PageWrap<QuerySystemRoleDTO> pageWrap) {
+ PageHelper.startPage(pageWrap.getPage(), pageWrap.getCapacity());
+ List<SystemRoleListVO> roleList = systemRoleMapper.selectManageList(pageWrap.getModel(), pageWrap.getOrderByClause());
+ for (SystemRoleListVO role : roleList) {
+ role.setMenus(systemMenuService.findByRoleId(role.getId()));
+ role.setPermissions(systemPermissionService.findByRoleId(role.getId()));
+ }
+ return PageData.from(new PageInfo<>(roleList));
+ }
+
+ @Override
+ public long count(SystemRole systemRole) {
+ Wrapper<SystemRole> wrapper = new QueryWrapper<>(systemRole);
+ return systemRoleMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemTraceLogServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemTraceLogServiceImpl.java
new file mode 100644
index 0000000..435a9ba
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemTraceLogServiceImpl.java
@@ -0,0 +1,126 @@
+package com.doumee.service.system.impl;
+
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.SystemTraceLogMapper;
+import com.doumee.dao.system.dto.QuerySystemTraceLogDTO;
+import com.doumee.dao.system.model.SystemTraceLog;
+import com.doumee.service.system.SystemTraceLogService;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 璺熻釜鏃ュ織Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemTraceLogServiceImpl implements SystemTraceLogService {
+
+ @Autowired
+ private SystemTraceLogMapper systemTraceLogMapper;
+
+ @Override
+ public Integer create(SystemTraceLog systemTraceLog) {
+ systemTraceLogMapper.insert(systemTraceLog);
+ return systemTraceLog.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ systemTraceLogMapper.deleteById(id);
+ }
+
+ @Override
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) return;
+ systemTraceLogMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void updateById(SystemTraceLog systemTraceLog) {
+ systemTraceLogMapper.updateById(systemTraceLog);
+ }
+
+ @Override
+ public void updateByIdInBatch(List<SystemTraceLog> systemTraceLogs) {
+ if (CollectionUtils.isEmpty(systemTraceLogs)) return;
+ for (SystemTraceLog systemTraceLog: systemTraceLogs) {
+ this.updateById(systemTraceLog);
+ }
+ }
+
+ @Override
+ public SystemTraceLog findById(Integer id) {
+ return systemTraceLogMapper.selectById(id);
+ }
+
+ @Override
+ public SystemTraceLog findOne(SystemTraceLog systemTraceLog) {
+ Wrapper<SystemTraceLog> wrapper = new QueryWrapper<>(systemTraceLog);
+ return systemTraceLogMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemTraceLog> findList(SystemTraceLog systemTraceLog) {
+ Wrapper<SystemTraceLog> wrapper = new QueryWrapper<>(systemTraceLog);
+ return systemTraceLogMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<SystemTraceLog> findPage(PageWrap<QuerySystemTraceLogDTO> pageWrap) {
+ IPage<SystemTraceLog> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<SystemTraceLog> queryWrapper = new QueryWrapper<>();
+ // 濮撳悕
+ if (StringUtils.isNotBlank(pageWrap.getModel().getUserRealname())) {
+ queryWrapper.lambda().like(SystemTraceLog::getUserRealname, pageWrap.getModel().getUserRealname());
+ }
+ // 涓氬姟妯″潡
+ if (StringUtils.isNotBlank(pageWrap.getModel().getOperaModule())) {
+ queryWrapper.lambda().like(SystemTraceLog::getOperaModule, pageWrap.getModel().getOperaModule());
+ }
+ // 璇锋眰鍦板潃
+ if (StringUtils.isNotBlank(pageWrap.getModel().getRequestUri())) {
+ queryWrapper.lambda().like(SystemTraceLog::getRequestUri, pageWrap.getModel().getRequestUri());
+ }
+ // 鐘舵��
+ if (pageWrap.getModel().getStatus() != null) {
+ queryWrapper.lambda().eq(SystemTraceLog::getStatus, pageWrap.getModel().getStatus());
+ }
+ // 寮傚父绛夌骇
+ if (pageWrap.getModel().getExceptionLevel() != null) {
+ queryWrapper.lambda().eq(SystemTraceLog::getExceptionLevel, pageWrap.getModel().getExceptionLevel());
+ }
+ // 鎿嶄綔寮�濮嬫椂闂�
+ if (pageWrap.getModel().getStartTime() != null) {
+ queryWrapper.lambda().ge(SystemTraceLog::getOperaTime, pageWrap.getModel().getStartTime());
+ }
+ // 鎿嶄綔缁撴潫鏃堕棿
+ if (pageWrap.getModel().getEndTime() != null) {
+ queryWrapper.lambda().lt(SystemTraceLog::getOperaTime, pageWrap.getModel().getEndTime());
+ }
+ // 瀛楁鎺掑簭
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(systemTraceLogMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(SystemTraceLog systemTraceLog) {
+ Wrapper<SystemTraceLog> wrapper = new QueryWrapper<>(systemTraceLog);
+ return systemTraceLogMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemUserRoleServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemUserRoleServiceImpl.java
new file mode 100644
index 0000000..872723f
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemUserRoleServiceImpl.java
@@ -0,0 +1,113 @@
+package com.doumee.service.system.impl;
+
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.system.SystemUserRoleMapper;
+import com.doumee.dao.system.model.SystemUserRole;
+import com.doumee.service.system.SystemUserRoleService;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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;
+
+/**
+ * 鐢ㄦ埛瑙掕壊鍏宠仈Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemUserRoleServiceImpl implements SystemUserRoleService {
+
+ @Autowired
+ private SystemUserRoleMapper systemUserRoleMapper;
+
+ @Override
+ public Integer create(SystemUserRole systemUserRole) {
+ systemUserRoleMapper.insert(systemUserRole);
+ return systemUserRole.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemUserRole systemUserRole = new SystemUserRole();
+ systemUserRole.setId(id);
+ systemUserRole.setDeleted(Boolean.TRUE);
+ this.updateById(systemUserRole);
+ }
+
+ @Override
+ public void delete(SystemUserRole systemUserRole) {
+ SystemUserRole newUserRole = new SystemUserRole();
+ newUserRole.setDeleted(Boolean.TRUE);
+ UpdateWrapper<SystemUserRole> updateWrapper = new UpdateWrapper<>(systemUserRole);
+ systemUserRoleMapper.update(newUserRole, updateWrapper);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) return;
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ public void updateById(SystemUserRole systemUserRole) {
+ systemUserRoleMapper.updateById(systemUserRole);
+ }
+
+ @Override
+ @Transactional
+ public void updateByIdInBatch(List<SystemUserRole> systemUserRoles) {
+ if (CollectionUtils.isEmpty(systemUserRoles)) return;
+ for (SystemUserRole systemUserRole: systemUserRoles) {
+ this.updateById(systemUserRole);
+ }
+ }
+
+ @Override
+ public SystemUserRole findById(Integer id) {
+ return systemUserRoleMapper.selectById(id);
+ }
+
+ @Override
+ public SystemUserRole findOne(SystemUserRole systemUserRole) {
+ Wrapper<SystemUserRole> wrapper = new QueryWrapper<>(systemUserRole);
+ return systemUserRoleMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemUserRole> findList(SystemUserRole systemUserRole) {
+ Wrapper<SystemUserRole> wrapper = new QueryWrapper<>(systemUserRole);
+ return systemUserRoleMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<SystemUserRole> findPage(PageWrap<SystemUserRole> pageWrap) {
+ IPage<SystemUserRole> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+ QueryWrapper<SystemUserRole> queryWrapper = new QueryWrapper<>(Utils.MP.blankToNull(pageWrap.getModel()));
+ for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+ if (sortData.getDirection().equalsIgnoreCase("DESC")) {
+ queryWrapper.orderByDesc(sortData.getProperty());
+ } else {
+ queryWrapper.orderByAsc(sortData.getProperty());
+ }
+ }
+ return PageData.from(systemUserRoleMapper.selectPage(page, queryWrapper));
+ }
+
+ @Override
+ public long count(SystemUserRole systemUserRole) {
+ Wrapper<SystemUserRole> wrapper = new QueryWrapper<>(systemUserRole);
+ return systemUserRoleMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/service/system/impl/SystemUserServiceImpl.java b/server/services/src/main/java/com/doumee/service/system/impl/SystemUserServiceImpl.java
new file mode 100644
index 0000000..a341b0a
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/service/system/impl/SystemUserServiceImpl.java
@@ -0,0 +1,107 @@
+package com.doumee.service.system.impl;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.doumee.core.model.PageData;
+import com.doumee.core.model.PageWrap;
+import com.doumee.dao.system.SystemUserMapper;
+import com.doumee.dao.system.dto.QuerySystemUserDTO;
+import com.doumee.dao.system.model.SystemUser;
+import com.doumee.dao.system.vo.SystemUserListVO;
+import com.doumee.service.system.SystemRoleService;
+import com.doumee.service.system.SystemUserService;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+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;
+
+/**
+ * 绯荤粺鐢ㄦ埛Service瀹炵幇
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Service
+public class SystemUserServiceImpl implements SystemUserService {
+
+ @Autowired
+ private SystemUserMapper systemUserMapper;
+
+ @Autowired
+ private SystemRoleService systemRoleService;
+
+ @Override
+ public Integer create(SystemUser systemUser) {
+ systemUserMapper.insert(systemUser);
+ return systemUser.getId();
+ }
+
+ @Override
+ public void deleteById(Integer id) {
+ SystemUser systemUser = new SystemUser();
+ systemUser.setId(id);
+ systemUser.setDeleted(Boolean.TRUE);
+ this.updateById(systemUser);
+ }
+
+ @Override
+ @Transactional
+ public void deleteByIdInBatch(List<Integer> ids) {
+ if (CollectionUtils.isEmpty(ids)) return;
+ for (Integer id : ids) {
+ this.deleteById(id);
+ }
+ }
+
+ @Override
+ public void updateById(SystemUser systemUser) {
+ systemUserMapper.updateById(systemUser);
+ }
+
+ @Override
+ @Transactional
+ public void updateByIdInBatch(List<SystemUser> systemUsers) {
+ if (CollectionUtils.isEmpty(systemUsers)) return;
+ for (SystemUser systemUser: systemUsers) {
+ this.updateById(systemUser);
+ }
+ }
+
+ @Override
+ public SystemUser findById(Integer id) {
+ return systemUserMapper.selectById(id);
+ }
+
+ @Override
+ public SystemUser findOne(SystemUser systemUser) {
+ Wrapper<SystemUser> wrapper = new QueryWrapper<>(systemUser);
+ return systemUserMapper.selectOne(wrapper);
+ }
+
+ @Override
+ public List<SystemUser> findList(SystemUser systemUser) {
+ Wrapper<SystemUser> wrapper = new QueryWrapper<>(systemUser);
+ return systemUserMapper.selectList(wrapper);
+ }
+
+ @Override
+ public PageData<SystemUserListVO> findPage(PageWrap<QuerySystemUserDTO> pageWrap) {
+ // 鎵ц鏌ヨ
+ PageHelper.startPage(pageWrap.getPage(), pageWrap.getCapacity());
+ List<SystemUserListVO> userList = systemUserMapper.selectManageList(pageWrap.getModel(), pageWrap.getOrderByClause());
+ for (SystemUserListVO user : userList) {
+ // 鏌ヨ鐢ㄦ埛瑙掕壊鍒楄〃
+ user.setRoles(systemRoleService.findByUserId(user.getId()));
+ }
+ return PageData.from(new PageInfo<>(userList));
+ }
+
+ @Override
+ public long count(SystemUser systemUser) {
+ Wrapper<SystemUser> wrapper = new QueryWrapper<>(systemUser);
+ return systemUserMapper.selectCount(wrapper);
+ }
+}
diff --git a/server/services/src/main/resources/application-dev.yml b/server/services/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..3c673e9
--- /dev/null
+++ b/server/services/src/main/resources/application-dev.yml
@@ -0,0 +1,87 @@
+spring:
+ # 鏁版嵁婧愰厤缃�
+ datasource:
+ url: jdbc:mysql://192.168.0.211:3306/jinkuai?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
+ username: root
+ password: Doumee@168
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ type: com.alibaba.druid.pool.DruidDataSource
+ redis:
+ # database: 0
+ host: 127.0.0.1
+ port: 6379
+ password:
+ timeout: 5000 # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+ jackson:
+ time-zone: GMT+8
+ date-format: yyyy-MM-dd HH:mm:ss
+# mail:
+# username: jiangping0849@outlook.com
+# password: mwzaislgioyhxnig
+# host: smtp-mail.outlook.com
+# port: 587
+# default-encoding: UTF-8
+# properties:
+# mail:
+# debug: true
+# smtp:
+# ssl:
+# socketFactory:
+# class: com.sun.mail.util.MailSSLSocketFactory
+# fallback: false
+# auth: true
+# starttls:
+# enable: true
+# required: true
+ mail:
+ host: smtp.exmail.qq.com
+ username: jp@doumee.com
+ password: 2Jz9HFW2U7vRnCRu
+ default-encoding: UTF-8
+ properties:
+ mail:
+ smtp:
+ auth: true
+ starttls:
+ enable: true
+ required: true
+
+debug_model: true
+
+# Swagger閰嶇疆
+swagger:
+ host:
+ title: ${project.name}鎺ュ彛鏂囨。
+ description: ${project.name}鎺ュ彛鏂囨。
+ # 鍚敤Swagger锛岀敓浜х幆澧冨缓璁叧闂�
+ enabled: true
+ # 鍚敤swagger鍔犲瘑
+ enable-encrypt: true
+ # 绂佺敤swagger鏃剁殑閲嶅畾鍚戝湴鍧�
+ redirect-uri: /
+
+
+des_pwd: 123456SDFKDJF
+knife4j:
+ enable: true
+ basic:
+ enable: true
+ username: admin
+ password: 111111
+
+qiwei:
+ serviceurl: https://qyapi.weixin.qq.com
+
+aes:
+ encrypt:
+ open: true # 鏄惁寮�鍚姞瀵� true or false
+ showLog: true # 鏄惁鎵撳嵃鍔犺В瀵唋og true or false
+ publicKey: mN4Yn8Or8r7SH1w3 # AES瀵嗛挜
+ privateKey: # RSA绉侀挜
+ time: 600000
+
+upload:
+ type: ftp
+
+
+
diff --git a/server/services/src/main/resources/application-pro.yml b/server/services/src/main/resources/application-pro.yml
new file mode 100644
index 0000000..f3a7fdd
--- /dev/null
+++ b/server/services/src/main/resources/application-pro.yml
@@ -0,0 +1,57 @@
+spring:
+ # 鏁版嵁婧愰厤缃�
+ datasource:
+ url: jdbc:mysql://192.168.0.211:3306/jinkuai?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
+ username: root
+ password: Doumee@168
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ type: com.alibaba.druid.pool.DruidDataSource
+ redis:
+ # database: 0
+ host: 127.0.0.1
+ port: 6379
+ password:
+ timeout: 5000 # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+ jackson:
+ time-zone: GMT+8
+ date-format: yyyy-MM-dd HH:mm:ss
+ mail:
+ host: smtp.aliyun.com
+ port: 465
+ username: your_email@aliyun.com
+ password: your_password
+ properties:
+ mail:
+ smtp:
+ auth: true
+ starttls:
+ enable: true
+ required: true
+ ssl:
+ enable: true
+debug_model: true
+
+# Swagger閰嶇疆
+swagger:
+ host: 127.0.0.1
+ title: ${project.name}鎺ュ彛鏂囨。
+ description: ${project.name}鎺ュ彛鏂囨。
+ enabled: true
+ context-path:
+ # 绂佺敤swagger鏃剁殑閲嶅畾鍚戝湴鍧�
+ redirect-uri: /
+
+des_pwd: 123456SDFKDJF
+
+knife4j:
+ enable: true
+ basic:
+ enable: true
+ username: admin
+ password:
+
+upload:
+ type: blob
+
+qiwei:
+ serviceurl: https://wecom-qyapi.unilever-china.com/
\ No newline at end of file
diff --git a/server/services/src/main/resources/application-test.yml b/server/services/src/main/resources/application-test.yml
new file mode 100644
index 0000000..64a5f9d
--- /dev/null
+++ b/server/services/src/main/resources/application-test.yml
@@ -0,0 +1,77 @@
+spring:
+ # 鏁版嵁婧愰厤缃�
+ datasource:
+ url: jdbc:mysql://192.168.0.211:3306/jinkuai?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
+ username: root
+ password: Doumee@168
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ type: com.alibaba.druid.pool.DruidDataSource
+ redis:
+ # database: 0
+ host: 127.0.0.1
+ port: 6379
+ password:
+ timeout: 5000 # 杩炴帴姹犱腑鐨勬渶灏忕┖闂茶繛鎺�
+ jackson:
+ time-zone: GMT+8
+ date-format: yyyy-MM-dd HH:mm:ss
+# mail:
+# username: jiangping0849@outlook.com
+# password: mwzaislgioyhxnig
+# host: smtp-mail.outlook.com
+# port: 587
+# default-encoding: UTF-8
+# properties:
+# mail:
+# debug: true
+# smtp:
+# ssl:
+# socketFactory:
+# class: com.sun.mail.util.MailSSLSocketFactory
+# fallback: false
+# auth: true
+# starttls:
+# enable: true
+# required: true
+ mail:
+ host: smtp.exmail.qq.com
+ username: jp@doumee.com
+ password: 2Jz9HFW2U7vRnCRu
+ default-encoding: UTF-8
+ properties:
+ mail:
+ smtp:
+ auth: true
+ starttls:
+ enable: true
+ required: true
+
+debug_model: true
+
+# Swagger閰嶇疆
+swagger:
+ host:
+ title: ${project.name}鎺ュ彛鏂囨。
+ description: ${project.name}鎺ュ彛鏂囨。
+ # 鍚敤Swagger锛岀敓浜х幆澧冨缓璁叧闂�
+ enabled: true
+ # 鍚敤swagger鍔犲瘑
+ enable-encrypt: true
+ # 绂佺敤swagger鏃剁殑閲嶅畾鍚戝湴鍧�
+ redirect-uri: /
+
+
+des_pwd: 123456SDFKDJF
+knife4j:
+ enable: true
+ basic:
+ enable: true
+ username: admin
+ password: 111111
+
+
+upload:
+ type: blob
+
+qiwei:
+ serviceurl: https://qyapi.weixin.qq.com
\ No newline at end of file
diff --git a/server/services/src/main/resources/banner.txt b/server/services/src/main/resources/banner.txt
new file mode 100644
index 0000000..e6519fd
--- /dev/null
+++ b/server/services/src/main/resources/banner.txt
@@ -0,0 +1,20 @@
+
+${AnsiColor.BLUE}
+================================================================================
+
+ 娆㈣繋浣跨敤璞嗙背妗嗘灦锛堝崟搴旂敤鐗堬級
+ Version :: 1.0
+
+ 鈻堚枅鈻堚枅鈻堚枅鈻堚枅 鈻堚枅 鈻堚枅
+ 鈻戔枅鈻堚枒鈻戔枒鈻戔枒 鈻堚枅 鈻戔枅鈻堚枒鈻堚枅 鈻堚枅 鈻堚枅
+ 鈻戔枅鈻� 鈻戔枒鈻堚枅 鈻戔枅鈻� 鈻戔枒鈻堚枅 鈻堚枅 鈻戔枒鈻堚枅
+ 鈻戔枅鈻� 鈻戔枅鈻� 鈻戔枅鈻� 鈻戔枒鈻堚枅鈻堚枅 鈻戔枒鈻堚枅
+ 鈻戔枅鈻� 鈻戔枅鈻� 鈻戔枅鈻� 鈻戔枒鈻堚枅 鈻戔枒鈻堚枅
+ 鈻戔枅鈻� 鈻堚枅 鈻戔枅鈻� 鈻戔枅鈻� 鈻戔枅鈻�
+ 鈻戔枅鈻堚枅鈻堚枅鈻堚枅鈻堚枒 鈻戔枅鈻� 鈻戔枅鈻� 鈻戔枅鈻�
+ 鈻戔枒鈻戔枒鈻戔枒鈻戔枒 鈻戔枒 鈻戔枒 鈻戔枒
+
+ 鍚姩绔彛: ${server.port} 鍚姩鐜: ${project.env} 鏃ュ織绛夌骇: ${logback.level} 鍚敤Swagger: ${swagger.enabled}
+
+================================================================================
+
diff --git a/server/services/src/main/resources/logback-spring.xml b/server/services/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..4e16308
--- /dev/null
+++ b/server/services/src/main/resources/logback-spring.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <pattern>%highlight(%date{yyyy-MM-dd HH:mm:ss}) | %highlight(%-5level) | %highlight(%thread) | %highlight(%logger) | %msg%n</pattern>
+ </layout>
+ </appender>
+ <property name="log.path" value="/usr/local/jars/official_website/logs"></property>
+ <property name="log.fileSize" value="100MB"></property>
+ <property name="log.historyDays" value="7"></property>
+ <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <filter class="ch.qos.logback.classic.filter.LevelFilter">
+ <level>ERROR</level>
+ <!--鍖归厤灏辫垗鍘�-->
+ <onMatch>DENY</onMatch>
+ <onMismatch>ACCEPT</onMismatch>
+ </filter>
+ <encoder>
+ <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+ </encoder>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <!--璺緞-->
+ <fileNamePattern>${log.path}/info.%d.%i.log</fileNamePattern>
+ <maxFileSize>${log.fileSize}</maxFileSize>
+ <maxHistory>${log.historyDays}</maxHistory>
+ <totalSizeCap>1GB</totalSizeCap>
+ </rollingPolicy>
+ </appender>
+ <appender name="fileSqlLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <encoder>
+ <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+ </encoder>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <!--璺緞-->
+ <fileNamePattern>${log.path}/sql.%d.%i.log</fileNamePattern>
+ <maxFileSize>${log.fileSize}</maxFileSize>
+ <maxHistory>${log.historyDays}</maxHistory>
+ <totalSizeCap>1GB</totalSizeCap>
+ </rollingPolicy>
+ </appender>
+
+ <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+ <level>ERROR</level>
+ </filter>
+ <encoder>
+ <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+ </encoder>
+ <!--婊氬姩绛栫暐-->
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <!--璺緞-->
+ <fileNamePattern>${log.path}/error.%d.%i.log</fileNamePattern>
+ <maxFileSize>${log.fileSize}</maxFileSize>
+ <maxHistory>${log.historyDays}</maxHistory>
+ <totalSizeCap>1GB</totalSizeCap>
+ </rollingPolicy>
+ </appender>
+ <!-- 寮傛鍐欏叆鏃ュ織 -->
+ <appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">
+ <!-- 涓嶄涪澶辨棩蹇�.榛樿鐨�,濡傛灉闃熷垪鐨�80%宸叉弧,鍒欎細涓㈠純TRACT銆丏EBUG銆両NFO绾у埆鐨勬棩蹇� -->
+ <discardingThreshold >0</discardingThreshold>
+ <!-- 鏇存敼榛樿鐨勯槦鍒楃殑娣卞害,璇ュ�间細褰卞搷鎬ц兘.榛樿鍊间负256 -->
+ <queueSize>512</queueSize>
+ <!-- 娣诲姞闄勫姞鐨刟ppender,鏈�澶氬彧鑳芥坊鍔犱竴涓� -->
+ <appender-ref ref ="fileInfoLog"/>
+ </appender>
+ <!-- MyBatis SQL鏃ュ織閰嶇疆 -->
+ <logger name="com.doumee.dao" level="DEBUG" additivity="false">
+ <appender-ref ref="fileSqlLog" />
+ </logger>
+ <!-- 濡傛灉浣犱娇鐢∕yBatis-Plus锛屼篃鍙互娣诲姞浠ヤ笅閰嶇疆 -->
+ <logger name="com.baomidou.mybatisplus" level="DEBUG" additivity="false" >
+ <appender-ref ref="fileSqlLog" />
+ </logger>
+ <root level="info">
+ <appender-ref ref="consoleLog"/>
+ <appender-ref ref="fileInfoLog"/>
+ <appender-ref ref="fileErrorLog"/>
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/server/services/src/main/resources/mappers/SystemDictDataMapper.xml b/server/services/src/main/resources/mappers/SystemDictDataMapper.xml
new file mode 100644
index 0000000..2a63d6c
--- /dev/null
+++ b/server/services/src/main/resources/mappers/SystemDictDataMapper.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.doumee.dao.system.SystemDictDataMapper">
+
+ <!-- 鏌ヨ瀛楀吀鏁版嵁鍒楄〃 -->
+ <resultMap id="SystemDictDataListVO" type="com.doumee.dao.system.vo.SystemDictDataListVO" autoMapping="true">
+ <id column="ID" property="id"/>
+ <association property="createUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <result column="CREATE_USER_ID" property="id"/>
+ <result column="CREATE_USER_NAME" property="username"/>
+ </association>
+ <association property="updateUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <result column="UPDATE_USER_ID" property="id"/>
+ <result column="UPDATE_USER_NAME" property="username"/>
+ </association>
+ </resultMap>
+ <select id="selectManageList" parameterType="com.doumee.dao.system.dto.QuerySystemDictDataDTO" resultMap="SystemDictDataListVO">
+ SELECT
+ dict_data.`ID`, dict_data.`remark`, dict_data.`DICT_ID`, dict_data.`CODE`, dict_data.`LABEL`, dict_data.`SORT`, dict_data.`DISABLED`, dict_data.`CREATE_TIME`, dict_data.`UPDATE_TIME`, dict_data.`CREATE_USER`, dict_data.`UPDATE_USER`,
+ create_user.ID CREATE_USER_ID, create_user.`USERNAME` CREATE_USER_NAME,
+ update_user.ID UPDETE_USER_ID, update_user.`USERNAME` UPDATE_USER_NAME
+ FROM SYSTEM_DICT_DATA dict_data
+ LEFT JOIN `SYSTEM_USER` create_user ON create_user.ID = dict_data.CREATE_USER
+ LEFT JOIN `SYSTEM_USER` update_user ON update_user.ID = dict_data.UPDATE_USER
+ <where>
+ dict_data.DELETED = 0
+ <if test="dictId != null">
+ AND dict_data.`DICT_ID` = #{dictId}
+ </if>
+ </where>
+ </select>
+
+</mapper>
diff --git a/server/services/src/main/resources/mappers/SystemDictMapper.xml b/server/services/src/main/resources/mappers/SystemDictMapper.xml
new file mode 100644
index 0000000..76338cb
--- /dev/null
+++ b/server/services/src/main/resources/mappers/SystemDictMapper.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.doumee.dao.system.SystemDictMapper">
+
+ <!-- 鏌ヨ瀛楀吀鍒楄〃 -->
+ <resultMap id="SystemDictListVO" type="com.doumee.dao.system.vo.SystemDictListVO" autoMapping="true">
+ <id column="ID" property="id"/>
+ <association property="createUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <result column="CREATE_USER_ID" property="id"/>
+ <result column="CREATE_USER_NAME" property="username"/>
+ </association>
+ <association property="updateUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <result column="UPDATE_USER_ID" property="id"/>
+ <result column="UPDATE_USER_NAME" property="username"/>
+ </association>
+ </resultMap>
+ <select id="selectManageList" parameterType="com.doumee.dao.system.dto.QuerySystemDictDTO" resultMap="SystemDictListVO">
+ SELECT
+ dict.`ID`, dict.`CODE`, dict.`NAME`, dict.`REMARK`, dict.`CREATE_TIME`, dict.`UPDATE_TIME`, dict.`CREATE_USER`, dict.`UPDATE_USER`,
+ create_user.ID CREATE_USER_ID, create_user.`USERNAME` CREATE_USER_NAME,
+ update_user.ID UPDETE_USER_ID, update_user.`USERNAME` UPDATE_USER_NAME
+ FROM SYSTEM_DICT dict
+ LEFT JOIN `SYSTEM_USER` create_user ON create_user.ID = dict.CREATE_USER
+ LEFT JOIN `SYSTEM_USER` update_user ON update_user.ID = dict.UPDATE_USER
+ <where>
+ dict.DELETED = 0
+ <if test="dto.code != null and dto.code != ''">
+ AND dict.`CODE` LIKE concat('%', #{dto.code}, '%')
+ </if>
+ <if test="dto.name != null and dto.name != ''">
+ AND dict.`NAME` LIKE concat('%', #{dto.name}, '%')
+ </if>
+ </where>
+ ${orderByClause}
+ </select>
+
+</mapper>
diff --git a/server/services/src/main/resources/mappers/SystemJobListMapper.xml b/server/services/src/main/resources/mappers/SystemJobListMapper.xml
new file mode 100644
index 0000000..29018e7
--- /dev/null
+++ b/server/services/src/main/resources/mappers/SystemJobListMapper.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.doumee.dao.system.SystemJobListMapper">
+
+ <!-- 绠$悊椤甸潰鏌ヨ -->
+ <resultMap id="SystemJobListListVO" type="com.doumee.dao.system.vo.SystemJobListVO" autoMapping="true">
+ <id column="ID" jdbcType="INTEGER" property="id"/>
+ <association property="createUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <result column="CREATEUSERINFO_USERNAME" jdbcType="VARCHAR" property="username"/>
+ <result column="CREATEUSERINFO_REALNAME" jdbcType="VARCHAR" property="realname"/>
+ </association>
+ <association property="updateUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <result column="UPDATEUSERINFO_USERNAME" jdbcType="VARCHAR" property="username"/>
+ <result column="UPDATEUSERINFO_REALNAME" jdbcType="VARCHAR" property="realname"/>
+ </association>
+ </resultMap>
+ <select id="selectList" parameterType="com.doumee.dao.system.dto.QuerySystemJobListDTO" resultMap="SystemJobListListVO">
+ SELECT
+ `job`.`ID`,
+ `job`.`JOB_NAME`,
+ `job`.`JOB_DESCRIPTION`,
+ `job`.`HANDLER`,
+ `job`.`DISTRIBUTE_HANDLER`,
+ `job`.`DISTRIBUTE_LIMIT`,
+ `job`.`DISALLOW_CONCURRENT`,
+ `job`.`DISABLED`,
+ `job`.`WITH_ASYNC`,
+ `job`.`WITH_LOG`,
+ `job`.`CRON_EXPRESSION`,
+ `job`.`ALLOW_SERVER_IPS`,
+ `job`.`STATUS`,
+ `job`.`CREATE_TIME`,
+ `job`.`UPDATE_TIME`,
+ `createUserInfo`.`USERNAME` AS CREATEUSERINFO_USERNAME,
+ `createUserInfo`.`REALNAME` AS CREATEUSERINFO_REALNAME,
+ `updateUserInfo`.`USERNAME` AS UPDATEUSERINFO_USERNAME,
+ `updateUserInfo`.`REALNAME` AS UPDATEUSERINFO_REALNAME
+ FROM `SYSTEM_JOB` `job`
+ INNER JOIN `SYSTEM_USER` `createUserInfo` ON createUserInfo.ID = job.CREATE_USER
+ LEFT JOIN `SYSTEM_USER` `updateUserInfo` ON updateUserInfo.ID = job.UPDATE_USER
+ <where>
+ <if test="jobName != null and jobName != ''">
+ AND `job`.`JOB_NAME` LIKE CONCAT('%', #{jobName}, '%')
+ </if>
+ </where>
+ </select>
+</mapper>
diff --git a/server/services/src/main/resources/mappers/SystemMenuMapper.xml b/server/services/src/main/resources/mappers/SystemMenuMapper.xml
new file mode 100644
index 0000000..0ec9ada
--- /dev/null
+++ b/server/services/src/main/resources/mappers/SystemMenuMapper.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.doumee.dao.system.SystemMenuMapper">
+
+ <!-- 鏌ヨ鑿滃崟鍒楄〃 -->
+ <resultMap id="SystemMenuListVO" type="com.doumee.dao.system.vo.SystemMenuListVO" autoMapping="true">
+ <id column="ID" property="id"/>
+ <association property="createUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <result column="CREATE_USER_ID" property="id"/>
+ <result column="CREATE_USER_NAME" property="username"/>
+ </association>
+ <association property="updateUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <result column="UPDATE_USER_ID" property="id"/>
+ <result column="UPDATE_USER_NAME" property="username"/>
+ </association>
+ </resultMap>
+ <select id="selectManageList" resultMap="SystemMenuListVO">
+ SELECT
+ menu.`ID`, menu.`PARENT_ID`, menu.`NAME`, menu.`PATH`, menu.`FIXED`, menu.`REMARK`, menu.`DISABLED`, menu.SORT, menu.`ICON`, menu.`CREATE_TIME`, menu.`UPDATE_TIME`, menu.`CREATE_USER`, menu.`UPDATE_USER`, menu.`DELETED`,
+ create_user.ID CREATE_USER_ID, create_user.`USERNAME` CREATE_USER_NAME,
+ update_user.ID UPDETE_USER_ID, update_user.`USERNAME` UPDATE_USER_NAME
+ FROM SYSTEM_MENU menu
+ LEFT JOIN `SYSTEM_USER` create_user ON create_user.ID = menu.CREATE_USER
+ LEFT JOIN `SYSTEM_USER` update_user ON update_user.ID = menu.UPDATE_USER
+ <where>
+ menu.DELETED = 0
+ </where>
+ ORDER BY menu.SORT
+ </select>
+
+ <!-- 鏌ヨ鑿滃崟鏍� -->
+ <select id="selectByUserId" parameterType="java.lang.Integer" resultType="com.doumee.dao.system.model.SystemMenu">
+ SELECT
+ DISTINCT menu.`ID`, menu.`PARENT_ID`, menu.`NAME`, menu.`PATH`, menu.`REMARK`, menu.`DISABLED`, menu.SORT, menu.`ICON`, menu.`CREATE_TIME`, menu.`UPDATE_TIME`, menu.`CREATE_USER`, menu.`UPDATE_USER`, menu.`DELETED`
+ FROM `SYSTEM_MENU` menu
+ INNER JOIN SYSTEM_ROLE_MENU role_menu ON role_menu.MENU_ID = menu.ID AND role_menu.DELETED = 0
+ INNER JOIN SYSTEM_USER_ROLE user_role ON user_role.ROLE_ID = role_menu.ROLE_ID AND user_role.DELETED = 0
+ <where>
+ AND menu.DELETED = 0
+ AND menu.DISABLED = 0
+ AND user_role.USER_ID = #{userId}
+ </where>
+ ORDER BY menu.SORT
+ </select>
+
+ <!-- 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鍒楄〃 -->
+ <select id="selectByRoleId" parameterType="java.lang.Integer" resultType="com.doumee.dao.system.model.SystemMenu">
+ SELECT
+ menu.`ID`, menu.`PARENT_ID`, menu.`NAME`, menu.`PATH`, menu.`REMARK`, menu.`DISABLED`, menu.SORT, menu.`ICON`, menu.`CREATE_TIME`, menu.`UPDATE_TIME`, menu.`CREATE_USER`, menu.`UPDATE_USER`, menu.`DELETED`
+ FROM `SYSTEM_MENU` menu
+ INNER JOIN `SYSTEM_ROLE_MENU` role_menu ON role_menu.MENU_ID = menu.ID AND role_menu.DELETED = 0
+ <where>
+ menu.DELETED = 0
+ AND role_menu.ROLE_ID = #{roleId}
+ </where>
+ </select>
+
+</mapper>
diff --git a/server/services/src/main/resources/mappers/SystemPermissionMapper.xml b/server/services/src/main/resources/mappers/SystemPermissionMapper.xml
new file mode 100644
index 0000000..91c5feb
--- /dev/null
+++ b/server/services/src/main/resources/mappers/SystemPermissionMapper.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.doumee.dao.system.SystemPermissionMapper">
+
+ <!-- 鏌ヨ绯荤粺鏉冮檺鍒楄〃 -->
+ <resultMap id="SystemPermissionListVO" type="com.doumee.dao.system.vo.SystemPermissionListVO" autoMapping="true">
+ <id column="ID" property="id"/>
+ <association property="createUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <id column="CREATE_USER_ID" property="id"/>
+ <result column="CREATE_USER_NAME" property="username"/>
+ </association>
+ <association property="updateUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <id column="UPDATE_USER_ID" property="id"/>
+ <result column="UPDATE_USER_NAME" property="username"/>
+ </association>
+ </resultMap>
+ <select id="selectManageList" resultMap="SystemPermissionListVO">
+ SELECT
+ perm.`ID`, perm.`CODE`, perm.`NAME`, perm.`MODULE`, perm.`REMARK`, perm.`FIXED`, perm.`CREATE_TIME`, perm.`UPDATE_TIME`, perm.`CREATE_USER`, perm.`UPDATE_USER`, perm.`DELETED`,
+ create_user.ID CREATE_USER_ID, create_user.`USERNAME` CREATE_USER_NAME,
+ update_user.ID UPDETE_USER_ID, update_user.`USERNAME` UPDATE_USER_NAME
+ FROM SYSTEM_PERMISSION perm
+ LEFT JOIN `SYSTEM_USER` create_user ON create_user.ID = perm.CREATE_USER
+ LEFT JOIN `SYSTEM_USER` update_user ON update_user.ID = perm.UPDATE_USER
+ <where>
+ perm.DELETED = 0
+ </where>
+ ORDER BY perm.CREATE_TIME ASC, perm.ID ASC
+ </select>
+
+ <!-- 鏍规嵁鐢ㄦ埛ID鏌ヨ鏉冮檺 -->
+ <select id="selectByUserId" parameterType="java.lang.Integer" resultType="com.doumee.dao.system.model.SystemPermission">
+ SELECT
+ perm.`ID`, perm.`CODE`, perm.`NAME`, perm.`REMARK`, perm.`CREATE_TIME`, perm.`UPDATE_TIME`, perm.`CREATE_USER`, perm.`UPDATE_USER`, perm.`DELETED`
+ FROM SYSTEM_PERMISSION perm
+ INNER JOIN SYSTEM_ROLE_PERMISSION role_perm ON role_perm.PERMISSION_ID = perm.ID AND role_perm.DELETED = 0
+ INNER JOIN SYSTEM_ROLE role ON role.ID = role_perm.ROLE_ID AND role.DELETED = 0
+ INNER JOIN SYSTEM_USER_ROLE user_role ON user_role.ROLE_ID = role.ID AND user_role.DELETED = 0
+ <where>
+ perm.DELETED = 0
+ AND user_role.USER_ID = #{userId}
+ </where>
+ </select>
+
+ <!-- 鏍规嵁瑙掕壊ID鏌ヨ鏉冮檺 -->
+ <select id="selectByRoleId" parameterType="java.lang.Integer" resultType="com.doumee.dao.system.model.SystemPermission">
+ SELECT
+ perm.`ID`, perm.`CODE`, perm.`NAME`, perm.`REMARK`, perm.`CREATE_TIME`, perm.`UPDATE_TIME`, perm.`CREATE_USER`, perm.`UPDATE_USER`, perm.`DELETED`
+ FROM SYSTEM_PERMISSION perm
+ INNER JOIN SYSTEM_ROLE_PERMISSION role_perm ON role_perm.PERMISSION_ID = perm.ID AND role_perm.DELETED = 0
+ <where>
+ perm.DELETED = 0
+ AND role_perm.ROLE_ID = #{roleId}
+ </where>
+ </select>
+
+</mapper>
diff --git a/server/services/src/main/resources/mappers/SystemRoleMapper.xml b/server/services/src/main/resources/mappers/SystemRoleMapper.xml
new file mode 100644
index 0000000..e2851b9
--- /dev/null
+++ b/server/services/src/main/resources/mappers/SystemRoleMapper.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.doumee.dao.system.SystemRoleMapper">
+
+ <!-- 鏌ヨ瑙掕壊鍒楄〃 -->
+ <resultMap id="SystemRoleListVO" type="com.doumee.dao.system.vo.SystemRoleListVO" autoMapping="true">
+ <id column="ID" property="id"/>
+ <association property="createUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <id column="CREATE_USER_ID" property="id"/>
+ <result column="CREATE_USER_NAME" property="username"/>
+ </association>
+ <association property="updateUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <id column="UPDATE_USER_ID" property="id"/>
+ <result column="UPDATE_USER_NAME" property="username"/>
+ </association>
+ </resultMap>
+ <select id="selectManageList" parameterType="com.doumee.dao.system.dto.QuerySystemUserDTO" resultMap="SystemRoleListVO">
+ SELECT
+ role.ID, role.`CODE`, role.`NAME`, role.`REMARK`, role.`FIXED`, role.`CREATE_TIME`, role.`UPDATE_TIME`,
+ create_user.ID CREATE_USER_ID, create_user.`USERNAME` CREATE_USER_NAME,
+ update_user.ID UPDETE_USER_ID, update_user.`USERNAME` UPDATE_USER_NAME
+ FROM SYSTEM_ROLE role
+ LEFT JOIN `SYSTEM_USER` create_user ON create_user.ID = role.CREATE_USER
+ LEFT JOIN `SYSTEM_USER` update_user ON update_user.ID = role.UPDATE_USER
+ <where>
+ role.DELETED = 0
+ <if test="dto.code != null and dto.code != ''">
+ AND role.`CODE` LIKE CONCAT('%', #{dto.code}, '%')
+ </if>
+ <if test="dto.name != null and dto.name != ''">
+ AND role.`NAME` LIKE CONCAT('%', #{dto.name}, '%')
+ </if>
+ </where>
+ ${orderByClause}
+ </select>
+
+ <!-- 鏌ヨ鐢ㄦ埛瑙掕壊鍒楄〃 -->
+ <select id="selectByUserId" parameterType="java.lang.Integer" resultType="com.doumee.dao.system.model.SystemRole">
+ SELECT
+ role.ID, role.`CODE`, role.`NAME`, role.`REMARK`, role.`CREATE_TIME`, role.`UPDATE_TIME`
+ FROM SYSTEM_ROLE role
+ INNER JOIN SYSTEM_USER_ROLE user_role ON user_role.ROLE_ID = role.ID AND user_role.DELETED = 0
+ <where>
+ role.DELETED = 0
+ AND user_role.USER_ID = #{userId}
+ </where>
+ </select>
+
+</mapper>
diff --git a/server/services/src/main/resources/mappers/SystemUserMapper.xml b/server/services/src/main/resources/mappers/SystemUserMapper.xml
new file mode 100644
index 0000000..6c3411b
--- /dev/null
+++ b/server/services/src/main/resources/mappers/SystemUserMapper.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.doumee.dao.system.SystemUserMapper">
+
+ <!-- 鏌ヨ鐢ㄦ埛鍒楄〃 -->
+ <resultMap id="SystemUserListVO" type="com.doumee.dao.system.vo.SystemUserListVO" autoMapping="true">
+ <id column="ID" property="id"/>
+ <association property="createUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <result column="CREATE_USER_ID" property="id"/>
+ <result column="CREATE_USER_NAME" property="username"/>
+ </association>
+ <association property="updateUserInfo" javaType="com.doumee.dao.system.model.SystemUser">
+ <result column="UPDATE_USER_ID" property="id"/>
+ <result column="UPDATE_USER_NAME" property="username"/>
+ </association>
+ </resultMap>
+ <select id="selectManageList" parameterType="com.doumee.dao.system.dto.QuerySystemUserDTO" resultMap="SystemUserListVO">
+ SELECT
+ DISTINCT
+ usr.ID, usr.BIRTHDAY, usr.EMAIL, usr.EMP_NO, usr.MOBILE, usr.AVATAR, usr.USERNAME, usr.REALNAME, usr.SEX, usr.FIXED, usr.CREATE_TIME, usr.UPDATE_TIME,
+ create_user.ID CREATE_USER_ID, create_user.`USERNAME` CREATE_USER_NAME,
+ update_user.ID UPDETE_USER_ID, update_user.`USERNAME` UPDATE_USER_NAME
+ FROM `SYSTEM_USER` usr
+ LEFT JOIN `SYSTEM_USER` create_user ON create_user.ID = usr.CREATE_USER
+ LEFT JOIN `SYSTEM_USER` update_user ON update_user.ID = usr.UPDATE_USER
+ <where>
+ usr.DELETED = 0
+ <if test="dto.username != null and dto.username != ''">
+ AND usr.`USERNAME` LIKE CONCAT('%', #{dto.username}, '%')
+ </if>
+ <if test="dto.realname != null and dto.realname != ''">
+ AND usr.`REALNAME` LIKE CONCAT('%', #{dto.realname}, '%')
+ </if>
+ <if test="dto.mobile != null and dto.mobile != ''">
+ AND usr.`MOBILE` LIKE CONCAT('%', #{dto.mobile}, '%')
+ </if>
+ </where>
+ ${orderByClause}
+ </select>
+
+</mapper>
diff --git a/server/web/src/main/java/com/doumee/JKWebApplication.java b/server/web/src/main/java/com/doumee/JKWebApplication.java
new file mode 100644
index 0000000..d4e8918
--- /dev/null
+++ b/server/web/src/main/java/com/doumee/JKWebApplication.java
@@ -0,0 +1,31 @@
+package com.doumee;
+
+import lombok.extern.slf4j.Slf4j;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.ApplicationContext;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+/**
+ * 鍚姩绫�
+ * @author dm
+ * @since 2025/03/31 16:44
+ */
+@Slf4j
+@SpringBootApplication
+@MapperScan("com.doumee.dao")
+@EnableAsync
+public class JKWebApplication extends SpringBootServletInitializer {
+ public static void main(String[] args) {
+ ApplicationContext context = SpringApplication.run(JKWebApplication.class);
+ context.getEnvironment();
+ }
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
+ return builder.sources(JKWebApplication.class) ;
+ }
+}
diff --git a/server/web/src/main/resources/application.yml b/server/web/src/main/resources/application.yml
new file mode 100644
index 0000000..28dea6f
--- /dev/null
+++ b/server/web/src/main/resources/application.yml
@@ -0,0 +1,89 @@
+# 绔彛鍣ㄩ厤缃�
+server:
+ port: 10011
+# 椤圭洰淇℃伅閰嶇疆
+project:
+ name: 杩戝揩
+ version: 1.0.0
+ # 鐜锛岀敓浜х幆澧僷roduction锛屽紑鍙戠幆澧僤evelopment
+ env: development
+ # 妯″紡锛宼esting娴嬭瘯妯″紡
+ mode: testing
+
+spring:
+ profiles:
+ active: pro
+ # JSON杩斿洖閰嶇疆
+ jackson:
+ # 榛樿鏃跺尯
+ time-zone: GMT+8
+ # 榛樿鏃ユ湡鏍煎紡鍖�
+ date-format: yyyy-MM-dd HH:mm:ss
+ # Quartz閰嶇疆
+ quartz:
+ # 鏄惁鑷姩鍚姩
+ auto-startup: true
+ # 璋冨害鍣ㄥ悕绉�
+ scheduler-name: EvaScheduler
+ servlet:
+ multipart:
+ max-file-size: 50MB
+ max-request-size: 50MB
+
+# MyBatis閰嶇疆
+mybatis-plus:
+ mapper-locations: classpath*:/mappers/**/*.xml
+ configuration:
+ map-underscore-to-camel-case: true
+ log-impl: com.doumee.config.mybatis.DmStdOutImpl
+# log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
+# log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
+
+
+# 缂撳瓨鍐呭璁剧疆
+cache:
+ session:
+ # 浼氳瘽杩囨湡鏃堕暱(s)
+ expire: 1800
+ captcha:
+ # 楠岃瘉鐮佽繃鏈熸椂闀�(s)
+ expire: 300
+
+# 璺熻釜鏃ュ織
+trace:
+ # 寮�鍚櫤鑳借窡韪ā寮�
+ smart: true
+ # 鎺掗櫎璺熻釜鐨刄RL姝e垯
+ exclude-patterns: .+/list[a-zA-Z0-9\-\_]*$, .+/tree[a-zA-Z0-9\-\_]*$, .+/page[a-zA-Z0-9\-\_]*$, .+/all[a-zA-Z0-9\-\_]*$, /swagger-resources.*
+
+# 瀹夊叏閰嶇疆
+security:
+ aes:
+ key: qklpNODl6JjmgcT+
+ iv: 7rnE4rm3h/hcfqN2
+
+
+# 鏃ュ織閰嶇疆
+logback:
+ level: ERROR
+ appender: ${project.env}
+# dao灞傜殑鏃ュ織璁剧疆涓篸ebug锛屾柟渚挎煡鐪媠ql
+logging:
+ level:
+ # JOB鐩稿叧
+ com.doumee.dao.system.SystemJobMapper: ERROR
+ com.doumee.dao.system.SystemJobListMapper: ERROR
+ com.doumee.dao.system.SystemJobSnippetMapper: ERROR
+ com.doumee.dao.system.SystemJobLogMapper: ERROR
+ com.doumee.dao.business: ERROR
+auth:
+ jwt:
+ enabled: true #鏄惁寮�鍚疛WT鐧诲綍璁よ瘉鍔熻兘
+ secret: fjkfaf;afa # JWT绉侀挜锛岀敤浜庢牎楠孞WT浠ょ墝鐨勫悎娉曟��
+ expiration: 1800000 #JWT浠ょ墝鐨勬湁鏁堟湡锛岀敤浜庢牎楠孞WT浠ょ墝鐨勫悎娉曟��
+ # expiration: 300000 #JWT浠ょ墝鐨勬湁鏁堟湡锛岀敤浜庢牎楠孞WT浠ょ墝鐨勫悎娉曟��
+ header: JWTHeaderName #HTTP璇锋眰鐨凥eader鍚嶇О锛岃Header浣滀负鍙傛暟浼犻�扟WT浠ょ墝
+ userParamName: username #鐢ㄦ埛鐧诲綍璁よ瘉鐢ㄦ埛鍚嶅弬鏁板悕绉�
+ pwdParamName: password #鐢ㄦ埛鐧诲綍璁よ瘉瀵嗙爜鍙傛暟鍚嶇О
+ useDefaultController: true # 鏄惁浣跨敤榛樿鐨凧wtAuthController
+
--
Gitblit v1.9.3