zhangyeguang
4 months ago
95 changed files with 4347 additions and 1 deletions
@ -0,0 +1,101 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
<parent> |
||||
|
<groupId>com.jiagutech</groupId> |
||||
|
<artifactId>ams-social</artifactId> |
||||
|
<version>${revision}</version> |
||||
|
</parent> |
||||
|
|
||||
|
<artifactId>common</artifactId> |
||||
|
|
||||
|
<properties> |
||||
|
<maven.compiler.source>17</maven.compiler.source> |
||||
|
<maven.compiler.target>17</maven.compiler.target> |
||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
|
</properties> |
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>org.projectlombok</groupId> |
||||
|
<artifactId>lombok</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>cn.hutool</groupId> |
||||
|
<artifactId>hutool-core</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>cn.hutool</groupId> |
||||
|
<artifactId>hutool-http</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>cn.hutool</groupId> |
||||
|
<artifactId>hutool-extra</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.alibaba.fastjson2</groupId> |
||||
|
<artifactId>fastjson2</artifactId> |
||||
|
</dependency> |
||||
|
<!-- https://mvnrepository.com/artifact/ma.glasnost.orika/orika-core --> |
||||
|
<dependency> |
||||
|
<groupId>ma.glasnost.orika</groupId> |
||||
|
<artifactId>orika-core</artifactId> |
||||
|
<version>1.5.4</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.mapstruct</groupId> |
||||
|
<artifactId>mapstruct</artifactId> |
||||
|
<version>1.5.5.Final</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.mapstruct</groupId> |
||||
|
<artifactId>mapstruct-processor</artifactId> |
||||
|
<version>1.5.5.Final</version> |
||||
|
<scope>compile</scope> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.commons</groupId> |
||||
|
<artifactId>commons-pool2</artifactId> |
||||
|
<version>2.12.0</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-data-jdbc</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.baomidou</groupId> |
||||
|
<artifactId>mybatis-plus-boot-starter</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-json</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.poi</groupId> |
||||
|
<artifactId>poi</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.poi</groupId> |
||||
|
<artifactId>poi-ooxml</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.alibaba</groupId> |
||||
|
<artifactId>easyexcel</artifactId> |
||||
|
<exclusions> |
||||
|
<exclusion> |
||||
|
<artifactId>poi-ooxml-schemas</artifactId> |
||||
|
<groupId>org.apache.poi</groupId> |
||||
|
</exclusion> |
||||
|
</exclusions> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>jakarta.servlet</groupId> |
||||
|
<artifactId>jakarta.servlet-api</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
</dependencies> |
||||
|
</project> |
@ -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}"; |
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
||||
|
|
@ -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:"; |
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
package com.jiagutech.ams.enums; |
||||
|
|
||||
|
/** |
||||
|
* 限流类型 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
*/ |
||||
|
|
||||
|
public enum LimitType { |
||||
|
/** |
||||
|
* 默认策略全局限流 |
||||
|
*/ |
||||
|
DEFAULT, |
||||
|
|
||||
|
/** |
||||
|
* 根据请求者IP进行限流 |
||||
|
*/ |
||||
|
IP, |
||||
|
|
||||
|
/** |
||||
|
* 实例限流(集群多后端实例) |
||||
|
*/ |
||||
|
CLUSTER |
||||
|
} |
@ -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; |
||||
|
} |
||||
|
|
||||
|
} |
@ -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; |
||||
|
} |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
package com.jiagutech.ams.exception; |
||||
|
|
||||
|
/** |
||||
|
* 业务异常接口 |
||||
|
*/ |
||||
|
public interface CodeInterface { |
||||
|
|
||||
|
/** |
||||
|
* 消息 |
||||
|
* |
||||
|
* @return String |
||||
|
*/ |
||||
|
String getMsg(); |
||||
|
|
||||
|
/** |
||||
|
* 业务代码 |
||||
|
* |
||||
|
* @return int |
||||
|
*/ |
||||
|
Integer getCode(); |
||||
|
|
||||
|
} |
@ -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<UserDTO> { |
||||
|
|
||||
|
List<RegionDTO> getRegionsByParentCode(@Param("regionCode") long regionCode, @Param("level") int level); |
||||
|
|
||||
|
|
||||
|
RegionVO getCompleteRegionInfo(@Param("regionCode") long regionCode); |
||||
|
} |
@ -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<UserDTO> { |
||||
|
|
||||
|
|
||||
|
LoginUser selectLoginUserByPhone(@Param("phone") String phone); |
||||
|
|
||||
|
UserDetail selectUserDetail(@Param("userId") Long userId, @Param("phone") String phone); |
||||
|
|
||||
|
List<Long> getUserIdsByRegionCodes(@Param("regionCodes") List<Long> regionCodes); |
||||
|
|
||||
|
List<UserDTO> getUsersByLikeRegionPath( @Param("regionPath") String regionPath); |
||||
|
|
||||
|
|
||||
|
|
||||
|
Page<UserDetail> userPage(Page<UserDetail> page,@Param("ew") QueryWrapper<UserDetail> queryWrapper); |
||||
|
} |
@ -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; |
||||
|
} |
@ -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<RoleDTO> roles; |
||||
|
|
||||
|
/** |
||||
|
* 区域编码 |
||||
|
*/ |
||||
|
private Long regionCode; |
||||
|
|
||||
|
private String regionPath; |
||||
|
|
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
} |
@ -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<T> { |
||||
|
|
||||
|
private int pageNum; |
||||
|
private int pageSize; |
||||
|
private String oderByColumn; |
||||
|
|
||||
|
private T request; |
||||
|
|
||||
|
|
||||
|
} |
@ -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<T> { |
||||
|
private int total; |
||||
|
private int pageSize; |
||||
|
private int pageNum; |
||||
|
private int pages; |
||||
|
private List<T> records; |
||||
|
|
||||
|
public static <T> PageResult<T> of(int total, int pageSize, int pageNum, List<T> records) { |
||||
|
PageResult<T> 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; |
||||
|
} |
||||
|
} |
@ -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<T> 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 <T> R<T> ok() { |
||||
|
return restResult(null, SUCCESS, "操作成功"); |
||||
|
} |
||||
|
|
||||
|
public static <T> R<T> ok(T data) { |
||||
|
return restResult(data, SUCCESS, "操作成功"); |
||||
|
} |
||||
|
|
||||
|
public static <T> R<T> ok(String msg) { |
||||
|
return restResult(null, SUCCESS, msg); |
||||
|
} |
||||
|
|
||||
|
public static <T> R<T> ok(String msg, T data) { |
||||
|
return restResult(data, SUCCESS, msg); |
||||
|
} |
||||
|
|
||||
|
public static <T> R<T> fail() { |
||||
|
return restResult(null, FAIL, "操作失败"); |
||||
|
} |
||||
|
|
||||
|
public static <T> R<T> fail(String msg) { |
||||
|
return restResult(null, FAIL, msg); |
||||
|
} |
||||
|
|
||||
|
public static <T> R<T> fail(T data) { |
||||
|
return restResult(data, FAIL, "操作失败"); |
||||
|
} |
||||
|
|
||||
|
public static <T> R<T> fail(String msg, T data) { |
||||
|
return restResult(data, FAIL, msg); |
||||
|
} |
||||
|
|
||||
|
public static <T> R<T> fail(int code, String msg) { |
||||
|
return restResult(null, code, msg); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 返回警告消息 |
||||
|
* |
||||
|
* @param msg 返回内容 |
||||
|
* @return 警告消息 |
||||
|
*/ |
||||
|
public static <T> R<T> warn(String msg) { |
||||
|
return restResult(null, HttpStatus.WARN, msg); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 返回警告消息 |
||||
|
* |
||||
|
* @param msg 返回内容 |
||||
|
* @param data 数据对象 |
||||
|
* @return 警告消息 |
||||
|
*/ |
||||
|
public static <T> R<T> warn(String msg, T data) { |
||||
|
return restResult(data, HttpStatus.WARN, msg); |
||||
|
} |
||||
|
|
||||
|
private static <T> R<T> restResult(T data, int code, String msg) { |
||||
|
R<T> r = new R<>(); |
||||
|
r.setCode(code); |
||||
|
r.setData(data); |
||||
|
r.setMsg(msg); |
||||
|
return r; |
||||
|
} |
||||
|
|
||||
|
public static <T> Boolean isError(R<T> ret) { |
||||
|
return !isSuccess(ret); |
||||
|
} |
||||
|
|
||||
|
public static <T> Boolean isSuccess(R<T> ret) { |
||||
|
return R.SUCCESS == ret.getCode(); |
||||
|
} |
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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<Long> { |
||||
|
|
||||
|
@Override |
||||
|
public Class<Long> 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<Object> 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<Object> cellData = new WriteCellData<>(new BigDecimal(object)); |
||||
|
cellData.setType(CellDataTypeEnum.NUMBER); |
||||
|
return cellData; |
||||
|
} |
||||
|
|
||||
|
} |
@ -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 <T> void exportExcel(List<T> list, String sheetName, Class<T> 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异常"); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -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<Long> { |
||||
|
|
||||
|
@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); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,185 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<groupId>com.jiagutech</groupId> |
||||
|
<artifactId>ams-social</artifactId> |
||||
|
<version>${revision}</version> |
||||
|
<packaging>pom</packaging> |
||||
|
<modules> |
||||
|
<module>system</module> |
||||
|
<module>social</module> |
||||
|
<module>web</module> |
||||
|
<module>common</module> |
||||
|
</modules> |
||||
|
<parent> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-parent</artifactId> |
||||
|
<version>3.1.7</version> |
||||
|
<relativePath/> |
||||
|
</parent> |
||||
|
<properties> |
||||
|
<java.version>17</java.version> |
||||
|
<lombok.version>1.18.30</lombok.version> |
||||
|
<revision>1.0.0-SNAPSHOT</revision> |
||||
|
<spring-boot.version>3.1.7</spring-boot.version> |
||||
|
<satoken.version>1.37.0</satoken.version> |
||||
|
<poi.version>5.2.5</poi.version> |
||||
|
|
||||
|
<easyexcel.version>3.3.2</easyexcel.version> |
||||
|
<springdoc.version>2.2.0</springdoc.version> |
||||
|
<hutool.version>5.8.22</hutool.version> |
||||
|
<mybatis-plus.version>3.5.5</mybatis-plus.version> |
||||
|
<spring-boot.mybatis>3.0.3</spring-boot.mybatis> |
||||
|
<fastjson.version>1.2.83</fastjson.version> |
||||
|
<mapstruct-plus.version>1.3.5</mapstruct-plus.version> |
||||
|
<!-- 插件版本 --> |
||||
|
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version> |
||||
|
<maven-compiler-plugin.verison>3.11.0</maven-compiler-plugin.verison> |
||||
|
<maven-surefire-plugin.version>3.1.2</maven-surefire-plugin.version> |
||||
|
<flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version> |
||||
|
</properties> |
||||
|
|
||||
|
<profiles> |
||||
|
<profile> |
||||
|
<id>dev</id> |
||||
|
<properties> |
||||
|
<!-- 环境标识,需要与配置文件的名称相对应 --> |
||||
|
<profiles.active>dev</profiles.active> |
||||
|
<logging.level>info</logging.level> |
||||
|
</properties> |
||||
|
<activation> |
||||
|
<!-- 默认环境 --> |
||||
|
<activeByDefault>true</activeByDefault> |
||||
|
</activation> |
||||
|
</profile> |
||||
|
<profile> |
||||
|
<id>prod</id> |
||||
|
<properties> |
||||
|
<profiles.active>prod</profiles.active> |
||||
|
<logging.level>info</logging.level> |
||||
|
</properties> |
||||
|
</profile> |
||||
|
</profiles> |
||||
|
<dependencyManagement> |
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-dependencies</artifactId> |
||||
|
<version>${spring-boot.version}</version> |
||||
|
<type>pom</type> |
||||
|
<scope>import</scope> |
||||
|
</dependency> |
||||
|
<!-- hutool 的依赖配置--> |
||||
|
<dependency> |
||||
|
<groupId>cn.hutool</groupId> |
||||
|
<artifactId>hutool-bom</artifactId> |
||||
|
<version>${hutool.version}</version> |
||||
|
<type>pom</type> |
||||
|
<scope>import</scope> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.alibaba.fastjson2</groupId> |
||||
|
<artifactId>fastjson2</artifactId> |
||||
|
<version>2.0.43</version> |
||||
|
</dependency> |
||||
|
<!-- 提供Redis连接池 --> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.commons</groupId> |
||||
|
<artifactId>commons-pool2</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>cn.dev33</groupId> |
||||
|
<artifactId>sa-token-spring-boot3-starter</artifactId> |
||||
|
<version>${satoken.version}</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) --> |
||||
|
<dependency> |
||||
|
<groupId>cn.dev33</groupId> |
||||
|
<artifactId>sa-token-redis-jackson</artifactId> |
||||
|
<version>${satoken.version}</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>cn.dev33</groupId> |
||||
|
<artifactId>sa-token-redis</artifactId> |
||||
|
<version>${satoken.version}</version> |
||||
|
</dependency> |
||||
|
<!-- Sa-Token 整合 jwt --> |
||||
|
<dependency> |
||||
|
<groupId>cn.dev33</groupId> |
||||
|
<artifactId>sa-token-jwt</artifactId> |
||||
|
<version>${satoken.version}</version> |
||||
|
<exclusions> |
||||
|
<exclusion> |
||||
|
<groupId>cn.hutool</groupId> |
||||
|
<artifactId>hutool-all</artifactId> |
||||
|
</exclusion> |
||||
|
</exclusions> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springdoc</groupId> |
||||
|
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> |
||||
|
<version>${springdoc.version}</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springdoc</groupId> |
||||
|
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId> |
||||
|
<version>${springdoc.version}</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.projectlombok</groupId> |
||||
|
<artifactId>lombok</artifactId> |
||||
|
<version>${lombok.version}</version> |
||||
|
</dependency> |
||||
|
<!-- MyBatis Plus Starter --> |
||||
|
<dependency> |
||||
|
<groupId>com.baomidou</groupId> |
||||
|
<artifactId>mybatis-plus-boot-starter</artifactId> |
||||
|
<version>${mybatis-plus.version}</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.baomidou</groupId> |
||||
|
<artifactId>mybatis-plus-extension</artifactId> |
||||
|
<version>${mybatis-plus.version}</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>mysql</groupId> |
||||
|
<artifactId>mysql-connector-java</artifactId> |
||||
|
<version>8.0.33</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.alibaba</groupId> |
||||
|
<artifactId>druid-spring-boot-starter</artifactId> |
||||
|
<version>1.1.21</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.apache.poi</groupId> |
||||
|
<artifactId>poi</artifactId> |
||||
|
<version>${poi.version}</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.poi</groupId> |
||||
|
<artifactId>poi-ooxml</artifactId> |
||||
|
<version>${poi.version}</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.alibaba</groupId> |
||||
|
<artifactId>easyexcel</artifactId> |
||||
|
<version>${easyexcel.version}</version> |
||||
|
<exclusions> |
||||
|
<exclusion> |
||||
|
<artifactId>poi-ooxml-schemas</artifactId> |
||||
|
<groupId>org.apache.poi</groupId> |
||||
|
</exclusion> |
||||
|
</exclusions> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
</dependencyManagement> |
||||
|
|
||||
|
</project> |
@ -0,0 +1,97 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
<parent> |
||||
|
<groupId>com.jiagutech</groupId> |
||||
|
<artifactId>ams-social</artifactId> |
||||
|
<version>${revision}</version> |
||||
|
</parent> |
||||
|
|
||||
|
<artifactId>social</artifactId> |
||||
|
|
||||
|
<properties> |
||||
|
<maven.compiler.source>17</maven.compiler.source> |
||||
|
<maven.compiler.target>17</maven.compiler.target> |
||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
|
</properties> |
||||
|
|
||||
|
<profiles> |
||||
|
<profile> |
||||
|
<id>dev</id> |
||||
|
<properties> |
||||
|
<!-- 环境标识,需要与配置文件的名称相对应 --> |
||||
|
<profiles.active>dev</profiles.active> |
||||
|
<logging.level>info</logging.level> |
||||
|
</properties> |
||||
|
<activation> |
||||
|
<!-- 默认环境 --> |
||||
|
<activeByDefault>true</activeByDefault> |
||||
|
</activation> |
||||
|
</profile> |
||||
|
<profile> |
||||
|
<id>prod</id> |
||||
|
<properties> |
||||
|
<profiles.active>prod</profiles.active> |
||||
|
<logging.level>info</logging.level> |
||||
|
</properties> |
||||
|
</profile> |
||||
|
</profiles> |
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>com.jiagutech</groupId> |
||||
|
<artifactId>common</artifactId> |
||||
|
<version>1.0.0-SNAPSHOT</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-data-jdbc</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>mysql</groupId> |
||||
|
<artifactId>mysql-connector-java</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-data-redis</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-validation</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.baomidou</groupId> |
||||
|
<artifactId>mybatis-plus-boot-starter</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>cn.dev33</groupId> |
||||
|
<artifactId>sa-token-spring-boot3-starter</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springdoc</groupId> |
||||
|
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.poi</groupId> |
||||
|
<artifactId>poi</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.poi</groupId> |
||||
|
<artifactId>poi-ooxml</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.alibaba</groupId> |
||||
|
<artifactId>easyexcel</artifactId> |
||||
|
<exclusions> |
||||
|
<exclusion> |
||||
|
<artifactId>poi-ooxml-schemas</artifactId> |
||||
|
<groupId>org.apache.poi</groupId> |
||||
|
</exclusion> |
||||
|
</exclusions> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
</project> |
@ -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<List<DeviceInfo>> 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)); |
||||
|
} |
||||
|
|
||||
|
} |
@ -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<List<JobTypeDTO>> getJobTypes() { |
||||
|
return R.ok(jobService.getJobTypes()); |
||||
|
} |
||||
|
@Operation(summary = "创建作业记录") |
||||
|
@PostMapping("/start") |
||||
|
@SaCheckRole("machinist") |
||||
|
public R<JobCreateResponse> createJob(@RequestBody JobCreateRequest jobCreateRequest) { |
||||
|
return R.ok(jobService.createJob(jobCreateRequest)); |
||||
|
} |
||||
|
|
||||
|
@Operation(summary = "更新作业状态") |
||||
|
@SaCheckRole(value = {"machinist", "admin"}, mode = SaMode.OR) |
||||
|
@PutMapping("/status") |
||||
|
public R<Void> 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<PageResult<JobItem>> getPages(@RequestBody PageRequest<JobPageRequest> pageRequest) { |
||||
|
return R.ok(jobService.getPages(pageRequest)); |
||||
|
} |
||||
|
|
||||
|
@Operation(summary = "获取当前作业任务") |
||||
|
@SaCheckRole("machinist") |
||||
|
@GetMapping("/inWorking") |
||||
|
public R<JobItem> 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); |
||||
|
} |
||||
|
} |
@ -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 { |
||||
|
|
||||
|
|
||||
|
} |
@ -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 { |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
package com.jiagutech.ams.mapper; |
||||
|
|
||||
|
import com.jiagutech.ams.model.response.DeviceInfo; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface DeviceMapper { |
||||
|
|
||||
|
List<DeviceInfo> queryDeviceList(Long detpId); |
||||
|
|
||||
|
} |
@ -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<JobDTO> { |
||||
|
|
||||
|
|
||||
|
Page<JobItem> jobPage(Page<JobItem> page, @Param("ew") QueryWrapper wrapper); |
||||
|
|
||||
|
List<JobItem> jobList(@Param("ew") QueryWrapper wrapper); |
||||
|
|
||||
|
List<JobItem> jobListCountByFarmer(@Param("ew") QueryWrapper wrapper); |
||||
|
} |
@ -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<JobTypeDTO> { |
||||
|
|
||||
|
|
||||
|
} |
@ -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); |
||||
|
} |
@ -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; |
||||
|
|
||||
|
|
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
|
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
|
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
package com.jiagutech.ams.service; |
||||
|
|
||||
|
import com.jiagutech.ams.model.response.DeviceInfo; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public interface DeviceService { |
||||
|
List<DeviceInfo> onlineAndRound(double maxLng, double maxLat, double minLng, double minLat); |
||||
|
} |
@ -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<DeviceInfo> onlineAndRound(double maxLng, double maxLat, double minLng, double minLat) { |
||||
|
Set<String> keys = stringRedisTemplate.keys(TRACK_PREFIX_REDIS_KEY); |
||||
|
List<DeviceInfo> deviceInfos = new ArrayList<>(); |
||||
|
if (CollectionUtils.isNotEmpty(keys)) { |
||||
|
List<String> values = stringRedisTemplate.opsForValue().multiGet(keys); |
||||
|
List<TrackDataJG> trackDataJGS = JSON.parseArray(JSON.toJSONString(values), TrackDataJG.class); |
||||
|
Predicate<TrackDataJG> predicate = t -> t.getLat() <= maxLat && t.getLat() >= minLat |
||||
|
&& ((t.getLng() >= -180 && t.getLng() <= maxLng) || (t.getLng() >= minLng && t.getLng() <= 180)); |
||||
|
Consumer<TrackDataJG> 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<DeviceInfo> deviceInfos1 = deviceMapper.queryDeviceList(deptId); |
||||
|
|
||||
|
Iterator<DeviceInfo> iterator = deviceInfos.iterator(); |
||||
|
while (iterator.hasNext()) { |
||||
|
DeviceInfo deviceInfo = iterator.next(); |
||||
|
Predicate<DeviceInfo> p = d -> d.getBoxNum().equals(deviceInfo.getBoxNum()); |
||||
|
Optional<DeviceInfo> exists = deviceInfos1.stream().filter(p).findFirst(); |
||||
|
if (!exists.isPresent()) { |
||||
|
iterator.remove(); |
||||
|
continue; |
||||
|
} |
||||
|
deviceInfo.setDeviceId(exists.get().getDeviceId()).setStatus(exists.get().getStatus()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return deviceInfos; |
||||
|
} |
||||
|
} |
@ -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<JobItem> getPages(PageRequest<JobPageRequest> pageRequest); |
||||
|
|
||||
|
List<JobItem> inJob(); |
||||
|
|
||||
|
List<JobTypeDTO> getJobTypes(); |
||||
|
|
||||
|
void exportJobs(JobPageRequest jobPageRequest, HttpServletResponse response); |
||||
|
|
||||
|
void exportByFarmer(JobPageRequest jobPageRequest, HttpServletResponse response); |
||||
|
} |
@ -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<JobItem> getPages(PageRequest<JobPageRequest> pageRequest) { |
||||
|
JobPageRequest requestParam = pageRequest.getRequest(); |
||||
|
QueryWrapper<JobItem> queryWrapper = buildQueryWrapper(requestParam); |
||||
|
Page<JobItem> page = new Page(pageRequest.getPageNum(), pageRequest.getPageSize()); |
||||
|
Page<JobItem> result = jobMapper.jobPage(page, queryWrapper); |
||||
|
return PageResult.of((int) result.getTotal(), (int) result.getSize(), (int) result.getCurrent(), result.getRecords()); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public List<JobItem> inJob() { |
||||
|
QueryWrapper<JobItem> queryWrapper = Wrappers.query(); |
||||
|
queryWrapper.eq("operator_id", StpUtil.getLoginIdAsLong()).eq("status", 1); |
||||
|
return jobMapper.jobList(queryWrapper); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<JobTypeDTO> getJobTypes() { |
||||
|
QueryWrapper<JobTypeDTO> queryWrapper = Wrappers.query(); |
||||
|
return jobTypeMapper.selectList(queryWrapper); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void exportJobs(JobPageRequest jobPageRequest, HttpServletResponse response) { |
||||
|
QueryWrapper<JobItem> queryWrapper = buildQueryWrapper(jobPageRequest); |
||||
|
List<JobItem> jobItems = jobMapper.jobList(queryWrapper); |
||||
|
ExcelUtil.exportExcel(jobItems, "作业记录", JobItem.class, response); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void exportByFarmer(JobPageRequest jobPageRequest, HttpServletResponse response) { |
||||
|
QueryWrapper<JobItem> queryWrapper = buildQueryWrapper(jobPageRequest); |
||||
|
List<JobItem> jobItems = jobMapper.jobListCountByFarmer(queryWrapper); |
||||
|
ExcelUtil.exportExcel(jobItems, "作业记录", JobItem.class, response); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private QueryWrapper<JobItem> 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<RoleDTO> predicate1 = r -> r.getKey().equals("manager"); |
||||
|
Predicate<RoleDTO> predicate2 = r -> r.getKey().equals("gov"); |
||||
|
Predicate<RoleDTO> 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<Long> 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; |
||||
|
} |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.jiagutech.ams.mapper.DeviceMapper"> |
||||
|
|
||||
|
|
||||
|
<select id="queryDeviceList" resultType="com.jiagutech.ams.model.response.DeviceInfo"> |
||||
|
select d.id as deviceId, d.device_num, d.box_num, d.dept_id, case when j.status = 1 then 1 else 0 end as status |
||||
|
from ams_device_info d |
||||
|
left join ams_job_info j on d.id = j.device_id |
||||
|
where d.dept_id = #{deptId} |
||||
|
</select> |
||||
|
</mapper> |
@ -0,0 +1,53 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.jiagutech.ams.mapper.JobMapper"> |
||||
|
|
||||
|
<sql id="jobItem"> |
||||
|
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 |
||||
|
|
||||
|
|
||||
|
</sql> |
||||
|
|
||||
|
<select id="jobPage" resultType="com.jiagutech.ams.model.response.JobItem"> |
||||
|
<include refid="jobItem"></include> |
||||
|
${ew.getCustomSqlSegment} |
||||
|
</select> |
||||
|
|
||||
|
<select id="jobList" resultType="com.jiagutech.ams.model.response.JobItem"> |
||||
|
<include refid="jobItem"></include> |
||||
|
${ew.getCustomSqlSegment} |
||||
|
order by j.farmer_id,j.start_time |
||||
|
</select> |
||||
|
<select id="jobListCountByFarmer" resultType="com.jiagutech.ams.model.response.JobItem"> |
||||
|
select ROUND(sum(j.area),2) as area,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 u2 on j.farmer_id = u2.id |
||||
|
${ew.getCustomSqlSegment} |
||||
|
group by j.farmer_id,j.job_type,t.name,d.id,d.name,u2.nick_name |
||||
|
</select> |
||||
|
</mapper> |
@ -0,0 +1,47 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.jiagutech.ams.mapper.RegionMapper"> |
||||
|
|
||||
|
|
||||
|
<select id="getRegionsByParentCode" resultType="com.jiagutech.ams.model.dto.RegionDTO"> |
||||
|
WITH RECURSIVE cte AS ( |
||||
|
SELECT r1.region_code,r1.parent_code, r1.region_name, r1.level |
||||
|
FROM region_info r1 |
||||
|
WHERE r1.region_code = #{regionCode} |
||||
|
UNION ALL |
||||
|
SELECT r2.region_code,r2.parent_code, r2.region_name, r2.level |
||||
|
FROM region_info r2 |
||||
|
JOIN cte ON r2.parent_code = cte.region_code |
||||
|
where r2.level <= ${level} |
||||
|
) |
||||
|
|
||||
|
select region_code,region_name from cte; |
||||
|
</select> |
||||
|
|
||||
|
|
||||
|
<select id="getCompleteRegionInfo" resultType="com.jiagutech.ams.model.RegionVO"> |
||||
|
WITH RECURSIVE cte AS ( |
||||
|
SELECT |
||||
|
region_code, |
||||
|
parent_code, |
||||
|
region_name, |
||||
|
level |
||||
|
FROM region_info |
||||
|
WHERE region_code=#{regionCode} |
||||
|
UNION ALL |
||||
|
|
||||
|
|
||||
|
SELECT |
||||
|
u.region_code, |
||||
|
u.parent_code, |
||||
|
u.region_name, |
||||
|
u.level |
||||
|
FROM region_info u |
||||
|
INNER JOIN cte p ON u.region_code = p.parent_code |
||||
|
) |
||||
|
SELECT |
||||
|
GROUP_CONCAT(region_code ORDER BY level SEPARATOR '->') AS region_code, |
||||
|
GROUP_CONCAT(region_name ORDER BY level SEPARATOR '->') AS regionName |
||||
|
from cte |
||||
|
</select> |
||||
|
</mapper> |
@ -0,0 +1,75 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
<parent> |
||||
|
<groupId>com.jiagutech</groupId> |
||||
|
<artifactId>ams-social</artifactId> |
||||
|
<version>${revision}</version> |
||||
|
</parent> |
||||
|
|
||||
|
<artifactId>system</artifactId> |
||||
|
|
||||
|
<properties> |
||||
|
<maven.compiler.source>17</maven.compiler.source> |
||||
|
<maven.compiler.target>17</maven.compiler.target> |
||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
|
</properties> |
||||
|
|
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-web</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.jiagutech</groupId> |
||||
|
<artifactId>common</artifactId> |
||||
|
<version>1.0.0-SNAPSHOT</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>cn.hutool</groupId> |
||||
|
<artifactId>hutool-core</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>cn.hutool</groupId> |
||||
|
<artifactId>hutool-captcha</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-data-redis</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-aop</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-validation</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>ma.glasnost.orika</groupId> |
||||
|
<artifactId>orika-core</artifactId> |
||||
|
<version>1.5.4</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>cn.dev33</groupId> |
||||
|
<artifactId>sa-token-spring-boot3-starter</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springdoc</groupId> |
||||
|
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
<!-- Sa-Token 整合 jwt --> |
||||
|
<dependency> |
||||
|
<groupId>cn.dev33</groupId> |
||||
|
<artifactId>sa-token-jwt</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
</dependencies> |
||||
|
|
||||
|
</project> |
@ -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 { |
||||
|
} |
@ -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<CaptchaVO> 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); |
||||
|
} |
||||
|
} |
@ -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<PageResult<DeptItem>> selectPage(@RequestBody PageRequest<DeptPageRequest> pageRequest) { |
||||
|
return R.ok(deptService.selectPage(pageRequest)); |
||||
|
} |
||||
|
|
||||
|
} |
@ -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<LoginResponse> login(@Validated @RequestBody LoginRequest loginBody) { |
||||
|
|
||||
|
LoginResponse loginVo = userService.login(loginBody); |
||||
|
return R.ok(loginVo); |
||||
|
} |
||||
|
|
||||
|
@Operation(summary = "添加用户") |
||||
|
@PostMapping("/add") |
||||
|
public R<Void> add(@Validated @RequestBody UserRequest user) { |
||||
|
userService.addUser(user); |
||||
|
return R.ok(); |
||||
|
} |
||||
|
|
||||
|
@Operation(summary = "获取用户登陆信息") |
||||
|
@GetMapping("/getUserInfo") |
||||
|
public R<LoginUser> getUserInfo() { |
||||
|
return R.ok(StpUtil.getSession().get(UserConstants.SYS_SESSION, new LoginUser())); |
||||
|
} |
||||
|
|
||||
|
@Operation(summary = "获取用户详情") |
||||
|
@GetMapping("/getUserDetail") |
||||
|
public R<UserDetail> 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<Void> updateUser(@Validated @RequestBody UserRequest user){ |
||||
|
userService.updateUser(user); |
||||
|
return R.ok(); |
||||
|
} |
||||
|
|
||||
|
@Operation(summary = "分页获取用户列表") |
||||
|
@PostMapping("/page") |
||||
|
public R<PageResult<UserDetail>> getUserList(@RequestBody PageRequest<PageUserRequest> pageRequest) { |
||||
|
return R.ok(userService.getUserPage(pageRequest)); |
||||
|
} |
||||
|
} |
@ -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<DeptDTO> { |
||||
|
Page<DeptItem> deptPage(Page<DeptItem> page, @Param("deptName") String deptName, @Param("regionPath") String regionPath); |
||||
|
} |
@ -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<RoleDTO> { |
||||
|
} |
@ -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<UserDeptDTO> { |
||||
|
|
||||
|
DeptDTO selectDeptByUserId(Long userId); |
||||
|
} |
@ -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<UserRoleDTO> { |
||||
|
|
||||
|
List<RoleDTO> selectRolesByUserId(Long userId); |
||||
|
|
||||
|
void insertUserRole(@Param("userId") Long userId, @Param("roleKey") String roleKey); |
||||
|
} |
@ -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); |
||||
|
|
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
|
||||
|
} |
@ -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<DeptItem> selectPage(PageRequest<DeptPageRequest> pageRequest) { |
||||
|
|
||||
|
DeptPageRequest requestParam = pageRequest.getRequest(); |
||||
|
Page<DeptItem> page = new Page(pageRequest.getPageNum(), pageRequest.getPageSize()); |
||||
|
LoginUser loginUser = StpUtil.getSession().get(UserConstants.SYS_SESSION,new LoginUser()); |
||||
|
|
||||
|
Page<DeptItem> 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()); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
@ -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<DeptItem> selectPage(PageRequest<DeptPageRequest> pageRequest); |
||||
|
} |
@ -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<UserDetail> getUserList(String roleKey); |
||||
|
|
||||
|
PageResult<UserDetail> getUserPage(PageRequest<PageUserRequest> pageRequest); |
||||
|
} |
@ -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<RoleDTO> 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<UserRoleDTO> 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<UserDeptDTO> queryWrapper = Wrappers.lambdaQuery(); |
||||
|
queryWrapper.eq(UserDeptDTO::getUserId, user.getUserId()); |
||||
|
userDeptMapper.update(userDeptDTO, queryWrapper); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<UserDetail> getUserList(String roleKey) { |
||||
|
return List.of(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public PageResult<UserDetail> getUserPage(PageRequest<PageUserRequest> pageRequest) { |
||||
|
PageUserRequest requestParam = pageRequest.getRequest(); |
||||
|
QueryWrapper<UserDetail> queryWrapper = buildQueryWrapper(requestParam); |
||||
|
Page<UserDetail> page = new Page(pageRequest.getPageNum(), pageRequest.getPageSize()); |
||||
|
Page<UserDetail> result = userMapper.userPage(page, queryWrapper); |
||||
|
return PageResult.of((int) result.getTotal(), (int) result.getSize(), (int) result.getCurrent(), result.getRecords()); |
||||
|
} |
||||
|
|
||||
|
private QueryWrapper<UserDetail> buildQueryWrapper(PageUserRequest requestParam) { |
||||
|
QueryWrapper<UserDetail> 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<RoleDTO> predicate1 = r -> r.getKey().equals("manager"); |
||||
|
Predicate<RoleDTO> predicate2 = r -> r.getKey().equals("gov"); |
||||
|
Predicate<RoleDTO> 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); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.jiagutech.ams.mapper.DeptMapper"> |
||||
|
|
||||
|
|
||||
|
<select id="deptPage" resultType="com.jiagutech.ams.model.DeptItem"> |
||||
|
select |
||||
|
dd.*,ui.user_id as manager_id,ui.nick_name as manager_name,ui.phone as manager_phone |
||||
|
from |
||||
|
( |
||||
|
select |
||||
|
d1.dept_id, |
||||
|
d2.name as dept_name |
||||
|
from |
||||
|
( |
||||
|
select |
||||
|
distinct dept_id |
||||
|
from |
||||
|
ams_job_info j |
||||
|
where |
||||
|
j.region_code in ( |
||||
|
select |
||||
|
region_code |
||||
|
from |
||||
|
ams_user u |
||||
|
where |
||||
|
|
||||
|
region_path like CONCAT(#{regionPath},'%') |
||||
|
) |
||||
|
) d1 |
||||
|
left join ams_dept d2 on d1.dept_id = d2.id |
||||
|
<if test="deptName!= null and deptName !=''"> |
||||
|
and d2.name like CONCAT('%',#{deptName},'%') |
||||
|
</if> |
||||
|
|
||||
|
) dd |
||||
|
left join( |
||||
|
select u.id as user_id ,u.nick_name,u.phone,ud.dept_id from ams_user u |
||||
|
join ams_user_role ur on u.id=ur.user_id |
||||
|
join ams_role r on ur.role_id=r.id |
||||
|
join ams_user_dept ud on ud.user_id=u.id |
||||
|
where r.key='manager' |
||||
|
) ui |
||||
|
on ui.dept_id=dd.dept_id |
||||
|
|
||||
|
</select> |
||||
|
</mapper> |
@ -0,0 +1,8 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.jiagutech.ams.mapper.RoleMapper"> |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
</mapper> |
@ -0,0 +1,13 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.jiagutech.ams.mapper.UserDeptMapper"> |
||||
|
|
||||
|
|
||||
|
<select id="selectDeptByUserId" resultType="com.jiagutech.ams.model.dto.DeptDTO" parameterType="java.lang.Long"> |
||||
|
SELECT d.id, d.name |
||||
|
FROM ams_user_dept ud |
||||
|
left join ams_dept d on ud.dept_id = d.id |
||||
|
WHERE ud.user_id = #{userId} |
||||
|
</select> |
||||
|
|
||||
|
</mapper> |
@ -0,0 +1,89 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.jiagutech.ams.mapper.UserMapper"> |
||||
|
|
||||
|
|
||||
|
<resultMap type="com.jiagutech.ams.model.LoginUser" id="LoginUserResult"> |
||||
|
<id property="userId" column="user_id"/> |
||||
|
<association property="dept" javaType="com.jiagutech.ams.model.dto.DeptDTO" column="user_id" |
||||
|
select="com.jiagutech.ams.mapper.UserDeptMapper.selectDeptByUserId"/> |
||||
|
<collection property="roles" javaType="java.util.List" column="user_id" select="com.jiagutech.ams.mapper.UserRoleMapper.selectRolesByUserId"/> |
||||
|
|
||||
|
</resultMap> |
||||
|
<resultMap type="com.jiagutech.ams.model.UserDetail" id="UserDetailResult"> |
||||
|
<id property="userId" column="user_id"/> |
||||
|
<association property="dept" javaType="com.jiagutech.ams.model.dto.DeptDTO" column="user_id" |
||||
|
select="com.jiagutech.ams.mapper.UserDeptMapper.selectDeptByUserId"/> |
||||
|
</resultMap> |
||||
|
<select id="selectLoginUserByPhone" resultMap="LoginUserResult"> |
||||
|
select id as user_id, |
||||
|
username, |
||||
|
nick_name, |
||||
|
email, |
||||
|
phone, |
||||
|
region_code, |
||||
|
del_flag, |
||||
|
create_time, |
||||
|
password, |
||||
|
avatar, |
||||
|
region_path |
||||
|
from ams_user |
||||
|
where phone = #{phone} |
||||
|
and del_flag = 0 |
||||
|
</select> |
||||
|
<select id="selectUserDetail" resultMap="UserDetailResult"> |
||||
|
select id as user_id, |
||||
|
username, |
||||
|
nick_name, |
||||
|
email, |
||||
|
phone, |
||||
|
create_time, |
||||
|
avatar, |
||||
|
u.region_code, |
||||
|
r.region_name |
||||
|
from ams_user u left join region_info r on u.region_code=r.region_code |
||||
|
where del_flag = 0 |
||||
|
<if test="userId!= null and userId!= 0"> |
||||
|
and id = #{userId} |
||||
|
</if> |
||||
|
<if test="phone != null"> |
||||
|
and phone = #{phone} |
||||
|
</if> |
||||
|
limit 1 |
||||
|
</select> |
||||
|
<select id="getUserIdsByRegionCodes" resultType="java.lang.Long"> |
||||
|
select id from ams_user |
||||
|
<where> |
||||
|
<if test="userIds != null and userIds.size() > 0"> |
||||
|
region_code IN |
||||
|
<foreach collection="regionCodes" item="regionCode" open="(" separator="," close=")"> |
||||
|
#{regionCode} |
||||
|
</foreach> |
||||
|
</if> |
||||
|
</where> |
||||
|
|
||||
|
</select> |
||||
|
|
||||
|
<select id="getUsersByLikeRegionPath" resultType="UserDTO"> |
||||
|
select id, nick_name, region_code |
||||
|
from ams_user |
||||
|
where region_path like CONCAT(#{regionPath}, '%') |
||||
|
and del_flag = 0 |
||||
|
</select> |
||||
|
<select id="userPage" resultType="com.jiagutech.ams.model.UserDetail"> |
||||
|
select u.id as user_id, |
||||
|
u.username, |
||||
|
u.nick_name, |
||||
|
u.email, |
||||
|
u.phone, |
||||
|
u.create_time, |
||||
|
u.avatar, |
||||
|
u.region_code |
||||
|
from ams_user u |
||||
|
left join ams_user_role ur on u.id = ur.user_id |
||||
|
left join ams_role r on ur.role_id = r.id |
||||
|
left join ams_user_dept ud on u.id=ud.user_id |
||||
|
${ew.getCustomSqlSegment} |
||||
|
</select> |
||||
|
|
||||
|
</mapper> |
@ -0,0 +1,20 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.jiagutech.ams.mapper.UserRoleMapper"> |
||||
|
|
||||
|
|
||||
|
<select id="selectRolesByUserId" resultType="com.jiagutech.ams.model.dto.RoleDTO" parameterType="java.lang.Long"> |
||||
|
SELECT r.id, r.name,r.key |
||||
|
FROM ams_role r |
||||
|
INNER JOIN ams_user_role ur ON r.id = ur.role_id |
||||
|
WHERE ur.user_id = #{userId} |
||||
|
</select> |
||||
|
|
||||
|
|
||||
|
<insert id="insertUserRole"> |
||||
|
insert into ams_user_role(user_id, role_id) |
||||
|
select #{userId}, r.id as role_id |
||||
|
from ams_role r |
||||
|
where r.key = #{roleKey} |
||||
|
</insert> |
||||
|
</mapper> |
@ -0,0 +1,102 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
<parent> |
||||
|
<groupId>com.jiagutech</groupId> |
||||
|
<artifactId>ams-social</artifactId> |
||||
|
<version>${revision}</version> |
||||
|
</parent> |
||||
|
|
||||
|
<artifactId>web</artifactId> |
||||
|
|
||||
|
<properties> |
||||
|
<maven.compiler.source>17</maven.compiler.source> |
||||
|
<maven.compiler.target>17</maven.compiler.target> |
||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
|
</properties> |
||||
|
|
||||
|
<profiles> |
||||
|
<profile> |
||||
|
<id>dev</id> |
||||
|
<properties> |
||||
|
<!-- 环境标识,需要与配置文件的名称相对应 --> |
||||
|
<profiles.active>dev</profiles.active> |
||||
|
<logging.level>info</logging.level> |
||||
|
</properties> |
||||
|
<activation> |
||||
|
<!-- 默认环境 --> |
||||
|
<activeByDefault>true</activeByDefault> |
||||
|
</activation> |
||||
|
</profile> |
||||
|
<profile> |
||||
|
<id>prod</id> |
||||
|
<properties> |
||||
|
<profiles.active>prod</profiles.active> |
||||
|
<logging.level>info</logging.level> |
||||
|
</properties> |
||||
|
</profile> |
||||
|
</profiles> |
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>com.jiagutech</groupId> |
||||
|
<artifactId>system</artifactId> |
||||
|
<version>1.0.0-SNAPSHOT</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>com.jiagutech</groupId> |
||||
|
<artifactId>social</artifactId> |
||||
|
<version>1.0.0-SNAPSHOT</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-data-jdbc</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>mysql</groupId> |
||||
|
<artifactId>mysql-connector-java</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springdoc</groupId> |
||||
|
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> |
||||
|
|
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.springdoc</groupId> |
||||
|
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.commons</groupId> |
||||
|
<artifactId>commons-pool2</artifactId> |
||||
|
<version>2.12.0</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>cn.dev33</groupId> |
||||
|
<artifactId>sa-token-spring-boot3-starter</artifactId> |
||||
|
</dependency> |
||||
|
|
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>cn.dev33</groupId> |
||||
|
<artifactId>sa-token-redis</artifactId> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
<build> |
||||
|
|
||||
|
<plugins> |
||||
|
<plugin> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-maven-plugin</artifactId> |
||||
|
<version>${spring-boot.version}</version> |
||||
|
<executions> |
||||
|
<execution> |
||||
|
<goals> |
||||
|
<goal>repackage</goal> |
||||
|
</goals> |
||||
|
</execution> |
||||
|
</executions> |
||||
|
</plugin> |
||||
|
</plugins> |
||||
|
</build> |
||||
|
</project> |
@ -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); |
||||
|
} |
||||
|
} |
@ -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<String, String> 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<String, String> 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()); |
||||
|
} |
||||
|
} |
@ -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; |
||||
|
} |
||||
|
} |
||||
|
|
@ -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; |
||||
|
|
||||
|
} |
||||
|
} |
@ -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; |
||||
|
} |
||||
|
|
||||
|
} |
@ -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<String> getPermissionList(Object loginId, String loginType) { |
||||
|
|
||||
|
return new ArrayList<>(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取角色权限列表 |
||||
|
*/ |
||||
|
@Override |
||||
|
public List<String> 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(); |
||||
|
} |
||||
|
} |
@ -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(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -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("/**"); |
||||
|
} |
||||
|
} |
@ -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"); |
||||
|
} |
||||
|
|
||||
|
} |
@ -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); |
||||
|
} |
||||
|
|
||||
|
} |
@ -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 |
||||
|
|
@ -0,0 +1,103 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<configuration> |
||||
|
<include resource="org/springframework/boot/logging/logback/defaults.xml"/> |
||||
|
|
||||
|
<springProperty scope="context" name="springAppName" source="spring.application.name"/> |
||||
|
<!--<springProperty scope="context" name="serverIp" source="spring.cloud.client.hostname" />--> |
||||
|
<!-- Example for logging into the build folder of your project --> |
||||
|
<property name="LOG_FILE" value="log"/> |
||||
|
<property name="LOG_PATTERN" |
||||
|
value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%.-5level) -- %X{traceId:-} -- [%10.10t] %cyan(%-36.36logger{32}) : %m%n"/> |
||||
|
|
||||
|
<!-- Appender to log to console --> |
||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> |
||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
||||
|
<!-- Minimum logging level to be presented in the console logs--> |
||||
|
<level>DEBUG</level> |
||||
|
</filter> |
||||
|
<encoder> |
||||
|
<pattern>${LOG_PATTERN}</pattern> |
||||
|
<charset>utf8</charset> |
||||
|
</encoder> |
||||
|
</appender> |
||||
|
|
||||
|
<!-- INFO日志 appender: 按照每天生成日志文件 --> |
||||
|
<appender name="INFO-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
||||
|
<!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 --> |
||||
|
<file>${LOG_FILE}/${springAppName}-info.log</file> |
||||
|
<!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 --> |
||||
|
<append>true</append> |
||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
||||
|
<!-- 日志文件输出的文件名: %d可以包含一个Java.text.SimpleDateFormat指定的时间格式 --> |
||||
|
<fileNamePattern>${LOG_FILE}/${springAppName}-info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> |
||||
|
<!-- 日志文件保存历史数量:控制保留的归档文件的最大数量,如果超出数量就删除旧文件 --> |
||||
|
<maxHistory>20</maxHistory> |
||||
|
<!-- 文件大小超过100MB归档 --> |
||||
|
<maxFileSize>100MB</maxFileSize> |
||||
|
</rollingPolicy> |
||||
|
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
||||
|
<pattern>${LOG_PATTERN}</pattern> |
||||
|
<charset>utf8</charset> |
||||
|
</encoder> |
||||
|
</appender> |
||||
|
<appender name="ASYNC-INFO-APPENDER" class="ch.qos.logback.classic.AsyncAppender"> |
||||
|
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> |
||||
|
<discardingThreshold>0</discardingThreshold> |
||||
|
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --> |
||||
|
<queueSize>256</queueSize> |
||||
|
<!-- 添加附加的appender,最多只能添加一个 --> |
||||
|
<appender-ref ref="INFO-APPENDER"/> |
||||
|
</appender> |
||||
|
<!-- 错误日志 appender: 按照每天生成日志文件 --> |
||||
|
<appender name="ERROR-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
||||
|
<!-- 过滤器,只记录error级别的日志 --> |
||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter"> |
||||
|
<level>ERROR</level> |
||||
|
<onMatch>ACCEPT</onMatch> |
||||
|
<onMismatch>DENY</onMismatch> |
||||
|
</filter> |
||||
|
<!-- 日志名称 --> |
||||
|
<file>${LOG_FILE}/${springAppName}-error.log</file> |
||||
|
<append>true</append> |
||||
|
<!-- 每天生成一个日志文件,保存30天的日志文件 --> |
||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
||||
|
<!-- 日志文件输出的文件名:按天回滚 daily --> |
||||
|
<fileNamePattern>${LOG_FILE}/${springAppName}-error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> |
||||
|
<!-- 日志文件保留天数 --> |
||||
|
<maxHistory>20</maxHistory> |
||||
|
<!-- 文件大小超过100MB归档 --> |
||||
|
<maxFileSize>100MB</maxFileSize> |
||||
|
</rollingPolicy> |
||||
|
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
||||
|
<pattern>${LOG_PATTERN}</pattern> |
||||
|
<charset>utf8</charset> |
||||
|
</encoder> |
||||
|
</appender> |
||||
|
<appender name="ASYNC-ERROR-APPENDER" class="ch.qos.logback.classic.AsyncAppender"> |
||||
|
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> |
||||
|
<discardingThreshold>0</discardingThreshold> |
||||
|
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --> |
||||
|
<queueSize>256</queueSize> |
||||
|
<!-- 添加附加的appender,最多只能添加一个 --> |
||||
|
<appender-ref ref="ERROR-APPENDER"/> |
||||
|
</appender> |
||||
|
|
||||
|
<logger name="com.jiagu.oper.dao" level="DEBUG"> |
||||
|
<appender-ref ref="console"/> |
||||
|
<appender-ref ref="ASYNC-INFO-APPENDER"/> |
||||
|
</logger> |
||||
|
|
||||
|
<root level="INFO"> |
||||
|
<appender-ref ref="console"/> |
||||
|
<appender-ref ref="ASYNC-INFO-APPENDER"/> |
||||
|
<appender-ref ref="ASYNC-ERROR-APPENDER"/> |
||||
|
</root> |
||||
|
|
||||
|
|
||||
|
<springProfile name="local"> |
||||
|
<root level="INFO"> |
||||
|
<appender-ref ref="console"/> |
||||
|
</root> |
||||
|
</springProfile> |
||||
|
|
||||
|
</configuration> |
Loading…
Reference in new issue