add
This commit is contained in:
22
pom.xml
22
pom.xml
@ -21,7 +21,7 @@
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.11</version>
|
||||
<!-- 解决子模块继承不到父模块中dependencyManagement中包的version信息 -->
|
||||
<relativePath />
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
@ -110,6 +110,16 @@
|
||||
<artifactId>qiaoba-auth</artifactId>
|
||||
<version>${qiaoba.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-module-system</artifactId>
|
||||
<version>${qiaoba.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-module-file</artifactId>
|
||||
<version>${qiaoba.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-common-base</artifactId>
|
||||
@ -130,11 +140,6 @@
|
||||
<artifactId>qiaoba-api-system</artifactId>
|
||||
<version>${qiaoba.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-module-system</artifactId>
|
||||
<version>${qiaoba.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-common-doc</artifactId>
|
||||
@ -150,6 +155,11 @@
|
||||
<artifactId>qiaoba-common-redis</artifactId>
|
||||
<version>${qiaoba.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-api-file</artifactId>
|
||||
<version>${qiaoba.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
@ -14,28 +14,8 @@
|
||||
<modules>
|
||||
<module>qiaoba-api-system</module>
|
||||
<module>qiaoba-api-job</module>
|
||||
<module>qiaoba-api-file</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-common-datasource</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-common-doc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.validation</groupId>
|
||||
<artifactId>jakarta.validation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-auth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-common-poi</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
24
qiaoba-apis/qiaoba-api-file/pom.xml
Normal file
24
qiaoba-apis/qiaoba-api-file/pom.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?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">
|
||||
<parent>
|
||||
<artifactId>qiaoba-apis</artifactId>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>qiaoba-api-file</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-auth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-common-doc</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,20 @@
|
||||
package com.qiaoba.api.file.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 文件
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/19 9:43
|
||||
*/
|
||||
@Data
|
||||
public class File implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String url;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.qiaoba.api.file.service;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 文件对外暴露接口
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023-04-23 20:33:43
|
||||
*/
|
||||
public interface FileApiService {
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*
|
||||
* @param file file
|
||||
* @return url
|
||||
*/
|
||||
String upload(MultipartFile file);
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param path 路径
|
||||
* @return 结果
|
||||
*/
|
||||
boolean delete(String path);
|
||||
}
|
1
qiaoba-apis/qiaoba-api-file/src/test/java/.gitkeep
Normal file
1
qiaoba-apis/qiaoba-api-file/src/test/java/.gitkeep
Normal file
@ -0,0 +1 @@
|
||||
null not found
|
@ -11,5 +11,27 @@
|
||||
|
||||
<artifactId>qiaoba-api-system</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-common-datasource</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-common-doc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.validation</groupId>
|
||||
<artifactId>jakarta.validation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-auth</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-common-poi</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -34,7 +34,7 @@ public class SysRole extends BaseEntity {
|
||||
@Excel(name = "岗位序号", width = 20)
|
||||
private Integer roleSort;
|
||||
|
||||
@Excel(name = "数据范围" , width = 20, replace = {"所有数据权限_1" , "自定义数据权限_2" , "本部门数据权限_3" , "本部门及以下数据权限_4" , "仅本人数据权限_5"})
|
||||
@Excel(name = "数据范围", width = 20, replace = {"所有数据权限_1", "自定义数据权限_2", "本部门数据权限_3", "本部门及以下数据权限_4", "仅本人数据权限_5"})
|
||||
private String dataScope;
|
||||
|
||||
@Excel(name = "状态", width = 20, replace = {"正常_1", "禁用_0"})
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.qiaoba.api.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
@ -2,6 +2,8 @@ package com.qiaoba.api.system.entity.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 用户登录对象
|
||||
*
|
||||
@ -10,7 +12,9 @@ import lombok.Data;
|
||||
* @since 2021/10/15 0015 上午 10:05
|
||||
*/
|
||||
@Data
|
||||
public class LoginDto {
|
||||
public class LoginDto implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
@ -30,6 +34,6 @@ public class LoginDto {
|
||||
/**
|
||||
* 唯一标识
|
||||
*/
|
||||
private String uuid = "";
|
||||
private String uuid;
|
||||
|
||||
}
|
||||
|
@ -6,17 +6,25 @@ import lombok.Setter;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 更改密码
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/10 14:03
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ResetPwdDto implements Serializable {
|
||||
public class ResetPasswordDto implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 新密码
|
||||
*/
|
||||
private String password;
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.qiaoba.api.system.entity.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 更改用户基础信息
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/19 13:46
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class ResetUserBasicInfoDto implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 姓名
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 邮箱号
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 性别
|
||||
*/
|
||||
private String gender;
|
||||
|
||||
}
|
@ -6,6 +6,8 @@ import lombok.Setter;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 更改用户状态
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/10 14:03
|
||||
@ -16,7 +18,13 @@ public class ResetUserStatusDto implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private String status;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.qiaoba.api.system.service;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.qiaoba.api.system.entity.SysDept;
|
||||
import com.qiaoba.api.system.entity.param.SysDeptParam;
|
||||
|
||||
|
@ -5,7 +5,6 @@ import com.qiaoba.api.system.entity.param.SysMenuParam;
|
||||
import com.qiaoba.api.system.entity.vo.SysMenuVo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 菜单对外暴露接口
|
||||
|
@ -1,11 +1,7 @@
|
||||
package com.qiaoba.api.system.service;
|
||||
|
||||
import com.qiaoba.api.system.entity.SysUser;
|
||||
import com.qiaoba.api.system.entity.dto.ResetPwdDto;
|
||||
import com.qiaoba.api.system.entity.dto.ResetUserStatusDto;
|
||||
import com.qiaoba.api.system.entity.dto.SysUserDto;
|
||||
import com.qiaoba.api.system.entity.param.SysUserParam;
|
||||
import com.qiaoba.api.system.entity.vo.SysUserVo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -28,6 +24,13 @@ public interface SysUserApiService {
|
||||
*/
|
||||
int saveOrUpdate(SysUserDto dto, Boolean isUpdate);
|
||||
|
||||
/**
|
||||
* 检查是否允许新增或修改
|
||||
*
|
||||
* @param sysUser sysUser
|
||||
*/
|
||||
void checkAddOrUpdate(SysUser sysUser);
|
||||
|
||||
/**
|
||||
* 查询用户
|
||||
*
|
||||
@ -45,22 +48,6 @@ public interface SysUserApiService {
|
||||
*/
|
||||
SysUser selectByUsername(String username);
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
*
|
||||
* @param dto dto
|
||||
* @return 结果
|
||||
*/
|
||||
int resetPwd(ResetPwdDto dto);
|
||||
|
||||
/**
|
||||
* 更改用户状态
|
||||
*
|
||||
* @param dto dto
|
||||
* @return 结果
|
||||
*/
|
||||
int updateUserStatus(ResetUserStatusDto dto);
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
@ -78,5 +65,11 @@ public interface SysUserApiService {
|
||||
*/
|
||||
void handleUserRole(String userId, Set<String> roleIds, boolean isUpdate);
|
||||
|
||||
|
||||
/**
|
||||
* 用户更改
|
||||
*
|
||||
* @param sysUser sysUser
|
||||
* @return 结果
|
||||
*/
|
||||
int updateById(SysUser sysUser);
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package com.qiaoba.api.system.service;
|
||||
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
/**
|
||||
* SysUserDetails 暴露接口
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/19 17:17
|
||||
*/
|
||||
public interface SysUserDetailsApiService {
|
||||
|
||||
/**
|
||||
* 查询UserDetails 并缓存到Redis中
|
||||
*
|
||||
* @param username username
|
||||
* @return UserDetails
|
||||
*/
|
||||
UserDetails toCache(String username);
|
||||
}
|
@ -16,6 +16,10 @@
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-module-system</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-module-file</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -1,11 +1,8 @@
|
||||
package com.qiaoba.application;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.qiaoba.api.system.entity.SysMenu;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
@ -1,4 +1,5 @@
|
||||
qiaoba:
|
||||
file-upload-path: C:/${spring.application.name}/uploadPath/
|
||||
datasource:
|
||||
master:
|
||||
driver: com.mysql.cj.jdbc.Driver
|
||||
|
44
qiaoba-application/src/main/resources/application-prod.yml
Normal file
44
qiaoba-application/src/main/resources/application-prod.yml
Normal file
@ -0,0 +1,44 @@
|
||||
qiaoba:
|
||||
file-upload-path: /opt/${spring.application.name}/uploadPath/
|
||||
datasource:
|
||||
master:
|
||||
driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/qiaoba-boot?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
username: root
|
||||
password: root
|
||||
pool:
|
||||
init: 5 #连接池初始化大小
|
||||
min: 10 #最小空闲连接数
|
||||
max: 20 #最大连接数
|
||||
slaves:
|
||||
- driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://121.5.136.69:3306/qiaoba-boot-1?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
username: root
|
||||
password: LpYN7LUoL?l0OSpR2
|
||||
pool:
|
||||
init: 5
|
||||
min: 10
|
||||
max: 20
|
||||
weight: 2 #权重 默认 1
|
||||
is-use: true #是否使用 默认 true
|
||||
- driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/qiaoba-boot?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
|
||||
username: root
|
||||
password: root
|
||||
pool:
|
||||
init: 5
|
||||
min: 10
|
||||
max: 20
|
||||
is-use: false # 不使用该库
|
||||
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
# 自动驼峰命名规则(camel case)映射
|
||||
mapUnderscoreToCamelCase: true
|
||||
# MyBatis 自动映射策略
|
||||
# NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射
|
||||
autoMappingBehavior: PARTIAL
|
||||
# MyBatis 自动映射时未知列或未知属性处理策
|
||||
# NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息
|
||||
autoMappingUnknownColumnBehavior: NONE
|
@ -44,6 +44,9 @@ springdoc:
|
||||
- group: '系统管理'
|
||||
paths-to-match: '/**'
|
||||
packages-to-scan: com.qiaoba.module.system.controller
|
||||
- group: '文件管理'
|
||||
paths-to-match: '/**'
|
||||
packages-to-scan: com.qiaoba.module.file.controller
|
||||
|
||||
# knife4j的增强配置,不需要增强可以不配
|
||||
knife4j:
|
||||
@ -54,7 +57,7 @@ knife4j:
|
||||
enable-footer-custom: true
|
||||
footer-custom-content: create by ailanyin
|
||||
|
||||
# mybatis-plus:
|
||||
# mybatis-plus:
|
||||
# 对应的 XML 文件位置
|
||||
# mapperLocations: classpath*:mapper/**/*Mapper.xml
|
||||
# 实体扫描,多个package用逗号或者分号分隔
|
||||
|
@ -8,6 +8,7 @@ import com.qiaoba.auth.handler.AccessDeniedHandler;
|
||||
import com.qiaoba.auth.handler.LogoutHandler;
|
||||
import com.qiaoba.auth.properties.AuthConfigProperties;
|
||||
import com.qiaoba.auth.utils.TokenUtil;
|
||||
import com.qiaoba.common.base.constants.BaseConstant;
|
||||
import com.qiaoba.common.redis.service.RedisService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -21,6 +22,7 @@ import org.springframework.security.config.annotation.web.configurers.Expression
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.authentication.logout.LogoutFilter;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
@ -40,9 +42,9 @@ public class SpringSecurityConfig {
|
||||
|
||||
private final AuthConfigProperties authConfigProperties;
|
||||
private final AccessDeniedHandler accessDeniedHandler;
|
||||
private final LogoutHandler logoutHandler;
|
||||
private final JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
|
||||
private final RedisService redisService;
|
||||
private final LogoutHandler logoutHandler;
|
||||
|
||||
/**
|
||||
* 创建Token秘钥
|
||||
@ -65,7 +67,8 @@ public class SpringSecurityConfig {
|
||||
for (String url : authConfigProperties.getWhitelist()) {
|
||||
registry.antMatchers(url).permitAll();
|
||||
}
|
||||
|
||||
// 文件资源 无需鉴权
|
||||
registry.antMatchers(BaseConstant.RESOURCE_PREFIX + "/**").permitAll();
|
||||
// 由于使用的是JWT,我们这里不需要csrf
|
||||
httpSecurity.csrf()
|
||||
.disable()
|
||||
@ -90,7 +93,7 @@ public class SpringSecurityConfig {
|
||||
httpSecurity.logout().logoutUrl(SecurityConstant.LOGOUT_URL).logoutSuccessHandler(logoutHandler);
|
||||
// 添加JWT filter
|
||||
httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter, LogoutFilter.class);
|
||||
return httpSecurity.build();
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ public class SecurityConstant {
|
||||
public static final String REGISTER_ON_OFF_KEY = "sys_config:sys.account.registerUser";
|
||||
public static final String REGISTER_ON = "true";
|
||||
public static final String REDIS_SECRET_KEY = "sys:secret:secret";
|
||||
public static final String USER_DETAILS_REDIS_KEY = "user_details:";
|
||||
/**
|
||||
* 登录成功
|
||||
*/
|
||||
@ -54,7 +55,7 @@ public class SecurityConstant {
|
||||
* Xss过滤白名单
|
||||
*/
|
||||
public final static List<String> XSS_WHITELIST = Arrays.asList(
|
||||
"/captchaImage" ,
|
||||
"/captchaImage",
|
||||
"/login",
|
||||
"/workflow/process/start",
|
||||
"/workflow/model/save"
|
||||
@ -64,8 +65,8 @@ public class SecurityConstant {
|
||||
* 需要限流的接口
|
||||
*/
|
||||
public final static List<String> LIMIT_URI = Arrays.asList(
|
||||
"/captchaImage" ,
|
||||
"/login" ,
|
||||
"/captchaImage",
|
||||
"/login",
|
||||
"/register"
|
||||
);
|
||||
|
||||
@ -78,4 +79,5 @@ public class SecurityConstant {
|
||||
* 同IP每秒最大允许访问次数
|
||||
*/
|
||||
public final static Integer MAX_RATE_LIMIT_TOTAL = 5;
|
||||
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public class LoginUser implements UserDetails {
|
||||
/**
|
||||
* 角色列表
|
||||
*/
|
||||
private List<String> roleIds;
|
||||
private List<String> roleKeys;
|
||||
|
||||
|
||||
/**
|
||||
@ -58,13 +58,13 @@ public class LoginUser implements UserDetails {
|
||||
public LoginUser() {
|
||||
}
|
||||
|
||||
public LoginUser(String userId, String deptId, String username, String nickname, List<String> roleIds, Set<String> permissions) {
|
||||
public LoginUser(String userId, String deptId, String username, String nickname, List<String> roleKeys, Set<String> permissions) {
|
||||
this.userId = userId;
|
||||
this.deptId = deptId;
|
||||
this.username = username;
|
||||
this.permissions = permissions;
|
||||
this.nickname = nickname;
|
||||
this.roleIds = roleIds;
|
||||
this.roleKeys = roleKeys;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
@ -84,12 +84,12 @@ public class LoginUser implements UserDetails {
|
||||
}
|
||||
|
||||
|
||||
public List<String> getRoleIds() {
|
||||
return roleIds;
|
||||
public List<String> getRoleKeys() {
|
||||
return roleKeys;
|
||||
}
|
||||
|
||||
public void setRoleIds(List<String> roleIds) {
|
||||
this.roleIds = roleIds;
|
||||
public void setRoleKeys(List<String> roleKeys) {
|
||||
this.roleKeys = roleKeys;
|
||||
}
|
||||
|
||||
public Set<String> getPermissions() {
|
||||
|
@ -0,0 +1,55 @@
|
||||
package com.qiaoba.auth.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/19 16:55
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SecurityUser implements Serializable {
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
private String deptId;
|
||||
|
||||
/**
|
||||
* 登录账号
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 用户名称
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
|
||||
/**
|
||||
* 角色列表
|
||||
*/
|
||||
private List<String> roleKeys;
|
||||
|
||||
|
||||
/**
|
||||
* 权限列表
|
||||
*/
|
||||
private Set<String> permissions;
|
||||
|
||||
}
|
@ -2,7 +2,6 @@ package com.qiaoba.auth.filters;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.qiaoba.auth.constants.SecurityConstant;
|
||||
import com.qiaoba.auth.properties.AuthConfigProperties;
|
||||
import com.qiaoba.auth.utils.TokenUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
@ -17,7 +16,6 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* JwtAuthenticationTokenFilter
|
||||
@ -31,25 +29,20 @@ import java.util.Objects;
|
||||
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
||||
|
||||
private final UserDetailsService userDetailsService;
|
||||
private final AuthConfigProperties authConfigProperties;
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
FilterChain chain) throws ServletException, IOException {
|
||||
// 鉴权白名单, 放行
|
||||
if (authConfigProperties.getWhitelist().contains(request.getRequestURI())) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// 取Header中的Token
|
||||
String authHeader = request.getHeader(SecurityConstant.TOKEN_HEADER);
|
||||
if (StrUtil.isNotBlank(authHeader) && authHeader.startsWith(SecurityConstant.TOKEN_HEAD)) {
|
||||
String authToken = authHeader.substring(SecurityConstant.TOKEN_HEAD.length());
|
||||
if (TokenUtil.validateToken(authToken)) {
|
||||
String username = TokenUtil.getUserNameFromToken(authToken);
|
||||
if (StrUtil.isNotBlank(username) && Objects.isNull(SecurityContextHolder.getContext().getAuthentication())) {
|
||||
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
|
||||
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
|
||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
|
@ -1,12 +1,16 @@
|
||||
package com.qiaoba.auth.handler;
|
||||
|
||||
import com.qiaoba.auth.entity.LoginUser;
|
||||
import com.qiaoba.common.redis.service.RedisService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 退出处理器
|
||||
@ -16,11 +20,15 @@ import javax.servlet.http.HttpServletResponse;
|
||||
* @since 2022/1/4 0004 下午 16:20
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class LogoutHandler implements LogoutSuccessHandler {
|
||||
|
||||
private final RedisService redisService;
|
||||
|
||||
@Override
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse httpServletResponse, Authentication authentication) {
|
||||
//删除SecurityContext上下文中的信息
|
||||
SecurityContextHolder.clearContext();
|
||||
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
|
||||
// 删除缓存中的用户信息
|
||||
LoginUser user = (LoginUser) authentication.getPrincipal();
|
||||
redisService.del(user.getUserId());
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.jwt.JWTPayload;
|
||||
import cn.hutool.jwt.JWTUtil;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -23,7 +24,6 @@ public class TokenUtil {
|
||||
*/
|
||||
public static String secret;
|
||||
|
||||
|
||||
public static String generateToken(String username) {
|
||||
DateTime now = DateTime.now();
|
||||
// 3天过期
|
||||
@ -38,7 +38,6 @@ public class TokenUtil {
|
||||
payload.put(JWTPayload.NOT_BEFORE, now);
|
||||
//载荷
|
||||
payload.put(JWTPayload.SUBJECT, username);
|
||||
|
||||
return JWTUtil.createToken(payload, secret.getBytes());
|
||||
}
|
||||
|
||||
|
@ -38,4 +38,9 @@ public class BaseConstant {
|
||||
* https请求
|
||||
*/
|
||||
public static final String HTTPS = "https://";
|
||||
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
public static final String RESOURCE_PREFIX = "/resource";
|
||||
}
|
||||
|
@ -13,13 +13,13 @@ import lombok.Getter;
|
||||
public enum BaseEnum {
|
||||
|
||||
// 是
|
||||
YES("1" , "是"),
|
||||
YES("1", "是"),
|
||||
// 否
|
||||
NO("0" , "否"),
|
||||
NO("0", "否"),
|
||||
// 正常
|
||||
NORMAL("1" , "正常"),
|
||||
NORMAL("1", "正常"),
|
||||
// 不正常
|
||||
ABNORMAL("0" , "不正常");
|
||||
ABNORMAL("0", "不正常");
|
||||
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
@ -74,7 +74,7 @@ public class AjaxResult extends HashMap<String, Object> {
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResult success(Object data) {
|
||||
return AjaxResult.success("操作成功" , data);
|
||||
return AjaxResult.success("操作成功", data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,11 +31,11 @@ public class ObjectUtil {
|
||||
// 得到此属性的值
|
||||
Object val = f.get(obj);
|
||||
// 只要有1个属性不为空,那么就不是所有的属性值都为空
|
||||
if(val != null) {
|
||||
if (val != null) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}catch (IllegalAccessException e){
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 全局跨域配置
|
||||
* 多数据源配置
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
|
@ -11,6 +11,8 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* MybatisPlusConfig
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/8 11:18
|
||||
|
@ -1,11 +1,7 @@
|
||||
package com.qiaoba.common.database.factories;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import com.qiaoba.common.database.config.DynamicDataSourceConfig;
|
||||
import com.qiaoba.common.database.config.DynamicDataSourceContext;
|
||||
import com.qiaoba.common.database.config.MybatisPlusConfig;
|
||||
import com.qiaoba.common.database.filters.DynamicDataSourceFilter;
|
||||
import com.qiaoba.common.database.properties.DefaultDataSourceProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
@ -1,14 +1,18 @@
|
||||
package com.qiaoba.common.database.filters;
|
||||
|
||||
import com.qiaoba.common.base.utils.TenantUtil;
|
||||
import com.qiaoba.common.database.config.DynamicDataSourceContext;
|
||||
import com.qiaoba.common.database.constants.DynamicDatasourceConstant;
|
||||
import com.qiaoba.common.base.utils.TenantUtil;
|
||||
import com.qiaoba.common.web.utils.ResponseUtil;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@ -21,17 +25,18 @@ import java.io.IOException;
|
||||
*/
|
||||
@Component
|
||||
@Order(-10000)
|
||||
public class DynamicDataSourceFilter implements Filter {
|
||||
public class DynamicDataSourceFilter extends OncePerRequestFilter {
|
||||
|
||||
@Resource
|
||||
private DynamicDataSourceContext dynamicDataSourceContext;
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||
//设置当前租户对应的数据库
|
||||
dynamicDataSourceContext.setDataSource(DynamicDatasourceConstant.DEFAULT_MASTER_DATASOURCE_KEY);
|
||||
// todo
|
||||
TenantUtil.setTenantId("1");
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
filterChain.doFilter(request, response);
|
||||
dynamicDataSourceContext.clearDataSource();
|
||||
TenantUtil.clearTenantId();
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.*;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.Db;
|
||||
import com.qiaoba.common.web.utils.BeanCopyUtil;
|
||||
@ -135,6 +135,7 @@ public interface BaseMapperPlus<M, T, V> extends BaseMapper<T> {
|
||||
|
||||
/**
|
||||
* 插入或更新
|
||||
*
|
||||
* @param entity entity
|
||||
* @return 结果
|
||||
*/
|
||||
@ -144,6 +145,7 @@ public interface BaseMapperPlus<M, T, V> extends BaseMapper<T> {
|
||||
|
||||
/**
|
||||
* 查询Vo by id
|
||||
*
|
||||
* @param id 主键
|
||||
* @return Vo
|
||||
*/
|
||||
|
@ -219,13 +219,13 @@ public class RedisServiceImpl implements RedisService {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getObject(String key, Class<T> clazz) {
|
||||
return (T) get(handleKey(key));
|
||||
return (T) get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> List<T> getObjectList(String key, Class<T> clazz) {
|
||||
return (List<T>) get(handleKey(key));
|
||||
return (List<T>) get(key);
|
||||
}
|
||||
|
||||
private String handleKey(String key) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.qiaoba.application.config;
|
||||
package com.qiaoba.common.web.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -30,7 +30,7 @@ public class GlobalCorsConfig {
|
||||
config.setMaxAge(1800L);
|
||||
// 添加映射路径,拦截一切请求
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**" , config);
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
// 返回新的CorsFilter
|
||||
return new CorsFilter(source);
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.qiaoba.common.web.advice.ExceptionAdvice
|
||||
com.qiaoba.common.web.advice.ExceptionAdvice,\
|
||||
com.qiaoba.common.web.config.GlobalCorsConfig
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
<modules>
|
||||
<module>qiaoba-module-system</module>
|
||||
<module>qiaoba-module-job</module>
|
||||
<module>qiaoba-module-file</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
|
20
qiaoba-modules/qiaoba-module-file/pom.xml
Normal file
20
qiaoba-modules/qiaoba-module-file/pom.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>qiaoba-modules</artifactId>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>qiaoba-module-file</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-api-file</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,33 @@
|
||||
package com.qiaoba.module.file.config;
|
||||
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import com.qiaoba.common.base.constants.BaseConstant;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* 配置静态文件资源服务器
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2022/2/28 0028 上午 9:12
|
||||
*/
|
||||
@Configuration
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileConfig implements WebMvcConfigurer {
|
||||
|
||||
@Value("${qiaoba.file-upload-path}")
|
||||
private String uploadPath;
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler(BaseConstant.RESOURCE_PREFIX + "/**")
|
||||
.addResourceLocations(URLUtil.FILE_URL_PREFIX + uploadPath);
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.qiaoba.module.file.controller;
|
||||
|
||||
import com.qiaoba.api.file.entity.File;
|
||||
import com.qiaoba.common.base.result.AjaxResult;
|
||||
import com.qiaoba.module.file.service.FileService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 文件管理 Web层
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/19 9:14
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/file")
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "文件管理")
|
||||
public class FileController {
|
||||
|
||||
private final FileService fileService;
|
||||
|
||||
@PostMapping("/upload")
|
||||
@Operation(summary = "上传文件")
|
||||
public AjaxResult upload(MultipartFile file) {
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("url", fileService.upload(file));
|
||||
ajax.put("fileName", file.getOriginalFilename());
|
||||
return ajax;
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除文件")
|
||||
public AjaxResult remove(@RequestBody File file) {
|
||||
return fileService.delete(file.getUrl()) ? AjaxResult.success("文件删除成功") : AjaxResult.error("文件删除失败");
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.qiaoba.module.file.service;
|
||||
|
||||
import com.qiaoba.api.file.service.FileApiService;
|
||||
|
||||
/**
|
||||
* 文件管理 服务层
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/19 9:15
|
||||
*/
|
||||
public interface FileService extends FileApiService {
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.qiaoba.module.file.service.impl;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.qiaoba.common.base.constants.BaseConstant;
|
||||
import com.qiaoba.common.base.exceptions.ServiceException;
|
||||
import com.qiaoba.module.file.config.FileConfig;
|
||||
import com.qiaoba.module.file.service.FileService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 文件管理 服务层实现
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/19 9:15
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class FileServiceImpl implements FileService {
|
||||
|
||||
private FileConfig fileConfig;
|
||||
|
||||
@Override
|
||||
public String upload(MultipartFile file) {
|
||||
return com.qiaoba.module.file.utils.FileUtil.upload(file, fileConfig.getUploadPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(String path) {
|
||||
String localPath = fileConfig.getUploadPath() + StrUtil.removePrefix(path, BaseConstant.RESOURCE_PREFIX);
|
||||
if (FileUtil.isDirectory(localPath)) {
|
||||
throw new ServiceException("删除路径异常, 请勿非法操作");
|
||||
}
|
||||
return FileUtil.del(localPath);
|
||||
}
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
package com.qiaoba.module.file.utils;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.qiaoba.common.base.constants.BaseConstant;
|
||||
import com.qiaoba.common.base.exceptions.ServiceException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 文件工具类
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2021/10/25 0025 上午 9:15
|
||||
*/
|
||||
public class FileUtil {
|
||||
|
||||
private static final String[] DEFAULT_ALLOWED_EXTENSION = {
|
||||
// 图片
|
||||
"bmp", "gif", "jpg", "jpeg", "png",
|
||||
// word excel powerpoint
|
||||
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
|
||||
// 压缩文件
|
||||
"rar", "zip", "gz", "bz2",
|
||||
// 音频
|
||||
"mp3", "wav", "wma", "mp2", "flac", "midi", "ra", "ape", "aac", "cda", "mov",
|
||||
// 视频
|
||||
"mp4", "avi", "rmvb", "blob",
|
||||
// pdf
|
||||
"pdf"};
|
||||
|
||||
|
||||
/**
|
||||
* @param file 上传的文件
|
||||
* @return 文件全路径名称
|
||||
*/
|
||||
public static String upload(MultipartFile file, String path) {
|
||||
// 获取文件后缀名
|
||||
String extension = getExtension(file);
|
||||
// 判断是否允许上传
|
||||
isAllowedExtension(extension);
|
||||
// 重命名文件
|
||||
String fileName = extractFilename(extension);
|
||||
// 日期 + 格式 分类
|
||||
String dir = DateUtil.format(new Date(), "yyyy/MM/dd") + "/" + extension + "/";
|
||||
path = path + dir;
|
||||
// 新建文件
|
||||
File newFile = getAbsoluteFile(fileName, path);
|
||||
try {
|
||||
file.transferTo(newFile);
|
||||
return getPathFileName(fileName, path, dir);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new ServiceException("文件上传失败, 请联系管理员处理");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断文件类型是否是允许上传的类型
|
||||
*
|
||||
* @param extension 文件类型
|
||||
*/
|
||||
private static void isAllowedExtension(String extension) {
|
||||
boolean flag = true;
|
||||
for (String str : DEFAULT_ALLOWED_EXTENSION) {
|
||||
if (str.equalsIgnoreCase(extension)) {
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
throw new ServiceException("不允许上传该文件类型");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件名的后缀
|
||||
*
|
||||
* @param file 表单文件
|
||||
* @return 后缀名
|
||||
*/
|
||||
private static String getExtension(MultipartFile file) {
|
||||
String fileName = file.getOriginalFilename();
|
||||
if (StrUtil.isBlank(fileName)) {
|
||||
throw new ServiceException("上传文件-获取文件后缀名失败");
|
||||
}
|
||||
return fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码文件名(UUID去除-)
|
||||
*/
|
||||
private static String extractFilename(String extension) {
|
||||
return UUID.fastUUID().toString(true) + "." + extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文件
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return file
|
||||
*/
|
||||
private static File getAbsoluteFile(String fileName, String path) {
|
||||
File desc = new File(path + File.separator + fileName);
|
||||
|
||||
if (!desc.exists()) {
|
||||
if (!desc.getParentFile().exists()) {
|
||||
boolean result = desc.getParentFile().mkdirs();
|
||||
if (!result) {
|
||||
throw new ServiceException("上传文件-创建父目录失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
private static String getPathFileName(String fileName, String path, String dir) {
|
||||
int dirLastIndex = path.length() + 1;
|
||||
String currentDir = StringUtils.substring(path, dirLastIndex);
|
||||
return currentDir + BaseConstant.RESOURCE_PREFIX + "/" + dir + fileName;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"groups": [
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"name": "qiaoba.file-upload-path",
|
||||
"type": "java.lang.String"
|
||||
}
|
||||
],
|
||||
"hints": []
|
||||
}
|
1
qiaoba-modules/qiaoba-module-file/src/test/java/.gitkeep
Normal file
1
qiaoba-modules/qiaoba-module-file/src/test/java/.gitkeep
Normal file
@ -0,0 +1 @@
|
||||
null not found
|
@ -16,5 +16,9 @@
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-api-system</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.qiaoba</groupId>
|
||||
<artifactId>qiaoba-api-file</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -29,10 +29,11 @@ public class SysLoginController {
|
||||
private final SysMenuService sysMenuService;
|
||||
private final SysLoginService sysLoginService;
|
||||
|
||||
|
||||
@GetMapping("/captchaImage")
|
||||
public AjaxResult getCaptchaImage() {
|
||||
return sysLoginService.getCaptchaImage();
|
||||
AjaxResult result = AjaxResult.success();
|
||||
result.putAll(sysLoginService.getCaptchaImage());
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
@ -44,21 +45,20 @@ public class SysLoginController {
|
||||
}
|
||||
|
||||
@GetMapping("/getInfo")
|
||||
public String getInfo() {
|
||||
List<String> roleIds = SecurityUtil.getLoginUser().getRoleIds();
|
||||
public AjaxResult getInfo() {
|
||||
List<String> roles = SecurityUtil.getLoginUser().getRoleKeys();
|
||||
Set<String> permissions = SecurityUtil.getLoginUser().getPermissions();
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("permissions", permissions);
|
||||
ajax.put("roles", roleIds);
|
||||
ajax.put("user",sysLoginService.selectUserFromCache(SecurityUtil.getLoginUserId()));
|
||||
return "{\"msg\":\"操作成功\",\"code\":200,\"permissions\":[\"*:*:*\"],\"roles\":[\"admin\"],\"user\":{\"createBy\":\"admin\",\"createTime\":\"2023-04-23 16:11:38\",\"updateBy\":null,\"updateTime\":null,\"remark\":\"管理员\",\"userId\":1,\"deptId\":103,\"userName\":\"admin\",\"nickName\":\"若依\",\"email\":\"ry@163.com\",\"phonenumber\":\"15888888888\",\"sex\":\"1\",\"avatar\":\"\",\"password\":\"$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2\",\"status\":\"0\",\"delFlag\":\"0\",\"loginIp\":\"27.154.23.192\",\"loginDate\":\"2023-05-05T09:45:24.000+08:00\",\"dept\":{\"createBy\":null,\"createTime\":null,\"updateBy\":null,\"updateTime\":null,\"remark\":null,\"deptId\":103,\"parentId\":101,\"ancestors\":\"0,100,101\",\"deptName\":\"研发部门\",\"orderNum\":1,\"leader\":\"若依\",\"phone\":null,\"email\":null,\"status\":\"0\",\"delFlag\":null,\"parentName\":null,\"children\":[]},\"roles\":[{\"createBy\":null,\"createTime\":null,\"updateBy\":null,\"updateTime\":null,\"remark\":null,\"roleId\":1,\"roleName\":\"超级管理员\",\"roleKey\":\"admin\",\"roleSort\":1,\"dataScope\":\"1\",\"menuCheckStrictly\":false,\"deptCheckStrictly\":false,\"status\":\"0\",\"delFlag\":null,\"flag\":false,\"menuIds\":null,\"deptIds\":null,\"permissions\":null,\"admin\":true}],\"roleIds\":null,\"postIds\":null,\"roleId\":null,\"admin\":true}}";
|
||||
ajax.put("roles", roles);
|
||||
ajax.put("user", SecurityUtil.getLoginUser());
|
||||
return ajax;
|
||||
}
|
||||
|
||||
@GetMapping("/getRouters")
|
||||
public Object getRouters() {
|
||||
List<SysMenuVo> sysMenuVos = sysMenuService.selectByUserId("1650123803828019202");
|
||||
public AjaxResult getRouters() {
|
||||
List<SysMenuVo> sysMenuVos = sysMenuService.selectByUserId(SecurityUtil.getLoginUserId());
|
||||
return AjaxResult.success(sysMenuService.menusToRouters(sysMenuVos));
|
||||
//return "{\"msg\":\"操作成功\",\"code\":200,\"data\":[{\"name\":\"System\",\"path\":\"/system\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"Layout\",\"alwaysShow\":true,\"meta\":{\"title\":\"系统管理\",\"icon\":\"system\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"User\",\"path\":\"user\",\"hidden\":false,\"component\":\"system/user/index\",\"meta\":{\"title\":\"用户管理\",\"icon\":\"user\",\"noCache\":false,\"link\":null}},{\"name\":\"Role\",\"path\":\"role\",\"hidden\":false,\"component\":\"system/role/index\",\"meta\":{\"title\":\"角色管理\",\"icon\":\"peoples\",\"noCache\":false,\"link\":null}},{\"name\":\"Menu\",\"path\":\"menu\",\"hidden\":false,\"component\":\"system/menu/index\",\"meta\":{\"title\":\"菜单管理\",\"icon\":\"tree-table\",\"noCache\":false,\"link\":null}},{\"name\":\"Dept\",\"path\":\"dept\",\"hidden\":false,\"component\":\"system/dept/index\",\"meta\":{\"title\":\"部门管理\",\"icon\":\"tree\",\"noCache\":false,\"link\":null}},{\"name\":\"Post\",\"path\":\"post\",\"hidden\":false,\"component\":\"system/post/index\",\"meta\":{\"title\":\"岗位管理\",\"icon\":\"post\",\"noCache\":false,\"link\":null}},{\"name\":\"Dict\",\"path\":\"dict\",\"hidden\":false,\"component\":\"system/dict/index\",\"meta\":{\"title\":\"字典管理\",\"icon\":\"dict\",\"noCache\":false,\"link\":null}},{\"name\":\"Config\",\"path\":\"config\",\"hidden\":false,\"component\":\"system/config/index\",\"meta\":{\"title\":\"参数设置\",\"icon\":\"edit\",\"noCache\":false,\"link\":null}},{\"name\":\"Notice\",\"path\":\"notice\",\"hidden\":false,\"component\":\"system/notice/index\",\"meta\":{\"title\":\"通知公告\",\"icon\":\"message\",\"noCache\":false,\"link\":null}},{\"name\":\"Log\",\"path\":\"log\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"ParentView\",\"alwaysShow\":true,\"meta\":{\"title\":\"日志管理\",\"icon\":\"log\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"Operlog\",\"path\":\"operlog\",\"hidden\":false,\"component\":\"monitor/operlog/index\",\"meta\":{\"title\":\"操作日志\",\"icon\":\"form\",\"noCache\":false,\"link\":null}},{\"name\":\"Logininfor\",\"path\":\"logininfor\",\"hidden\":false,\"component\":\"monitor/logininfor/index\",\"meta\":{\"title\":\"登录日志\",\"icon\":\"logininfor\",\"noCache\":false,\"link\":null}}]}]},{\"name\":\"Monitor\",\"path\":\"/monitor\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"Layout\",\"alwaysShow\":true,\"meta\":{\"title\":\"系统监控\",\"icon\":\"monitor\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"Online\",\"path\":\"online\",\"hidden\":false,\"component\":\"monitor/online/index\",\"meta\":{\"title\":\"在线用户\",\"icon\":\"online\",\"noCache\":false,\"link\":null}},{\"name\":\"Job\",\"path\":\"job\",\"hidden\":false,\"component\":\"monitor/job/index\",\"meta\":{\"title\":\"定时任务\",\"icon\":\"job\",\"noCache\":false,\"link\":null}},{\"name\":\"Druid\",\"path\":\"druid\",\"hidden\":false,\"component\":\"monitor/druid/index\",\"meta\":{\"title\":\"数据监控\",\"icon\":\"druid\",\"noCache\":false,\"link\":null}},{\"name\":\"Server\",\"path\":\"server\",\"hidden\":false,\"component\":\"monitor/server/index\",\"meta\":{\"title\":\"服务监控\",\"icon\":\"server\",\"noCache\":false,\"link\":null}},{\"name\":\"Cache\",\"path\":\"cache\",\"hidden\":false,\"component\":\"monitor/cache/index\",\"meta\":{\"title\":\"缓存监控\",\"icon\":\"redis\",\"noCache\":false,\"link\":null}},{\"name\":\"CacheList\",\"path\":\"cacheList\",\"hidden\":false,\"component\":\"monitor/cache/list\",\"meta\":{\"title\":\"缓存列表\",\"icon\":\"redis-list\",\"noCache\":false,\"link\":null}}]},{\"name\":\"Tool\",\"path\":\"/tool\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"Layout\",\"alwaysShow\":true,\"meta\":{\"title\":\"系统工具\",\"icon\":\"tool\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"Build\",\"path\":\"build\",\"hidden\":false,\"component\":\"tool/build/index\",\"meta\":{\"title\":\"表单构建\",\"icon\":\"build\",\"noCache\":false,\"link\":null}},{\"name\":\"Gen\",\"path\":\"gen\",\"hidden\":false,\"component\":\"tool/gen/index\",\"meta\":{\"title\":\"代码生成\",\"icon\":\"code\",\"noCache\":false,\"link\":null}},{\"name\":\"Swagger\",\"path\":\"swagger\",\"hidden\":false,\"component\":\"tool/swagger/index\",\"meta\":{\"title\":\"系统接口\",\"icon\":\"swagger\",\"noCache\":false,\"link\":null}}]},{\"name\":\"Http://ruoyi.vip\",\"path\":\"http://ruoyi.vip\",\"hidden\":false,\"component\":\"Layout\",\"meta\":{\"title\":\"若依官网\",\"icon\":\"guide\",\"noCache\":false,\"link\":\"http://ruoyi.vip\"}}]}";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
package com.qiaoba.module.system.controller;
|
||||
|
||||
import com.qiaoba.api.system.entity.dto.ResetUserBasicInfoDto;
|
||||
import com.qiaoba.auth.utils.SecurityUtil;
|
||||
import com.qiaoba.common.base.result.AjaxResult;
|
||||
import com.qiaoba.module.system.service.SysProfileService;
|
||||
import com.qiaoba.module.system.service.SysUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 个人信息 Web层
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/19 11:25
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/user/profile")
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "用户管理-个人中心")
|
||||
public class SysProfileController {
|
||||
|
||||
private final SysProfileService sysProfileService;
|
||||
private final SysUserService sysUserService;
|
||||
|
||||
@GetMapping
|
||||
@Operation(summary = "基本信息")
|
||||
public AjaxResult profile() {
|
||||
String username = SecurityUtil.getLoginUserId();
|
||||
AjaxResult ajax = AjaxResult.success(sysUserService.selectById(username, false));
|
||||
// todo
|
||||
ajax.put("roleGroup", "超级管理员,普通角色");
|
||||
ajax.put("postGroup", "董事长");
|
||||
return ajax;
|
||||
}
|
||||
|
||||
@PutMapping("/update-avatar")
|
||||
@Operation(summary = "更改头像")
|
||||
public AjaxResult updateAvatar(@RequestParam("file") MultipartFile file) {
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("imgUrl", sysProfileService.updateAvatar(file));
|
||||
return ajax;
|
||||
}
|
||||
|
||||
@PutMapping("/update-password")
|
||||
@Operation(summary = "更改密码")
|
||||
public AjaxResult updatePassword(String oldPassword, String newPassword) {
|
||||
sysProfileService.updatePassword(oldPassword, newPassword);
|
||||
return AjaxResult.success("密码更改成功");
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "更改信息")
|
||||
public AjaxResult updateBasicInfo(@RequestBody ResetUserBasicInfoDto dto) {
|
||||
sysProfileService.updateBasicInfo(dto);
|
||||
return AjaxResult.success("基本信息更改成功");
|
||||
}
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
package com.qiaoba.module.system.controller;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.qiaoba.api.system.entity.SysRole;
|
||||
import com.qiaoba.api.system.entity.SysUser;
|
||||
import com.qiaoba.api.system.entity.dto.ResetPwdDto;
|
||||
import com.qiaoba.api.system.entity.dto.ResetPasswordDto;
|
||||
import com.qiaoba.api.system.entity.dto.ResetUserStatusDto;
|
||||
import com.qiaoba.api.system.entity.dto.SysUserDto;
|
||||
import com.qiaoba.api.system.entity.param.SysPostParam;
|
||||
@ -70,15 +71,18 @@ public class SysUserController {
|
||||
@PreAuthorize("hasAuthority('system:user:resetPwd')")
|
||||
@PutMapping("/resetPwd")
|
||||
@Operation(summary = "重置密码")
|
||||
public AjaxResult resetPwd(@RequestBody ResetPwdDto dto) {
|
||||
return AjaxResult.toAjax(sysUserService.resetPwd(dto));
|
||||
public AjaxResult resetPwd(@RequestBody ResetPasswordDto dto) {
|
||||
SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class);
|
||||
sysUser.setPassword(SecurityUtil.encryptPassword(dto.getPassword()));
|
||||
return AjaxResult.toAjax(sysUserService.updateById(sysUser));
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('system:user:edit')")
|
||||
@PutMapping("/changeStatus")
|
||||
@Operation(summary = "更改状态")
|
||||
public AjaxResult changeStatus(@RequestBody ResetUserStatusDto dto) {
|
||||
return AjaxResult.toAjax(sysUserService.updateUserStatus(dto));
|
||||
SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class);
|
||||
return AjaxResult.toAjax(sysUserService.updateById(sysUser));
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('system:user:remove')")
|
||||
@ -154,15 +158,4 @@ public class SysUserController {
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 个人中心-个人信息
|
||||
*/
|
||||
@GetMapping("/profile")
|
||||
public AjaxResult profile() {
|
||||
String username = SecurityUtil.getLoginUserId();
|
||||
AjaxResult ajax = AjaxResult.success(sysUserService.selectById(username, false));
|
||||
ajax.put("roleGroup", "超级管理员,普通角色");
|
||||
ajax.put("postGroup", "董事长");
|
||||
return ajax;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,15 @@ public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
|
||||
*/
|
||||
List<String> selectRoleIdsByUserId(@Param("userId") String userId, @Param("status") String status);
|
||||
|
||||
/**
|
||||
* 通过userId查询所绑定的角色Key列表
|
||||
*
|
||||
* @param userId userId
|
||||
* @param status 状态
|
||||
* @return roleIds
|
||||
*/
|
||||
List<String> selectRoleKeysByUserId(@Param("userId") String userId, @Param("status") String status);
|
||||
|
||||
/**
|
||||
* 批量取消角色所绑定的用户
|
||||
*
|
||||
|
@ -4,6 +4,8 @@ import com.qiaoba.api.system.entity.SysUser;
|
||||
import com.qiaoba.api.system.entity.dto.LoginDto;
|
||||
import com.qiaoba.common.base.result.AjaxResult;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 登录 服务层
|
||||
*
|
||||
@ -18,7 +20,7 @@ public interface SysLoginService {
|
||||
*
|
||||
* @return uuid + base64
|
||||
*/
|
||||
AjaxResult getCaptchaImage();
|
||||
Map<String, Object> getCaptchaImage();
|
||||
|
||||
/**
|
||||
* 登录
|
||||
@ -28,11 +30,4 @@ public interface SysLoginService {
|
||||
*/
|
||||
String login(LoginDto dto);
|
||||
|
||||
/**
|
||||
* 从缓存中读取user
|
||||
*
|
||||
* @param userId userId
|
||||
* @return SysUser
|
||||
*/
|
||||
SysUser selectUserFromCache(String userId);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.qiaoba.module.system.service;
|
||||
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.qiaoba.api.system.entity.SysMenu;
|
||||
import com.qiaoba.api.system.entity.vo.RouterVo;
|
||||
import com.qiaoba.api.system.entity.vo.SysMenuVo;
|
||||
import com.qiaoba.api.system.service.SysMenuApiService;
|
||||
@ -37,6 +36,7 @@ public interface SysMenuService extends SysMenuApiService {
|
||||
|
||||
/**
|
||||
* 通过 userId 查询目录和菜单
|
||||
*
|
||||
* @param userId userId
|
||||
* @return list
|
||||
*/
|
||||
|
@ -1,11 +1,8 @@
|
||||
package com.qiaoba.module.system.service;
|
||||
|
||||
import com.qiaoba.api.system.entity.SysPost;
|
||||
import com.qiaoba.api.system.entity.SysRole;
|
||||
import com.qiaoba.api.system.entity.param.SysPostParam;
|
||||
import com.qiaoba.api.system.entity.param.SysRoleParam;
|
||||
import com.qiaoba.api.system.service.SysPostApiService;
|
||||
import com.qiaoba.api.system.service.SysRoleApiService;
|
||||
import com.qiaoba.common.database.entity.PageQuery;
|
||||
import com.qiaoba.common.database.entity.TableDataInfo;
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
package com.qiaoba.module.system.service;
|
||||
|
||||
import com.qiaoba.api.system.entity.dto.ResetUserBasicInfoDto;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 个人信息 服务层
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/19 11:28
|
||||
*/
|
||||
public interface SysProfileService {
|
||||
|
||||
/**
|
||||
* 更新个人头像
|
||||
*
|
||||
* @param file file
|
||||
* @return 头像链接
|
||||
*/
|
||||
String updateAvatar(MultipartFile file);
|
||||
|
||||
/**
|
||||
* 更改密码
|
||||
*
|
||||
* @param oldPassword 旧密码
|
||||
* @param newPassword 新密码
|
||||
*/
|
||||
void updatePassword(String oldPassword, String newPassword);
|
||||
|
||||
/**
|
||||
* 更改基本信息
|
||||
*
|
||||
* @param dto dto
|
||||
*/
|
||||
void updateBasicInfo(ResetUserBasicInfoDto dto);
|
||||
}
|
@ -51,6 +51,15 @@ public interface SysUserRoleService {
|
||||
*/
|
||||
List<String> selectRoleIdsByUserId(String userId, String status);
|
||||
|
||||
/**
|
||||
* 通过userId查询所绑定的角色Key列表
|
||||
*
|
||||
* @param userId userId
|
||||
* @param status 状态
|
||||
* @return roleIds
|
||||
*/
|
||||
List<String> selectRoleKeysByUserId(String userId, String status);
|
||||
|
||||
/**
|
||||
* 批量选择用户授权
|
||||
*
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.qiaoba.module.system.service;
|
||||
|
||||
import com.qiaoba.api.system.entity.SysUser;
|
||||
import com.qiaoba.api.system.entity.dto.ResetPwdDto;
|
||||
import com.qiaoba.api.system.entity.param.SysUserParam;
|
||||
import com.qiaoba.api.system.entity.vo.SysUserVo;
|
||||
import com.qiaoba.api.system.service.SysUserApiService;
|
||||
|
@ -3,25 +3,26 @@ package com.qiaoba.module.system.service.impl;
|
||||
import cn.hutool.captcha.CaptchaUtil;
|
||||
import cn.hutool.captcha.LineCaptcha;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.qiaoba.api.system.entity.SysUser;
|
||||
import com.qiaoba.api.system.entity.dto.LoginDto;
|
||||
import com.qiaoba.api.system.service.SysUserDetailsApiService;
|
||||
import com.qiaoba.auth.constants.SecurityConstant;
|
||||
import com.qiaoba.auth.utils.SecurityUtil;
|
||||
import com.qiaoba.auth.utils.TokenUtil;
|
||||
import com.qiaoba.common.base.enums.BaseEnum;
|
||||
import com.qiaoba.common.base.exceptions.ServiceException;
|
||||
import com.qiaoba.common.base.result.AjaxResult;
|
||||
import com.qiaoba.common.redis.service.RedisService;
|
||||
import com.qiaoba.module.system.service.SysLoginService;
|
||||
import com.qiaoba.module.system.service.SysUserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 登录 服务层实现
|
||||
@ -36,24 +37,26 @@ public class SysLoginServiceImpl implements SysLoginService {
|
||||
|
||||
private final RedisService redisService;
|
||||
private final HttpServletRequest request;
|
||||
private final UserDetailsService userDetailsService;
|
||||
private final SysUserDetailsApiService userDetailsService;
|
||||
private final SysUserService sysUserService;
|
||||
|
||||
@Override
|
||||
public AjaxResult getCaptchaImage() {
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("register", getRegisterConfig());
|
||||
public Map<String, Object> getCaptchaImage() {
|
||||
Map<String, Object> map = new HashMap<String, Object>(4);
|
||||
|
||||
map.put("register", getRegisterConfig());
|
||||
if (!getCaptchaConfig()) {
|
||||
ajax.put("captchaEnabled", false);
|
||||
return ajax;
|
||||
map.put("captchaEnabled", false);
|
||||
return map;
|
||||
}
|
||||
|
||||
String uuid = UUID.randomUUID().toString(true);
|
||||
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(150, 50, 4, 20);
|
||||
ajax.put("uuid", uuid);
|
||||
ajax.put("img", captcha.getImageBase64());
|
||||
map.put("uuid", uuid);
|
||||
map.put("img", captcha.getImageBase64());
|
||||
redisService.set(SecurityConstant.CAPTCHA_KEY + uuid, captcha.getCode(), 120);
|
||||
|
||||
return ajax;
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -67,27 +70,15 @@ public class SysLoginServiceImpl implements SysLoginService {
|
||||
// 检验密码
|
||||
validatePassword(dto.getUsername(), sysUser.getPassword(), dto.getPassword());
|
||||
// 缓存user
|
||||
addUserToCache(sysUser);
|
||||
// 创建UserDetails
|
||||
UserDetails userDetails = userDetailsService.loadUserByUsername(dto.getUsername());
|
||||
userDetailsService.toCache(sysUser.getUsername());
|
||||
// 生成Token
|
||||
return TokenUtil.generateToken(userDetails.getUsername());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysUser selectUserFromCache(String userId) {
|
||||
return redisService.getObject(userId, SysUser.class);
|
||||
}
|
||||
|
||||
private void addUserToCache(SysUser sysUser) {
|
||||
sysUser.setPassword(null);
|
||||
redisService.set(sysUser.getUserId(), sysUser);
|
||||
return TokenUtil.generateToken(sysUser.getUsername());
|
||||
}
|
||||
|
||||
private void validatePassword(String username, String password, String inputPassword) {
|
||||
boolean result = SecurityUtil.matchesPassword(inputPassword, password);
|
||||
if (!result) {
|
||||
beforePasswordError(username);
|
||||
ThreadUtil.execAsync(() -> beforePasswordError(username));
|
||||
throw new ServiceException(SecurityConstant.PASSWORD_ERROR);
|
||||
}
|
||||
}
|
||||
@ -105,7 +96,7 @@ public class SysLoginServiceImpl implements SysLoginService {
|
||||
}
|
||||
|
||||
private boolean getCaptchaConfig() {
|
||||
return false;
|
||||
return true;
|
||||
/* try {
|
||||
return SecurityConstant.CAPTCHA_ON.equals(redisService.get(SecurityConstant.CAPTCHA_ON_OFF_KEY));
|
||||
} catch (Exception e) {
|
||||
@ -114,7 +105,7 @@ public class SysLoginServiceImpl implements SysLoginService {
|
||||
}
|
||||
|
||||
private boolean getRegisterConfig() {
|
||||
return false;
|
||||
return true;
|
||||
/* try {
|
||||
return SecurityConstant.REGISTER_ON.equals(redisService.get(SecurityConstant.REGISTER_ON_OFF_KEY));
|
||||
} catch (Exception e) {
|
||||
|
@ -5,10 +5,10 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.qiaoba.api.system.entity.SysPost;
|
||||
import com.qiaoba.api.system.entity.param.SysPostParam;
|
||||
import com.qiaoba.auth.utils.SecurityUtil;
|
||||
import com.qiaoba.common.base.exceptions.ServiceException;
|
||||
import com.qiaoba.common.database.entity.PageQuery;
|
||||
import com.qiaoba.common.database.entity.TableDataInfo;
|
||||
import com.qiaoba.auth.utils.SecurityUtil;
|
||||
import com.qiaoba.module.system.mapper.SysPostMapper;
|
||||
import com.qiaoba.module.system.service.SysPostService;
|
||||
import com.qiaoba.module.system.service.SysUserPostService;
|
||||
|
@ -0,0 +1,62 @@
|
||||
package com.qiaoba.module.system.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.qiaoba.api.file.service.FileApiService;
|
||||
import com.qiaoba.api.system.entity.SysUser;
|
||||
import com.qiaoba.api.system.entity.dto.ResetUserBasicInfoDto;
|
||||
import com.qiaoba.auth.utils.SecurityUtil;
|
||||
import com.qiaoba.common.base.exceptions.ServiceException;
|
||||
import com.qiaoba.module.system.service.SysProfileService;
|
||||
import com.qiaoba.module.system.service.SysUserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 个人信息 服务层实现
|
||||
*
|
||||
* @author ailanyin
|
||||
* @version 1.0
|
||||
* @since 2023/5/19 11:29
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysProfileServiceImpl implements SysProfileService {
|
||||
|
||||
private final FileApiService fileService;
|
||||
private final SysUserService sysUserService;
|
||||
|
||||
@Override
|
||||
public String updateAvatar(MultipartFile file) {
|
||||
String url = fileService.upload(file);
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setUserId(SecurityUtil.getLoginUserId());
|
||||
sysUser.setAvatar(url);
|
||||
if (sysUserService.updateById(sysUser) == 0) {
|
||||
fileService.delete(url);
|
||||
throw new ServiceException("修改头像失败");
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePassword(String oldPassword, String newPassword) {
|
||||
String userId = SecurityUtil.getLoginUserId();
|
||||
String password = sysUserService.selectById(userId, true).getPassword();
|
||||
if (!SecurityUtil.matchesPassword(oldPassword, password)) {
|
||||
throw new ServiceException("旧密码错误, 请重新输入");
|
||||
}
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setUserId(SecurityUtil.getLoginUserId());
|
||||
sysUser.setPassword(SecurityUtil.encryptPassword(newPassword));
|
||||
sysUserService.updateById(sysUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBasicInfo(ResetUserBasicInfoDto dto) {
|
||||
SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class);
|
||||
sysUser.setUserId(SecurityUtil.getLoginUserId());
|
||||
sysUserService.checkAddOrUpdate(sysUser);
|
||||
sysUserService.updateById(sysUser);
|
||||
}
|
||||
}
|
@ -10,10 +10,10 @@ import com.qiaoba.api.system.entity.SysRoleMenu;
|
||||
import com.qiaoba.api.system.entity.dto.DataScopeDto;
|
||||
import com.qiaoba.api.system.entity.dto.SysRoleDto;
|
||||
import com.qiaoba.api.system.entity.param.SysRoleParam;
|
||||
import com.qiaoba.auth.utils.SecurityUtil;
|
||||
import com.qiaoba.common.base.exceptions.ServiceException;
|
||||
import com.qiaoba.common.database.entity.PageQuery;
|
||||
import com.qiaoba.common.database.entity.TableDataInfo;
|
||||
import com.qiaoba.auth.utils.SecurityUtil;
|
||||
import com.qiaoba.module.system.mapper.SysRoleMapper;
|
||||
import com.qiaoba.module.system.service.SysRoleDeptService;
|
||||
import com.qiaoba.module.system.service.SysRoleMenuService;
|
||||
|
@ -3,10 +3,9 @@ package com.qiaoba.module.system.service.impl;
|
||||
import com.qiaoba.api.system.entity.SysTenant;
|
||||
import com.qiaoba.module.system.mapper.SysTenantMapper;
|
||||
import com.qiaoba.module.system.service.SysTenantService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 租户管理 业务层实现
|
||||
*
|
||||
@ -15,18 +14,18 @@ import javax.annotation.Resource;
|
||||
* @since 2023-04-24 19:46:00
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysTenantServiceImpl implements SysTenantService {
|
||||
|
||||
@Resource
|
||||
private SysTenantMapper baseMapper;
|
||||
private final SysTenantMapper sysTenantMapper;
|
||||
|
||||
@Override
|
||||
public int insert(SysTenant sysTenant) {
|
||||
return baseMapper.insert(sysTenant);
|
||||
return sysTenantMapper.insert(sysTenant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(SysTenant sysTenant) {
|
||||
return baseMapper.updateById(sysTenant);
|
||||
return sysTenantMapper.updateById(sysTenant);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,14 @@
|
||||
package com.qiaoba.module.system.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.qiaoba.api.system.entity.SysUser;
|
||||
import com.qiaoba.api.system.service.SysUserDetailsApiService;
|
||||
import com.qiaoba.auth.constants.SecurityConstant;
|
||||
import com.qiaoba.auth.entity.LoginUser;
|
||||
import com.qiaoba.auth.entity.SecurityUser;
|
||||
import com.qiaoba.common.base.enums.BaseEnum;
|
||||
import com.qiaoba.common.redis.service.RedisService;
|
||||
import com.qiaoba.module.system.service.SysMenuService;
|
||||
import com.qiaoba.module.system.service.SysUserRoleService;
|
||||
import com.qiaoba.module.system.service.SysUserService;
|
||||
@ -25,23 +30,36 @@ import java.util.Set;
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysUserDetailsServiceImpl implements UserDetailsService {
|
||||
public class SysUserDetailsServiceImpl implements UserDetailsService, SysUserDetailsApiService {
|
||||
|
||||
private final SysUserService sysUserService;
|
||||
private final SysMenuService sysMenuService;
|
||||
private final SysUserRoleService sysUserRoleService;
|
||||
private final RedisService redisService;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
SysUser user = sysUserService.selectByUsername(username);
|
||||
return createUserDetails(user);
|
||||
if (redisService.hasKey(SecurityConstant.USER_DETAILS_REDIS_KEY + username)) {
|
||||
SecurityUser user = redisService.getObject(SecurityConstant.USER_DETAILS_REDIS_KEY + username, SecurityUser.class);
|
||||
return new LoginUser(user.getUserId(), user.getDeptId(), user.getUsername(), user.getNickname(), user.getRoleKeys(), user.getPermissions());
|
||||
}
|
||||
|
||||
return toCache(username);
|
||||
}
|
||||
|
||||
|
||||
private UserDetails createUserDetails(SysUser user) {
|
||||
Set<String> perms = sysMenuService.selectPermsByUserId(user.getUserId());
|
||||
List<String> roleIds = sysUserRoleService.selectRoleIdsByUserId(user.getUserId(), BaseEnum.NORMAL.getCode());
|
||||
return new LoginUser(user.getUserId(), user.getDeptId(), user.getUsername(), user.getNickname(), roleIds, perms);
|
||||
List<String> roleKeys = sysUserRoleService.selectRoleKeysByUserId(user.getUserId(), BaseEnum.NORMAL.getCode());
|
||||
return new LoginUser(user.getUserId(), user.getDeptId(), user.getUsername(), user.getNickname(), roleKeys, perms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails toCache(String username) {
|
||||
SysUser user = sysUserService.selectByUsername(username);
|
||||
UserDetails details = createUserDetails(user);
|
||||
SecurityUser securityUser = BeanUtil.copyProperties(details, SecurityUser.class);
|
||||
redisService.set(SecurityConstant.USER_DETAILS_REDIS_KEY + username, securityUser);
|
||||
return details;
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,14 @@ package com.qiaoba.module.system.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.qiaoba.api.system.entity.SysUser;
|
||||
import com.qiaoba.api.system.entity.dto.SysUserDto;
|
||||
import com.qiaoba.auth.utils.SecurityUtil;
|
||||
import com.qiaoba.common.base.constants.BaseConstant;
|
||||
import com.qiaoba.common.base.exceptions.ServiceException;
|
||||
import com.qiaoba.common.base.utils.ObjectUtil;
|
||||
import com.qiaoba.module.system.service.SysUserImportService;
|
||||
import com.qiaoba.module.system.service.SysUserService;
|
||||
import com.qiaoba.module.system.templates.SysUserImport;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -27,7 +25,7 @@ import java.util.stream.Collectors;
|
||||
* @since 2023/5/18 14:50
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
@RequiredArgsConstructor
|
||||
public class SysUserImportServiceImpl implements SysUserImportService {
|
||||
|
||||
private final SysUserService sysUserService;
|
||||
|
@ -49,6 +49,11 @@ public class SysUserRoleServiceImpl implements SysUserRoleService {
|
||||
return sysUserRoleMapper.selectRoleIdsByUserId(userId, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> selectRoleKeysByUserId(String userId, String status) {
|
||||
return sysUserRoleMapper.selectRoleKeysByUserId(userId, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAuthUsers(String roleId, List<String> userIds) {
|
||||
List<SysUserRole> list = new ArrayList<>();
|
||||
|
@ -9,13 +9,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.qiaoba.api.system.entity.SysUser;
|
||||
import com.qiaoba.api.system.entity.SysUserPost;
|
||||
import com.qiaoba.api.system.entity.SysUserRole;
|
||||
import com.qiaoba.api.system.entity.dto.ResetPwdDto;
|
||||
import com.qiaoba.api.system.entity.dto.ResetUserStatusDto;
|
||||
import com.qiaoba.api.system.entity.dto.SysUserDto;
|
||||
import com.qiaoba.api.system.entity.param.SysUserParam;
|
||||
import com.qiaoba.api.system.entity.vo.SysUserVo;
|
||||
import com.qiaoba.auth.utils.SecurityUtil;
|
||||
import com.qiaoba.common.base.enums.BaseEnum;
|
||||
import com.qiaoba.common.base.exceptions.ServiceException;
|
||||
import com.qiaoba.common.database.entity.PageQuery;
|
||||
import com.qiaoba.common.database.entity.TableDataInfo;
|
||||
@ -83,18 +80,6 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
return sysUserMapper.selectOne(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int resetPwd(ResetPwdDto dto) {
|
||||
SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class);
|
||||
sysUser.setPassword(SecurityUtil.encryptPassword(dto.getPassword()));
|
||||
return sysUserMapper.updateById(sysUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateUserStatus(ResetUserStatusDto dto) {
|
||||
SysUser sysUser = BeanUtil.copyProperties(dto, SysUser.class);
|
||||
return sysUserMapper.updateById(sysUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@ -150,6 +135,11 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
sysUserRoleService.insertBatch(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateById(SysUser sysUser) {
|
||||
return sysUserMapper.updateById(sysUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysUserExport> selectExportData(SysUserParam param) {
|
||||
List<SysUserExport> list = sysUserMapper.selectExportData(param);
|
||||
@ -188,15 +178,16 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
return sysUser;
|
||||
}
|
||||
|
||||
private void checkAddOrUpdate(SysUser sysUser) {
|
||||
if (checkUsernameNotUnique(sysUser)) {
|
||||
throw new ServiceException(StrUtil.format("新增或修改用户'{}'失败,登录账号已存在", sysUser.getUsername()));
|
||||
@Override
|
||||
public void checkAddOrUpdate(SysUser sysUser) {
|
||||
if (StrUtil.isNotBlank(sysUser.getUsername()) && checkUsernameNotUnique(sysUser)) {
|
||||
throw new ServiceException("登录账号已存在");
|
||||
}
|
||||
if (StrUtil.isNotBlank(sysUser.getPhone()) && checkPhoneNotUnique(sysUser)) {
|
||||
throw new ServiceException(StrUtil.format("新增或修改用户'{}'失败,手机号已存在", sysUser.getUsername()));
|
||||
throw new ServiceException("手机号已存在");
|
||||
}
|
||||
if (StrUtil.isNotBlank(sysUser.getEmail()) && checkEmailNotUnique(sysUser)) {
|
||||
throw new ServiceException(StrUtil.format("新增或修改用户'{}'失败,邮箱号已存在", sysUser.getUsername()));
|
||||
throw new ServiceException("邮箱号已存在");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,9 +3,6 @@ package com.qiaoba.module.system.templates;
|
||||
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户导入模板
|
||||
*
|
||||
|
@ -73,7 +73,8 @@
|
||||
</select>
|
||||
|
||||
<select id="selectExportData" resultMap="ExportData">
|
||||
select t1.user_id, t1.username, t1.nickname, t1.email, t1.phone, t1.gender, t1.status,t1.create_time, t2.dept_name,t4.role_name,t6.post_name
|
||||
select t1.user_id, t1.username, t1.nickname, t1.email, t1.phone, t1.gender, t1.status,t1.create_time,
|
||||
t2.dept_name,t4.role_name,t6.post_name
|
||||
from sys_user t1
|
||||
left join sys_dept t2 on t1.dept_id = t2.dept_id
|
||||
left join sys_user_role t3 on t1.user_id = t3.user_id
|
||||
@ -124,13 +125,15 @@
|
||||
</select>
|
||||
|
||||
<select id="selectUnAllocatedList" resultMap="SysUserVoResult">
|
||||
select distinct t1.user_id, t2.dept_name, t1.username, t1.nickname, t1.email, t1.phone, t1.status, t1.create_time
|
||||
select distinct t1.user_id, t2.dept_name, t1.username, t1.nickname, t1.email, t1.phone, t1.status,
|
||||
t1.create_time
|
||||
from sys_user t1
|
||||
left join sys_dept t2 on t1.dept_id = t2.dept_id
|
||||
left join sys_user_role t3 on t1.user_id = t3.user_id
|
||||
left join sys_role t4 on t4.role_id = t3.role_id
|
||||
where (t4.role_id != #{param.roleId} or t4.role_id IS NULL)
|
||||
and t1.user_id not in (select t1.user_id from sys_user t1 inner join sys_user_role t3 on t1.user_id = t3.user_id and
|
||||
and t1.user_id not in (select t1.user_id from sys_user t1 inner join sys_user_role t3 on t1.user_id = t3.user_id
|
||||
and
|
||||
t3.role_id = #{param.roleId})
|
||||
<if test="param.username != null and param.username != ''">
|
||||
AND t1.username like concat('%', #{param.username}, '%')
|
||||
|
@ -13,6 +13,15 @@
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="selectRoleKeysByUserId" resultType="string">
|
||||
select t2.role_key from sys_user_role t1
|
||||
left join sys_role t2 on t2.role_id = t1.role_id
|
||||
where t1.user_id = #{userId}
|
||||
<if test="status != null and status != ''">
|
||||
and t2.status = #{status}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<delete id="deleteByRoleIdAndUserIds">
|
||||
delete from sys_user_role where role_id = #{roleId} and user_id in
|
||||
<foreach collection="list" item="userId" open="(" separator="," close=")">
|
||||
|
Reference in New Issue
Block a user