From 85cc4c1bd448699a6ec7c6272b3e1f6e23020a12 Mon Sep 17 00:00:00 2001 From: zhangyeguang Date: Fri, 6 Sep 2024 14:34:07 +0800 Subject: [PATCH] ams social project --- .gitignore | 3 +- common/pom.xml | 101 +++++++++ .../jiagutech/ams/annotation/RateLimiter.java | 43 ++++ .../com/jiagutech/ams/constant/Constants.java | 81 +++++++ .../ams/constant/GlobalConstants.java | 39 ++++ .../jiagutech/ams/constant/HttpStatus.java | 93 ++++++++ .../jiagutech/ams/constant/UserConstants.java | 143 +++++++++++++ .../com/jiagutech/ams/enums/LimitType.java | 24 +++ .../com/jiagutech/ams/exception/BizCode.java | 62 ++++++ .../ams/exception/BusinessException.java | 53 +++++ .../ams/exception/CodeInterface.java | 22 ++ .../jiagutech/ams/mapper/RegionMapper.java | 26 +++ .../com/jiagutech/ams/mapper/UserMapper.java | 34 +++ .../com/jiagutech/ams/model/DeptItem.java | 22 ++ .../com/jiagutech/ams/model/LoginUser.java | 97 +++++++++ .../com/jiagutech/ams/model/RegionVO.java | 12 ++ .../com/jiagutech/ams/model/UserDetail.java | 30 +++ .../ams/model/common/PageRequest.java | 22 ++ .../ams/model/common/PageResult.java | 33 +++ .../com/jiagutech/ams/model/common/R.java | 111 ++++++++++ .../com/jiagutech/ams/model/dto/DeptDTO.java | 22 ++ .../jiagutech/ams/model/dto/RegionDTO.java | 22 ++ .../com/jiagutech/ams/model/dto/RoleDTO.java | 26 +++ .../com/jiagutech/ams/model/dto/UserDTO.java | 28 +++ .../jiagutech/ams/model/dto/UserDeptDTO.java | 24 +++ .../jiagutech/ams/model/dto/UserRoleDTO.java | 25 +++ .../ams/utils/ExcelBigNumberConvert.java | 52 +++++ .../com/jiagutech/ams/utils/ExcelUtil.java | 49 +++++ .../ams/utils/StringToLongDeserializer.java | 21 ++ pom.xml | 185 ++++++++++++++++ social/pom.xml | 97 +++++++++ .../ams/controller/DeviceController.java | 42 ++++ .../ams/controller/JobController.java | 83 ++++++++ .../ams/controller/RegionController.java | 22 ++ .../ams/controller/TrackController.java | 21 ++ .../jiagutech/ams/mapper/DeviceMapper.java | 11 + .../com/jiagutech/ams/mapper/JobMapper.java | 21 ++ .../jiagutech/ams/mapper/JobTypeMapper.java | 9 + .../com/jiagutech/ams/model/JobMapping.java | 16 ++ .../com/jiagutech/ams/model/TrackDataJG.java | 120 +++++++++++ .../jiagutech/ams/model/dto/DeviceDTO.java | 24 +++ .../com/jiagutech/ams/model/dto/JobDTO.java | 44 ++++ .../jiagutech/ams/model/dto/JobTypeDTO.java | 23 ++ .../ams/model/request/JobCreateRequest.java | 46 ++++ .../ams/model/request/JobPageRequest.java | 35 ++++ .../ams/model/response/DeviceInfo.java | 31 +++ .../ams/model/response/JobCreateResponse.java | 30 +++ .../jiagutech/ams/model/response/JobItem.java | 54 +++++ .../ams/model/response/JobTypeItem.java | 18 ++ .../jiagutech/ams/rest/CenterRestClient.java | 23 ++ .../jiagutech/ams/service/DeviceService.java | 9 + .../ams/service/DeviceServiceImpl.java | 68 ++++++ .../com/jiagutech/ams/service/JobService.java | 28 +++ .../jiagutech/ams/service/JobServiceImpl.java | 169 +++++++++++++++ .../main/resources/mapper/DeviceMapper.xml | 12 ++ .../src/main/resources/mapper/JobMapper.xml | 53 +++++ .../main/resources/mapper/RegionMapper.xml | 47 +++++ system/pom.xml | 75 +++++++ .../jiagutech/ams/config/MybatisConfig.java | 16 ++ .../ams/controller/CommonController.java | 51 +++++ .../ams/controller/DeptController.java | 34 +++ .../ams/controller/UserController.java | 76 +++++++ .../com/jiagutech/ams/mapper/DeptMapper.java | 18 ++ .../com/jiagutech/ams/mapper/RoleMapper.java | 7 + .../jiagutech/ams/mapper/UserDeptMapper.java | 10 + .../jiagutech/ams/mapper/UserRoleMapper.java | 22 ++ .../com/jiagutech/ams/model/UserMapping.java | 24 +++ .../ams/model/request/DeptPageRequest.java | 18 ++ .../ams/model/request/LoginRequest.java | 59 ++++++ .../ams/model/request/PageUserRequest.java | 19 ++ .../ams/model/request/UserRequest.java | 86 ++++++++ .../ams/model/response/CaptchaVO.java | 24 +++ .../ams/model/response/LoginResponse.java | 37 ++++ .../ams/service/DeptServcieImpl.java | 41 ++++ .../jiagutech/ams/service/DeptService.java | 17 ++ .../jiagutech/ams/service/UserService.java | 27 +++ .../ams/service/UserServiceImpl.java | 198 ++++++++++++++++++ .../src/main/resources/mapper/DeptMapper.xml | 47 +++++ .../src/main/resources/mapper/RoleMapper.xml | 8 + .../main/resources/mapper/UserDeptMapper.xml | 13 ++ .../src/main/resources/mapper/UserMapper.xml | 89 ++++++++ .../main/resources/mapper/UserRoleMapper.xml | 20 ++ web/pom.xml | 102 +++++++++ .../com/jiagutech/ams/SocialApplication.java | 18 ++ .../ams/common/GlobalExceptionHandler.java | 74 +++++++ .../ams/common/RestTemplateConfig.java | 41 ++++ .../ams/common/RestTemplateInterceptor.java | 36 ++++ .../ams/config/MybatisPlusConfig.java | 23 ++ .../ams/config/SaPermissionImpl.java | 39 ++++ .../jiagutech/ams/config/SaTokenConfig.java | 30 +++ .../ams/config/SaTokenConfigure.java | 16 ++ .../jiagutech/ams/config/SpringDocConfig.java | 46 ++++ .../com/jiagutech/ams/config/WebConfig.java | 32 +++ web/src/main/resources/application.yml | 91 ++++++++ web/src/main/resources/logback-spring.xml | 103 +++++++++ 95 files changed, 4347 insertions(+), 1 deletion(-) create mode 100644 common/pom.xml create mode 100644 common/src/main/java/com/jiagutech/ams/annotation/RateLimiter.java create mode 100644 common/src/main/java/com/jiagutech/ams/constant/Constants.java create mode 100644 common/src/main/java/com/jiagutech/ams/constant/GlobalConstants.java create mode 100644 common/src/main/java/com/jiagutech/ams/constant/HttpStatus.java create mode 100644 common/src/main/java/com/jiagutech/ams/constant/UserConstants.java create mode 100644 common/src/main/java/com/jiagutech/ams/enums/LimitType.java create mode 100644 common/src/main/java/com/jiagutech/ams/exception/BizCode.java create mode 100644 common/src/main/java/com/jiagutech/ams/exception/BusinessException.java create mode 100644 common/src/main/java/com/jiagutech/ams/exception/CodeInterface.java create mode 100644 common/src/main/java/com/jiagutech/ams/mapper/RegionMapper.java create mode 100644 common/src/main/java/com/jiagutech/ams/mapper/UserMapper.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/DeptItem.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/LoginUser.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/RegionVO.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/UserDetail.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/common/PageRequest.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/common/PageResult.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/common/R.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/dto/DeptDTO.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/dto/RegionDTO.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/dto/RoleDTO.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/dto/UserDTO.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/dto/UserDeptDTO.java create mode 100644 common/src/main/java/com/jiagutech/ams/model/dto/UserRoleDTO.java create mode 100644 common/src/main/java/com/jiagutech/ams/utils/ExcelBigNumberConvert.java create mode 100644 common/src/main/java/com/jiagutech/ams/utils/ExcelUtil.java create mode 100644 common/src/main/java/com/jiagutech/ams/utils/StringToLongDeserializer.java create mode 100644 pom.xml create mode 100644 social/pom.xml create mode 100644 social/src/main/java/com/jiagutech/ams/controller/DeviceController.java create mode 100644 social/src/main/java/com/jiagutech/ams/controller/JobController.java create mode 100644 social/src/main/java/com/jiagutech/ams/controller/RegionController.java create mode 100644 social/src/main/java/com/jiagutech/ams/controller/TrackController.java create mode 100644 social/src/main/java/com/jiagutech/ams/mapper/DeviceMapper.java create mode 100644 social/src/main/java/com/jiagutech/ams/mapper/JobMapper.java create mode 100644 social/src/main/java/com/jiagutech/ams/mapper/JobTypeMapper.java create mode 100644 social/src/main/java/com/jiagutech/ams/model/JobMapping.java create mode 100644 social/src/main/java/com/jiagutech/ams/model/TrackDataJG.java create mode 100644 social/src/main/java/com/jiagutech/ams/model/dto/DeviceDTO.java create mode 100644 social/src/main/java/com/jiagutech/ams/model/dto/JobDTO.java create mode 100644 social/src/main/java/com/jiagutech/ams/model/dto/JobTypeDTO.java create mode 100644 social/src/main/java/com/jiagutech/ams/model/request/JobCreateRequest.java create mode 100644 social/src/main/java/com/jiagutech/ams/model/request/JobPageRequest.java create mode 100644 social/src/main/java/com/jiagutech/ams/model/response/DeviceInfo.java create mode 100644 social/src/main/java/com/jiagutech/ams/model/response/JobCreateResponse.java create mode 100644 social/src/main/java/com/jiagutech/ams/model/response/JobItem.java create mode 100644 social/src/main/java/com/jiagutech/ams/model/response/JobTypeItem.java create mode 100644 social/src/main/java/com/jiagutech/ams/rest/CenterRestClient.java create mode 100644 social/src/main/java/com/jiagutech/ams/service/DeviceService.java create mode 100644 social/src/main/java/com/jiagutech/ams/service/DeviceServiceImpl.java create mode 100644 social/src/main/java/com/jiagutech/ams/service/JobService.java create mode 100644 social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java create mode 100644 social/src/main/resources/mapper/DeviceMapper.xml create mode 100644 social/src/main/resources/mapper/JobMapper.xml create mode 100644 social/src/main/resources/mapper/RegionMapper.xml create mode 100644 system/pom.xml create mode 100644 system/src/main/java/com/jiagutech/ams/config/MybatisConfig.java create mode 100644 system/src/main/java/com/jiagutech/ams/controller/CommonController.java create mode 100644 system/src/main/java/com/jiagutech/ams/controller/DeptController.java create mode 100644 system/src/main/java/com/jiagutech/ams/controller/UserController.java create mode 100644 system/src/main/java/com/jiagutech/ams/mapper/DeptMapper.java create mode 100644 system/src/main/java/com/jiagutech/ams/mapper/RoleMapper.java create mode 100644 system/src/main/java/com/jiagutech/ams/mapper/UserDeptMapper.java create mode 100644 system/src/main/java/com/jiagutech/ams/mapper/UserRoleMapper.java create mode 100644 system/src/main/java/com/jiagutech/ams/model/UserMapping.java create mode 100644 system/src/main/java/com/jiagutech/ams/model/request/DeptPageRequest.java create mode 100644 system/src/main/java/com/jiagutech/ams/model/request/LoginRequest.java create mode 100644 system/src/main/java/com/jiagutech/ams/model/request/PageUserRequest.java create mode 100644 system/src/main/java/com/jiagutech/ams/model/request/UserRequest.java create mode 100644 system/src/main/java/com/jiagutech/ams/model/response/CaptchaVO.java create mode 100644 system/src/main/java/com/jiagutech/ams/model/response/LoginResponse.java create mode 100644 system/src/main/java/com/jiagutech/ams/service/DeptServcieImpl.java create mode 100644 system/src/main/java/com/jiagutech/ams/service/DeptService.java create mode 100644 system/src/main/java/com/jiagutech/ams/service/UserService.java create mode 100644 system/src/main/java/com/jiagutech/ams/service/UserServiceImpl.java create mode 100644 system/src/main/resources/mapper/DeptMapper.xml create mode 100644 system/src/main/resources/mapper/RoleMapper.xml create mode 100644 system/src/main/resources/mapper/UserDeptMapper.xml create mode 100644 system/src/main/resources/mapper/UserMapper.xml create mode 100644 system/src/main/resources/mapper/UserRoleMapper.xml create mode 100644 web/pom.xml create mode 100644 web/src/main/java/com/jiagutech/ams/SocialApplication.java create mode 100644 web/src/main/java/com/jiagutech/ams/common/GlobalExceptionHandler.java create mode 100644 web/src/main/java/com/jiagutech/ams/common/RestTemplateConfig.java create mode 100644 web/src/main/java/com/jiagutech/ams/common/RestTemplateInterceptor.java create mode 100644 web/src/main/java/com/jiagutech/ams/config/MybatisPlusConfig.java create mode 100644 web/src/main/java/com/jiagutech/ams/config/SaPermissionImpl.java create mode 100644 web/src/main/java/com/jiagutech/ams/config/SaTokenConfig.java create mode 100644 web/src/main/java/com/jiagutech/ams/config/SaTokenConfigure.java create mode 100644 web/src/main/java/com/jiagutech/ams/config/SpringDocConfig.java create mode 100644 web/src/main/java/com/jiagutech/ams/config/WebConfig.java create mode 100644 web/src/main/resources/application.yml create mode 100644 web/src/main/resources/logback-spring.xml diff --git a/.gitignore b/.gitignore index 0ba064c..28f7412 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,8 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* - +.vscode +log # ---> Maven target/ pom.xml.tag diff --git a/common/pom.xml b/common/pom.xml new file mode 100644 index 0000000..da33fe6 --- /dev/null +++ b/common/pom.xml @@ -0,0 +1,101 @@ + + + 4.0.0 + + com.jiagutech + ams-social + ${revision} + + + common + + + 17 + 17 + UTF-8 + + + + org.projectlombok + lombok + + + cn.hutool + hutool-core + + + + cn.hutool + hutool-http + + + + cn.hutool + hutool-extra + + + com.alibaba.fastjson2 + fastjson2 + + + + ma.glasnost.orika + orika-core + 1.5.4 + + + org.mapstruct + mapstruct + 1.5.5.Final + + + org.mapstruct + mapstruct-processor + 1.5.5.Final + compile + + + org.apache.commons + commons-pool2 + 2.12.0 + + + org.springframework.boot + spring-boot-starter-data-jdbc + + + com.baomidou + mybatis-plus-boot-starter + + + org.springframework.boot + spring-boot-starter-json + + + org.apache.poi + poi + + + org.apache.poi + poi-ooxml + + + com.alibaba + easyexcel + + + poi-ooxml-schemas + org.apache.poi + + + + + + jakarta.servlet + jakarta.servlet-api + + + + \ No newline at end of file diff --git a/common/src/main/java/com/jiagutech/ams/annotation/RateLimiter.java b/common/src/main/java/com/jiagutech/ams/annotation/RateLimiter.java new file mode 100644 index 0000000..ed4f8a4 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/annotation/RateLimiter.java @@ -0,0 +1,43 @@ +package com.jiagutech.ams.annotation; + + + +import com.jiagutech.ams.enums.LimitType; + +import java.lang.annotation.*; + +/** + * 限流注解 + * + * @author Lion Li + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RateLimiter { + /** + * 限流key,支持使用Spring el表达式来动态获取方法上的参数值 + * 格式类似于 #code.id #{#code} + */ + String key() default ""; + + /** + * 限流时间,单位秒 + */ + int time() default 60; + + /** + * 限流次数 + */ + int count() default 100; + + /** + * 限流类型 + */ + LimitType limitType() default LimitType.DEFAULT; + + /** + * 提示消息 支持国际化 格式为 {code} + */ + String message() default "{rate.limiter.message}"; +} diff --git a/common/src/main/java/com/jiagutech/ams/constant/Constants.java b/common/src/main/java/com/jiagutech/ams/constant/Constants.java new file mode 100644 index 0000000..5452593 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/constant/Constants.java @@ -0,0 +1,81 @@ +package com.jiagutech.ams.constant; + +/** + * 通用常量信息 + * + * @author ruoyi + */ +public interface Constants { + + /** + * UTF-8 字符集 + */ + String UTF8 = "UTF-8"; + + /** + * GBK 字符集 + */ + String GBK = "GBK"; + + /** + * www主域 + */ + String WWW = "www."; + + /** + * http请求 + */ + String HTTP = "http://"; + + /** + * https请求 + */ + String HTTPS = "https://"; + + /** + * 通用成功标识 + */ + String SUCCESS = "0"; + + /** + * 通用失败标识 + */ + String FAIL = "1"; + + /** + * 登录成功 + */ + String LOGIN_SUCCESS = "Success"; + + /** + * 注销 + */ + String LOGOUT = "Logout"; + + /** + * 注册 + */ + String REGISTER = "Register"; + + /** + * 登录失败 + */ + String LOGIN_FAIL = "Error"; + + /** + * 验证码有效期(分钟) + */ + Integer CAPTCHA_EXPIRATION = 2; + + /** + * 令牌 + */ + String TOKEN = "token"; + + /** + * 顶级部门id + */ + Long TOP_PARENT_ID = 0L; + +} + diff --git a/common/src/main/java/com/jiagutech/ams/constant/GlobalConstants.java b/common/src/main/java/com/jiagutech/ams/constant/GlobalConstants.java new file mode 100644 index 0000000..45aa3fe --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/constant/GlobalConstants.java @@ -0,0 +1,39 @@ +package com.jiagutech.ams.constant; + +/** + * 全局的key常量 (业务无关的key) + * + * @author Lion Li + */ +public interface GlobalConstants { + + /** + * 全局 redis key (业务无关的key) + */ + String GLOBAL_REDIS_KEY = "global:"; + + /** + * 验证码 redis key + */ + String CAPTCHA_CODE_KEY = GLOBAL_REDIS_KEY + "captcha_codes:"; + + /** + * 防重提交 redis key + */ + String REPEAT_SUBMIT_KEY = GLOBAL_REDIS_KEY + "repeat_submit:"; + + /** + * 限流 redis key + */ + String RATE_LIMIT_KEY = GLOBAL_REDIS_KEY + "rate_limit:"; + + /** + * 登录账户密码错误次数 redis key + */ + String PWD_ERR_CNT_KEY = GLOBAL_REDIS_KEY + "pwd_err_cnt:"; + + /** + * 三方认证 redis key + */ + String SOCIAL_AUTH_CODE_KEY = GLOBAL_REDIS_KEY + "social_auth_codes:"; +} diff --git a/common/src/main/java/com/jiagutech/ams/constant/HttpStatus.java b/common/src/main/java/com/jiagutech/ams/constant/HttpStatus.java new file mode 100644 index 0000000..8da2d60 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/constant/HttpStatus.java @@ -0,0 +1,93 @@ +package com.jiagutech.ams.constant; + +/** + * 返回状态码 + * + * @author Lion Li + */ +public interface HttpStatus { + /** + * 操作成功 + */ + int SUCCESS = 200; + + /** + * 对象创建成功 + */ + int CREATED = 201; + + /** + * 请求已经被接受 + */ + int ACCEPTED = 202; + + /** + * 操作已经执行成功,但是没有返回数据 + */ + int NO_CONTENT = 204; + + /** + * 资源已被移除 + */ + int MOVED_PERM = 301; + + /** + * 重定向 + */ + int SEE_OTHER = 303; + + /** + * 资源没有被修改 + */ + int NOT_MODIFIED = 304; + + /** + * 参数列表错误(缺少,格式不匹配) + */ + int BAD_REQUEST = 400; + + /** + * 未授权 + */ + int UNAUTHORIZED = 401; + + /** + * 访问受限,授权过期 + */ + int FORBIDDEN = 403; + + /** + * 资源,服务未找到 + */ + int NOT_FOUND = 404; + + /** + * 不允许的http方法 + */ + int BAD_METHOD = 405; + + /** + * 资源冲突,或者资源被锁 + */ + int CONFLICT = 409; + + /** + * 不支持的数据,媒体类型 + */ + int UNSUPPORTED_TYPE = 415; + + /** + * 系统内部错误 + */ + int ERROR = 500; + + /** + * 接口未实现 + */ + int NOT_IMPLEMENTED = 501; + + /** + * 系统警告消息 + */ + int WARN = 601; +} diff --git a/common/src/main/java/com/jiagutech/ams/constant/UserConstants.java b/common/src/main/java/com/jiagutech/ams/constant/UserConstants.java new file mode 100644 index 0000000..0df6306 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/constant/UserConstants.java @@ -0,0 +1,143 @@ +package com.jiagutech.ams.constant; + +/** + * 用户常量信息 + * + * @author ruoyi + */ +public interface UserConstants { + + /** + * 平台内系统用户的唯一标志 + */ + String SYS_SESSION = "CURRENT_USER"; + + + /** + * 正常状态 + */ + String NORMAL = "0"; + + /** + * 异常状态 + */ + String EXCEPTION = "1"; + + /** + * 用户正常状态 + */ + String USER_NORMAL = "0"; + + /** + * 用户封禁状态 + */ + String USER_DISABLE = "1"; + + /** + * 角色正常状态 + */ + String ROLE_NORMAL = "0"; + + /** + * 角色封禁状态 + */ + String ROLE_DISABLE = "1"; + + /** + * 部门正常状态 + */ + String DEPT_NORMAL = "0"; + + /** + * 部门停用状态 + */ + String DEPT_DISABLE = "1"; + + /** + * 岗位正常状态 + */ + String POST_NORMAL = "0"; + + /** + * 岗位停用状态 + */ + String POST_DISABLE = "1"; + + /** + * 字典正常状态 + */ + String DICT_NORMAL = "0"; + + /** + * 是否为系统默认(是) + */ + String YES = "Y"; + + /** + * 是否菜单外链(是) + */ + String YES_FRAME = "0"; + + /** + * 是否菜单外链(否) + */ + String NO_FRAME = "1"; + + /** + * 菜单正常状态 + */ + String MENU_NORMAL = "0"; + + /** + * 菜单停用状态 + */ + String MENU_DISABLE = "1"; + + /** + * 菜单类型(目录) + */ + String TYPE_DIR = "M"; + + /** + * 菜单类型(菜单) + */ + String TYPE_MENU = "C"; + + /** + * 菜单类型(按钮) + */ + String TYPE_BUTTON = "F"; + + /** + * Layout组件标识 + */ + String LAYOUT = "Layout"; + + /** + * ParentView组件标识 + */ + String PARENT_VIEW = "ParentView"; + + /** + * InnerLink组件标识 + */ + String INNER_LINK = "InnerLink"; + + /** + * 用户名长度限制 + */ + int USERNAME_MIN_LENGTH = 2; + int USERNAME_MAX_LENGTH = 20; + + /** + * 密码长度限制 + */ + int PASSWORD_MIN_LENGTH = 5; + int PASSWORD_MAX_LENGTH = 20; + + /** + * 超级管理员ID + */ + Long SUPER_ADMIN_ID = 1L; + +} diff --git a/common/src/main/java/com/jiagutech/ams/enums/LimitType.java b/common/src/main/java/com/jiagutech/ams/enums/LimitType.java new file mode 100644 index 0000000..56d3fb2 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/enums/LimitType.java @@ -0,0 +1,24 @@ +package com.jiagutech.ams.enums; + +/** + * 限流类型 + * + * @author ruoyi + */ + +public enum LimitType { + /** + * 默认策略全局限流 + */ + DEFAULT, + + /** + * 根据请求者IP进行限流 + */ + IP, + + /** + * 实例限流(集群多后端实例) + */ + CLUSTER +} diff --git a/common/src/main/java/com/jiagutech/ams/exception/BizCode.java b/common/src/main/java/com/jiagutech/ams/exception/BizCode.java new file mode 100644 index 0000000..31e7cc8 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/exception/BizCode.java @@ -0,0 +1,62 @@ +package com.jiagutech.ams.exception; + +import lombok.Getter; + +@Getter +public enum BizCode implements CodeInterface { + General_Success(200, "接口调用成功"), + ServerError(10001, "服务器异常"), + General_Failure(10004, "接口调用失败"), + General_DBError(10005, "DB错误"), + General_ParameterInvalid(12001, "参数校验失败"), + /** + * 通用类 + */ + USER_UNREGISTERED(12001, "用户未注册"), + NOT_FOUND(12002, "数据不存在"), + LOGIN_TYPE_ERROR(12005, "登录类型错误"), + + /** + * 文件服务 + */ + FILE_DOWNLOAD_ERROR(90001, "文件下载错误"), + + FILE_UPLOAD_ERROR(90002, "文件上传失败"), + + + + USER_NOT_FOUND(40004, "用户不存在"), + + CAPTCHA_ERROR(40003, "验证码错误"), + + PASSWORD_ERROR(40002, "密码错误"), + + TOKEN_TIMEOUT_ERROR(40006, "token已过期"), + + USER_STOP_FOUND(40008, "用户被禁用"), + + USER_NOT_LOGIN(40011, "用户未登录,请登录后再操作"), + + ACCESS_TOKEN_INVALID(40040, "用户token无效,请重新登录"), + + ACCESS_NOT_ALLOWABLE(50001, "服务不允许直接访问"), + + PERMISSION_NOT_FOUND(40001,"该用户无操作权限"), + + USER_PHONE_EXIST(40012, "用户手机号已存在"), + + NOT_ALLOWABLE(13001, "当前正在作业中无法创建新的作业,请先完成作业任务后再创建") + + ; + + + private final Integer code; + + private final String msg; + + BizCode(Integer code, String msg) { + this.code = code; + this.msg = msg; + } + +} diff --git a/common/src/main/java/com/jiagutech/ams/exception/BusinessException.java b/common/src/main/java/com/jiagutech/ams/exception/BusinessException.java new file mode 100644 index 0000000..ecd1fab --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/exception/BusinessException.java @@ -0,0 +1,53 @@ +package com.jiagutech.ams.exception; + +import lombok.Data; + +@Data +public class BusinessException extends RuntimeException { + + private int code; + + private String message; + + public BusinessException( int code,String message) { + super(message); + this.code = code; + this.message = message; + } + + public BusinessException(String message, Throwable cause, int code, String message1) { + super(message, cause); + this.code = code; + this.message = message1; + } + + public BusinessException(Throwable cause, int code, String message) { + super(cause); + this.code = code; + this.message = message; + } + + public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, int code, String message1) { + super(message, cause, enableSuppression, writableStackTrace); + this.code = code; + this.message = message1; + } + + public BusinessException(CodeInterface biz) { + super(); + this.code = biz.getCode(); + this.message = biz.getMsg(); + } + + public BusinessException(String message) { + super(message); + this.code= BizCode.General_ParameterInvalid.getCode(); + this.message =message; + } + + public BusinessException(BizCode biz, String msg) { + super(); + this.code = biz.getCode(); + this.message = msg; + } +} diff --git a/common/src/main/java/com/jiagutech/ams/exception/CodeInterface.java b/common/src/main/java/com/jiagutech/ams/exception/CodeInterface.java new file mode 100644 index 0000000..77c615b --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/exception/CodeInterface.java @@ -0,0 +1,22 @@ +package com.jiagutech.ams.exception; + +/** + * 业务异常接口 + */ +public interface CodeInterface { + + /** + * 消息 + * + * @return String + */ + String getMsg(); + + /** + * 业务代码 + * + * @return int + */ + Integer getCode(); + +} diff --git a/common/src/main/java/com/jiagutech/ams/mapper/RegionMapper.java b/common/src/main/java/com/jiagutech/ams/mapper/RegionMapper.java new file mode 100644 index 0000000..96e0892 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/mapper/RegionMapper.java @@ -0,0 +1,26 @@ +package com.jiagutech.ams.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.jiagutech.ams.model.LoginUser; +import com.jiagutech.ams.model.RegionVO; +import com.jiagutech.ams.model.UserDetail; +import com.jiagutech.ams.model.dto.RegionDTO; +import com.jiagutech.ams.model.dto.UserDTO; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @ClassName UserMapper + * @author: zhangyeguang + * @create: 2024-08-30 15:50 + * @Version 1.0 + * @description: + **/ +public interface RegionMapper extends BaseMapper { + + List getRegionsByParentCode(@Param("regionCode") long regionCode, @Param("level") int level); + + + RegionVO getCompleteRegionInfo(@Param("regionCode") long regionCode); +} diff --git a/common/src/main/java/com/jiagutech/ams/mapper/UserMapper.java b/common/src/main/java/com/jiagutech/ams/mapper/UserMapper.java new file mode 100644 index 0000000..f25b709 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/mapper/UserMapper.java @@ -0,0 +1,34 @@ +package com.jiagutech.ams.mapper; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.jiagutech.ams.model.LoginUser; +import com.jiagutech.ams.model.dto.UserDTO; +import com.jiagutech.ams.model.UserDetail; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @ClassName UserMapper + * @author: zhangyeguang + * @create: 2024-08-30 15:50 + * @Version 1.0 + * @description: + **/ +public interface UserMapper extends BaseMapper { + + + LoginUser selectLoginUserByPhone(@Param("phone") String phone); + + UserDetail selectUserDetail(@Param("userId") Long userId, @Param("phone") String phone); + + List getUserIdsByRegionCodes(@Param("regionCodes") List regionCodes); + + List getUsersByLikeRegionPath( @Param("regionPath") String regionPath); + + + + Page userPage(Page page,@Param("ew") QueryWrapper queryWrapper); +} diff --git a/common/src/main/java/com/jiagutech/ams/model/DeptItem.java b/common/src/main/java/com/jiagutech/ams/model/DeptItem.java new file mode 100644 index 0000000..cd10bd3 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/DeptItem.java @@ -0,0 +1,22 @@ +package com.jiagutech.ams.model; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; + +/** + * @ClassName DeptItem + * @author: zhangyeguang + * @create: 2024-09-02 16:52 + * @Version 1.0 + * @description: + **/ +@Data +public class DeptItem { + @JsonSerialize(using = ToStringSerializer.class) + private String deptId; + private String deptName; + private Long managerId; + private String managerName; + private String managerPhone; +} diff --git a/common/src/main/java/com/jiagutech/ams/model/LoginUser.java b/common/src/main/java/com/jiagutech/ams/model/LoginUser.java new file mode 100644 index 0000000..528421d --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/LoginUser.java @@ -0,0 +1,97 @@ +package com.jiagutech.ams.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.jiagutech.ams.model.dto.DeptDTO; +import com.jiagutech.ams.model.dto.RoleDTO; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * @ClassName LoginUser + * @author: zhangyeguang + * @create: 2024-09-01 09:28 + * @Version 1.0 + * @description: + **/ +@Data +@NoArgsConstructor +public class LoginUser implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + + /** + * 用户ID + */ + private Long userId; + + /** + * 部门 + */ + private DeptDTO dept; + + /** + * 用户唯一标识 + */ + private String token; + + + /** + * 登录时间 + */ + private Long loginTime; + + /** + * 过期时间 + */ + private Long expireTime; + + /** + * 登录IP地址 + */ + private String ipaddr; + + + /** + * 用户名 + */ + private String username; + + /** + * 用户昵称 + */ + private String nickName; + /** + * 手机号 + */ + private String phone; + @JsonIgnore + private String password; + + private String email; + /** + * 头像 + */ + private String avatar; + + private Long createTime; + + /** + * 角色对象 + */ + private List roles; + + /** + * 区域编码 + */ + private Long regionCode; + + private String regionPath; + + +} diff --git a/common/src/main/java/com/jiagutech/ams/model/RegionVO.java b/common/src/main/java/com/jiagutech/ams/model/RegionVO.java new file mode 100644 index 0000000..7bc48e3 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/RegionVO.java @@ -0,0 +1,12 @@ +package com.jiagutech.ams.model; + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class RegionVO { + private String regionCode; + private String regionName; + +} diff --git a/common/src/main/java/com/jiagutech/ams/model/UserDetail.java b/common/src/main/java/com/jiagutech/ams/model/UserDetail.java new file mode 100644 index 0000000..bc0f71d --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/UserDetail.java @@ -0,0 +1,30 @@ +package com.jiagutech.ams.model; + +/** + * @ClassName UserDetailVO + * @author: zhangyeguang + * @create: 2024-09-02 10:03 + * @Version 1.0 + * @description: + **/ + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.jiagutech.ams.model.dto.DeptDTO; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class UserDetail { + @JsonSerialize(using = ToStringSerializer.class) + private Long userId; + private String userName; + private String email; + private String phone; + private String nickName; + private DeptDTO dept; + private Long regionCode; + private String regionName; + private String userIdStr; +} diff --git a/common/src/main/java/com/jiagutech/ams/model/common/PageRequest.java b/common/src/main/java/com/jiagutech/ams/model/common/PageRequest.java new file mode 100644 index 0000000..30d8850 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/common/PageRequest.java @@ -0,0 +1,22 @@ +package com.jiagutech.ams.model.common; + +import lombok.Data; + +/** + * @ClassName PageInfo + * @author: zhangyeguang + * @create: 2024-09-02 15:21 + * @Version 1.0 + * @description: + **/ +@Data +public class PageRequest { + + private int pageNum; + private int pageSize; + private String oderByColumn; + + private T request; + + +} diff --git a/common/src/main/java/com/jiagutech/ams/model/common/PageResult.java b/common/src/main/java/com/jiagutech/ams/model/common/PageResult.java new file mode 100644 index 0000000..699875e --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/common/PageResult.java @@ -0,0 +1,33 @@ +package com.jiagutech.ams.model.common; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * @ClassName PageResult + * @author: zhangyeguang + * @create: 2024-09-02 15:22 + * @Version 1.0 + * @description: + **/ +@Data +@Accessors(chain = true) +public class PageResult { + private int total; + private int pageSize; + private int pageNum; + private int pages; + private List records; + + public static PageResult of(int total, int pageSize, int pageNum, List records) { + PageResult pageResult = new PageResult<>(); + pageResult.setTotal(total); + pageResult.setPageSize(pageSize); + pageResult.setPageNum(pageNum); + pageResult.setPages(total % pageSize == 0 ? total / pageSize : total / pageSize + 1); + pageResult.setRecords(records); + return pageResult; + } +} diff --git a/common/src/main/java/com/jiagutech/ams/model/common/R.java b/common/src/main/java/com/jiagutech/ams/model/common/R.java new file mode 100644 index 0000000..afa5a83 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/common/R.java @@ -0,0 +1,111 @@ +package com.jiagutech.ams.model.common; + + +import com.jiagutech.ams.constant.HttpStatus; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 响应信息主体 + * + * @author Lion Li + */ +@Data +@NoArgsConstructor +public class R implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 成功 + */ + public static final int SUCCESS = 200; + + /** + * 失败 + */ + public static final int FAIL = 500; + + private int code; + + private String msg; + + private T data; + + public static R ok() { + return restResult(null, SUCCESS, "操作成功"); + } + + public static R ok(T data) { + return restResult(data, SUCCESS, "操作成功"); + } + + public static R ok(String msg) { + return restResult(null, SUCCESS, msg); + } + + public static R ok(String msg, T data) { + return restResult(data, SUCCESS, msg); + } + + public static R fail() { + return restResult(null, FAIL, "操作失败"); + } + + public static R fail(String msg) { + return restResult(null, FAIL, msg); + } + + public static R fail(T data) { + return restResult(data, FAIL, "操作失败"); + } + + public static R fail(String msg, T data) { + return restResult(data, FAIL, msg); + } + + public static R fail(int code, String msg) { + return restResult(null, code, msg); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static R warn(String msg) { + return restResult(null, HttpStatus.WARN, msg); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static R warn(String msg, T data) { + return restResult(data, HttpStatus.WARN, msg); + } + + private static R restResult(T data, int code, String msg) { + R r = new R<>(); + r.setCode(code); + r.setData(data); + r.setMsg(msg); + return r; + } + + public static Boolean isError(R ret) { + return !isSuccess(ret); + } + + public static Boolean isSuccess(R ret) { + return R.SUCCESS == ret.getCode(); + } +} diff --git a/common/src/main/java/com/jiagutech/ams/model/dto/DeptDTO.java b/common/src/main/java/com/jiagutech/ams/model/dto/DeptDTO.java new file mode 100644 index 0000000..1401435 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/dto/DeptDTO.java @@ -0,0 +1,22 @@ +package com.jiagutech.ams.model.dto; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName DeptDTO + * @author: zhangyeguang + * @create: 2024-09-01 10:22 + * @Version 1.0 + * @description: + **/ +@Data +@TableName("ams_dept") +public class DeptDTO implements Serializable { + private static final long serialVersionUID = 1L; + + private Long id; + private String name; +} diff --git a/common/src/main/java/com/jiagutech/ams/model/dto/RegionDTO.java b/common/src/main/java/com/jiagutech/ams/model/dto/RegionDTO.java new file mode 100644 index 0000000..df7db70 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/dto/RegionDTO.java @@ -0,0 +1,22 @@ +package com.jiagutech.ams.model.dto; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @ClassName RegionDTO + * @author: zhangyeguang + * @create: 2024-09-02 17:59 + * @Version 1.0 + * @description: + **/ +@Data +@TableName("region_info") +public class RegionDTO { + + private Long regionCode; + + private String regionName; + + private Integer level; +} diff --git a/common/src/main/java/com/jiagutech/ams/model/dto/RoleDTO.java b/common/src/main/java/com/jiagutech/ams/model/dto/RoleDTO.java new file mode 100644 index 0000000..0d0a160 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/dto/RoleDTO.java @@ -0,0 +1,26 @@ +package com.jiagutech.ams.model.dto; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @ClassName RoleDTO + * @author: zhangyeguang + * @create: 2024-09-01 09:29 + * @Version 1.0 + * @description: + **/ +@Data +@TableName("ams_role") +public class RoleDTO implements Serializable { + private static final long serialVersionUID = 1L; + @TableId + private Long id; + + private String name; + + private String key; +} diff --git a/common/src/main/java/com/jiagutech/ams/model/dto/UserDTO.java b/common/src/main/java/com/jiagutech/ams/model/dto/UserDTO.java new file mode 100644 index 0000000..e6b7518 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/dto/UserDTO.java @@ -0,0 +1,28 @@ +package com.jiagutech.ams.model.dto; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @ClassName UserDTO + * @author: zhangyeguang + * @create: 2024-08-30 15:47 + * @Version 1.0 + * @description: + **/ +@Data +@TableName("ams_user") +public class UserDTO { + @TableId + private Long id; + private String username; + private String password; + private String nickName; + private String email; + private String phone; + private Integer delFlag = 0; + private Long regionCode; + private String regionPath; + +} \ No newline at end of file diff --git a/common/src/main/java/com/jiagutech/ams/model/dto/UserDeptDTO.java b/common/src/main/java/com/jiagutech/ams/model/dto/UserDeptDTO.java new file mode 100644 index 0000000..a47a2a5 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/dto/UserDeptDTO.java @@ -0,0 +1,24 @@ +package com.jiagutech.ams.model.dto; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @ClassName UserDeptDTO + * @author: zhangyeguang + * @create: 2024-09-01 09:58 + * @Version 1.0 + * @description: + **/ +@Data +@Accessors(chain = true) +@TableName("ams_user_dept") +public class UserDeptDTO { + + private Long userId; + + private Long deptId; +} diff --git a/common/src/main/java/com/jiagutech/ams/model/dto/UserRoleDTO.java b/common/src/main/java/com/jiagutech/ams/model/dto/UserRoleDTO.java new file mode 100644 index 0000000..1566e1f --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/model/dto/UserRoleDTO.java @@ -0,0 +1,25 @@ +package com.jiagutech.ams.model.dto; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @ClassName UserRoleDTO + * @author: zhangyeguang + * @create: 2024-09-01 09:58 + * @Version 1.0 + * @description: + **/ +@Data +@Accessors(chain = true) +@TableName("ams_user_role") +public class UserRoleDTO { + + private Long userId; + + private Long roleId; + +} diff --git a/common/src/main/java/com/jiagutech/ams/utils/ExcelBigNumberConvert.java b/common/src/main/java/com/jiagutech/ams/utils/ExcelBigNumberConvert.java new file mode 100644 index 0000000..5bc125b --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/utils/ExcelBigNumberConvert.java @@ -0,0 +1,52 @@ +package com.jiagutech.ams.utils; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import lombok.extern.slf4j.Slf4j; + +import java.math.BigDecimal; + +/** + * 大数值转换 + * Excel 数值长度位15位 大于15位的数值转换位字符串 + * + * @author Lion Li + */ +@Slf4j +public class ExcelBigNumberConvert implements Converter { + + @Override + public Class supportJavaTypeKey() { + return Long.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public Long convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + return Convert.toLong(cellData.getData()); + } + + @Override + public WriteCellData convertToExcelData(Long object, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { + if (ObjectUtil.isNotNull(object)) { + String str = Convert.toStr(object); + if (str.length() > 15) { + return new WriteCellData<>(str); + } + } + WriteCellData cellData = new WriteCellData<>(new BigDecimal(object)); + cellData.setType(CellDataTypeEnum.NUMBER); + return cellData; + } + +} diff --git a/common/src/main/java/com/jiagutech/ams/utils/ExcelUtil.java b/common/src/main/java/com/jiagutech/ams/utils/ExcelUtil.java new file mode 100644 index 0000000..456f128 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/utils/ExcelUtil.java @@ -0,0 +1,49 @@ +package com.jiagutech.ams.utils; + +import cn.hutool.core.util.IdUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; +import com.alibaba.excel.write.handler.impl.DefaultRowWriteHandler; +import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.List; + +/** + * @ClassName ExcelUtil + * @author: zhangyeguang + * @create: 2024-09-04 10:28 + * @Version 1.0 + * @description: + **/ +public class ExcelUtil { + + + public static void exportExcel(List list, String sheetName, Class clazz, HttpServletResponse response) { + try { + String filename = IdUtil.fastSimpleUUID() + "_" + sheetName + ".xlsx"; + String percentEncodedFileName = URLEncoder.encode(filename, StandardCharsets.UTF_8).replaceAll("\\+", "%20"); + String contentDispositionValue = "attachment; filename=%s;filename*=utf-8''%s".formatted(percentEncodedFileName, percentEncodedFileName); + response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename"); + response.setHeader("Content-disposition", contentDispositionValue); + response.setHeader("download-filename", percentEncodedFileName); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"); + ServletOutputStream os = response.getOutputStream(); + ExcelWriterSheetBuilder builder = EasyExcel.write(os, clazz) + .autoCloseStream(false) + // 自动适配 + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) + // 大数值自动转换 防止失真 + .registerConverter(new ExcelBigNumberConvert()) + .sheet(sheetName); + builder.registerWriteHandler(new DefaultRowWriteHandler()); + builder.doWrite(list); + } catch (IOException e) { + throw new RuntimeException("导出Excel异常"); + } + } +} diff --git a/common/src/main/java/com/jiagutech/ams/utils/StringToLongDeserializer.java b/common/src/main/java/com/jiagutech/ams/utils/StringToLongDeserializer.java new file mode 100644 index 0000000..591d369 --- /dev/null +++ b/common/src/main/java/com/jiagutech/ams/utils/StringToLongDeserializer.java @@ -0,0 +1,21 @@ +package com.jiagutech.ams.utils; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; + +public class StringToLongDeserializer extends JsonDeserializer { + + @Override + public Long deserialize(JsonParser jsonParser, DeserializationContext context) + throws IOException { + String value = jsonParser.getText(); + try { + return Long.parseLong(value); + } catch (NumberFormatException e) { + throw new IOException("Unable to parse value as Long: " + value, e); + } + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..25dbbbd --- /dev/null +++ b/pom.xml @@ -0,0 +1,185 @@ + + + 4.0.0 + + com.jiagutech + ams-social + ${revision} + pom + + system + social + web + common + + + org.springframework.boot + spring-boot-starter-parent + 3.1.7 + + + + 17 + 1.18.30 + 1.0.0-SNAPSHOT + 3.1.7 + 1.37.0 + 5.2.5 + + 3.3.2 + 2.2.0 + 5.8.22 + 3.5.5 + 3.0.3 + 1.2.83 + 1.3.5 + + 3.2.2 + 3.11.0 + 3.1.2 + 1.3.0 + + + + + dev + + + dev + info + + + + true + + + + prod + + prod + info + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + cn.hutool + hutool-bom + ${hutool.version} + pom + import + + + com.alibaba.fastjson2 + fastjson2 + 2.0.43 + + + + org.apache.commons + commons-pool2 + + + + cn.dev33 + sa-token-spring-boot3-starter + ${satoken.version} + + + + + cn.dev33 + sa-token-redis-jackson + ${satoken.version} + + + cn.dev33 + sa-token-redis + ${satoken.version} + + + + cn.dev33 + sa-token-jwt + ${satoken.version} + + + cn.hutool + hutool-all + + + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + ${springdoc.version} + + + org.springdoc + springdoc-openapi-starter-webmvc-api + ${springdoc.version} + + + org.projectlombok + lombok + ${lombok.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + com.baomidou + mybatis-plus-extension + ${mybatis-plus.version} + + + mysql + mysql-connector-java + 8.0.33 + + + com.alibaba + druid-spring-boot-starter + 1.1.21 + + + + org.apache.poi + poi + ${poi.version} + + + org.apache.poi + poi-ooxml + ${poi.version} + + + com.alibaba + easyexcel + ${easyexcel.version} + + + poi-ooxml-schemas + org.apache.poi + + + + + + + \ No newline at end of file diff --git a/social/pom.xml b/social/pom.xml new file mode 100644 index 0000000..47f2452 --- /dev/null +++ b/social/pom.xml @@ -0,0 +1,97 @@ + + + 4.0.0 + + com.jiagutech + ams-social + ${revision} + + + social + + + 17 + 17 + UTF-8 + + + + + dev + + + dev + info + + + + true + + + + prod + + prod + info + + + + + + com.jiagutech + common + 1.0.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-data-jdbc + + + mysql + mysql-connector-java + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.springframework.boot + spring-boot-starter-validation + + + com.baomidou + mybatis-plus-boot-starter + + + + cn.dev33 + sa-token-spring-boot3-starter + + + org.springdoc + springdoc-openapi-starter-webmvc-api + + + org.apache.poi + poi + + + org.apache.poi + poi-ooxml + + + com.alibaba + easyexcel + + + poi-ooxml-schemas + org.apache.poi + + + + + \ No newline at end of file diff --git a/social/src/main/java/com/jiagutech/ams/controller/DeviceController.java b/social/src/main/java/com/jiagutech/ams/controller/DeviceController.java new file mode 100644 index 0000000..71c01ee --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/controller/DeviceController.java @@ -0,0 +1,42 @@ +package com.jiagutech.ams.controller; + +import cn.dev33.satoken.annotation.SaCheckRole; +import com.jiagutech.ams.model.common.R; +import com.jiagutech.ams.model.response.DeviceInfo; +import com.jiagutech.ams.service.DeviceService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * @ClassName DeviceController + * @author: zhangyeguang + * @create: 2024-09-01 20:26 + * @Version 1.0 + * @description: + **/ +@RequiredArgsConstructor +@RestController +@RequestMapping("/device") +@Tag(name = "设备", description = "农机管理") +public class DeviceController { + + private final DeviceService deviceService; + + @Operation(summary = "获取在线设备列表") + @GetMapping("/onlineAndRound") + @SaCheckRole("machinist") + public R> onlineAndRound(@RequestParam(required = false, defaultValue = "0") double maxLng, + @RequestParam(required = false, defaultValue = "0") double maxLat, + @RequestParam(required = false, defaultValue = "0") double minLng, + @RequestParam(required = false, defaultValue = "0") double minLat) { + return R.ok(deviceService.onlineAndRound(maxLng, maxLat, minLng, minLat)); + } + +} diff --git a/social/src/main/java/com/jiagutech/ams/controller/JobController.java b/social/src/main/java/com/jiagutech/ams/controller/JobController.java new file mode 100644 index 0000000..2e71f43 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/controller/JobController.java @@ -0,0 +1,83 @@ +package com.jiagutech.ams.controller; + +import cn.dev33.satoken.annotation.SaCheckRole; +import cn.dev33.satoken.annotation.SaMode; +import cn.hutool.core.collection.CollectionUtil; +import com.jiagutech.ams.model.common.PageRequest; +import com.jiagutech.ams.model.common.PageResult; +import com.jiagutech.ams.model.common.R; +import com.jiagutech.ams.model.dto.JobTypeDTO; +import com.jiagutech.ams.model.request.JobCreateRequest; +import com.jiagutech.ams.model.request.JobPageRequest; +import com.jiagutech.ams.model.response.JobCreateResponse; +import com.jiagutech.ams.model.response.JobItem; +import com.jiagutech.ams.model.response.JobTypeItem; +import com.jiagutech.ams.service.JobService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * @ClassName JobController + * @author: zhangyeguang + * @create: 2024-09-01 19:29 + * @Version 1.0 + * @description: + **/ +@RequiredArgsConstructor +@RestController +@RequestMapping("/job") +@Tag(name = "作业", description = "作业管理") +public class JobController { + private final JobService jobService; + + @GetMapping("/types") + @Operation(summary = "作业类型列表") + public R> getJobTypes() { + return R.ok(jobService.getJobTypes()); + } + @Operation(summary = "创建作业记录") + @PostMapping("/start") + @SaCheckRole("machinist") + public R createJob(@RequestBody JobCreateRequest jobCreateRequest) { + return R.ok(jobService.createJob(jobCreateRequest)); + } + + @Operation(summary = "更新作业状态") + @SaCheckRole(value = {"machinist", "admin"}, mode = SaMode.OR) + @PutMapping("/status") + public R updateJobStatus(@RequestParam("jobId") Long jobId, @RequestParam("status") Integer status) { + jobService.updateJobStatus(jobId, status); + return R.ok(); + } + + @Operation(summary = "分页获取作业列表") + @SaCheckRole(value = {"machinist","gov","manager"}, mode = SaMode.OR) + @PostMapping("/page") + public R> getPages(@RequestBody PageRequest pageRequest) { + return R.ok(jobService.getPages(pageRequest)); + } + + @Operation(summary = "获取当前作业任务") + @SaCheckRole("machinist") + @GetMapping("/inWorking") + public R inJob() { + return R.ok(CollectionUtil.isNotEmpty(jobService.inJob()) ? jobService.inJob().get(0) : null); + } + + + @PostMapping("/export") + @Operation(summary = "导出作业记录") + public void exportJobs(@RequestBody(required = false) JobPageRequest jobPageRequest, HttpServletResponse response){ + jobService.exportJobs(jobPageRequest, response); + } + @PostMapping("/exportByFarmer") + @Operation(summary = "导出作业记录") + public void exportByFarmer(@RequestBody(required = false) JobPageRequest jobPageRequest, HttpServletResponse response){ + jobService.exportByFarmer(jobPageRequest, response); + } +} diff --git a/social/src/main/java/com/jiagutech/ams/controller/RegionController.java b/social/src/main/java/com/jiagutech/ams/controller/RegionController.java new file mode 100644 index 0000000..fe5c642 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/controller/RegionController.java @@ -0,0 +1,22 @@ +package com.jiagutech.ams.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName RegionController + * @author: zhangyeguang + * @create: 2024-09-02 14:32 + * @Version 1.0 + * @description: + **/ +@RestController +@RequestMapping("/region") +@RequiredArgsConstructor +@Tag(name = "区域", description = "区域管理接口") +public class RegionController { + + +} diff --git a/social/src/main/java/com/jiagutech/ams/controller/TrackController.java b/social/src/main/java/com/jiagutech/ams/controller/TrackController.java new file mode 100644 index 0000000..24a4315 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/controller/TrackController.java @@ -0,0 +1,21 @@ +package com.jiagutech.ams.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @ClassName TrackController + * @author: zhangyeguang + * @create: 2024-09-03 16:07 + * @Version 1.0 + * @description: + **/ +@RestController +@RequestMapping("/track") +@Tag(name = "轨迹") +public class TrackController { + + + +} diff --git a/social/src/main/java/com/jiagutech/ams/mapper/DeviceMapper.java b/social/src/main/java/com/jiagutech/ams/mapper/DeviceMapper.java new file mode 100644 index 0000000..4da3a85 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/mapper/DeviceMapper.java @@ -0,0 +1,11 @@ +package com.jiagutech.ams.mapper; + +import com.jiagutech.ams.model.response.DeviceInfo; + +import java.util.List; + +public interface DeviceMapper { + + List queryDeviceList(Long detpId); + +} diff --git a/social/src/main/java/com/jiagutech/ams/mapper/JobMapper.java b/social/src/main/java/com/jiagutech/ams/mapper/JobMapper.java new file mode 100644 index 0000000..d25a9fb --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/mapper/JobMapper.java @@ -0,0 +1,21 @@ +package com.jiagutech.ams.mapper; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.jiagutech.ams.model.dto.JobDTO; +import com.jiagutech.ams.model.response.JobItem; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface JobMapper extends BaseMapper { + + + Page jobPage(Page page, @Param("ew") QueryWrapper wrapper); + + List jobList(@Param("ew") QueryWrapper wrapper); + + List jobListCountByFarmer(@Param("ew") QueryWrapper wrapper); +} diff --git a/social/src/main/java/com/jiagutech/ams/mapper/JobTypeMapper.java b/social/src/main/java/com/jiagutech/ams/mapper/JobTypeMapper.java new file mode 100644 index 0000000..416e87a --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/mapper/JobTypeMapper.java @@ -0,0 +1,9 @@ +package com.jiagutech.ams.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.jiagutech.ams.model.dto.JobTypeDTO; + +public interface JobTypeMapper extends BaseMapper { + + +} diff --git a/social/src/main/java/com/jiagutech/ams/model/JobMapping.java b/social/src/main/java/com/jiagutech/ams/model/JobMapping.java new file mode 100644 index 0000000..fcc11b8 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/JobMapping.java @@ -0,0 +1,16 @@ +package com.jiagutech.ams.model; + +import com.jiagutech.ams.model.dto.JobDTO; +import com.jiagutech.ams.model.request.JobCreateRequest; +import com.jiagutech.ams.model.response.JobCreateResponse; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface JobMapping { + JobMapping INSTANCE = Mappers.getMapper(JobMapping.class); + + JobDTO jobCreateToJobDTO(JobCreateRequest job); + + JobCreateResponse jobDTOToJobCreateResponse(JobDTO job); +} diff --git a/social/src/main/java/com/jiagutech/ams/model/TrackDataJG.java b/social/src/main/java/com/jiagutech/ams/model/TrackDataJG.java new file mode 100644 index 0000000..6af2c40 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/TrackDataJG.java @@ -0,0 +1,120 @@ +package com.jiagutech.ams.model; + + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class TrackDataJG implements Serializable { + + + private String droneId; + + /** + * 架次ID + */ + //替换Int-long + //private Integer sortieId; + private Long sortieId; + + /** + * 该记录点数据产生的时间 + */ + private Long timeStamp; + + /** + * 纬度 + */ + private Double lat; + + /** + * 经度 + */ + private Double lng; + + /** + * 海拔高度,单位:米 + */ + private Float alt; + + /** + * 当前相对于作物冠层的高度,单位:米 + */ + private Float height; + + /** + * 飞行方向水平速度,单位:米/秒 + */ + private Float hvel; + + /** + * 飞行方向垂直速度,单位:米/秒 + */ + private Float vvel; + + /** + * 航向角.无人机飞行方向与地球北极之间的夹角,(-180 度,180 度],单位为 0.01 度 + */ + private Float yaw; + + /** + * 俯仰角。无人机机体坐标系 x 轴与水平面的夹角。当 x 轴的正半轴位于过坐标原点的 + * 水平面之上时,俯仰角为正;否则为负。单位为 0.01 度 + */ + private Float pitch; + + /** + * 横滚角。无人机机体坐标系 y 轴与水平面的夹角。当 y 轴的正半轴位于过坐标原点的 + * 水平面之上时,俯仰角为正;否则为负。单位为 0.01 度 + */ + private Float roll; + + /** + * 本架次起飞后,已飞行的时间。单位:秒 + */ + private Integer ftime; + + /** + * 本架次起飞后,已喷洒的面积。单位:亩 + */ + private Float farea; + + /** + * 喷洒流速,单位:升/分钟 + */ + private Float curFlow; + + /** + * 目前接收到的导航卫星的数量 + */ + private Integer gpsNum; + + /** + * 定位精度类型,1:GPS/BD 单点,2:差分,4:RTK 固定解,5:RTK 浮点解 + */ + private Integer posAccur; + + private Integer areaCode; + + private Integer flying;//1=正在飞 0在地上 + + //替换 int - long + //private Integer operUserId; + private Long operUserId; + + private Float totalArea;//飞控总亩数 + + private Integer errorCode; + + private Integer deviceType; + + // 耕深(厘米)[浮点数,最多保留一位小数] + private Double deep; + // 流量(脉冲值)[浮点数,最多保留一位小数] + private Double flow; + // 播种速度 粒/s生成对应的实体类 + private Double seeding; + + +} diff --git a/social/src/main/java/com/jiagutech/ams/model/dto/DeviceDTO.java b/social/src/main/java/com/jiagutech/ams/model/dto/DeviceDTO.java new file mode 100644 index 0000000..927922f --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/dto/DeviceDTO.java @@ -0,0 +1,24 @@ +package com.jiagutech.ams.model.dto; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @ClassName DeviceDTO + * @author: zhangyeguang + * @create: 2024-09-01 19:40 + * @Version 1.0 + * @description: + **/ +@Data +@TableName("ams_device_info") +public class DeviceDTO { + + private Long id; + + private String deviceNum; + + private String boxNum; + + private Long deptId; +} diff --git a/social/src/main/java/com/jiagutech/ams/model/dto/JobDTO.java b/social/src/main/java/com/jiagutech/ams/model/dto/JobDTO.java new file mode 100644 index 0000000..839f2ba --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/dto/JobDTO.java @@ -0,0 +1,44 @@ +package com.jiagutech.ams.model.dto; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @ClassName JobDTO + * @author: zhangyeguang + * @create: 2024-09-01 19:35 + * @Version 1.0 + * @description: + **/ +@Data +@Accessors(chain = true) +@TableName("ams_job_info") +public class JobDTO { + @TableId + private Long id; + + private Long deviceId; + + private Long startTime; + + private Long endTime; + + private Long operatorId; + + private Long farmerId; + + private Float area; + + private Long regionCode; + + private Float duration; + + private Integer status; + + private Integer jobType; + + private Long deptId; + +} diff --git a/social/src/main/java/com/jiagutech/ams/model/dto/JobTypeDTO.java b/social/src/main/java/com/jiagutech/ams/model/dto/JobTypeDTO.java new file mode 100644 index 0000000..72258a1 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/dto/JobTypeDTO.java @@ -0,0 +1,23 @@ +package com.jiagutech.ams.model.dto; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @ClassName JobTypeDTO + * @author: zhangyeguang + * @create: 2024-09-03 15:03 + * @Version 1.0 + * @description: + **/ +@Data +@TableName("ams_job_type") +public class JobTypeDTO { + @TableId(value = "id", type = IdType.AUTO) + private Integer typeId; + @TableField(value = "name") + private String typeName; +} diff --git a/social/src/main/java/com/jiagutech/ams/model/request/JobCreateRequest.java b/social/src/main/java/com/jiagutech/ams/model/request/JobCreateRequest.java new file mode 100644 index 0000000..5f99215 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/request/JobCreateRequest.java @@ -0,0 +1,46 @@ +package com.jiagutech.ams.model.request; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.NumberDeserializers; +import com.jiagutech.ams.utils.StringToLongDeserializer; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @ClassName JobCreateRequest + * @author: zhangyeguang + * @create: 2024-09-01 19:31 + * @Version 1.0 + * @description: + **/ +@Data +@Accessors(chain = true) +public class JobCreateRequest { + + private long startTime; + /** + * 机手 + */ + @JsonDeserialize(using = StringToLongDeserializer.class) + private long operatorId; + /** + * 农户ID + */ + @JsonDeserialize(using = StringToLongDeserializer.class) + private long farmerId; + /** + * 区域 + */ + private long regionCode; + /** + * 设备ID + */ + @JsonDeserialize(using = StringToLongDeserializer.class) + private long deviceId; + /** + * 作业类型 + */ + private int jobType; + + +} diff --git a/social/src/main/java/com/jiagutech/ams/model/request/JobPageRequest.java b/social/src/main/java/com/jiagutech/ams/model/request/JobPageRequest.java new file mode 100644 index 0000000..6bffe63 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/request/JobPageRequest.java @@ -0,0 +1,35 @@ +package com.jiagutech.ams.model.request; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.NumberDeserializers; +import com.jiagutech.ams.utils.StringToLongDeserializer; +import lombok.Data; + +/** + * @ClassName JobPageRequest + * @author: zhangyeguang + * @create: 2024-09-02 15:18 + * @Version 1.0 + * @description: + **/ +@Data +public class JobPageRequest { + private long startTimeBegin; + + private long startTimeEnd; + + private long regionCode; + + private int JobType; + + private int status; + @JsonDeserialize(using = StringToLongDeserializer.class) + private long operatorId; + @JsonDeserialize(using = StringToLongDeserializer.class) + private long farmerId; + @JsonDeserialize(using = StringToLongDeserializer.class) + private long deviceId; + @JsonDeserialize(using = StringToLongDeserializer.class) + private long deptId; + +} diff --git a/social/src/main/java/com/jiagutech/ams/model/response/DeviceInfo.java b/social/src/main/java/com/jiagutech/ams/model/response/DeviceInfo.java new file mode 100644 index 0000000..54c5995 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/response/DeviceInfo.java @@ -0,0 +1,31 @@ +package com.jiagutech.ams.model.response; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @ClassName DeviceInfo + * @author: zhangyeguang + * @create: 2024-09-03 16:26 + * @Version 1.0 + * @description: + **/ +@Data +@Accessors(chain = true) +public class DeviceInfo { + @JsonSerialize(using = ToStringSerializer.class) + private long deviceId; + + private double lat; + + private double lng; + + private int status; + + private String deviceNum; + + private String boxNum; + +} diff --git a/social/src/main/java/com/jiagutech/ams/model/response/JobCreateResponse.java b/social/src/main/java/com/jiagutech/ams/model/response/JobCreateResponse.java new file mode 100644 index 0000000..b0cf77d --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/response/JobCreateResponse.java @@ -0,0 +1,30 @@ +package com.jiagutech.ams.model.response; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @ClassName JobVO + * @author: zhangyeguang + * @create: 2024-09-01 19:31 + * @Version 1.0 + * @description: + **/ +@Data +@Accessors(chain = true) +public class JobCreateResponse { + @JsonSerialize(using = ToStringSerializer.class) + private long jobId; + + private long startTime; + + private long farmerId; + + private long deviceId; + + private Integer status; + + +} diff --git a/social/src/main/java/com/jiagutech/ams/model/response/JobItem.java b/social/src/main/java/com/jiagutech/ams/model/response/JobItem.java new file mode 100644 index 0000000..e25b67e --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/response/JobItem.java @@ -0,0 +1,54 @@ +package com.jiagutech.ams.model.response; + +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; + +/** + * @ClassName JobItem + * @author: zhangyeguang + * @create: 2024-09-02 15:18 + * @Version 1.0 + * @description: + **/ +@Data +public class JobItem { + @ExcelIgnore + @JsonSerialize(using = ToStringSerializer.class) + private Long jobId; + @ExcelIgnore + private Long operatorId; + @ExcelProperty(value = "机手") + private String operatorName; + @ExcelIgnore + private Long farmerId; + @ExcelProperty(value = "农户") + private String farmerName; + @ExcelIgnore + private Long startTime; + @ExcelIgnore + private Long endTime; + + @ExcelProperty(value = "开始作业时间") + private String startTimeStr; + + @ExcelProperty(value = "作业面积") + private Float area; + @ExcelIgnore + private Integer status; + @ExcelIgnore + private Integer JobType; + + @ExcelProperty(value = "作业类型") + private String typeName; + @ExcelIgnore + private Long deviceId; + @ExcelIgnore + private long deptId; + @ExcelProperty(value = "合作社") + private String deptName; + + +} diff --git a/social/src/main/java/com/jiagutech/ams/model/response/JobTypeItem.java b/social/src/main/java/com/jiagutech/ams/model/response/JobTypeItem.java new file mode 100644 index 0000000..bc9b818 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/model/response/JobTypeItem.java @@ -0,0 +1,18 @@ +package com.jiagutech.ams.model.response; + +import lombok.Data; + +/** + * @ClassName JobTypeItem + * @author: zhangyeguang + * @create: 2024-09-03 15:02 + * @Version 1.0 + * @description: + **/ +@Data +public class JobTypeItem { + + private Integer id; + + private String name; +} diff --git a/social/src/main/java/com/jiagutech/ams/rest/CenterRestClient.java b/social/src/main/java/com/jiagutech/ams/rest/CenterRestClient.java new file mode 100644 index 0000000..6052e1b --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/rest/CenterRestClient.java @@ -0,0 +1,23 @@ +package com.jiagutech.ams.rest; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +/** + * @ClassName CenterClient + * @author: zhangyeguang + * @create: 2024-09-03 16:32 + * @Version 1.0 + * @description: + **/ +@Component +@Slf4j +@RequiredArgsConstructor +public class CenterRestClient { + private final RestTemplate restTemplate; + + + +} diff --git a/social/src/main/java/com/jiagutech/ams/service/DeviceService.java b/social/src/main/java/com/jiagutech/ams/service/DeviceService.java new file mode 100644 index 0000000..a5c2c76 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/service/DeviceService.java @@ -0,0 +1,9 @@ +package com.jiagutech.ams.service; + +import com.jiagutech.ams.model.response.DeviceInfo; + +import java.util.List; + +public interface DeviceService { + List onlineAndRound(double maxLng, double maxLat, double minLng, double minLat); +} diff --git a/social/src/main/java/com/jiagutech/ams/service/DeviceServiceImpl.java b/social/src/main/java/com/jiagutech/ams/service/DeviceServiceImpl.java new file mode 100644 index 0000000..3a33c84 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/service/DeviceServiceImpl.java @@ -0,0 +1,68 @@ +package com.jiagutech.ams.service; + +import cn.dev33.satoken.annotation.SaCheckLogin; +import cn.dev33.satoken.annotation.SaCheckRole; +import cn.dev33.satoken.stp.StpUtil; +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.jiagutech.ams.constant.UserConstants; +import com.jiagutech.ams.mapper.DeviceMapper; +import com.jiagutech.ams.model.LoginUser; +import com.jiagutech.ams.model.TrackDataJG; +import com.jiagutech.ams.model.response.DeviceInfo; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Predicate; + +/** + * @ClassName DeviceServiceImpl + * @author: zhangyeguang + * @create: 2024-09-03 16:46 + * @Version 1.0 + * @description: + **/ +@Slf4j +@Service +@RequiredArgsConstructor +public class DeviceServiceImpl implements DeviceService { + public static final String TRACK_PREFIX_REDIS_KEY = "mtrack:*"; + private final StringRedisTemplate stringRedisTemplate; + private final DeviceMapper deviceMapper; + + @Override + public List onlineAndRound(double maxLng, double maxLat, double minLng, double minLat) { + Set keys = stringRedisTemplate.keys(TRACK_PREFIX_REDIS_KEY); + List deviceInfos = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(keys)) { + List values = stringRedisTemplate.opsForValue().multiGet(keys); + List trackDataJGS = JSON.parseArray(JSON.toJSONString(values), TrackDataJG.class); + Predicate predicate = t -> t.getLat() <= maxLat && t.getLat() >= minLat + && ((t.getLng() >= -180 && t.getLng() <= maxLng) || (t.getLng() >= minLng && t.getLng() <= 180)); + Consumer consumer = t -> deviceInfos.add(new DeviceInfo().setBoxNum(t.getDroneId()).setLng(t.getLng()).setLat(t.getLat())); + trackDataJGS.stream().filter(predicate).forEach(consumer); + LoginUser loginUser = StpUtil.getSession().get(UserConstants.SYS_SESSION, new LoginUser()); + if (loginUser != null && loginUser.getDept() != null) { + long deptId = loginUser.getDept().getId(); + List deviceInfos1 = deviceMapper.queryDeviceList(deptId); + + Iterator iterator = deviceInfos.iterator(); + while (iterator.hasNext()) { + DeviceInfo deviceInfo = iterator.next(); + Predicate p = d -> d.getBoxNum().equals(deviceInfo.getBoxNum()); + Optional exists = deviceInfos1.stream().filter(p).findFirst(); + if (!exists.isPresent()) { + iterator.remove(); + continue; + } + deviceInfo.setDeviceId(exists.get().getDeviceId()).setStatus(exists.get().getStatus()); + } + } + } + return deviceInfos; + } +} diff --git a/social/src/main/java/com/jiagutech/ams/service/JobService.java b/social/src/main/java/com/jiagutech/ams/service/JobService.java new file mode 100644 index 0000000..af01a06 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/service/JobService.java @@ -0,0 +1,28 @@ +package com.jiagutech.ams.service; + +import com.jiagutech.ams.model.common.PageRequest; +import com.jiagutech.ams.model.common.PageResult; +import com.jiagutech.ams.model.dto.JobTypeDTO; +import com.jiagutech.ams.model.request.JobCreateRequest; +import com.jiagutech.ams.model.request.JobPageRequest; +import com.jiagutech.ams.model.response.JobCreateResponse; +import com.jiagutech.ams.model.response.JobItem; +import jakarta.servlet.http.HttpServletResponse; + +import java.util.List; + +public interface JobService { + JobCreateResponse createJob(JobCreateRequest jobCreateRequest); + + void updateJobStatus(Long jobId, Integer status); + + PageResult getPages(PageRequest pageRequest); + + List inJob(); + + List getJobTypes(); + + void exportJobs(JobPageRequest jobPageRequest, HttpServletResponse response); + + void exportByFarmer(JobPageRequest jobPageRequest, HttpServletResponse response); +} diff --git a/social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java b/social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java new file mode 100644 index 0000000..f0ead06 --- /dev/null +++ b/social/src/main/java/com/jiagutech/ams/service/JobServiceImpl.java @@ -0,0 +1,169 @@ +package com.jiagutech.ams.service; + +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.excel.EasyExcel; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.jiagutech.ams.constant.UserConstants; +import com.jiagutech.ams.exception.BizCode; +import com.jiagutech.ams.exception.BusinessException; +import com.jiagutech.ams.mapper.JobMapper; +import com.jiagutech.ams.mapper.JobTypeMapper; +import com.jiagutech.ams.mapper.RegionMapper; +import com.jiagutech.ams.mapper.UserMapper; +import com.jiagutech.ams.model.JobMapping; +import com.jiagutech.ams.model.LoginUser; +import com.jiagutech.ams.model.common.PageRequest; +import com.jiagutech.ams.model.common.PageResult; +import com.jiagutech.ams.model.dto.JobDTO; +import com.jiagutech.ams.model.dto.JobTypeDTO; +import com.jiagutech.ams.model.dto.RegionDTO; +import com.jiagutech.ams.model.dto.RoleDTO; +import com.jiagutech.ams.model.request.JobCreateRequest; +import com.jiagutech.ams.model.request.JobPageRequest; +import com.jiagutech.ams.model.response.JobCreateResponse; +import com.jiagutech.ams.model.response.JobItem; +import com.jiagutech.ams.utils.ExcelUtil; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.util.StringUtil; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + * @ClassName JobServiceImpl + * @author: zhangyeguang + * @create: 2024-09-01 19:34 + * @Version 1.0 + * @description: + **/ +@Slf4j +@Service +@RequiredArgsConstructor +public class JobServiceImpl implements JobService { + private final JobMapper jobMapper; + private final UserMapper userMapper; + private final RegionMapper regionMapper; + + private final JobTypeMapper jobTypeMapper; + + @Override + public JobCreateResponse createJob(JobCreateRequest jobCreateRequest) { + LoginUser loginUser = StpUtil.getSession().get(UserConstants.SYS_SESSION, new LoginUser()); + log.info("create job, loginUser: {}", loginUser); + if (CollectionUtil.isNotEmpty(inJob())) { + throw new BusinessException(BizCode.NOT_ALLOWABLE); + } + JobDTO jobDTO = JobMapping.INSTANCE.jobCreateToJobDTO(jobCreateRequest); + jobDTO.setStartTime(System.currentTimeMillis()); + jobDTO.setArea(0f); + jobDTO.setStatus(1); + jobDTO.setOperatorId(StpUtil.getLoginIdAsLong()); + jobDTO.setDeptId(loginUser.getDept().getId()); + jobDTO.setRegionCode(userMapper.selectById(jobCreateRequest.getFarmerId()).getRegionCode()); + jobMapper.insert(jobDTO); + return JobMapping.INSTANCE.jobDTOToJobCreateResponse(jobDTO); + } + + @Override + public void updateJobStatus(Long jobId, Integer status) { + JobDTO jobDTO = new JobDTO().setId(jobId).setStatus(status).setEndTime(System.currentTimeMillis()); + jobMapper.updateById(jobDTO); + + } + + @Override + public PageResult getPages(PageRequest pageRequest) { + JobPageRequest requestParam = pageRequest.getRequest(); + QueryWrapper queryWrapper = buildQueryWrapper(requestParam); + Page page = new Page(pageRequest.getPageNum(), pageRequest.getPageSize()); + Page result = jobMapper.jobPage(page, queryWrapper); + return PageResult.of((int) result.getTotal(), (int) result.getSize(), (int) result.getCurrent(), result.getRecords()); + } + + + @Override + public List inJob() { + QueryWrapper queryWrapper = Wrappers.query(); + queryWrapper.eq("operator_id", StpUtil.getLoginIdAsLong()).eq("status", 1); + return jobMapper.jobList(queryWrapper); + } + + @Override + public List getJobTypes() { + QueryWrapper queryWrapper = Wrappers.query(); + return jobTypeMapper.selectList(queryWrapper); + } + + @Override + public void exportJobs(JobPageRequest jobPageRequest, HttpServletResponse response) { + QueryWrapper queryWrapper = buildQueryWrapper(jobPageRequest); + List jobItems = jobMapper.jobList(queryWrapper); + ExcelUtil.exportExcel(jobItems, "作业记录", JobItem.class, response); + } + + @Override + public void exportByFarmer(JobPageRequest jobPageRequest, HttpServletResponse response) { + QueryWrapper queryWrapper = buildQueryWrapper(jobPageRequest); + List jobItems = jobMapper.jobListCountByFarmer(queryWrapper); + ExcelUtil.exportExcel(jobItems, "作业记录", JobItem.class, response); + } + + + private QueryWrapper buildQueryWrapper(JobPageRequest requestParam) { + + QueryWrapper queryWrapper = Wrappers.query(); + if (requestParam != null) { + if (requestParam.getStartTimeBegin() != 0l && requestParam.getStartTimeEnd() != 0l) { + queryWrapper.between("j.start_time", requestParam.getStartTimeBegin(), requestParam.getStartTimeEnd()); + } + if (requestParam.getJobType() != 0) { + queryWrapper.eq("j.job_type", requestParam.getJobType()); + } + if (requestParam.getStatus() != 0) { + queryWrapper.eq("j.status", requestParam.getStatus()); + } + if (requestParam.getOperatorId() != 0l) { + queryWrapper.eq("j.operator_id", requestParam.getOperatorId()); + } + if (requestParam.getFarmerId() != 0l) { + queryWrapper.eq("j.farmer_id", requestParam.getFarmerId()); + } + } + + + LoginUser loginUser = StpUtil.getSession().get(UserConstants.SYS_SESSION, new LoginUser()); + Predicate predicate1 = r -> r.getKey().equals("manager"); + Predicate predicate2 = r -> r.getKey().equals("gov"); + Predicate predicate3 = r -> r.getKey().equals("machinist"); + + boolean hasManager = loginUser.getRoles().stream().anyMatch(predicate1); + boolean hasGov = loginUser.getRoles().stream().anyMatch(predicate2); + boolean hasMachinist = loginUser.getRoles().stream().anyMatch(predicate3); + if (hasManager) { + queryWrapper.eq("j.dept_id", loginUser.getDept().getId()); + } + if (hasGov && loginUser.getRegionCode() != null && StringUtils.isNotBlank(loginUser.getRegionPath())) { + List farmerIds = userMapper.getUsersByLikeRegionPath(loginUser.getRegionPath()).stream().map(u -> u.getId()).collect(Collectors.toList()); + queryWrapper.in("j.farmer_id", farmerIds); + if (requestParam != null && requestParam.getDeptId() != 0l) { + queryWrapper.eq("d.id", requestParam.getDeptId()); + } + } + if (hasMachinist) { + queryWrapper.eq("j.operator_id", loginUser.getUserId()); + } + return queryWrapper; + } +} diff --git a/social/src/main/resources/mapper/DeviceMapper.xml b/social/src/main/resources/mapper/DeviceMapper.xml new file mode 100644 index 0000000..d78647b --- /dev/null +++ b/social/src/main/resources/mapper/DeviceMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/social/src/main/resources/mapper/JobMapper.xml b/social/src/main/resources/mapper/JobMapper.xml new file mode 100644 index 0000000..8939b7f --- /dev/null +++ b/social/src/main/resources/mapper/JobMapper.xml @@ -0,0 +1,53 @@ + + + + + + select j.id as job_id, + j.start_time, + j.end_time, + j.area, + j.status, + j.device_id, + j.operator_id, + FROM_UNIXTIME(j.start_time/1000,'%Y-%m-%d %H:%i:%s') as start_time_str, + u1.nick_name as operator_name, + j.farmer_id, + u2.nick_name as farmer_name, + j.job_type, + t.name as type_name, + d.id as dept_id, + d.name as dept_name + from ams_job_info j + left join ams_job_type t on j.job_type = t.id + left join ams_dept d on j.dept_id=d.id + left join ams_user u1 on j.operator_id = u1.id + left join ams_user u2 on j.farmer_id = u2.id + + + + + + + + + \ No newline at end of file diff --git a/social/src/main/resources/mapper/RegionMapper.xml b/social/src/main/resources/mapper/RegionMapper.xml new file mode 100644 index 0000000..3aa30da --- /dev/null +++ b/social/src/main/resources/mapper/RegionMapper.xml @@ -0,0 +1,47 @@ + + + + + + + + + + \ No newline at end of file diff --git a/system/pom.xml b/system/pom.xml new file mode 100644 index 0000000..d901bea --- /dev/null +++ b/system/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + com.jiagutech + ams-social + ${revision} + + + system + + + 17 + 17 + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-web + + + com.jiagutech + common + 1.0.0-SNAPSHOT + + + + cn.hutool + hutool-core + + + cn.hutool + hutool-captcha + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-validation + + + + ma.glasnost.orika + orika-core + 1.5.4 + + + cn.dev33 + sa-token-spring-boot3-starter + + + org.springdoc + springdoc-openapi-starter-webmvc-api + + + + + cn.dev33 + sa-token-jwt + + + + + \ No newline at end of file diff --git a/system/src/main/java/com/jiagutech/ams/config/MybatisConfig.java b/system/src/main/java/com/jiagutech/ams/config/MybatisConfig.java new file mode 100644 index 0000000..5c51b59 --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/config/MybatisConfig.java @@ -0,0 +1,16 @@ +package com.jiagutech.ams.config; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Configuration; + +/** + * @ClassName MybatisConfig + * @author: zhangyeguang + * @create: 2024-08-30 15:53 + * @Version 1.0 + * @description: + **/ +@MapperScan("com.jiagutech.ams.mapper") +@Configuration +public class MybatisConfig { +} diff --git a/system/src/main/java/com/jiagutech/ams/controller/CommonController.java b/system/src/main/java/com/jiagutech/ams/controller/CommonController.java new file mode 100644 index 0000000..71f7d2a --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/controller/CommonController.java @@ -0,0 +1,51 @@ +package com.jiagutech.ams.controller; + +import cn.hutool.captcha.CaptchaUtil; +import cn.hutool.captcha.ShearCaptcha; +import cn.hutool.core.util.IdUtil; +import com.jiagutech.ams.constant.Constants; +import com.jiagutech.ams.constant.GlobalConstants; +import com.jiagutech.ams.model.response.CaptchaVO; +import com.jiagutech.ams.model.common.R; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.Duration; + +/** + * @ClassName CommonController + * @author: zhangyeguang + * @create: 2024-08-30 11:54 + * @Version 1.0 + * @description: + **/ +@RequestMapping("/common") +@RestController +@RequiredArgsConstructor +@Tag(name = "基础", description = "基础功能") +public class CommonController { + private final RedisTemplate redisTemplate; + + @Operation(summary = "验证码") + @GetMapping("/code") + public R getCode() { + CaptchaVO captchaVo = new CaptchaVO(); + // 保存验证码信息 + String uuid = IdUtil.simpleUUID(); + String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid; + + ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(150, 40, 5, 4); + + String code = shearCaptcha.getCode(); + + redisTemplate.opsForValue().set(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); + captchaVo.setUuid(uuid); + captchaVo.setImg(shearCaptcha.getImageBase64()); + return R.ok(captchaVo); + } +} diff --git a/system/src/main/java/com/jiagutech/ams/controller/DeptController.java b/system/src/main/java/com/jiagutech/ams/controller/DeptController.java new file mode 100644 index 0000000..04dfd9e --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/controller/DeptController.java @@ -0,0 +1,34 @@ +package com.jiagutech.ams.controller; + +import cn.dev33.satoken.annotation.SaCheckRole; +import com.jiagutech.ams.model.DeptItem; +import com.jiagutech.ams.model.common.PageRequest; +import com.jiagutech.ams.model.common.PageResult; +import com.jiagutech.ams.model.common.R; +import com.jiagutech.ams.model.request.DeptPageRequest; +import com.jiagutech.ams.service.DeptService; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +/** + * @ClassName DeptController + * @author: zhangyeguang + * @create: 2024-09-02 16:47 + * @Version 1.0 + * @description: + **/ +@RestController +@RequestMapping("/dept") +@RequiredArgsConstructor +@Tag(name = "部门", description = "部门管理") +public class DeptController { + private final DeptService deptService; + + @SaCheckRole("gov") + @PostMapping("/page") + public R> selectPage(@RequestBody PageRequest pageRequest) { + return R.ok(deptService.selectPage(pageRequest)); + } + +} diff --git a/system/src/main/java/com/jiagutech/ams/controller/UserController.java b/system/src/main/java/com/jiagutech/ams/controller/UserController.java new file mode 100644 index 0000000..f265c39 --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/controller/UserController.java @@ -0,0 +1,76 @@ +package com.jiagutech.ams.controller; + +import cn.dev33.satoken.stp.StpUtil; +import com.jiagutech.ams.constant.UserConstants; +import com.jiagutech.ams.model.LoginUser; +import com.jiagutech.ams.model.common.PageRequest; +import com.jiagutech.ams.model.common.PageResult; +import com.jiagutech.ams.model.common.R; +import com.jiagutech.ams.model.request.LoginRequest; +import com.jiagutech.ams.model.request.PageUserRequest; +import com.jiagutech.ams.model.request.UserRequest; +import com.jiagutech.ams.model.response.LoginResponse; +import com.jiagutech.ams.model.UserDetail; +import com.jiagutech.ams.service.UserService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * @ClassName UserController + * @author: zhangyeguang + * @create: 2024-08-30 15:11 + * @Version 1.0 + * @description: + **/ +@RestController +@RequestMapping("/user") +@RequiredArgsConstructor +@Tag(name = "用户", description = "用户管理") +public class UserController { + private final UserService userService; + + @Operation(summary = "登录接口") + @PostMapping("/login") + public R login(@Validated @RequestBody LoginRequest loginBody) { + + LoginResponse loginVo = userService.login(loginBody); + return R.ok(loginVo); + } + + @Operation(summary = "添加用户") + @PostMapping("/add") + public R add(@Validated @RequestBody UserRequest user) { + userService.addUser(user); + return R.ok(); + } + + @Operation(summary = "获取用户登陆信息") + @GetMapping("/getUserInfo") + public R getUserInfo() { + return R.ok(StpUtil.getSession().get(UserConstants.SYS_SESSION, new LoginUser())); + } + + @Operation(summary = "获取用户详情") + @GetMapping("/getUserDetail") + public R getUserDetail(@RequestParam(value = "userId", required = false) Long userId, + @RequestParam(value = "phone", required = false) String phone) { + return R.ok(userService.getUserDetail(userId, phone)); + } + @Operation(summary = "更新用户信息") + @PutMapping("/update") + public R updateUser(@Validated @RequestBody UserRequest user){ + userService.updateUser(user); + return R.ok(); + } + + @Operation(summary = "分页获取用户列表") + @PostMapping("/page") + public R> getUserList(@RequestBody PageRequest pageRequest) { + return R.ok(userService.getUserPage(pageRequest)); + } +} diff --git a/system/src/main/java/com/jiagutech/ams/mapper/DeptMapper.java b/system/src/main/java/com/jiagutech/ams/mapper/DeptMapper.java new file mode 100644 index 0000000..c01016c --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/mapper/DeptMapper.java @@ -0,0 +1,18 @@ +package com.jiagutech.ams.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.jiagutech.ams.model.DeptItem; +import com.jiagutech.ams.model.dto.DeptDTO; +import org.apache.ibatis.annotations.Param; + +/** + * @ClassName DeptMapper + * @author: zhangyeguang + * @create: 2024-09-05 14:58 + * @Version 1.0 + * @description: + **/ +public interface DeptMapper extends BaseMapper { + Page deptPage(Page page, @Param("deptName") String deptName, @Param("regionPath") String regionPath); +} diff --git a/system/src/main/java/com/jiagutech/ams/mapper/RoleMapper.java b/system/src/main/java/com/jiagutech/ams/mapper/RoleMapper.java new file mode 100644 index 0000000..89e4d96 --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/mapper/RoleMapper.java @@ -0,0 +1,7 @@ +package com.jiagutech.ams.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.jiagutech.ams.model.dto.RoleDTO; + +public interface RoleMapper extends BaseMapper { +} diff --git a/system/src/main/java/com/jiagutech/ams/mapper/UserDeptMapper.java b/system/src/main/java/com/jiagutech/ams/mapper/UserDeptMapper.java new file mode 100644 index 0000000..8ef5817 --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/mapper/UserDeptMapper.java @@ -0,0 +1,10 @@ +package com.jiagutech.ams.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.jiagutech.ams.model.dto.DeptDTO; +import com.jiagutech.ams.model.dto.UserDeptDTO; + +public interface UserDeptMapper extends BaseMapper { + + DeptDTO selectDeptByUserId(Long userId); +} diff --git a/system/src/main/java/com/jiagutech/ams/mapper/UserRoleMapper.java b/system/src/main/java/com/jiagutech/ams/mapper/UserRoleMapper.java new file mode 100644 index 0000000..5d2946b --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/mapper/UserRoleMapper.java @@ -0,0 +1,22 @@ +package com.jiagutech.ams.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.jiagutech.ams.model.dto.RoleDTO; +import com.jiagutech.ams.model.dto.UserRoleDTO; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @ClassName UserRoleMapper + * @author: zhangyeguang + * @create: 2024-09-01 09:57 + * @Version 1.0 + * @description: + **/ +public interface UserRoleMapper extends BaseMapper { + + List selectRolesByUserId(Long userId); + + void insertUserRole(@Param("userId") Long userId, @Param("roleKey") String roleKey); +} diff --git a/system/src/main/java/com/jiagutech/ams/model/UserMapping.java b/system/src/main/java/com/jiagutech/ams/model/UserMapping.java new file mode 100644 index 0000000..2705596 --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/model/UserMapping.java @@ -0,0 +1,24 @@ +package com.jiagutech.ams.model; + +import com.jiagutech.ams.model.dto.UserDTO; +import com.jiagutech.ams.model.request.UserRequest; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @ClassName UserMapping + * @author: zhangyeguang + * @create: 2024-08-31 15:13 + * @Version 1.0 + * @description: + **/ +@Mapper +public interface UserMapping { + + UserMapping INSTANCE = Mappers.getMapper(UserMapping.class); + + UserDTO userToUserDTO(UserRequest user); + + LoginUser userDTOToLoginUser(UserDTO userDTO); + +} diff --git a/system/src/main/java/com/jiagutech/ams/model/request/DeptPageRequest.java b/system/src/main/java/com/jiagutech/ams/model/request/DeptPageRequest.java new file mode 100644 index 0000000..351101a --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/model/request/DeptPageRequest.java @@ -0,0 +1,18 @@ +package com.jiagutech.ams.model.request; + +import lombok.Data; + +/** + * @ClassName JobPageRequest + * @author: zhangyeguang + * @create: 2024-09-02 15:18 + * @Version 1.0 + * @description: + **/ +@Data +public class DeptPageRequest { + + private long deptId; + + private String deptName; +} diff --git a/system/src/main/java/com/jiagutech/ams/model/request/LoginRequest.java b/system/src/main/java/com/jiagutech/ams/model/request/LoginRequest.java new file mode 100644 index 0000000..54282aa --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/model/request/LoginRequest.java @@ -0,0 +1,59 @@ +package com.jiagutech.ams.model.request; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.jiagutech.ams.constant.UserConstants; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 用户登录对象 + */ + +@Data +public class LoginRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + + /** + * 登陆方式 + */ + + private String grantType = "password"; + + + /** + * 验证码 + */ + private String code; + + /** + * 唯一标识 + */ + private String uuid; + + /** + * 用户名 + */ + //@NotBlank(message = "{user.username.not.blank}") + @Length(min = UserConstants.USERNAME_MIN_LENGTH, max = UserConstants.USERNAME_MAX_LENGTH, message = "{user.username.length.valid}") + @JsonIgnore + private String username; + + /** + * 用户密码 + */ + @NotBlank(message = "{user.password.not.blank}") + @Length(min = UserConstants.PASSWORD_MIN_LENGTH, max = UserConstants.PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}") + private String password; + + private String phone; + + private Integer clientType = 1; + +} diff --git a/system/src/main/java/com/jiagutech/ams/model/request/PageUserRequest.java b/system/src/main/java/com/jiagutech/ams/model/request/PageUserRequest.java new file mode 100644 index 0000000..739fe88 --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/model/request/PageUserRequest.java @@ -0,0 +1,19 @@ +package com.jiagutech.ams.model.request; + +import lombok.Data; + +/** + * @ClassName PageUserRequest + * @author: zhangyeguang + * @create: 2024-09-05 11:48 + * @Version 1.0 + * @description: + **/ +@Data +public class PageUserRequest { + + + private Long userId; + private String phone; + private String roleKey; +} diff --git a/system/src/main/java/com/jiagutech/ams/model/request/UserRequest.java b/system/src/main/java/com/jiagutech/ams/model/request/UserRequest.java new file mode 100644 index 0000000..06a1d16 --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/model/request/UserRequest.java @@ -0,0 +1,86 @@ +package com.jiagutech.ams.model.request; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.NumberDeserializers; +import com.jiagutech.ams.utils.StringToLongDeserializer; +import jakarta.validation.constraints.*; +import lombok.Data; +import lombok.NonNull; + +/** + * @ClassName UserRequest + * @author: zhangyeguang + * @create: 2024-08-31 10:00 + * @Version 1.0 + * @description: + **/ +@Data +public class UserRequest { + /** + * 用户ID + */ + @JsonIgnore + private Long userId; + + /** + * 部门ID + */ + @JsonDeserialize(using = StringToLongDeserializer.class) + private Long deptId; + + /** + * 用户账号 + */ + @JsonIgnore + //@NotBlank(message = "用户账号不能为空") + @Size(min = 0, max = 30, message = "用户账号长度不能超过{max}个字符") + private String userName; + + /** + * 用户昵称 + */ + @NotBlank(message = "用户昵称不能为空") + @Size(min = 2, max = 30, message = "用户昵称长度不能超过{max}个字符") + private String nickName; + + + @JsonIgnore + private String userType; + + /** + * 用户邮箱 + */ + @Email(message = "邮箱格式不正确") + @Size(min = 0, max = 50, message = "邮箱长度不能超过{max}个字符") + private String email; + + /** + * 手机号码 + */ + @Pattern(regexp = "^1[34578]\\d{9}$", message = "手机号码格式不正确") + private String phone; + + /** + * 用户性别(0男 1女 2未知) + */ + @JsonIgnore + private String sex; + + /** + * 密码 + */ + private String password; + + /** + * 帐号状态(0正常 1停用) + */ + @JsonIgnore + private String status; + @JsonIgnore + private Long roleId; + // @NotBlank(message = "角色不能为空") + private String roleKey; + + private Long regionCode; +} diff --git a/system/src/main/java/com/jiagutech/ams/model/response/CaptchaVO.java b/system/src/main/java/com/jiagutech/ams/model/response/CaptchaVO.java new file mode 100644 index 0000000..80cbf67 --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/model/response/CaptchaVO.java @@ -0,0 +1,24 @@ +package com.jiagutech.ams.model.response; + +import lombok.Data; + +/** + * 验证码信息 + * + */ +@Data +public class CaptchaVO { + + /** + * 是否开启验证码 + */ + private Boolean captchaEnabled = true; + + private String uuid; + + /** + * 验证码图片 + */ + private String img; + +} diff --git a/system/src/main/java/com/jiagutech/ams/model/response/LoginResponse.java b/system/src/main/java/com/jiagutech/ams/model/response/LoginResponse.java new file mode 100644 index 0000000..62ba89e --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/model/response/LoginResponse.java @@ -0,0 +1,37 @@ +package com.jiagutech.ams.model.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * 登录验证信息 + */ +@Data +public class LoginResponse { + + /** + * 授权令牌 + */ + @JsonProperty("access_token") + private String accessToken; + + /** + * 刷新令牌 + */ + @JsonProperty("refresh_token") + private String refreshToken; + + /** + * 授权令牌 access_token 的有效期 + */ + @JsonProperty("expire_in") + private Long expireIn; + + /** + * 刷新令牌 refresh_token 的有效期 + */ + @JsonProperty("refresh_expire_in") + private Long refreshExpireIn; + + +} diff --git a/system/src/main/java/com/jiagutech/ams/service/DeptServcieImpl.java b/system/src/main/java/com/jiagutech/ams/service/DeptServcieImpl.java new file mode 100644 index 0000000..4700fa4 --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/service/DeptServcieImpl.java @@ -0,0 +1,41 @@ +package com.jiagutech.ams.service; + +import cn.dev33.satoken.stp.StpUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.jiagutech.ams.constant.UserConstants; +import com.jiagutech.ams.mapper.DeptMapper; +import com.jiagutech.ams.model.DeptItem; +import com.jiagutech.ams.model.LoginUser; +import com.jiagutech.ams.model.common.PageRequest; +import com.jiagutech.ams.model.common.PageResult; +import com.jiagutech.ams.model.request.DeptPageRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +/** + * @ClassName DeptServcieImpl + * @author: zhangyeguang + * @create: 2024-09-02 17:35 + * @Version 1.0 + * @description: + **/ +@Service +@RequiredArgsConstructor +public class DeptServcieImpl implements DeptService { + private final DeptMapper deptMapper; + @Override + public PageResult selectPage(PageRequest pageRequest) { + + DeptPageRequest requestParam = pageRequest.getRequest(); + Page page = new Page(pageRequest.getPageNum(), pageRequest.getPageSize()); + LoginUser loginUser = StpUtil.getSession().get(UserConstants.SYS_SESSION,new LoginUser()); + + Page result = deptMapper.deptPage(page,requestParam!=null ?requestParam.getDeptName():null, loginUser.getRegionPath()); + return PageResult.of((int) result.getTotal(), (int) result.getSize(), (int) result.getCurrent(), result.getRecords()); + + } + + + +} diff --git a/system/src/main/java/com/jiagutech/ams/service/DeptService.java b/system/src/main/java/com/jiagutech/ams/service/DeptService.java new file mode 100644 index 0000000..de2b7b7 --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/service/DeptService.java @@ -0,0 +1,17 @@ +package com.jiagutech.ams.service; + +import com.jiagutech.ams.model.DeptItem; +import com.jiagutech.ams.model.common.PageRequest; +import com.jiagutech.ams.model.common.PageResult; +import com.jiagutech.ams.model.request.DeptPageRequest; + +/** + * @ClassName DeptService + * @author: zhangyeguang + * @create: 2024-09-02 17:34 + * @Version 1.0 + * @description: + **/ +public interface DeptService { + PageResult selectPage(PageRequest pageRequest); +} diff --git a/system/src/main/java/com/jiagutech/ams/service/UserService.java b/system/src/main/java/com/jiagutech/ams/service/UserService.java new file mode 100644 index 0000000..818efa9 --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/service/UserService.java @@ -0,0 +1,27 @@ +package com.jiagutech.ams.service; + + +import com.jiagutech.ams.model.UserDetail; +import com.jiagutech.ams.model.common.PageRequest; +import com.jiagutech.ams.model.common.PageResult; +import com.jiagutech.ams.model.request.LoginRequest; +import com.jiagutech.ams.model.request.PageUserRequest; +import com.jiagutech.ams.model.request.UserRequest; +import com.jiagutech.ams.model.response.LoginResponse; + +import java.util.List; + +public interface UserService { + LoginResponse login(LoginRequest loginRequest); + + + void addUser(UserRequest userRequest); + + UserDetail getUserDetail(Long userId, String phone); + + void updateUser(UserRequest user); + + List getUserList(String roleKey); + + PageResult getUserPage(PageRequest pageRequest); +} diff --git a/system/src/main/java/com/jiagutech/ams/service/UserServiceImpl.java b/system/src/main/java/com/jiagutech/ams/service/UserServiceImpl.java new file mode 100644 index 0000000..d451c3c --- /dev/null +++ b/system/src/main/java/com/jiagutech/ams/service/UserServiceImpl.java @@ -0,0 +1,198 @@ +package com.jiagutech.ams.service; + +import cn.dev33.satoken.secure.BCrypt; +import cn.dev33.satoken.stp.StpUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.jiagutech.ams.constant.GlobalConstants; +import com.jiagutech.ams.constant.UserConstants; +import com.jiagutech.ams.exception.BizCode; +import com.jiagutech.ams.exception.BusinessException; +import com.jiagutech.ams.mapper.RegionMapper; +import com.jiagutech.ams.mapper.UserDeptMapper; +import com.jiagutech.ams.mapper.UserMapper; +import com.jiagutech.ams.mapper.UserRoleMapper; +import com.jiagutech.ams.model.LoginUser; +import com.jiagutech.ams.model.RegionVO; +import com.jiagutech.ams.model.UserDetail; +import com.jiagutech.ams.model.UserMapping; +import com.jiagutech.ams.model.common.PageRequest; +import com.jiagutech.ams.model.common.PageResult; +import com.jiagutech.ams.model.dto.RoleDTO; +import com.jiagutech.ams.model.dto.UserDTO; +import com.jiagutech.ams.model.dto.UserDeptDTO; +import com.jiagutech.ams.model.dto.UserRoleDTO; +import com.jiagutech.ams.model.request.LoginRequest; +import com.jiagutech.ams.model.request.PageUserRequest; +import com.jiagutech.ams.model.request.UserRequest; +import com.jiagutech.ams.model.response.LoginResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.function.Predicate; + +/** + * @ClassName UserServiceImpl + * @author: zhangyeguang + * @create: 2024-08-30 15:21 + * @Version 1.0 + * @description: + **/ +@Service +@RequiredArgsConstructor +public class UserServiceImpl implements UserService { + + private final RedisTemplate redisTemplate; + + private final UserMapper userMapper; + + private final UserRoleMapper userRoleMapper; + + private final UserDeptMapper userDeptMapper; + + private final RegionMapper regionMapper; + + @Override + public LoginResponse login(LoginRequest loginRequest) { + String phone = loginRequest.getPhone(); + String password = loginRequest.getPassword(); + String code = loginRequest.getCode(); + String uuid = loginRequest.getUuid(); + +// validateCaptcha(code, uuid); + Integer clientType = loginRequest.getClientType(); + LoginUser user = userMapper.selectLoginUserByPhone(phone); + Predicate predicate = role -> role.getKey().equals("manager") || role.getKey().equals("machinist"); + if (clientType == 2 && user.getRoles().stream().noneMatch(predicate)) { + throw new BusinessException(BizCode.LOGIN_TYPE_ERROR); + } + boolean checkpw = BCrypt.checkpw(password, user.getPassword()); + if (!checkpw) { + throw new BusinessException(BizCode.PASSWORD_ERROR); + } + StpUtil.login(user.getUserId()); + StpUtil.getSession().set(UserConstants.SYS_SESSION, user); + LoginResponse loginVO = new LoginResponse(); + loginVO.setAccessToken(StpUtil.getTokenValue()); + loginVO.setExpireIn(StpUtil.getTokenTimeout()); + return loginVO; + } + + + @Override + @Transactional + public void addUser(UserRequest userRequest) { + UserDTO userDTO = UserMapping.INSTANCE.userToUserDTO(userRequest); + userDTO.setPassword(BCrypt.hashpw(userRequest.getPassword())); + if (userDTO.getRegionCode() != null && userDTO.getRegionCode() != 0l) { + RegionVO completeRegionInfo = regionMapper.getCompleteRegionInfo(userDTO.getRegionCode()); + if (completeRegionInfo != null) { + userDTO.setRegionPath(completeRegionInfo.getRegionCode()); + } + } + userMapper.insert(userDTO); + insertUserRoleAndDept(userDTO, userRequest.getRoleKey(), userRequest.getDeptId()); + + } + + @Override + public UserDetail getUserDetail(Long userId, String phone) { + return userMapper.selectUserDetail(userId, phone); + } + + + @Override + public void updateUser(UserRequest user) { + UserDTO userDTO = UserMapping.INSTANCE.userToUserDTO(user); + userMapper.updateById(userDTO); + updateUserRoleAndDept(user); + } + + private void insertUserRoleAndDept(UserDTO user, String roleKey, Long deptId) { + if (StringUtils.isNotBlank(roleKey)) { + userRoleMapper.insertUserRole(user.getId(), roleKey); + } + if (deptId != null) { + UserDeptDTO userDeptDTO = new UserDeptDTO().setUserId(user.getId()).setDeptId(deptId); + userDeptMapper.insert(userDeptDTO); + } + } + + private void updateUserRoleAndDept(UserRequest user) { + if (user.getRoleId() != null) { + UserRoleDTO userRoleDTO = new UserRoleDTO().setUserId(user.getUserId()).setRoleId(user.getRoleId()); + LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); + lambdaQueryWrapper.eq(UserRoleDTO::getUserId, user.getUserId()); + userRoleMapper.update(userRoleDTO, lambdaQueryWrapper); + } + if (user.getDeptId() != null) { + UserDeptDTO userDeptDTO = new UserDeptDTO().setUserId(user.getUserId()).setDeptId(user.getDeptId()); + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(UserDeptDTO::getUserId, user.getUserId()); + userDeptMapper.update(userDeptDTO, queryWrapper); + } + } + + @Override + public List getUserList(String roleKey) { + return List.of(); + } + + @Override + public PageResult getUserPage(PageRequest pageRequest) { + PageUserRequest requestParam = pageRequest.getRequest(); + QueryWrapper queryWrapper = buildQueryWrapper(requestParam); + Page page = new Page(pageRequest.getPageNum(), pageRequest.getPageSize()); + Page result = userMapper.userPage(page, queryWrapper); + return PageResult.of((int) result.getTotal(), (int) result.getSize(), (int) result.getCurrent(), result.getRecords()); + } + + private QueryWrapper buildQueryWrapper(PageUserRequest requestParam) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + if (requestParam != null) { + if (requestParam.getUserId() != null) { + queryWrapper.eq("u.id", requestParam.getUserId()); + } + if (requestParam.getPhone() != null) { + queryWrapper.like("u.phone", requestParam.getPhone()); + } + if (requestParam.getRoleKey() != null) { + queryWrapper.eq("r.key", requestParam.getRoleKey()); + } + } + + LoginUser loginUser = StpUtil.getSession().get(UserConstants.SYS_SESSION, new LoginUser()); + Predicate predicate1 = r -> r.getKey().equals("manager"); + Predicate predicate2 = r -> r.getKey().equals("gov"); + Predicate predicate3 = r -> r.getKey().equals("machinist"); + + boolean hasManager = loginUser.getRoles().stream().anyMatch(predicate1); + boolean hasGov = loginUser.getRoles().stream().anyMatch(predicate2); + boolean hasMachinist = loginUser.getRoles().stream().anyMatch(predicate3); + if (hasManager) { + queryWrapper.eq("ud.dept_id", loginUser.getDept().getId()); + } + if (hasGov) { + queryWrapper.likeRight("u.region_path", loginUser.getRegionPath()); + } + return queryWrapper; + } + + private void validateCaptcha(String code, String uuid) { + String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid; + String captcha = String.valueOf(redisTemplate.opsForValue().get(verifyKey)); + redisTemplate.delete(verifyKey); + if (captcha == null) { + throw new BusinessException(BizCode.CAPTCHA_ERROR); + } + if (!code.equalsIgnoreCase(captcha)) { + throw new BusinessException(BizCode.CAPTCHA_ERROR); + } + } +} diff --git a/system/src/main/resources/mapper/DeptMapper.xml b/system/src/main/resources/mapper/DeptMapper.xml new file mode 100644 index 0000000..34db5fa --- /dev/null +++ b/system/src/main/resources/mapper/DeptMapper.xml @@ -0,0 +1,47 @@ + + + + + + + \ No newline at end of file diff --git a/system/src/main/resources/mapper/RoleMapper.xml b/system/src/main/resources/mapper/RoleMapper.xml new file mode 100644 index 0000000..a1cf5dd --- /dev/null +++ b/system/src/main/resources/mapper/RoleMapper.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/system/src/main/resources/mapper/UserDeptMapper.xml b/system/src/main/resources/mapper/UserDeptMapper.xml new file mode 100644 index 0000000..810a3bc --- /dev/null +++ b/system/src/main/resources/mapper/UserDeptMapper.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/system/src/main/resources/mapper/UserMapper.xml b/system/src/main/resources/mapper/UserMapper.xml new file mode 100644 index 0000000..781e23e --- /dev/null +++ b/system/src/main/resources/mapper/UserMapper.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/system/src/main/resources/mapper/UserRoleMapper.xml b/system/src/main/resources/mapper/UserRoleMapper.xml new file mode 100644 index 0000000..bdb94a3 --- /dev/null +++ b/system/src/main/resources/mapper/UserRoleMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + insert into ams_user_role(user_id, role_id) + select #{userId}, r.id as role_id + from ams_role r + where r.key = #{roleKey} + + \ No newline at end of file diff --git a/web/pom.xml b/web/pom.xml new file mode 100644 index 0000000..d94e045 --- /dev/null +++ b/web/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + + com.jiagutech + ams-social + ${revision} + + + web + + + 17 + 17 + UTF-8 + + + + + dev + + + dev + info + + + + true + + + + prod + + prod + info + + + + + + com.jiagutech + system + 1.0.0-SNAPSHOT + + + com.jiagutech + social + 1.0.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-data-jdbc + + + mysql + mysql-connector-java + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + + + + org.springdoc + springdoc-openapi-starter-webmvc-api + + + org.apache.commons + commons-pool2 + 2.12.0 + + + cn.dev33 + sa-token-spring-boot3-starter + + + + + cn.dev33 + sa-token-redis + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + \ No newline at end of file diff --git a/web/src/main/java/com/jiagutech/ams/SocialApplication.java b/web/src/main/java/com/jiagutech/ams/SocialApplication.java new file mode 100644 index 0000000..24f64ea --- /dev/null +++ b/web/src/main/java/com/jiagutech/ams/SocialApplication.java @@ -0,0 +1,18 @@ +package com.jiagutech.ams; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @ClassName SocialApplication + * @author: zhangyeguang + * @create: 2024-08-30 14:26 + * @Version 1.0 + * @description: + **/ +@SpringBootApplication +public class SocialApplication { + public static void main(String[] args) { + SpringApplication.run(SocialApplication.class, args); + } +} diff --git a/web/src/main/java/com/jiagutech/ams/common/GlobalExceptionHandler.java b/web/src/main/java/com/jiagutech/ams/common/GlobalExceptionHandler.java new file mode 100644 index 0000000..d190501 --- /dev/null +++ b/web/src/main/java/com/jiagutech/ams/common/GlobalExceptionHandler.java @@ -0,0 +1,74 @@ +package com.jiagutech.ams.common; + + +import cn.dev33.satoken.exception.NotLoginException; +import cn.dev33.satoken.exception.NotRoleException; +import com.alibaba.fastjson2.JSON; +import com.jiagutech.ams.exception.BizCode; +import com.jiagutech.ams.exception.BusinessException; +import com.jiagutech.ams.model.common.R; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.BindException; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; + +import java.sql.SQLIntegrityConstraintViolationException; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(BindException.class) + public R handleBindExceptions(BindException ex) { + log.error("参数绑定失败", ex); + Map errorMap = new HashMap<>(); + for (FieldError fieldError : ex.getFieldErrors()) { + errorMap.put(fieldError.getField(), fieldError.getDefaultMessage()); + } + return R.fail(BizCode.General_ParameterInvalid.getCode(), JSON.toJSONString(errorMap)); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public R handleValidationExceptions(MethodArgumentNotValidException ex) { + log.error("参数校验失败", ex); + Map errorMap = new HashMap<>(); + for (FieldError fieldError : ex.getBindingResult().getFieldErrors()) { + errorMap.put(fieldError.getField(), fieldError.getDefaultMessage()); + } + return R.fail(BizCode.General_ParameterInvalid.getCode(), JSON.toJSONString(errorMap)); + } + + @ExceptionHandler(BusinessException.class) + public R handleBusinessException(BusinessException ex) { + return R.fail(ex.getCode(), ex.getMessage()); + } + + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public R handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException ex) { + log.error("参数类型错误", ex); + return R.fail(new BusinessException("参数类型错误")); + } + + @ExceptionHandler(NotLoginException.class) + public R handleLoginException(Exception ex) { + log.error("系统异常", ex); + return R.fail(BizCode.USER_NOT_LOGIN.getCode(), BizCode.USER_NOT_LOGIN.getMsg()); + } + + @ExceptionHandler(NotRoleException.class) + public R handlePermissionException(Exception ex) { + log.error("鉴权失败", ex); + return R.fail(BizCode.PERMISSION_NOT_FOUND.getCode(), BizCode.PERMISSION_NOT_FOUND.getMsg()); + } + + @ExceptionHandler(SQLIntegrityConstraintViolationException.class) + public R handleDuplicateException(Exception ex){ + log.error("数据重复", ex); + return R.fail(BizCode.USER_PHONE_EXIST.getCode(), BizCode.USER_PHONE_EXIST.getMsg()); + } +} diff --git a/web/src/main/java/com/jiagutech/ams/common/RestTemplateConfig.java b/web/src/main/java/com/jiagutech/ams/common/RestTemplateConfig.java new file mode 100644 index 0000000..1527ff2 --- /dev/null +++ b/web/src/main/java/com/jiagutech/ams/common/RestTemplateConfig.java @@ -0,0 +1,41 @@ +package com.jiagutech.ams.common; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.web.client.RestTemplate; + +import java.nio.charset.StandardCharsets; +import java.util.Collections; + + +/** + * RestTemplate工具类,主要用来提供RestTemplate对象 + */ +@Configuration +public class RestTemplateConfig { + + + + @Value("${http.template.connect-timeout}") + private int connectionTimeout; + @Value("${http.template.read-timeout}") + private int readTimeout; + + /** + * 创建RestTemplate对象 + */ + @Bean + public RestTemplate restTemplate() { + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + factory.setConnectTimeout(connectionTimeout); // 设置连接超时时间(毫秒) + factory.setReadTimeout(readTimeout); // 设置读取超时时间(毫秒) + RestTemplate restTemplate = new RestTemplate(factory); + restTemplate.setInterceptors(Collections.singletonList(new RestTemplateInterceptor())); + restTemplate.getMessageConverters().set(1,new StringHttpMessageConverter(StandardCharsets.UTF_8)); // 支持中文编码 + return restTemplate; + } +} + diff --git a/web/src/main/java/com/jiagutech/ams/common/RestTemplateInterceptor.java b/web/src/main/java/com/jiagutech/ams/common/RestTemplateInterceptor.java new file mode 100644 index 0000000..f9fd9c1 --- /dev/null +++ b/web/src/main/java/com/jiagutech/ams/common/RestTemplateInterceptor.java @@ -0,0 +1,36 @@ +package com.jiagutech.ams.common; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +@Slf4j +public class RestTemplateInterceptor implements ClientHttpRequestInterceptor { + + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { + + // 打印出请求的详细信息 + log.info("URI: {}", request.getURI()); + if (body != null && body.length > 0) { + log.debug("Request Body: {}", new String(body, StandardCharsets.UTF_8)); + } + + // 执行请求并获取响应 + ClientHttpResponse response = execution.execute(request, body); + + // 打印出响应的详细信息 + log.info("Response Status: {}", response.getStatusCode()); + log.info("Response Headers: {}", response.getHeaders()); + response.getBody(); // 读取响应体,确保内容被完全读取,这样连接才能被关闭 + + return response; + + } +} diff --git a/web/src/main/java/com/jiagutech/ams/config/MybatisPlusConfig.java b/web/src/main/java/com/jiagutech/ams/config/MybatisPlusConfig.java new file mode 100644 index 0000000..5426ec4 --- /dev/null +++ b/web/src/main/java/com/jiagutech/ams/config/MybatisPlusConfig.java @@ -0,0 +1,23 @@ +package com.jiagutech.ams.config; + + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MybatisPlusConfig { + + /** + * 添加分页插件 + */ + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加 + return interceptor; + } + +} \ No newline at end of file diff --git a/web/src/main/java/com/jiagutech/ams/config/SaPermissionImpl.java b/web/src/main/java/com/jiagutech/ams/config/SaPermissionImpl.java new file mode 100644 index 0000000..4227c62 --- /dev/null +++ b/web/src/main/java/com/jiagutech/ams/config/SaPermissionImpl.java @@ -0,0 +1,39 @@ +package com.jiagutech.ams.config; + +import cn.dev33.satoken.stp.StpInterface; +import cn.dev33.satoken.stp.StpUtil; +import com.jiagutech.ams.constant.UserConstants; +import com.jiagutech.ams.model.LoginUser; + + +import java.util.ArrayList; +import java.util.List; + +/** + * sa-token 权限管理实现类 + * + * @author Lion Li + */ +public class SaPermissionImpl implements StpInterface { + + /** + * 获取菜单权限列表 + */ + @Override + public List getPermissionList(Object loginId, String loginType) { + + return new ArrayList<>(); + } + + /** + * 获取角色权限列表 + */ + @Override + public List getRoleList(Object loginId, String loginType) { + LoginUser loginUser = StpUtil.getSession().get(UserConstants.SYS_SESSION, new LoginUser()); + if (loginUser == null || loginUser.getRoles() == null) { + return new ArrayList<>(); + } + return loginUser.getRoles().stream().map(role -> role.getKey()).toList(); + } +} diff --git a/web/src/main/java/com/jiagutech/ams/config/SaTokenConfig.java b/web/src/main/java/com/jiagutech/ams/config/SaTokenConfig.java new file mode 100644 index 0000000..ad2ad26 --- /dev/null +++ b/web/src/main/java/com/jiagutech/ams/config/SaTokenConfig.java @@ -0,0 +1,30 @@ +package com.jiagutech.ams.config; + +import cn.dev33.satoken.jwt.StpLogicJwtForSimple; +import cn.dev33.satoken.stp.StpInterface; +import cn.dev33.satoken.stp.StpLogic; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * sa-token 配置 + */ +@Configuration +public class SaTokenConfig { + + @Bean + public StpLogic getStpLogicJwt() { + // Sa-Token 整合 jwt (简单模式) + return new StpLogicJwtForSimple(); + } + + /** + * 权限接口实现(使用bean注入方便用户替换) + */ + @Bean + public StpInterface stpInterface() { + return new SaPermissionImpl(); + } + + +} diff --git a/web/src/main/java/com/jiagutech/ams/config/SaTokenConfigure.java b/web/src/main/java/com/jiagutech/ams/config/SaTokenConfigure.java new file mode 100644 index 0000000..64c861c --- /dev/null +++ b/web/src/main/java/com/jiagutech/ams/config/SaTokenConfigure.java @@ -0,0 +1,16 @@ +package com.jiagutech.ams.config; + +import cn.dev33.satoken.interceptor.SaInterceptor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class SaTokenConfigure implements WebMvcConfigurer { + // 注册 Sa-Token 拦截器,打开注解式鉴权功能 + @Override + public void addInterceptors(InterceptorRegistry registry) { + // 注册 Sa-Token 拦截器,打开注解式鉴权功能 + registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**"); + } +} diff --git a/web/src/main/java/com/jiagutech/ams/config/SpringDocConfig.java b/web/src/main/java/com/jiagutech/ams/config/SpringDocConfig.java new file mode 100644 index 0000000..e10df36 --- /dev/null +++ b/web/src/main/java/com/jiagutech/ams/config/SpringDocConfig.java @@ -0,0 +1,46 @@ +package com.jiagutech.ams.config; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SpringDocConfig { + + @Bean + public OpenAPI openAPI() { + return new OpenAPI() + // 配置接口文档基本信息 + .info(this.getApiInfo()) + .addSecurityItem(new SecurityRequirement().addList("Bearer Authentication")) + .components(new io.swagger.v3.oas.models.Components() + .addSecuritySchemes("Bearer Authentication", new SecurityScheme() + .type(SecurityScheme.Type.HTTP) + .scheme("bearer") + .bearerFormat("JWT"))); + + } + + private Info getApiInfo() { + return new Info() + // 配置文档标题 + .title("SpringBoot3集成Swagger3") + // 配置文档描述 + .description("SpringBoot3集成Swagger3示例文档") + // 配置作者信息 + .contact(new Contact().name("农机管理-社会化").url("https://www.baidu.com")) + // 配置License许可证信息 + .license(new License().name("Apache 2.0").url("https://www.xiezhrspace.cn")) + // 概述信息 + .summary("SpringBoot3集成Swagger3示例文档aaa") + .termsOfService("https://www.xiezhrspace.cn") + // 配置版本号 + .version("2.0"); + } + +} diff --git a/web/src/main/java/com/jiagutech/ams/config/WebConfig.java b/web/src/main/java/com/jiagutech/ams/config/WebConfig.java new file mode 100644 index 0000000..11eafcd --- /dev/null +++ b/web/src/main/java/com/jiagutech/ams/config/WebConfig.java @@ -0,0 +1,32 @@ +package com.jiagutech.ams.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +@Configuration +public class WebConfig { + + + @Bean + public CorsFilter corsFilter() { + CorsConfiguration config = new CorsConfiguration(); + config.addAllowedOrigin("*"); + config.addAllowedMethod("GET"); + config.addAllowedMethod("POST"); + config.addAllowedMethod("PUT"); + config.addAllowedMethod("DELETE"); + config.addAllowedMethod("OPTIONS"); + config.addAllowedHeader("*"); + config.setAllowCredentials(false); + config.setMaxAge(3600L); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", config); + + return new CorsFilter(source); + } + +} \ No newline at end of file diff --git a/web/src/main/resources/application.yml b/web/src/main/resources/application.yml new file mode 100644 index 0000000..fee8d7b --- /dev/null +++ b/web/src/main/resources/application.yml @@ -0,0 +1,91 @@ +server: + port: 8180 + + +spring: + application: + name: ams-social + datasource: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + # url: jdbc:mysql://192.168.10.111:23306/ams_social?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + # username: root + # password: 123456 + url: jdbc:mysql://101.34.243.138:7306/ams_social?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: ams + password: ams@1234 + hikari: + # 最大连接池数量 + maxPoolSize: 20 + # 最小空闲线程数量 + minIdle: 10 + # 配置获取连接等待超时的时间 + connectionTimeout: 30000 + # 校验超时时间 + validationTimeout: 5000 + # 空闲连接存活最大时间,默认10分钟 + idleTimeout: 600000 + # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟 + maxLifetime: 1800000 + # 多久检查一次连接的活性 + keepaliveTime: 30000 + data: + redis: + host: 192.168.10.111 + port: 6379 + database: 10 + # host: 101.34.243.138 + # port: 7379 + # database: 10 + # # password: 123456 + timeout: 10s + # password: tent_zyg@1234 + lettuce: + pool: + # 连接池最大连接数 + max-active: 200 + # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: 3000ms + # 连接池中的最大空闲连接 + max-idle: 100 + # 连接池中的最小空闲连接 + min-idle: 10 + + +mybatis-plus: + mapper-locations: classpath*:mapper/*.xml + type-aliases-package: com.jiagutech.ams.model.dto + configuration: + map-underscore-to-camel-case: true + log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl + global-config: + db-config: + id-type: assign_id + + +sa-token: + # token名称 (同时也是cookie名称) + token-name: Authorization + token-prefix: Bearer + # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + is-concurrent: true + # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + is-share: false + # jwt秘钥 + jwt-secret-key: abcdefghijklmnopqrstuvwxyz + is-print: true + is-log: false + +http: + template: + # 连接超时时间 + connect-timeout: 1000 + # 读取超时时间 + read-timeout: 5000 + + +logging: + level: + root: INFO + com.jiagutech.ams.mapper: DEBUG + diff --git a/web/src/main/resources/logback-spring.xml b/web/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..e26f874 --- /dev/null +++ b/web/src/main/resources/logback-spring.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + DEBUG + + + ${LOG_PATTERN} + utf8 + + + + + + + ${LOG_FILE}/${springAppName}-info.log + + true + + + ${LOG_FILE}/${springAppName}-info.%d{yyyy-MM-dd}.%i.log.gz + + 20 + + 100MB + + + ${LOG_PATTERN} + utf8 + + + + + 0 + + 256 + + + + + + + + ERROR + ACCEPT + DENY + + + ${LOG_FILE}/${springAppName}-error.log + true + + + + ${LOG_FILE}/${springAppName}-error.%d{yyyy-MM-dd}.%i.log.gz + + 20 + + 100MB + + + ${LOG_PATTERN} + utf8 + + + + + 0 + + 256 + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file