mirror of https://gitee.com/xiaonuobase/snowy
parent
550a118068
commit
9dd127479a
54
pom.xml
54
pom.xml
|
@ -245,21 +245,28 @@
|
|||
<version>3.3.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-token-core -->
|
||||
<!-- json-flattener -->
|
||||
<dependency>
|
||||
<groupId>com.github.wnameless.json</groupId>
|
||||
<artifactId>json-flattener</artifactId>
|
||||
<version>0.16.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- sa-token-core -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-core</artifactId>
|
||||
<version>1.37.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-token -->
|
||||
<!-- sa-token -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot3-starter</artifactId>
|
||||
<version>1.37.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-token 整合 redis (使用jackson序列化方式) -->
|
||||
<!-- sa-token 整合 redis (使用jackson序列化方式) -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-redis-jackson</artifactId>
|
||||
|
@ -343,25 +350,18 @@
|
|||
<version>3.1.944</version>
|
||||
</dependency>
|
||||
|
||||
<!--阿里云短信sdk-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dysmsapi20170525</artifactId>
|
||||
<version>2.0.24</version>
|
||||
</dependency>
|
||||
|
||||
<!--腾讯云短信sdk-->
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java-sms</artifactId>
|
||||
<version>3.1.893</version>
|
||||
</dependency>
|
||||
|
||||
<!-- sms4j短信sdk -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.sms4j</groupId>
|
||||
<artifactId>sms4j-javase-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<version>3.3.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- sms4j消息推送sdk -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.sms4j</groupId>
|
||||
<artifactId>sms4j-oa-core</artifactId>
|
||||
<version>3.3.4</version>
|
||||
</dependency>
|
||||
|
||||
<!--系统硬件信息-->
|
||||
|
@ -371,6 +371,14 @@
|
|||
<version>6.4.11</version>
|
||||
</dependency>
|
||||
|
||||
<!-- junit -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.10.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- dynamic-datasource -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
|
@ -432,7 +440,7 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.12.1</version>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
|
@ -461,11 +469,19 @@
|
|||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>_sql/*</exclude>
|
||||
<exclude>*.md</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*.xml</include>
|
||||
<include>**/*.ttf</include>
|
||||
<include>**/*.ttc</include>
|
||||
<include>**/*.TTF</include>
|
||||
<include>**/*.TTC</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
|
|
|
@ -129,5 +129,11 @@
|
|||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>easyexcel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- json-flattener -->
|
||||
<dependency>
|
||||
<groupId>com.github.wnameless.json</groupId>
|
||||
<artifactId>json-flattener</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -58,21 +58,13 @@ public class CommonCacheOperator {
|
|||
|
||||
public Collection<String> getAllKeys() {
|
||||
Set<String> keys = redisTemplate.keys(CACHE_KEY_PREFIX + "*");
|
||||
if (keys != null) {
|
||||
// 去掉缓存key的common prefix前缀
|
||||
return keys.stream().map(key -> StrUtil.removePrefix(key, CACHE_KEY_PREFIX)).collect(Collectors.toSet());
|
||||
} else {
|
||||
return CollectionUtil.newHashSet();
|
||||
}
|
||||
// 去掉缓存key的common prefix前缀
|
||||
return keys.stream().map(key -> StrUtil.removePrefix(key, CACHE_KEY_PREFIX)).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Collection<Object> getAllValues() {
|
||||
Set<String> keys = redisTemplate.keys(CACHE_KEY_PREFIX + "*");
|
||||
if (keys != null) {
|
||||
return redisTemplate.opsForValue().multiGet(keys);
|
||||
} else {
|
||||
return CollectionUtil.newArrayList();
|
||||
}
|
||||
return redisTemplate.opsForValue().multiGet(keys);
|
||||
}
|
||||
|
||||
public Map<String, Object> getAllKeyValues() {
|
||||
|
@ -86,8 +78,6 @@ public class CommonCacheOperator {
|
|||
|
||||
public void removeBatch(String pattern) {
|
||||
Set<String> keys = redisTemplate.keys(CACHE_KEY_PREFIX + pattern);
|
||||
if (keys != null) {
|
||||
redisTemplate.delete(keys);
|
||||
}
|
||||
redisTemplate.delete(keys);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
package vip.xiaonuo.common.consts;
|
||||
|
||||
/**
|
||||
* @description 缓存静态常量
|
||||
* 缓存静态常量
|
||||
*
|
||||
* @author dongxiayu
|
||||
* @date 2023/1/30 0:44
|
||||
**/
|
||||
|
|
|
@ -42,8 +42,4 @@ public enum CommonSortOrderEnum {
|
|||
throw new CommonException("不支持该排序方式:{}", value);
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,20 +42,20 @@ public class CommonSm4CbcTypeHandler<T> extends BaseTypeHandler<T> {
|
|||
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
String columnValue = rs.getString(columnName);
|
||||
//有一些可能是空字符
|
||||
return StringUtils.isBlank(columnValue) ? (T)columnValue : (T)CommonCryptogramUtil.doSm4CbcDecrypt(columnValue);
|
||||
return StringUtils.isBlank(columnValue) ? (T)columnValue : (T) CommonCryptogramUtil.doSm4CbcDecrypt(columnValue);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
@Override
|
||||
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
String columnValue = rs.getString(columnIndex);
|
||||
return StringUtils.isBlank(columnValue) ? (T)columnValue : (T)CommonCryptogramUtil.doSm4CbcDecrypt(columnValue);
|
||||
return StringUtils.isBlank(columnValue) ? (T)columnValue : (T) CommonCryptogramUtil.doSm4CbcDecrypt(columnValue);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
@Override
|
||||
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
String columnValue = cs.getString(columnIndex);
|
||||
return StringUtils.isBlank(columnValue) ? (T)columnValue : (T)CommonCryptogramUtil.doSm4CbcDecrypt(columnValue);
|
||||
return StringUtils.isBlank(columnValue) ? (T)columnValue : (T) CommonCryptogramUtil.doSm4CbcDecrypt(columnValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ package vip.xiaonuo.common.listener;
|
|||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.Getter;
|
||||
import vip.xiaonuo.common.exception.CommonException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -31,15 +32,11 @@ public class CommonDataChangeEventCenter {
|
|||
|
||||
// --------- 注册侦听器
|
||||
|
||||
private static List<CommonDataChangeListener> listenerList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 获取已注册的所有侦听器
|
||||
* @return /
|
||||
*/
|
||||
public static List<CommonDataChangeListener> getListenerList() {
|
||||
return listenerList;
|
||||
}
|
||||
@Getter
|
||||
private static List<CommonDataChangeListener> listenerList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 重置侦听器集合
|
||||
|
|
|
@ -56,7 +56,6 @@ public class CommonPageRequest {
|
|||
}
|
||||
} catch (Exception e) {
|
||||
log.error(">>> 分页条数转换异常:", e);
|
||||
size = 20;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +66,6 @@ public class CommonPageRequest {
|
|||
page = Convert.toInt(pageString);
|
||||
} catch (Exception e) {
|
||||
log.error(">>> 分页页数转换异常:", e);
|
||||
page = 1;
|
||||
}
|
||||
}
|
||||
Page<T> objectPage = new Page<>(page, size);
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
package vip.xiaonuo.common.pojo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
|
@ -23,6 +25,7 @@ import java.io.Serializable;
|
|||
* @date 2022/8/15 16:08
|
||||
**/
|
||||
public class CommonResult<T> implements Serializable{
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
public static final int CODE_SUCCESS = 200;
|
||||
public static final int CODE_ERROR = 500;
|
||||
|
@ -30,9 +33,17 @@ public class CommonResult<T> implements Serializable{
|
|||
@Schema(description = "状态码")
|
||||
private int code;
|
||||
|
||||
/**
|
||||
* 获取msg
|
||||
*/
|
||||
@Getter
|
||||
@Schema(description = "提示语")
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 获取data
|
||||
*/
|
||||
@Getter
|
||||
@Schema(description = "返回数据")
|
||||
private T data;
|
||||
|
||||
|
@ -53,21 +64,6 @@ public class CommonResult<T> implements Serializable{
|
|||
return this.code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取msg
|
||||
* @return msg
|
||||
*/
|
||||
public String getMsg() {
|
||||
return this.msg;
|
||||
}
|
||||
/**
|
||||
* 获取data
|
||||
* @return data
|
||||
*/
|
||||
public T getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 给code赋值,连缀风格
|
||||
* @param code code
|
||||
|
|
|
@ -29,9 +29,6 @@ import org.springframework.stereotype.Component;
|
|||
@ConfigurationProperties(prefix = "snowy.config.common")
|
||||
public class CommonProperties {
|
||||
|
||||
/** 前端地址 */
|
||||
private String frontUrl;
|
||||
|
||||
/** 后端地址 */
|
||||
private String backendUrl;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import com.antherd.smcrypto.sm4.Sm4Options;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 加密工具类,本框架目前使用 https://github.com/antherd/sm-crypto 项目中一些加解密方式
|
||||
* 加密工具类,本框架目前使用 <a href="https://github.com/antherd/sm-crypto">sm-crypto</a> 项目中一些加解密方式
|
||||
* 使用小伙伴需要过等保密评相关,请在此处更改为自己的加密方法,或加密机,使用加密机同时需要替换公钥,私钥在内部无法导出,提供加密的方法
|
||||
* 如果不涉及到加密机方面的内容,请更改公私要为自己重新生成的,生成方式请看集成的sm-crypto主页
|
||||
*
|
||||
|
|
|
@ -30,8 +30,8 @@ public class CommonEmailUtil {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/8/15 13:32
|
||||
**/
|
||||
public static boolean isEmail(String email) {
|
||||
return Validator.isEmail(email);
|
||||
public static boolean isNotEmail(String email) {
|
||||
return !Validator.isEmail(email);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,7 +42,7 @@ public class CommonEmailUtil {
|
|||
**/
|
||||
public static void validEmail(String emails) {
|
||||
StrUtil.split(emails, StrUtil.COMMA).forEach(email -> {
|
||||
if(!isEmail(email)) {
|
||||
if(isNotEmail(email)) {
|
||||
throw new CommonException("邮件地址:{}格式错误", email);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -26,7 +26,7 @@ import java.io.InputStream;
|
|||
|
||||
/**
|
||||
* 根据ip地址定位工具类,离线方式
|
||||
* 参考地址:https://gitee.com/lionsoul/ip2region/tree/master/binding/java
|
||||
* 参考地址:<a href="https://gitee.com/lionsoul/ip2region/tree/master/binding/java">ip2region</a>
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2020/3/16 11:25
|
||||
|
|
|
@ -77,29 +77,15 @@ public class CommonTimeFormatUtil {
|
|||
String weekday;
|
||||
//获取是本周的第几天
|
||||
int dayOfWeek = DateUtil.dayOfWeek(date) - 1;
|
||||
switch (dayOfWeek) {
|
||||
case 1:
|
||||
weekday = "周一";
|
||||
break;
|
||||
case 2:
|
||||
weekday = "周二";
|
||||
break;
|
||||
case 3:
|
||||
weekday = "周三";
|
||||
break;
|
||||
case 4:
|
||||
weekday = "周四";
|
||||
break;
|
||||
case 5:
|
||||
weekday = "周五";
|
||||
break;
|
||||
case 6:
|
||||
weekday = "周六";
|
||||
break;
|
||||
default:
|
||||
weekday = "周日";
|
||||
break;
|
||||
}
|
||||
weekday = switch (dayOfWeek) {
|
||||
case 1 -> "周一";
|
||||
case 2 -> "周二";
|
||||
case 3 -> "周三";
|
||||
case 4 -> "周四";
|
||||
case 5 -> "周五";
|
||||
case 6 -> "周六";
|
||||
default -> "周日";
|
||||
};
|
||||
//显示本周时分
|
||||
return weekday + " " + DateUtil.format(date, "HH:mm");
|
||||
} else {
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
<artifactId>sa-token-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -66,6 +66,14 @@ public interface SaBaseLoginUserApi {
|
|||
**/
|
||||
SaBaseLoginUser getUserByPhone(String phone);
|
||||
|
||||
/**
|
||||
* 根据邮箱获取B端用户信息,查不到则返回null
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/3/10 16:14
|
||||
**/
|
||||
SaBaseLoginUser getUserByEmail(String email);
|
||||
|
||||
/**
|
||||
* 根据手机号获取C端用户信息,查不到则返回null
|
||||
*
|
||||
|
@ -74,6 +82,14 @@ public interface SaBaseLoginUserApi {
|
|||
**/
|
||||
SaBaseClientLoginUser getClientUserByPhone(String phone);
|
||||
|
||||
/**
|
||||
* 根据邮箱获取C端用户信息,查不到则返回null
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/3/10 16:14
|
||||
**/
|
||||
SaBaseClientLoginUser getClientUserByEmail(String email);
|
||||
|
||||
/**
|
||||
* 根据用户id获取用户集合
|
||||
*
|
||||
|
@ -121,4 +137,44 @@ public interface SaBaseLoginUserApi {
|
|||
* @date 2022/4/27 22:57
|
||||
*/
|
||||
void updateUserLoginInfo(String userId, String device);
|
||||
|
||||
/**
|
||||
* 使用手机号创建B端用户
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/3/10 16:14
|
||||
**/
|
||||
SaBaseLoginUser createUserWithPhone(String phone);
|
||||
|
||||
/**
|
||||
* 使用手机号创建C端用户
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/3/10 16:14
|
||||
**/
|
||||
SaBaseClientLoginUser createClientUserWithPhone(String phone);
|
||||
|
||||
/**
|
||||
* 使用邮箱创建B端用户
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/3/10 16:14
|
||||
**/
|
||||
SaBaseLoginUser createUserWithEmail(String email);
|
||||
|
||||
/**
|
||||
* 使用邮箱创建C端用户
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/3/10 16:14
|
||||
**/
|
||||
SaBaseClientLoginUser createClientUserWithEmail(String email);
|
||||
|
||||
/**
|
||||
* 执行注册
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/3/10 16:14
|
||||
**/
|
||||
void doRegister(String account, String password);
|
||||
}
|
||||
|
|
|
@ -63,28 +63,22 @@
|
|||
<artifactId>tencentcloud-sdk-java-ses</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--阿里云短信sdk-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dysmsapi20170525</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--腾讯云短信sdk-->
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java-sms</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sms4j短信sdk -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.sms4j</groupId>
|
||||
<artifactId>sms4j-javase-plugin</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- sms4j消息推送sdk -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.sms4j</groupId>
|
||||
<artifactId>sms4j-oa-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--系统硬件信息-->
|
||||
<dependency>
|
||||
<groupId>com.github.oshi</groupId>
|
||||
<artifactId>oshi-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -27,6 +27,28 @@ import java.util.Map;
|
|||
**/
|
||||
public interface DevEmailApi {
|
||||
|
||||
/**
|
||||
* 动态发送TXT邮件(使用系统配置的默认邮件引擎)
|
||||
*
|
||||
* @param tos 收件人邮箱,逗号拼接
|
||||
* @param subject 邮件主题
|
||||
* @param content 邮件内容
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/7 22:29
|
||||
*/
|
||||
void sendDynamicTxtEmail(String tos, String subject, String content);
|
||||
|
||||
/**
|
||||
* 动态发送HTML邮件(使用系统配置的默认邮件引擎)
|
||||
*
|
||||
* @param tos 收件人邮箱,逗号拼接
|
||||
* @param subject 邮件主题
|
||||
* @param content 邮件内容
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/7 22:29
|
||||
*/
|
||||
void sendDynamicHtmlEmail(String tos, String subject, String content);
|
||||
|
||||
/* =========本地邮件========= */
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,6 +31,14 @@ public interface DevFileApi {
|
|||
**/
|
||||
String uploadDynamicReturnId(MultipartFile file);
|
||||
|
||||
/**
|
||||
* 动态上传文件返回url(使用系统配置的默认文件引擎)
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/13 14:01
|
||||
**/
|
||||
String uploadDynamicReturnUrl(MultipartFile file);
|
||||
|
||||
/* =========本地文件========= */
|
||||
|
||||
/**
|
||||
|
@ -119,6 +127,7 @@ public interface DevFileApi {
|
|||
*/
|
||||
JSONObject getFileInfoById(String id);
|
||||
|
||||
|
||||
/**
|
||||
* 根据文件id物理删除文件
|
||||
*
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.dev.api;
|
||||
|
||||
/**
|
||||
* 邮件API接口
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/6/22 15:21
|
||||
**/
|
||||
public interface DevPushApi {
|
||||
|
||||
/**
|
||||
* 动态推送消息(使用系统配置的默认消息推送引擎)
|
||||
*
|
||||
* @param content 内容
|
||||
* @param noticeAll 是否通知所有人
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/23 14:24
|
||||
*/
|
||||
void pushDynamicText(String content, boolean noticeAll);
|
||||
|
||||
/**
|
||||
* 推送消息——飞书TXT
|
||||
*
|
||||
* @param content 内容
|
||||
* @param noticeAll 是否通知所有人
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/23 14:24
|
||||
*/
|
||||
void pushFeiShuText(String content, boolean noticeAll);
|
||||
|
||||
/**
|
||||
* 推送消息——钉钉TXT
|
||||
*
|
||||
* @param content 内容
|
||||
* @param noticeAll 是否通知所有人
|
||||
* @param phones 通知的用户手机号,英文逗号分割
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/23 14:24
|
||||
*/
|
||||
void pushDingTalkText(String content, boolean noticeAll, String phones);
|
||||
|
||||
/**
|
||||
* 推送消息——钉钉MARKDOWN
|
||||
*
|
||||
* @param title 标题
|
||||
* @param content 内容
|
||||
* @param noticeAll 是否通知所有人
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/23 14:24
|
||||
*/
|
||||
void pushDingTalkMarkdown(String title, String content, boolean noticeAll);
|
||||
|
||||
/**
|
||||
* 推送消息——钉钉LINK
|
||||
*
|
||||
* @param title 标题
|
||||
* @param content 内容
|
||||
* @param picUrl 封面图片地址
|
||||
* @param messageUrl 消息链接地址
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/23 14:24
|
||||
*/
|
||||
void pushDingTalkLink(String title, String content, String picUrl,String messageUrl);
|
||||
|
||||
/**
|
||||
* 推送消息——企业微信TXT
|
||||
*
|
||||
* @param content 内容
|
||||
* @param noticeAll 是否通知所有人
|
||||
* @param phones 通知的用户手机号,英文逗号分割
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/23 14:24
|
||||
*/
|
||||
void pushWorkWechatText(String content, boolean noticeAll, String phones);
|
||||
|
||||
/**
|
||||
* 推送消息——企业微信MARKDOWN
|
||||
*
|
||||
* @param title 标题
|
||||
* @param content 内容
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/23 14:24
|
||||
*/
|
||||
void pushWorkWechatMarkdown(String title, String content);
|
||||
|
||||
/**
|
||||
* 推送消息——企业微信NEWS
|
||||
*
|
||||
* @param title 标题
|
||||
* @param content 内容
|
||||
* @param picUrl 封面图片地址
|
||||
* @param messageUrl 消息链接地址
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/23 14:24
|
||||
*/
|
||||
void pushWorkWechatNews(String title, String content, String picUrl,String messageUrl);
|
||||
}
|
|
@ -12,6 +12,8 @@
|
|||
*/
|
||||
package vip.xiaonuo.dev.api;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
|
||||
/**
|
||||
* 短信API
|
||||
*
|
||||
|
@ -20,6 +22,17 @@ package vip.xiaonuo.dev.api;
|
|||
**/
|
||||
public interface DevSmsApi {
|
||||
|
||||
/**
|
||||
* 动态发送短信(使用系统配置的默认短信引擎)
|
||||
*
|
||||
* @param phoneNumbers 手机号
|
||||
* @param templateCodeOrId 模板id或编码
|
||||
* @param paramMap 发送参数
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/7 22:29
|
||||
*/
|
||||
void sendDynamicSms(String phoneNumbers, String templateCodeOrId, JSONObject paramMap);
|
||||
|
||||
/* =========阿里云短信========= */
|
||||
|
||||
/**
|
||||
|
@ -27,7 +40,7 @@ public interface DevSmsApi {
|
|||
*
|
||||
* @param phoneNumbers 手机号码,支持对多个手机号码发送短信,手机号码之间以半角逗号(,)分隔。
|
||||
* 上限为1000个手机号码。批量调用相对于单条调用及时性稍有延迟。
|
||||
* @param signName 短信服务控制台配置且审核通过的短信签名,为空则使用默认签名
|
||||
* @param signName 短信服务控制台配置且审核通过的短信签名
|
||||
* @param templateCode 短信服务控制台配置且审核通过的模板编码
|
||||
* @param templateParam 短信模板变量对应的实际值,JSON格式。支持传入多个参数,示例:{"name":"张三","number":"15038****76"}
|
||||
* @author xuyuxiang
|
||||
|
@ -40,17 +53,15 @@ public interface DevSmsApi {
|
|||
/**
|
||||
* 发送短信
|
||||
*
|
||||
* @param sdkAppId 短信 SdkAppId,在 短信控制台 添加应用后生成的实际 SdkAppId,示例如1400006666。
|
||||
* 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
|
||||
* @param phoneNumbers 手机号码,支持对多个手机号码发送短信,手机号码之间以半角逗号(,)分隔。
|
||||
* 上限为1000个手机号码。批量调用相对于单条调用及时性稍有延迟。
|
||||
* @param signName 短信服务控制台配置且审核通过的短信签名,为空则使用默认签名
|
||||
* @param signName 短信服务控制台配置且审核通过的短信签名
|
||||
* @param templateCode 短信服务控制台配置且审核通过的模板编码
|
||||
* @param templateParam 短信模板变量对应的顺序。支持传入多个参数,逗号拼接,示例:"张三,15038****76,进行中"}
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/24 13:42
|
||||
**/
|
||||
void sendSmsTencent(String sdkAppId, String phoneNumbers, String signName, String templateCode, String templateParam);
|
||||
void sendSmsTencent(String phoneNumbers, String signName, String templateCode, String templateParam);
|
||||
|
||||
/* =========小诺短信========= */
|
||||
|
||||
|
@ -58,10 +69,11 @@ public interface DevSmsApi {
|
|||
* 发送短信
|
||||
*
|
||||
* @param phoneNumbers 手机号码,支持对多个手机号码发送短信,手机号码之间以半角逗号(,)分隔。
|
||||
* @param signName 短信签名,为空则使用默认签名
|
||||
* @param message 短信内容
|
||||
* @author xuyuxiang
|
||||
* @date 2022/2/24 13:42
|
||||
* 上限为1000个手机号码。批量调用相对于单条调用及时性稍有延迟。
|
||||
* @param signName 短信服务控制台配置且审核通过的短信签名
|
||||
* @param message 短信内容,发送时编写好的整条短信内容,不带签名【】
|
||||
* @author yubaoshan
|
||||
* @date 2024/5/20 12:00
|
||||
**/
|
||||
void sendSmsXiaonuo(String phoneNumbers, String signName, String message);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.dev.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 弱密码库APi接口
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/6/17 10:37
|
||||
**/
|
||||
public interface DevWeakPasswordApi {
|
||||
|
||||
/**
|
||||
* 获取弱密码库列表
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/6/17 11:11
|
||||
**/
|
||||
List<String> weakPasswordList();
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.mobile.api;
|
||||
|
||||
/**
|
||||
* 移动端综合API
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/9/26 14:24
|
||||
**/
|
||||
public interface MobileApi {
|
||||
}
|
|
@ -28,5 +28,5 @@ public interface MobileButtonApi {
|
|||
* @author 每天一点
|
||||
* @date 2023/2/5 13:26
|
||||
**/
|
||||
List<String> listByIds(List<String> idList);
|
||||
List<String> listButtonCodeListByIdList(List<String> idList);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,14 @@ public interface MobileMenuApi {
|
|||
**/
|
||||
List<JSONObject> mobileMenuTreeSelector();
|
||||
|
||||
/**
|
||||
* 获取移动端菜单授权树
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2023/1/31 10:10
|
||||
**/
|
||||
List<JSONObject> mobileMenuTreeSelector(List<JSONObject> originDataList);
|
||||
|
||||
/**
|
||||
* 获取移动端登录菜单树
|
||||
*
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.sys.api;
|
||||
|
||||
/**
|
||||
* 系统模块综合API
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/9/26 14:24
|
||||
**/
|
||||
public interface SysApi {
|
||||
|
||||
/**
|
||||
* 获取系统默认密码
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/9/26 14:25
|
||||
**/
|
||||
String getDefaultPassword();
|
||||
}
|
|
@ -13,6 +13,7 @@
|
|||
package vip.xiaonuo.sys.api;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,5 +37,5 @@ public interface SysPositionApi {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/7/22 14:47
|
||||
**/
|
||||
Page<JSONObject> positionSelector(String orgId, String searchKey);
|
||||
Page<JSONObject> positionSelector(String orgId, String searchKey, Integer current, Integer size);
|
||||
}
|
||||
|
|
|
@ -48,4 +48,20 @@ public interface SysRoleApi {
|
|||
* @date 2022/11/1 15:58
|
||||
**/
|
||||
void grantForGenMenuAndButton(String menuId);
|
||||
|
||||
/**
|
||||
* 获取资源授权树
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
List<JSONObject> resourceTreeSelector();
|
||||
|
||||
/**
|
||||
* 获取权限授权树
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:08
|
||||
*/
|
||||
List<String> permissionTreeSelector();
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@ import cn.dev33.satoken.interceptor.SaInterceptor;
|
|||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
@ -71,6 +72,7 @@ public class AuthConfigure implements WebMvcConfigurer {
|
|||
|
||||
@Bean("stpClientLogic")
|
||||
public StpLogic getStpClientLogic(SaTokenConfig saTokenConfig) {
|
||||
|
||||
// 重写Sa-Token的StpLogic,默认客户端类型为C
|
||||
return new StpLogic(SaClientTypeEnum.C.getValue()).setConfig(saTokenConfig);
|
||||
}
|
||||
|
@ -105,7 +107,12 @@ public class AuthConfigure implements WebMvcConfigurer {
|
|||
} else {
|
||||
permissionListObject = commonCacheOperator.get(CacheConstant.AUTH_C_PERMISSION_LIST_CACHE_KEY + loginId);
|
||||
}
|
||||
return JSONUtil.parseArray(permissionListObject).toList(String.class);
|
||||
// 转为字符串
|
||||
String permissionListString = permissionListObject.toString();
|
||||
// 去除首尾的方括号
|
||||
String trimmedStr = StrUtil.sub(permissionListString, 1, -1);
|
||||
// 使用逗号和空格分割字符串,并转换为列表
|
||||
return CollectionUtil.newArrayList(StrUtil.split(trimmedStr, ", "));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.auth.core.util;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import vip.xiaonuo.dev.api.DevConfigApi;
|
||||
|
||||
/**
|
||||
* 认证相关邮件格式化工具类
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2025/3/21 19:07
|
||||
**/
|
||||
public class AuthEmailFormatUtl {
|
||||
|
||||
/** 系统名称 */
|
||||
private static final String SNOWY_SYS_NAME_KEY = "SNOWY_SYS_NAME";
|
||||
|
||||
/**
|
||||
* 格式化邮件内容
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2025/3/21 19:08
|
||||
**/
|
||||
public static String format(String content, JSONObject paramMap) {
|
||||
DevConfigApi devConfigApi = SpringUtil.getBean(DevConfigApi.class);
|
||||
// 获取系统名称
|
||||
String sysName = devConfigApi.getValueByKey(SNOWY_SYS_NAME_KEY);
|
||||
// 系统名称
|
||||
paramMap.set("sysName", sysName);
|
||||
// 当前时间
|
||||
paramMap.set("sysNowTime", DateUtil.now());
|
||||
return StrUtil.format(content, paramMap);
|
||||
}
|
||||
}
|
|
@ -18,6 +18,12 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
import vip.xiaonuo.common.util.CommonServletUtil;
|
||||
|
||||
/**
|
||||
* 认证相关异常处理工具类
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/9 14:24
|
||||
**/
|
||||
@Slf4j
|
||||
public class AuthExceptionUtil {
|
||||
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
*/
|
||||
package vip.xiaonuo.auth.modular.login.controller;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -28,10 +29,13 @@ import vip.xiaonuo.auth.core.util.StpClientUtil;
|
|||
import vip.xiaonuo.auth.modular.login.param.AuthAccountPasswordLoginParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthGetPhoneValidCodeParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthPhoneValidCodeLoginParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthRegisterParam;
|
||||
import vip.xiaonuo.auth.modular.login.result.AuthPicValidCodeResult;
|
||||
import vip.xiaonuo.auth.modular.login.service.AuthService;
|
||||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* C端登录控制器
|
||||
*
|
||||
|
@ -39,6 +43,7 @@ import vip.xiaonuo.common.pojo.CommonResult;
|
|||
* @date 2021/12/23 21:50
|
||||
*/
|
||||
@Tag(name = "C端登录控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 1)
|
||||
@RestController
|
||||
@Validated
|
||||
public class AuthClientController {
|
||||
|
@ -52,6 +57,7 @@ public class AuthClientController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/7/8 9:26
|
||||
**/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "C端获取图片验证码")
|
||||
@GetMapping("/auth/c/getPicCaptcha")
|
||||
public CommonResult<AuthPicValidCodeResult> getPicCaptcha() {
|
||||
|
@ -64,6 +70,7 @@ public class AuthClientController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/7/8 9:26
|
||||
**/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "C端获取手机验证码")
|
||||
@GetMapping("/auth/c/getPhoneValidCode")
|
||||
public CommonResult<String> getPhoneValidCode(@Valid AuthGetPhoneValidCodeParam authGetPhoneValidCodeParam) {
|
||||
|
@ -76,6 +83,7 @@ public class AuthClientController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "C端账号密码登录")
|
||||
@PostMapping("/auth/c/doLogin")
|
||||
public CommonResult<String> doLogin(@RequestBody @Valid AuthAccountPasswordLoginParam authAccountPasswordLoginParam) {
|
||||
|
@ -88,6 +96,7 @@ public class AuthClientController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "C端手机验证码登录")
|
||||
@PostMapping("/auth/c/doLoginByPhone")
|
||||
public CommonResult<String> doLoginByPhone(@RequestBody @Valid AuthPhoneValidCodeLoginParam authPhoneValidCodeLoginParam) {
|
||||
|
@ -100,6 +109,7 @@ public class AuthClientController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "C端退出")
|
||||
@SaClientCheckLogin
|
||||
@GetMapping("/auth/c/doLogout")
|
||||
|
@ -114,10 +124,25 @@ public class AuthClientController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "C端获取用户信息")
|
||||
@SaClientCheckLogin
|
||||
@GetMapping("/auth/c/getLoginUser")
|
||||
public CommonResult<SaBaseClientLoginUser> getLoginUser() {
|
||||
return CommonResult.data(authService.getClientLoginUser());
|
||||
}
|
||||
|
||||
/**
|
||||
* C端注册
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 7)
|
||||
@Operation(summary = "C端注册")
|
||||
@PostMapping("/auth/c/register")
|
||||
public CommonResult<String> register(@RequestBody @Valid AuthRegisterParam authRegisterParam) {
|
||||
authService.register(authRegisterParam, SaClientTypeEnum.C.getValue());
|
||||
return CommonResult.ok();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,11 @@ package vip.xiaonuo.auth.modular.login.controller;
|
|||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -25,13 +26,13 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||
import org.springframework.web.bind.annotation.RestController;
|
||||
import vip.xiaonuo.auth.core.enums.SaClientTypeEnum;
|
||||
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthAccountPasswordLoginParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthGetPhoneValidCodeParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthPhoneValidCodeLoginParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.*;
|
||||
import vip.xiaonuo.auth.modular.login.result.AuthPicValidCodeResult;
|
||||
import vip.xiaonuo.auth.modular.login.service.AuthService;
|
||||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* B端登录控制器
|
||||
*
|
||||
|
@ -39,6 +40,7 @@ import vip.xiaonuo.common.pojo.CommonResult;
|
|||
* @date 2021/12/23 21:50
|
||||
*/
|
||||
@Tag(name = "B端登录控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 2)
|
||||
@RestController
|
||||
@Validated
|
||||
public class AuthController {
|
||||
|
@ -52,6 +54,7 @@ public class AuthController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/7/8 9:26
|
||||
**/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "B端获取图片验证码")
|
||||
@GetMapping("/auth/b/getPicCaptcha")
|
||||
public CommonResult<AuthPicValidCodeResult> getPicCaptcha() {
|
||||
|
@ -59,23 +62,38 @@ public class AuthController {
|
|||
}
|
||||
|
||||
/**
|
||||
* B端获取手机验证码
|
||||
* B端获取手机登录验证码
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/7/8 9:26
|
||||
**/
|
||||
@Operation(summary = "B端获取手机验证码")
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "B端获取手机登录验证码")
|
||||
@GetMapping("/auth/b/getPhoneValidCode")
|
||||
public CommonResult<String> getPhoneValidCode(@Valid AuthGetPhoneValidCodeParam authGetPhoneValidCodeParam) {
|
||||
return CommonResult.data(authService.getPhoneValidCode(authGetPhoneValidCodeParam, SaClientTypeEnum.B.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* B端获取邮箱登录验证码
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/7/8 9:26
|
||||
**/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "B端获取邮箱登录验证码")
|
||||
@GetMapping("/auth/b/getEmailValidCode")
|
||||
public CommonResult<String> getEmailValidCode(@Valid AuthGetEmailValidCodeParam authGetEmailValidCodeParam) {
|
||||
return CommonResult.data(authService.getEmailValidCode(authGetEmailValidCodeParam, SaClientTypeEnum.B.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* B端账号密码登录
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "B端账号密码登录")
|
||||
@PostMapping("/auth/b/doLogin")
|
||||
public CommonResult<String> doLogin(@RequestBody @Valid AuthAccountPasswordLoginParam authAccountPasswordLoginParam) {
|
||||
|
@ -88,18 +106,33 @@ public class AuthController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "B端手机验证码登录")
|
||||
@PostMapping("/auth/b/doLoginByPhone")
|
||||
public CommonResult<String> doLoginByPhone(@RequestBody @Valid AuthPhoneValidCodeLoginParam authPhoneValidCodeLoginParam) {
|
||||
return CommonResult.data(authService.doLoginByPhone(authPhoneValidCodeLoginParam, SaClientTypeEnum.B.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* B端邮箱验证码登录
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "B端邮箱验证码登录")
|
||||
@PostMapping("/auth/b/doLoginByEmail")
|
||||
public CommonResult<String> doLoginByEmail(@RequestBody @Valid AuthEmailValidCodeLoginParam authEmailValidCodeLoginParam) {
|
||||
return CommonResult.data(authService.doLoginByEmail(authEmailValidCodeLoginParam, SaClientTypeEnum.B.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* B端退出
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 7)
|
||||
@Operation(summary = "B端退出")
|
||||
@SaCheckLogin
|
||||
@GetMapping("/auth/b/doLogout")
|
||||
|
@ -114,10 +147,25 @@ public class AuthController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 8)
|
||||
@Operation(summary = "B端获取用户信息")
|
||||
@SaCheckLogin
|
||||
@GetMapping("/auth/b/getLoginUser")
|
||||
public CommonResult<SaBaseLoginUser> getLoginUser() {
|
||||
return CommonResult.data(authService.getLoginUser());
|
||||
}
|
||||
|
||||
/**
|
||||
* B端注册
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 9)
|
||||
@Operation(summary = "B端注册")
|
||||
@PostMapping("/auth/b/register")
|
||||
public CommonResult<String> register(@RequestBody @Valid AuthRegisterParam authRegisterParam) {
|
||||
authService.register(authRegisterParam, SaClientTypeEnum.B.getValue());
|
||||
return CommonResult.ok();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,19 +24,13 @@ import vip.xiaonuo.common.exception.CommonException;
|
|||
@Getter
|
||||
public enum AuthDeviceTypeEnum {
|
||||
|
||||
/**
|
||||
* PC端
|
||||
*/
|
||||
/** PC端 */
|
||||
PC("PC"),
|
||||
|
||||
/**
|
||||
* 移动端
|
||||
*/
|
||||
/** 移动端 */
|
||||
APP("APP"),
|
||||
|
||||
/**
|
||||
* 小程序端
|
||||
*/
|
||||
/** 小程序端 */
|
||||
MINI("MINI");
|
||||
|
||||
private final String value;
|
||||
|
|
|
@ -23,59 +23,37 @@ import lombok.Getter;
|
|||
@Getter
|
||||
public enum AuthExceptionEnum {
|
||||
|
||||
/**
|
||||
* 验证码不能为空
|
||||
*/
|
||||
/** 验证码不能为空 */
|
||||
VALID_CODE_EMPTY("验证码不能为空"),
|
||||
|
||||
/**
|
||||
* 验证码请求号不能为空
|
||||
*/
|
||||
/** 验证码请求号不能为空 */
|
||||
VALID_CODE_REQ_NO_EMPTY("验证码请求号不能为空"),
|
||||
|
||||
/**
|
||||
* 验证码错误
|
||||
*/
|
||||
/** 验证码错误 */
|
||||
VALID_CODE_ERROR("验证码错误"),
|
||||
|
||||
/**
|
||||
* 账号错误
|
||||
*/
|
||||
/** 账号错误 */
|
||||
ACCOUNT_ERROR("账号错误"),
|
||||
|
||||
/**
|
||||
* 账号已停用
|
||||
*/
|
||||
/** 账号已停用 */
|
||||
ACCOUNT_DISABLED("账号已停用"),
|
||||
|
||||
/**
|
||||
* 密码错误
|
||||
*/
|
||||
/** 密码错误 */
|
||||
PWD_ERROR("密码错误"),
|
||||
|
||||
/**
|
||||
* 手机号格式错误
|
||||
*/
|
||||
/** 手机号格式错误 */
|
||||
PHONE_FORMAT_ERROR("手机号格式错误"),
|
||||
|
||||
/**
|
||||
* 手机号不存在
|
||||
*/
|
||||
PHONE_ERROR("手机号不存在"),
|
||||
/** 邮箱格式错误 */
|
||||
EMAIL_FORMAT_ERROR("邮箱格式错误"),
|
||||
|
||||
/**
|
||||
* 客户端类型不能为空
|
||||
*/
|
||||
/** 客户端类型不能为空 */
|
||||
CLIENT_TYPE_EMPTY("客户端类型不能为空"),
|
||||
|
||||
/**
|
||||
* 客户端类型错误
|
||||
*/
|
||||
/** 客户端类型错误 */
|
||||
CLIENT_TYPE_ERROR("客户端类型错误"),
|
||||
|
||||
/**
|
||||
* 密码解密失败,请检查前端公钥
|
||||
*/
|
||||
/** 密码解密失败,请检查前端公钥 */
|
||||
PWD_DECRYPT_ERROR("密码解密失败,请检查前端公钥");
|
||||
|
||||
private final String value;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.auth.modular.login.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import vip.xiaonuo.common.exception.CommonException;
|
||||
|
||||
/**
|
||||
* 手机号邮箱类型枚举
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/11 14:02
|
||||
**/
|
||||
@Getter
|
||||
public enum AuthPhoneOrEmailTypeEnum {
|
||||
|
||||
/** 手机号 */
|
||||
PHONE("PHONE"),
|
||||
|
||||
/** 邮箱 */
|
||||
EMAIL("EMAIL");
|
||||
|
||||
private final String value;
|
||||
|
||||
AuthPhoneOrEmailTypeEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static void validate(String value) {
|
||||
boolean flag = PHONE.getValue().equals(value) || EMAIL.getValue().equals(value);
|
||||
if(!flag) {
|
||||
throw new CommonException("不支持的手机号邮箱类型:{}", value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.auth.modular.login.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 短信发送引擎类型枚举
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/6/16 16:14
|
||||
**/
|
||||
@Getter
|
||||
public enum AuthSmsEngineTypeEnum {
|
||||
|
||||
/** 阿里云 */
|
||||
ALIYUN("ALIYUN"),
|
||||
|
||||
/** 腾讯云 */
|
||||
TENCENT("TENCENT"),
|
||||
|
||||
/** 小诺短信 */
|
||||
XIAONUO("XIAONUO");
|
||||
|
||||
private final String value;
|
||||
|
||||
AuthSmsEngineTypeEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.auth.modular.login.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import vip.xiaonuo.common.exception.CommonException;
|
||||
|
||||
/**
|
||||
* 手机号或邮箱无对应用户时策略
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/11 14:02
|
||||
**/
|
||||
@Getter
|
||||
public enum AuthStrategyWhenNoUserWithPhoneOrEmailEnum {
|
||||
|
||||
/** 不允许登录 */
|
||||
NOT_ALLOW_LOGIN("NOT_ALLOW_LOGIN"),
|
||||
|
||||
/** 自动创建用户 */
|
||||
AUTO_CREATE_USER("AUTO_CREATE_USER");
|
||||
|
||||
private final String value;
|
||||
|
||||
AuthStrategyWhenNoUserWithPhoneOrEmailEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static void validate(String value) {
|
||||
boolean flag = NOT_ALLOW_LOGIN.getValue().equals(value) || AUTO_CREATE_USER.getValue().equals(value);
|
||||
if(!flag) {
|
||||
throw new CommonException("不支持的手机号或邮箱无对应用户时策略型:{}", value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.auth.modular.login.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 邮箱验证码登录参数
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/7/7 16:46
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthEmailValidCodeLoginParam {
|
||||
|
||||
/** 邮箱 */
|
||||
@Schema(description = "邮箱", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "邮箱不能为空")
|
||||
private String email;
|
||||
|
||||
/** 验证码 */
|
||||
@Schema(description = "验证码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String validCode;
|
||||
|
||||
/** 验证码请求号 */
|
||||
@Schema(description = "验证码请求号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "验证码请求号不能为空")
|
||||
private String validCodeReqNo;
|
||||
|
||||
/** 设备 */
|
||||
@Schema(description = "设备")
|
||||
private String device;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.auth.modular.login.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 获取邮箱验证码参数
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/8/25 13:45
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthGetEmailValidCodeParam {
|
||||
|
||||
/** 邮箱 */
|
||||
@Schema(description = "邮箱", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "邮箱不能为空")
|
||||
private String email;
|
||||
|
||||
/** 验证码 */
|
||||
@Schema(description = "验证码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "验证码不能为空")
|
||||
private String validCode;
|
||||
|
||||
/** 验证码请求号 */
|
||||
@Schema(description = "验证码请求号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "验证码请求号不能为空")
|
||||
private String validCodeReqNo;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.auth.modular.login.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 注册参数
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/7/7 16:46
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthRegisterParam {
|
||||
|
||||
/** 账号 */
|
||||
@Schema(description = "账号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "账号不能为空")
|
||||
private String account;
|
||||
|
||||
/** 密码 */
|
||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "密码不能为空")
|
||||
private String password;
|
||||
|
||||
/** 验证码 */
|
||||
@Schema(description = "验证码")
|
||||
private String validCode;
|
||||
|
||||
/** 验证码请求号 */
|
||||
@Schema(description = "验证码请求号")
|
||||
private String validCodeReqNo;
|
||||
}
|
|
@ -14,9 +14,7 @@ package vip.xiaonuo.auth.modular.login.service;
|
|||
|
||||
import vip.xiaonuo.auth.core.pojo.SaBaseClientLoginUser;
|
||||
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthAccountPasswordLoginParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthGetPhoneValidCodeParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthPhoneValidCodeLoginParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.*;
|
||||
import vip.xiaonuo.auth.modular.login.result.AuthPicValidCodeResult;
|
||||
|
||||
/**
|
||||
|
@ -36,13 +34,21 @@ public interface AuthService {
|
|||
AuthPicValidCodeResult getPicCaptcha(String type);
|
||||
|
||||
/**
|
||||
* 获取手机验证码
|
||||
* 获取手机登录验证码
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/12/28 14:46
|
||||
**/
|
||||
String getPhoneValidCode(AuthGetPhoneValidCodeParam authGetPhoneValidCodeParam, String type);
|
||||
|
||||
/**
|
||||
* 获取邮箱登录验证码
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/12/28 14:46
|
||||
**/
|
||||
String getEmailValidCode(AuthGetEmailValidCodeParam authGetEmailValidCodeParam, String type);
|
||||
|
||||
/**
|
||||
* 账号密码登录
|
||||
*
|
||||
|
@ -59,6 +65,14 @@ public interface AuthService {
|
|||
**/
|
||||
String doLoginByPhone(AuthPhoneValidCodeLoginParam authPhoneValidCodeLoginParam, String type);
|
||||
|
||||
/**
|
||||
* 邮箱验证码登录
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/12/28 14:46
|
||||
**/
|
||||
String doLoginByEmail(AuthEmailValidCodeLoginParam authEmailValidCodeLoginParam, String type);
|
||||
|
||||
/**
|
||||
* 获取B端登录用户信息
|
||||
*
|
||||
|
@ -82,4 +96,12 @@ public interface AuthService {
|
|||
* @date 2022/7/9 14:44
|
||||
*/
|
||||
String doLoginById(String userId, String device, String type);
|
||||
|
||||
/**
|
||||
* C端注册
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/7/9 14:44
|
||||
*/
|
||||
void register(AuthRegisterParam authRegisterParam, String type);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import cn.hutool.core.util.PhoneUtil;
|
|||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -30,14 +31,15 @@ import vip.xiaonuo.auth.api.SaBaseLoginUserApi;
|
|||
import vip.xiaonuo.auth.core.enums.SaClientTypeEnum;
|
||||
import vip.xiaonuo.auth.core.pojo.SaBaseClientLoginUser;
|
||||
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
|
||||
import vip.xiaonuo.auth.core.util.AuthEmailFormatUtl;
|
||||
import vip.xiaonuo.auth.core.util.StpClientLoginUserUtil;
|
||||
import vip.xiaonuo.auth.core.util.StpClientUtil;
|
||||
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
|
||||
import vip.xiaonuo.auth.modular.login.enums.AuthDeviceTypeEnum;
|
||||
import vip.xiaonuo.auth.modular.login.enums.AuthExceptionEnum;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthAccountPasswordLoginParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthGetPhoneValidCodeParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthPhoneValidCodeLoginParam;
|
||||
import vip.xiaonuo.auth.modular.login.enums.AuthPhoneOrEmailTypeEnum;
|
||||
import vip.xiaonuo.auth.modular.login.enums.AuthStrategyWhenNoUserWithPhoneOrEmailEnum;
|
||||
import vip.xiaonuo.auth.modular.login.param.*;
|
||||
import vip.xiaonuo.auth.modular.login.result.AuthPicValidCodeResult;
|
||||
import vip.xiaonuo.auth.modular.login.service.AuthService;
|
||||
import vip.xiaonuo.common.cache.CommonCacheOperator;
|
||||
|
@ -45,7 +47,9 @@ import vip.xiaonuo.common.consts.CacheConstant;
|
|||
import vip.xiaonuo.common.exception.CommonException;
|
||||
import vip.xiaonuo.common.util.CommonCryptogramUtil;
|
||||
import vip.xiaonuo.common.util.CommonEmailUtil;
|
||||
import vip.xiaonuo.common.util.CommonTimeFormatUtil;
|
||||
import vip.xiaonuo.dev.api.DevConfigApi;
|
||||
import vip.xiaonuo.dev.api.DevEmailApi;
|
||||
import vip.xiaonuo.dev.api.DevSmsApi;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -60,10 +64,82 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
public class AuthServiceImpl implements AuthService {
|
||||
|
||||
private static final String SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_KEY = "SNOWY_SYS_DEFAULT_CAPTCHA_OPEN";
|
||||
/** B端验证码是否开启(适用图片验证码) */
|
||||
private static final String SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_FLAG_FOR_B_KEY = "SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_FLAG_FOR_B";
|
||||
|
||||
/** C端验证码是否开启(适用图片验证码) */
|
||||
private static final String SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_FLAG_FOR_C_KEY = "SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_FLAG_FOR_C";
|
||||
|
||||
/** B端验证码失效时间(适用图片验证码和短信验证码,单位:分钟,默认5分钟有效) */
|
||||
private static final String SNOWY_SYS_DEFAULT_CAPTCHA_EXPIRED_DURATION_FOR_B_KEY = "SNOWY_SYS_DEFAULT_CAPTCHA_EXPIRED_DURATION_FOR_B";
|
||||
|
||||
/** C端验证码失效时间(适用图片验证码和短信验证码,单位:分钟,默认5分钟有效) */
|
||||
private static final String SNOWY_SYS_DEFAULT_CAPTCHA_EXPIRED_DURATION_FOR_C_KEY = "SNOWY_SYS_DEFAULT_CAPTCHA_EXPIRED_DURATION_FOR_C";
|
||||
|
||||
/** B端登录验证码短信消息模板编码 */
|
||||
private static final String SNOWY_SMS_TEMPLATE_VALID_CODE_LOGIN_FOR_B_KEY = "SNOWY_SMS_TEMPLATE_VALID_CODE_LOGIN_FOR_B";
|
||||
|
||||
/** C端登录验证码短信消息模板编码 */
|
||||
private static final String SNOWY_SMS_TEMPLATE_VALID_CODE_LOGIN_FOR_C_KEY = "SNOWY_SMS_TEMPLATE_VALID_CODE_LOGIN_FOR_C";
|
||||
|
||||
/** B端登录验证码邮件消息模板内容 */
|
||||
private static final String SNOWY_EMAIL_TEMPLATE_VALID_CODE_LOGIN_FOR_B_KEY = "SNOWY_EMAIL_TEMPLATE_VALID_CODE_LOGIN_FOR_B";
|
||||
|
||||
/** C端登录验证码邮件消息模板内容 */
|
||||
private static final String SNOWY_EMAIL_TEMPLATE_VALID_CODE_LOGIN_FOR_C_KEY = "SNOWY_EMAIL_TEMPLATE_VALID_CODE_LOGIN_FOR_C";
|
||||
|
||||
/** B端连续登录失败持续时间(即N分钟内连续登录失败,单位:分钟) */
|
||||
private static final String SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_DURATION_FOR_B_KEY = "SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_DURATION_FOR_B";
|
||||
|
||||
/** C端连续登录失败持续时间(即N分钟内连续登录失败,单位:分钟) */
|
||||
private static final String SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_DURATION_FOR_C_KEY = "SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_DURATION_FOR_C";
|
||||
|
||||
/** B端连续登录失败次数(即指定分钟内连续登录失败N次) */
|
||||
private static final String SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_TIMES_FOR_B_KEY = "SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_TIMES_FOR_B";
|
||||
|
||||
/** C端连续登录失败次数(即指定分钟内连续登录失败N次) */
|
||||
private static final String SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_TIMES_FOR_C_KEY = "SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_TIMES_FOR_C";
|
||||
|
||||
/** B端连续登录失败锁定时间(即指定分钟内连续登录失败指定次数,锁定N分钟,单位:分钟) */
|
||||
private static final String SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_LOCK_DURATION_FOR_B_KEY = "SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_LOCK_DURATION_FOR_B";
|
||||
|
||||
/** C端连续登录失败锁定时间(即指定分钟内连续登录失败指定次数,锁定N分钟,单位:分钟) */
|
||||
private static final String SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_LOCK_DURATION_FOR_C_KEY = "SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_LOCK_DURATION_FOR_C";
|
||||
|
||||
/** B端手机号登录是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_B_KEY = "SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_B";
|
||||
|
||||
/** C端手机号登录是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_C_KEY = "SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_C";
|
||||
|
||||
/** B端邮箱登录是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_B_KEY = "SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_B";
|
||||
|
||||
/** C端邮箱登录是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_C_KEY = "SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_C";
|
||||
|
||||
/** B端手机号无对应用户时策略 */
|
||||
private static final String SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_PHONE_FOR_B_KEY = "SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_PHONE_FOR_B";
|
||||
|
||||
/** C端手机号无对应用户时策略 */
|
||||
private static final String SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_PHONE_FOR_C_KEY = "SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_PHONE_FOR_C";
|
||||
|
||||
/** B端邮箱无对应用户时策略 */
|
||||
private static final String SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_EMAIL_FOR_B_KEY = "SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_EMAIL_FOR_B";
|
||||
|
||||
/** C端邮箱无对应用户时策略 */
|
||||
private static final String SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_EMAIL_FOR_C_KEY = "SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_EMAIL_FOR_C";
|
||||
|
||||
/** B端注册是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_B_KEY = "SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_B";
|
||||
|
||||
/** C端注册是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_C_KEY = "SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_C";
|
||||
|
||||
/** 验证码缓存前缀 */
|
||||
private static final String AUTH_VALID_CODE_CACHE_KEY = "auth-validCode:";
|
||||
|
||||
/** 失败次数缓存前缀 */
|
||||
private static final String LOGIN_ERROR_TIMES_KEY_PREFIX = "login-error-times:";
|
||||
|
||||
@Resource(name = "loginUserApi")
|
||||
|
@ -78,6 +154,9 @@ public class AuthServiceImpl implements AuthService {
|
|||
@Resource
|
||||
private DevSmsApi devSmsApi;
|
||||
|
||||
@Resource
|
||||
private DevEmailApi devEmailApi;
|
||||
|
||||
@Resource
|
||||
private CommonCacheOperator commonCacheOperator;
|
||||
|
||||
|
@ -97,13 +176,17 @@ public class AuthServiceImpl implements AuthService {
|
|||
authPicValidCodeResult.setValidCodeBase64(validCodeBase64);
|
||||
// 将请求号返回前端
|
||||
authPicValidCodeResult.setValidCodeReqNo(validCodeReqNo);
|
||||
// 将请求号作为key,验证码的值作为value放到redis,用于校验,5分钟有效
|
||||
commonCacheOperator.put(AUTH_VALID_CODE_CACHE_KEY + validCodeReqNo, validCode, 5 * 60);
|
||||
// 获取验证码失效时间(单位:秒)
|
||||
long validCodeExpiredDuration = this.getValidCodeExpiredDuration(type);
|
||||
// 将请求号作为key,验证码的值作为value放到redis,用于校验
|
||||
commonCacheOperator.put(AUTH_VALID_CODE_CACHE_KEY + validCodeReqNo, validCode, validCodeExpiredDuration);
|
||||
return authPicValidCodeResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPhoneValidCode(AuthGetPhoneValidCodeParam authGetPhoneValidCodeParam, String type) {
|
||||
// 校验是否允许手机号登录
|
||||
this.checkAllowPhoneLoginFlag(type);
|
||||
// 手机号
|
||||
String phone = authGetPhoneValidCodeParam.getPhone();
|
||||
// 验证码
|
||||
|
@ -111,26 +194,123 @@ public class AuthServiceImpl implements AuthService {
|
|||
// 验证码请求号
|
||||
String validCodeReqNo = authGetPhoneValidCodeParam.getValidCodeReqNo();
|
||||
// 校验参数
|
||||
validPhoneValidCodeParam(null, validCode, validCodeReqNo, type);
|
||||
validPhoneOrEmailValidCodeParam(null, AuthPhoneOrEmailTypeEnum.PHONE.getValue(), validCode, validCodeReqNo, type);
|
||||
// 生成手机验证码的值,随机6为数字
|
||||
String phoneValidCode = RandomUtil.randomNumbers(6);
|
||||
// 生成手机验证码的请求号
|
||||
String phoneValidCodeReqNo = IdWorker.getIdStr();
|
||||
|
||||
// TODO 使用阿里云执行发送验证码,将验证码作为短信内容的参数变量放入,
|
||||
// TODO 签名不传则使用系统默认配置的签名,支持传入多个参数,示例:{"name":"张三","number":"15038****76"}
|
||||
//devSmsApi.sendSmsAliyun(phone, null, "验证码模板号", JSONUtil.toJsonStr(JSONUtil.createObj().set("validCode", phoneValidCode)));
|
||||
|
||||
// TODO 使用腾讯云执行发送验证码,将验证码作为短信内容的参数变量放入,
|
||||
// TODO sdkAppId和签名不传则使用系统默认配置的sdkAppId和签名,支持传入多个参数,逗号拼接,示例:"张三,15038****76,进行中"
|
||||
devSmsApi.sendSmsTencent("sdkAppId", phone, "签名", "模板编码", phoneValidCode);
|
||||
|
||||
// 将请求号作为key,验证码的值作为value放到redis,用于校验,5分钟有效
|
||||
commonCacheOperator.put(AUTH_VALID_CODE_CACHE_KEY + phone + StrUtil.UNDERLINE + phoneValidCodeReqNo, phoneValidCode, 5 * 60);
|
||||
// 登录验证码短信消息模板编码
|
||||
String smsTemplateCode;
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
smsTemplateCode = devConfigApi.getValueByKey(SNOWY_SMS_TEMPLATE_VALID_CODE_LOGIN_FOR_B_KEY);
|
||||
} else {
|
||||
smsTemplateCode = devConfigApi.getValueByKey(SNOWY_SMS_TEMPLATE_VALID_CODE_LOGIN_FOR_C_KEY);
|
||||
}
|
||||
if(ObjectUtil.isEmpty(smsTemplateCode)){
|
||||
throw new CommonException("请联系管理员配置{}端登录验证码短信消息模板编码", type);
|
||||
}
|
||||
// 获取验证码失效时间(单位:秒)
|
||||
long validCodeExpiredDuration = this.getValidCodeExpiredDuration(type);
|
||||
// 模板内容转为JSONObject
|
||||
JSONObject contentJSONObject = JSONUtil.parseObj(smsTemplateCode);
|
||||
// 定义变量参数
|
||||
JSONObject paramMap = JSONUtil.createObj().set("userPhone", phone).set("validCode", phoneValidCode).set("validTime", validCodeExpiredDuration/60);
|
||||
// 获取编码
|
||||
String codeValue = contentJSONObject.getStr("code");
|
||||
// 发送短信
|
||||
devSmsApi.sendDynamicSms(phone, codeValue, paramMap);
|
||||
// 将请求号作为key,验证码的值作为value放到redis,用于校验
|
||||
commonCacheOperator.put(AUTH_VALID_CODE_CACHE_KEY + phone + StrUtil.UNDERLINE + phoneValidCodeReqNo, phoneValidCode, validCodeExpiredDuration);
|
||||
// 返回请求号
|
||||
return phoneValidCodeReqNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验是否允许手机号登录
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/8/25 15:16
|
||||
**/
|
||||
private void checkAllowPhoneLoginFlag(String type) {
|
||||
// 是否允许手机号登录
|
||||
String allowPhoneLoginFlag;
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
allowPhoneLoginFlag = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_B_KEY);
|
||||
} else {
|
||||
allowPhoneLoginFlag = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_C_KEY);
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(allowPhoneLoginFlag)) {
|
||||
if(!Convert.toBool(allowPhoneLoginFlag)) {
|
||||
throw new CommonException("管理员未开启手机号登录");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEmailValidCode(AuthGetEmailValidCodeParam authGetEmailValidCodeParam, String type) {
|
||||
// 校验是否允许邮箱登录
|
||||
this.checkAllowEmailLoginFlag(type);
|
||||
// 邮箱 */
|
||||
String email = authGetEmailValidCodeParam.getEmail();
|
||||
// 验证码
|
||||
String validCode = authGetEmailValidCodeParam.getValidCode();
|
||||
// 验证码请求号
|
||||
String validCodeReqNo = authGetEmailValidCodeParam.getValidCodeReqNo();
|
||||
// 校验参数
|
||||
validPhoneOrEmailValidCodeParam(null, AuthPhoneOrEmailTypeEnum.EMAIL.getValue(), validCode, validCodeReqNo, type);
|
||||
// 生成邮箱验证码的值,随机6为数字
|
||||
String emailValidCode = RandomUtil.randomNumbers(6);
|
||||
// 生成邮箱验证码的请求号
|
||||
String emailValidCodeReqNo = IdWorker.getIdStr();
|
||||
// 登录验证码邮件消息模板内容
|
||||
String emailTemplateContent;
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
emailTemplateContent = devConfigApi.getValueByKey(SNOWY_EMAIL_TEMPLATE_VALID_CODE_LOGIN_FOR_B_KEY);
|
||||
} else {
|
||||
emailTemplateContent = devConfigApi.getValueByKey(SNOWY_EMAIL_TEMPLATE_VALID_CODE_LOGIN_FOR_C_KEY);
|
||||
}
|
||||
if(ObjectUtil.isEmpty(emailTemplateContent)){
|
||||
throw new CommonException("请联系管理员配置{}端登录验证码邮件消息模板内容", type);
|
||||
}
|
||||
// 获取验证码失效时间(单位:秒)
|
||||
long validCodeExpiredDuration = this.getValidCodeExpiredDuration(type);
|
||||
// 模板内容转为JSONObject
|
||||
JSONObject contentJSONObject = JSONUtil.parseObj(emailTemplateContent);
|
||||
// 定义变量参数
|
||||
JSONObject paramMap = JSONUtil.createObj().set("userEmail", email).set("validCode", emailValidCode).set("validTime", validCodeExpiredDuration/60);
|
||||
// 获取格式化后的主题
|
||||
String subject = AuthEmailFormatUtl.format(contentJSONObject.getStr("subject"), paramMap);;
|
||||
// 获取格式化后的内容
|
||||
String content = AuthEmailFormatUtl.format(contentJSONObject.getStr("content"), paramMap);;
|
||||
// 发送邮件
|
||||
devEmailApi.sendDynamicHtmlEmail(email, subject, content);
|
||||
// 将请求号作为key,验证码的值作为value放到redis,用于校验
|
||||
commonCacheOperator.put(AUTH_VALID_CODE_CACHE_KEY + email + StrUtil.UNDERLINE + emailValidCodeReqNo, emailValidCode, validCodeExpiredDuration);
|
||||
// 返回请求号
|
||||
return emailValidCodeReqNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验是否允许邮箱登录
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/8/25 15:16
|
||||
**/
|
||||
private void checkAllowEmailLoginFlag(String type) {
|
||||
// 是否允许邮箱登录
|
||||
String allowEmailLoginFlag;
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
allowEmailLoginFlag = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_B_KEY);
|
||||
} else {
|
||||
allowEmailLoginFlag = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_C_KEY);
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(allowEmailLoginFlag)) {
|
||||
if(!Convert.toBool(allowEmailLoginFlag)) {
|
||||
throw new CommonException("管理员未开启邮箱登录");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码方法
|
||||
*
|
||||
|
@ -141,8 +321,10 @@ public class AuthServiceImpl implements AuthService {
|
|||
// 依据请求号,取出缓存中的验证码进行校验
|
||||
Object existValidCode;
|
||||
if(ObjectUtil.isEmpty(phoneOrEmail)) {
|
||||
// 图形验证码
|
||||
existValidCode = commonCacheOperator.get(AUTH_VALID_CODE_CACHE_KEY + validCodeReqNo);
|
||||
} else {
|
||||
// 手机或者邮箱验证码
|
||||
existValidCode = commonCacheOperator.get(AUTH_VALID_CODE_CACHE_KEY + phoneOrEmail + StrUtil.UNDERLINE + validCodeReqNo);
|
||||
}
|
||||
// 为空则直接验证码错误
|
||||
|
@ -151,8 +333,10 @@ public class AuthServiceImpl implements AuthService {
|
|||
}
|
||||
// 移除该验证码
|
||||
if(ObjectUtil.isEmpty(phoneOrEmail)) {
|
||||
// 图形验证码
|
||||
commonCacheOperator.remove(AUTH_VALID_CODE_CACHE_KEY + validCodeReqNo);
|
||||
} else {
|
||||
// 手机或者邮箱验证码
|
||||
commonCacheOperator.remove(AUTH_VALID_CODE_CACHE_KEY + phoneOrEmail + StrUtil.UNDERLINE + validCodeReqNo);
|
||||
}
|
||||
// 不一致则直接验证码错误
|
||||
|
@ -167,28 +351,59 @@ public class AuthServiceImpl implements AuthService {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/8/25 14:29
|
||||
**/
|
||||
private void validPhoneValidCodeParam(String phoneOrEmail, String validCode, String validCodeReqNo, String type) {
|
||||
private String validPhoneOrEmailValidCodeParam(String phoneOrEmail, String phoneOrEmailType, String validCode,
|
||||
String validCodeReqNo, String type) {
|
||||
// 验证码正确则校验手机号格式
|
||||
if(ObjectUtil.isEmpty(phoneOrEmail)) {
|
||||
// 执行校验验证码
|
||||
validValidCode(null, validCode, validCodeReqNo);
|
||||
} else {
|
||||
if(!PhoneUtil.isMobile(phoneOrEmail) && !CommonEmailUtil.isEmail(phoneOrEmail)) {
|
||||
throw new CommonException(AuthExceptionEnum.PHONE_FORMAT_ERROR.getValue());
|
||||
}
|
||||
// 执行校验验证码
|
||||
validValidCode(phoneOrEmail, validCode, validCodeReqNo);
|
||||
|
||||
// 根据手机号获取用户信息,判断用户是否存在,根据B端或C端判断
|
||||
// 根据手机号或者邮箱获取用户信息,判断用户是否存在,根据B端或C端判断
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
if(ObjectUtil.isEmpty(loginUserApi.getUserByPhone(phoneOrEmail))) {
|
||||
throw new CommonException(AuthExceptionEnum.PHONE_ERROR.getValue());
|
||||
if(phoneOrEmailType.equals(AuthPhoneOrEmailTypeEnum.PHONE.getValue())) {
|
||||
SaBaseLoginUser saBaseLoginUser = loginUserApi.getUserByPhone(phoneOrEmail);
|
||||
if(ObjectUtil.isEmpty(saBaseLoginUser)) {
|
||||
// B端手机号无对应用户时策略
|
||||
return devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_PHONE_FOR_B_KEY);
|
||||
}
|
||||
} else {
|
||||
SaBaseLoginUser saBaseLoginUser = loginUserApi.getUserByEmail(phoneOrEmail);
|
||||
if(ObjectUtil.isEmpty(saBaseLoginUser)) {
|
||||
// B端邮箱无对应用户时策略
|
||||
return devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_EMAIL_FOR_B_KEY);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(ObjectUtil.isEmpty(clientLoginUserApi.getClientUserByPhone(phoneOrEmail))) {
|
||||
throw new CommonException(AuthExceptionEnum.PHONE_ERROR.getValue());
|
||||
if(phoneOrEmailType.equals(AuthPhoneOrEmailTypeEnum.PHONE.getValue())) {
|
||||
SaBaseClientLoginUser saBaseClientLoginUser = clientLoginUserApi.getClientUserByPhone(phoneOrEmail);
|
||||
if(ObjectUtil.isEmpty(saBaseClientLoginUser)) {
|
||||
// C端手机号无对应用户时策略
|
||||
return devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_PHONE_FOR_C_KEY);
|
||||
}
|
||||
} else {
|
||||
SaBaseClientLoginUser saBaseClientLoginUser = clientLoginUserApi.getClientUserByEmail(phoneOrEmail);
|
||||
if(ObjectUtil.isEmpty(saBaseClientLoginUser)) {
|
||||
// BC端邮箱无对应用户时策略
|
||||
return devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_STRATEGY_WHEN_NO_USER_WITH_EMAIL_FOR_C_KEY);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 执行校验图形验证码
|
||||
validValidCode(null, validCode, validCodeReqNo);
|
||||
// 返回空值
|
||||
return null;
|
||||
} else {
|
||||
AuthPhoneOrEmailTypeEnum.validate(phoneOrEmailType);
|
||||
if(phoneOrEmailType.equals(AuthPhoneOrEmailTypeEnum.PHONE.getValue())) {
|
||||
if(!PhoneUtil.isMobile(phoneOrEmail)) {
|
||||
throw new CommonException(AuthExceptionEnum.PHONE_FORMAT_ERROR.getValue());
|
||||
}
|
||||
} else {
|
||||
if(CommonEmailUtil.isNotEmail(phoneOrEmail)) {
|
||||
throw new CommonException(AuthExceptionEnum.PHONE_FORMAT_ERROR.getValue());
|
||||
}
|
||||
}
|
||||
// 执行校验手机或者邮箱验证码
|
||||
validValidCode(phoneOrEmail, validCode, validCodeReqNo);
|
||||
// 返回空值
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,7 +424,12 @@ public class AuthServiceImpl implements AuthService {
|
|||
AuthDeviceTypeEnum.validate(device);
|
||||
}
|
||||
// 校验验证码
|
||||
String defaultCaptchaOpen = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_KEY);
|
||||
String defaultCaptchaOpen;
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
defaultCaptchaOpen = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_FLAG_FOR_B_KEY);
|
||||
} else {
|
||||
defaultCaptchaOpen = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_FLAG_FOR_C_KEY);
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(defaultCaptchaOpen)) {
|
||||
if(Convert.toBool(defaultCaptchaOpen)) {
|
||||
// 获取验证码
|
||||
|
@ -224,7 +444,7 @@ public class AuthServiceImpl implements AuthService {
|
|||
if(ObjectUtil.isEmpty(validCodeReqNo)) {
|
||||
throw new CommonException(AuthExceptionEnum.VALID_CODE_REQ_NO_EMPTY.getValue());
|
||||
}
|
||||
// 执行校验验证码
|
||||
// 执行校验图形验证码
|
||||
validValidCode(null, validCode, validCodeReqNo);
|
||||
}
|
||||
}
|
||||
|
@ -240,24 +460,24 @@ public class AuthServiceImpl implements AuthService {
|
|||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
SaBaseLoginUser saBaseLoginUser = loginUserApi.getUserByAccount(account);
|
||||
if(ObjectUtil.isEmpty(saBaseLoginUser)) {
|
||||
// 提示账号错误
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_ERROR.getValue());
|
||||
}
|
||||
if (!saBaseLoginUser.getPassword().equals(passwordHash)) {
|
||||
// 记录登录次数 和 过期时间
|
||||
saveLoginTimes(account);
|
||||
throw new CommonException(AuthExceptionEnum.PWD_ERROR.getValue());
|
||||
// 密码错误,处理剩余次数提示信息
|
||||
handleRemainingTimes(account, AuthExceptionEnum.PWD_ERROR.getValue(), type);
|
||||
}
|
||||
// 删除redis 中的key
|
||||
clearLoginErrorTimes(account);
|
||||
// 执行B端登录
|
||||
return execLoginB(saBaseLoginUser, device);
|
||||
} else {
|
||||
SaBaseClientLoginUser saBaseClientLoginUser = clientLoginUserApi.getClientUserByAccount(account);
|
||||
if(ObjectUtil.isEmpty(saBaseClientLoginUser)) {
|
||||
// 提示账号错误
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_ERROR.getValue());
|
||||
}
|
||||
if (!saBaseClientLoginUser.getPassword().equals(passwordHash)) {
|
||||
throw new CommonException(AuthExceptionEnum.PWD_ERROR.getValue());
|
||||
// 密码错误,处理剩余次数提示信息
|
||||
handleRemainingTimes(account, AuthExceptionEnum.PWD_ERROR.getValue(), type);
|
||||
}
|
||||
// 执行C端登录
|
||||
return execLoginC(saBaseClientLoginUser, device);
|
||||
|
@ -266,10 +486,14 @@ public class AuthServiceImpl implements AuthService {
|
|||
|
||||
@Override
|
||||
public String doLoginByPhone(AuthPhoneValidCodeLoginParam authPhoneValidCodeLoginParam, String type) {
|
||||
// 校验是否允许手机号登录
|
||||
this.checkAllowPhoneLoginFlag(type);
|
||||
// 手机号
|
||||
String phone = authPhoneValidCodeLoginParam.getPhone();
|
||||
// 校验参数
|
||||
validPhoneValidCodeParam(phone, authPhoneValidCodeLoginParam.getValidCode(), authPhoneValidCodeLoginParam.getValidCodeReqNo(), type);
|
||||
// 校验参数,返回手机号无对应用户时的策略
|
||||
String strategyWhenNoUserWithPhoneOrEmail = validPhoneOrEmailValidCodeParam(phone,
|
||||
AuthPhoneOrEmailTypeEnum.PHONE.getValue(), authPhoneValidCodeLoginParam.getValidCode(),
|
||||
authPhoneValidCodeLoginParam.getValidCodeReqNo(), type);
|
||||
// 设备
|
||||
String device = authPhoneValidCodeLoginParam.getDevice();
|
||||
// 默认指定为PC,如在小程序跟移动端的情况下,自行指定即可
|
||||
|
@ -282,20 +506,115 @@ public class AuthServiceImpl implements AuthService {
|
|||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
SaBaseLoginUser saBaseLoginUser = loginUserApi.getUserByPhone(phone);
|
||||
if(ObjectUtil.isEmpty(saBaseLoginUser)) {
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_ERROR.getValue());
|
||||
// 判断手机号无对应用户时的策略,如果为空则直接抛出异常
|
||||
if(ObjectUtil.isEmpty(strategyWhenNoUserWithPhoneOrEmail)) {
|
||||
throw new CommonException("手机号码:{}不存在对应用户", phone);
|
||||
} else {
|
||||
// 如果不允许登录,则抛出异常
|
||||
if(AuthStrategyWhenNoUserWithPhoneOrEmailEnum.NOT_ALLOW_LOGIN.getValue().equals(strategyWhenNoUserWithPhoneOrEmail)) {
|
||||
throw new CommonException("手机号码:{}不存在对应用户", phone);
|
||||
} else {
|
||||
// 根据手机号自动创建B端用户
|
||||
saBaseLoginUser = loginUserApi.createUserWithPhone(phone);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 执行B端登录
|
||||
return execLoginB(saBaseLoginUser, device);
|
||||
} else {
|
||||
SaBaseClientLoginUser saBaseClientLoginUser = clientLoginUserApi.getClientUserByPhone(phone);
|
||||
if(ObjectUtil.isEmpty(saBaseClientLoginUser)) {
|
||||
throw new CommonException(AuthExceptionEnum.ACCOUNT_ERROR.getValue());
|
||||
// 判断手机号无对应用户时的策略,如果为空则直接抛出异常
|
||||
if(ObjectUtil.isEmpty(strategyWhenNoUserWithPhoneOrEmail)) {
|
||||
throw new CommonException("手机号码:{}不存在对应用户", phone);
|
||||
} else {
|
||||
// 如果不允许登录,则抛出异常
|
||||
if(AuthStrategyWhenNoUserWithPhoneOrEmailEnum.NOT_ALLOW_LOGIN.getValue().equals(strategyWhenNoUserWithPhoneOrEmail)) {
|
||||
throw new CommonException("手机号码:{}不存在对应用户", phone);
|
||||
} else {
|
||||
// 根据手机号自动创建C端用户
|
||||
saBaseClientLoginUser = clientLoginUserApi.createClientUserWithPhone(phone);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 执行C端登录
|
||||
return execLoginC(saBaseClientLoginUser, device);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doLoginByEmail(AuthEmailValidCodeLoginParam authEmailValidCodeLoginParam, String type) {
|
||||
// 校验是否允许邮箱登录
|
||||
this.checkAllowEmailLoginFlag(type);
|
||||
// 邮箱
|
||||
String email = authEmailValidCodeLoginParam.getEmail();
|
||||
// 校验参数,返回邮箱无对应用户时的策略
|
||||
String strategyWhenNoUserWithPhoneOrEmail = validPhoneOrEmailValidCodeParam(email,
|
||||
AuthPhoneOrEmailTypeEnum.EMAIL.getValue(), authEmailValidCodeLoginParam.getValidCode(),
|
||||
authEmailValidCodeLoginParam.getValidCodeReqNo(), type);
|
||||
// 设备
|
||||
String device = authEmailValidCodeLoginParam.getDevice();
|
||||
// 默认指定为PC,如在小程序跟移动端的情况下,自行指定即可
|
||||
if(ObjectUtil.isEmpty(device)) {
|
||||
device = AuthDeviceTypeEnum.PC.getValue();
|
||||
} else {
|
||||
AuthDeviceTypeEnum.validate(device);
|
||||
}
|
||||
// 根据邮箱获取用户信息,根据B端或C端判断
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
SaBaseLoginUser saBaseLoginUser = loginUserApi.getUserByEmail(email);
|
||||
if(ObjectUtil.isEmpty(saBaseLoginUser)) {
|
||||
// 判断邮箱无对应用户时的策略,如果为空则直接抛出异常
|
||||
if(ObjectUtil.isEmpty(strategyWhenNoUserWithPhoneOrEmail)) {
|
||||
throw new CommonException("邮箱:{}不存在对应用户", email);
|
||||
} else {
|
||||
// 如果不允许登录,则抛出异常
|
||||
if(AuthStrategyWhenNoUserWithPhoneOrEmailEnum.NOT_ALLOW_LOGIN.getValue().equals(strategyWhenNoUserWithPhoneOrEmail)) {
|
||||
throw new CommonException("邮箱:{}不存在对应用户", email);
|
||||
} else {
|
||||
// 根据邮箱自动创建B端用户
|
||||
saBaseLoginUser = loginUserApi.createUserWithEmail(email);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 执行B端登录
|
||||
return execLoginB(saBaseLoginUser, device);
|
||||
} else {
|
||||
SaBaseClientLoginUser saBaseClientLoginUser = clientLoginUserApi.getClientUserByEmail(email);
|
||||
if(ObjectUtil.isEmpty(saBaseClientLoginUser)) {
|
||||
// 判断邮箱无对应用户时的策略,如果为空则直接抛出异常
|
||||
if(ObjectUtil.isEmpty(strategyWhenNoUserWithPhoneOrEmail)) {
|
||||
throw new CommonException("邮箱:{}不存在对应用户", email);
|
||||
} else {
|
||||
// 如果不允许登录,则抛出异常
|
||||
if(AuthStrategyWhenNoUserWithPhoneOrEmailEnum.NOT_ALLOW_LOGIN.getValue().equals(strategyWhenNoUserWithPhoneOrEmail)) {
|
||||
throw new CommonException("邮箱:{}不存在对应用户", email);
|
||||
} else {
|
||||
// 根据邮箱自动创建C端用户
|
||||
saBaseClientLoginUser = clientLoginUserApi.createClientUserWithEmail(email);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 执行C端登录
|
||||
return execLoginC(saBaseClientLoginUser, device);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理剩余次数提示信息
|
||||
*/
|
||||
private void handleRemainingTimes(String account, String errorMessage, String type) {
|
||||
// 记录登录次数 和 过期时间
|
||||
int remainingTimes = saveLoginTimes(account, type);
|
||||
if(remainingTimes == 0) {
|
||||
// 此时已封禁,返回提示语
|
||||
isDisableTime(account);
|
||||
} else {
|
||||
// 提示错误
|
||||
throw new CommonException(errorMessage + ",您还可以尝试【" + remainingTimes + "】次");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否封禁状态
|
||||
* 如果被封禁了,执行以下逻辑,返回前端还需等待的时间
|
||||
|
@ -304,33 +623,81 @@ public class AuthServiceImpl implements AuthService {
|
|||
// disableTime = -2表示未被封禁
|
||||
long disableTime = StpUtil.getDisableTime(userAccount);
|
||||
if (disableTime > 0) {
|
||||
if (disableTime > 60) {
|
||||
throw new CommonException(userAccount + "账号已被封禁, 请再"+ disableTime/60+ "分钟后重新尝试登录!!");
|
||||
}
|
||||
throw new CommonException(userAccount + "账号已被封禁, 请再"+ disableTime+ "秒后重新尝试登录!!");
|
||||
String formatTime = CommonTimeFormatUtil.formatSeconds(disableTime);
|
||||
throw new CommonException("账号" + userAccount + "已被封禁, 请在"+ formatTime+ "后重新尝试登录!");
|
||||
}
|
||||
}
|
||||
|
||||
// redis中保存登录错误次数
|
||||
private void saveLoginTimes(String userAccount){
|
||||
String loginErrorKey = LOGIN_ERROR_TIMES_KEY_PREFIX + userAccount;
|
||||
/**
|
||||
* redis中保存登录错误次数
|
||||
*/
|
||||
private int saveLoginTimes(String userAccount, String type){
|
||||
// 获取连续登录失败持续时间
|
||||
String configContinuousLoginFailDuration;
|
||||
// 获取连续登录失败次数
|
||||
String configContinuousLoginFailTimes;
|
||||
// 获取连续登录失败锁定时间
|
||||
String configContinuousLoginFailLockDuration;
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
configContinuousLoginFailDuration = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_DURATION_FOR_B_KEY);
|
||||
configContinuousLoginFailTimes = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_TIMES_FOR_B_KEY);
|
||||
configContinuousLoginFailLockDuration = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_LOCK_DURATION_FOR_B_KEY);
|
||||
} else {
|
||||
configContinuousLoginFailDuration = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_DURATION_FOR_C_KEY);
|
||||
configContinuousLoginFailTimes = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_TIMES_FOR_C_KEY);
|
||||
configContinuousLoginFailLockDuration = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CONTINUOUS_LOGIN_FAIL_LOCK_DURATION_FOR_C_KEY);
|
||||
}
|
||||
// 连续登录失败持续时间默认5分钟
|
||||
long continuousLoginFailDuration = 5 * 60;
|
||||
if(ObjectUtil.isNotEmpty(configContinuousLoginFailDuration)){
|
||||
// 配置了则使用配置的失效时间
|
||||
continuousLoginFailDuration = Convert.toLong(configContinuousLoginFailDuration) * 60;
|
||||
}
|
||||
|
||||
// 连续登录失败次数默认5次
|
||||
int continuousLoginFailTimes = 5;
|
||||
if(ObjectUtil.isNotEmpty(configContinuousLoginFailTimes)){
|
||||
// 配置了则使用配置的失效时间
|
||||
continuousLoginFailTimes = Convert.toInt(configContinuousLoginFailTimes);
|
||||
}
|
||||
|
||||
// 连续登录失败锁定时间默认5分钟
|
||||
long continuousLoginFailLockDuration = 5 * 60;
|
||||
if(ObjectUtil.isNotEmpty(configContinuousLoginFailLockDuration)){
|
||||
// 配置了则使用配置的失效时间
|
||||
continuousLoginFailLockDuration = Convert.toLong(configContinuousLoginFailLockDuration) * 60;
|
||||
}
|
||||
// 获取登录失败次数缓存键
|
||||
String loginErrorKey = LOGIN_ERROR_TIMES_KEY_PREFIX + ":" + userAccount;
|
||||
// 获取登录失败次数缓存值
|
||||
Integer number = (Integer) commonCacheOperator.get(loginErrorKey);
|
||||
if (number == null) {
|
||||
// 如果redis中没有保存,代表失败第一次
|
||||
number = 2;
|
||||
commonCacheOperator.put(loginErrorKey, number,5 * 60);
|
||||
return;
|
||||
// 如果redis中没有保存,代表失败第一次,如果配置的值为1次
|
||||
if(continuousLoginFailTimes == 1) {
|
||||
// 直接进入isDisableTime方法,返回用户还需等待时间
|
||||
StpUtil.disable(userAccount, continuousLoginFailLockDuration);
|
||||
// 删除redis 中的key
|
||||
clearLoginErrorTimes(userAccount);
|
||||
return 0;
|
||||
} else {
|
||||
// 否则失败次数为2
|
||||
number = 2;
|
||||
commonCacheOperator.put(loginErrorKey, number, continuousLoginFailDuration);
|
||||
return continuousLoginFailTimes - number + 1;
|
||||
}
|
||||
} else {
|
||||
if (number < continuousLoginFailTimes) {
|
||||
number++;
|
||||
commonCacheOperator.put(loginErrorKey, number, continuousLoginFailDuration);
|
||||
return continuousLoginFailTimes - number + 1;
|
||||
} else {
|
||||
// 第N次封禁账号,第N+1次进入isDisableTime方法,返回用户还需等待时间
|
||||
StpUtil.disable(userAccount, continuousLoginFailLockDuration);
|
||||
// 删除redis 中的key
|
||||
clearLoginErrorTimes(userAccount);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (number < 5) {
|
||||
number++;
|
||||
commonCacheOperator.put(loginErrorKey, number,5 * 60);
|
||||
return;
|
||||
}
|
||||
// 第五次封禁账号,第六次进入isDisableTime方法,返回用户还需等待时间
|
||||
StpUtil.disable(userAccount, 5 * 60);
|
||||
// 删除redis 中的key
|
||||
clearLoginErrorTimes(userAccount);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -338,7 +705,8 @@ public class AuthServiceImpl implements AuthService {
|
|||
* @param userAccount 账号
|
||||
*/
|
||||
private void clearLoginErrorTimes(String userAccount) {
|
||||
String loginErrorKey = LOGIN_ERROR_TIMES_KEY_PREFIX + userAccount;
|
||||
// 获取登录失败次数缓存键
|
||||
String loginErrorKey = LOGIN_ERROR_TIMES_KEY_PREFIX + ":" + userAccount;
|
||||
// 删除redis中的key
|
||||
commonCacheOperator.remove(loginErrorKey);
|
||||
}
|
||||
|
@ -466,11 +834,11 @@ public class AuthServiceImpl implements AuthService {
|
|||
// 填充B端用户信息并更新缓存
|
||||
fillSaBaseLoginUserAndUpdateCache(saBaseLoginUser);
|
||||
// 去掉密码
|
||||
saBaseLoginUser.setPassword(null);
|
||||
saBaseLoginUser.setPassword("******");
|
||||
// 去掉权限码
|
||||
saBaseLoginUser.setPermissionCodeList(null);
|
||||
saBaseLoginUser.setPermissionCodeList(CollectionUtil.newArrayList());
|
||||
// 去掉数据范围
|
||||
saBaseLoginUser.setDataScopeList(null);
|
||||
saBaseLoginUser.setDataScopeList(CollectionUtil.newArrayList());
|
||||
// 返回
|
||||
return saBaseLoginUser;
|
||||
}
|
||||
|
@ -490,11 +858,11 @@ public class AuthServiceImpl implements AuthService {
|
|||
// 填充C端用户信息并更新缓存
|
||||
fillSaBaseClientLoginUserAndUpdateCache(saBaseClientLoginUser);
|
||||
// 去掉密码
|
||||
saBaseClientLoginUser.setPassword(null);
|
||||
saBaseClientLoginUser.setPassword("******");
|
||||
// 去掉权限码
|
||||
saBaseClientLoginUser.setPermissionCodeList(null);
|
||||
saBaseClientLoginUser.setPermissionCodeList(CollectionUtil.newArrayList());
|
||||
// 去掉数据范围
|
||||
saBaseClientLoginUser.setDataScopeList(null);
|
||||
saBaseClientLoginUser.setDataScopeList(CollectionUtil.newArrayList());
|
||||
// 返回
|
||||
return saBaseClientLoginUser;
|
||||
}
|
||||
|
@ -518,4 +886,93 @@ public class AuthServiceImpl implements AuthService {
|
|||
return execLoginC(saBaseClientLoginUser, device);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(AuthRegisterParam authRegisterParam, String type) {
|
||||
// 校验是否允许注册
|
||||
this.checkAllowRegisterFlag(type);
|
||||
// 获取账号
|
||||
String account = authRegisterParam.getAccount();
|
||||
// 获取密码
|
||||
String password = authRegisterParam.getPassword();
|
||||
// 校验验证码
|
||||
String defaultCaptchaOpen;
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
defaultCaptchaOpen = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_FLAG_FOR_B_KEY);
|
||||
} else {
|
||||
defaultCaptchaOpen = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CAPTCHA_OPEN_FLAG_FOR_C_KEY);
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(defaultCaptchaOpen)) {
|
||||
if(Convert.toBool(defaultCaptchaOpen)) {
|
||||
// 获取验证码
|
||||
String validCode = authRegisterParam.getValidCode();
|
||||
// 获取验证码请求号
|
||||
String validCodeReqNo = authRegisterParam.getValidCodeReqNo();
|
||||
// 开启验证码则必须传入验证码
|
||||
if(ObjectUtil.isEmpty(validCode)) {
|
||||
throw new CommonException(AuthExceptionEnum.VALID_CODE_EMPTY.getValue());
|
||||
}
|
||||
// 开启验证码则必须传入验证码请求号
|
||||
if(ObjectUtil.isEmpty(validCodeReqNo)) {
|
||||
throw new CommonException(AuthExceptionEnum.VALID_CODE_REQ_NO_EMPTY.getValue());
|
||||
}
|
||||
// 执行校验图形验证码
|
||||
validValidCode(null, validCode, validCodeReqNo);
|
||||
}
|
||||
}
|
||||
// SM2解密前端传来的密码
|
||||
String passwordDecrypt = CommonCryptogramUtil.doSm2Decrypt(password);
|
||||
// 根据账号获取用户信息,根据B端或C端判断
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
clientLoginUserApi.doRegister(account, passwordDecrypt);
|
||||
} else {
|
||||
loginUserApi.doRegister(account, passwordDecrypt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验是否开启注册
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/8/25 15:16
|
||||
**/
|
||||
private void checkAllowRegisterFlag(String type) {
|
||||
// 是否允许注册
|
||||
String allowRegisterFlag;
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
allowRegisterFlag = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_B_KEY);
|
||||
} else {
|
||||
allowRegisterFlag = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_C_KEY);
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(allowRegisterFlag)) {
|
||||
if(!Convert.toBool(allowRegisterFlag)) {
|
||||
throw new CommonException("管理员未开启注册");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证码失效时间(单位:秒)
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2025/3/21 20:25
|
||||
**/
|
||||
private long getValidCodeExpiredDuration(String type) {
|
||||
// 默认5分钟
|
||||
int defaultExpiredTime = 5;
|
||||
// 获取配置验证码失效时间(单位:分钟)
|
||||
String configCaptchaExpiredDuration;
|
||||
if(SaClientTypeEnum.B.getValue().equals(type)) {
|
||||
configCaptchaExpiredDuration = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CAPTCHA_EXPIRED_DURATION_FOR_B_KEY);
|
||||
} else {
|
||||
configCaptchaExpiredDuration = devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_CAPTCHA_EXPIRED_DURATION_FOR_C_KEY);
|
||||
}
|
||||
// 判断是否为空
|
||||
if(ObjectUtil.isNotEmpty(configCaptchaExpiredDuration)){
|
||||
// 配置了则使用配置的失效时间
|
||||
defaultExpiredTime = Convert.toInt(configCaptchaExpiredDuration);
|
||||
}
|
||||
// 转为秒
|
||||
return defaultExpiredTime * 60L;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,10 +13,11 @@
|
|||
package vip.xiaonuo.auth.modular.monitor.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
@ -32,6 +33,7 @@ import vip.xiaonuo.auth.modular.monitor.service.AuthSessionService;
|
|||
import vip.xiaonuo.common.annotation.CommonLog;
|
||||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -41,6 +43,7 @@ import java.util.List;
|
|||
* @date 2022/6/24 15:20
|
||||
**/
|
||||
@Tag(name = "会话治理控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 3)
|
||||
@RestController
|
||||
@Validated
|
||||
public class AuthSessionController {
|
||||
|
@ -54,6 +57,7 @@ public class AuthSessionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/6/24 22:28
|
||||
*/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "会话统计")
|
||||
@GetMapping("/auth/session/analysis")
|
||||
public CommonResult<AuthSessionAnalysisResult> analysis() {
|
||||
|
@ -66,6 +70,7 @@ public class AuthSessionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/6/24 22:28
|
||||
*/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "查询B端会话")
|
||||
@GetMapping("/auth/session/b/page")
|
||||
public CommonResult<Page<AuthSessionPageResult>> pageForB(AuthSessionPageParam authSessionPageParam) {
|
||||
|
@ -78,6 +83,7 @@ public class AuthSessionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/6/24 22:28
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "查询C端会话")
|
||||
@GetMapping("/auth/session/c/page")
|
||||
public CommonResult<Page<AuthSessionPageResult>> pageForC(AuthSessionPageParam authSessionPageParam) {
|
||||
|
@ -90,11 +96,12 @@ public class AuthSessionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/12 10:25
|
||||
**/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "强退B端会话")
|
||||
@CommonLog("强退B端会话")
|
||||
@PostMapping("/auth/session/b/exit")
|
||||
public CommonResult<String> exitSessionForB(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
|
||||
List<AuthExitSessionParam> authExitSessionParamList) {
|
||||
List<AuthExitSessionParam> authExitSessionParamList) {
|
||||
authSessionService.exitSessionForB(authExitSessionParamList);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
@ -105,11 +112,12 @@ public class AuthSessionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/12 10:25
|
||||
**/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "强退C端会话")
|
||||
@CommonLog("强退C端会话")
|
||||
@PostMapping("/auth/session/c/exit")
|
||||
public CommonResult<String> exitSessionForC(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
|
||||
List<AuthExitSessionParam> authExitSessionParamList) {
|
||||
List<AuthExitSessionParam> authExitSessionParamList) {
|
||||
authSessionService.exitSessionForC(authExitSessionParamList);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
@ -120,6 +128,7 @@ public class AuthSessionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/12 10:25
|
||||
**/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "强退B端token")
|
||||
@CommonLog("强退B端token")
|
||||
@PostMapping("/auth/token/b/exit")
|
||||
|
@ -135,6 +144,7 @@ public class AuthSessionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/12 10:25
|
||||
**/
|
||||
@ApiOperationSupport(order = 7)
|
||||
@Operation(summary = "强退C端token")
|
||||
@CommonLog("强退C端token")
|
||||
@PostMapping("/auth/token/c/exit")
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.auth.modular.sso.controller;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import vip.xiaonuo.auth.core.enums.SaClientTypeEnum;
|
||||
import vip.xiaonuo.auth.modular.sso.param.AuthSsoTicketLoginParam;
|
||||
import vip.xiaonuo.auth.modular.sso.service.AuthSsoService;
|
||||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 单点登录控制器
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/8/30 9:20
|
||||
**/
|
||||
@Tag(name = "单点登录控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 4)
|
||||
@RestController
|
||||
@Validated
|
||||
public class AuthSsoController {
|
||||
|
||||
@Resource
|
||||
private AuthSsoService authSsoService;
|
||||
|
||||
/**
|
||||
* 根据ticket执行单点登录
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "根据ticket执行单点登录")
|
||||
@PostMapping("/auth/sso/doLogin")
|
||||
public CommonResult<String> doLogin(@RequestBody @Valid AuthSsoTicketLoginParam authAccountPasswordLoginParam) {
|
||||
return CommonResult.data(authSsoService.doLogin(authAccountPasswordLoginParam, SaClientTypeEnum.B.getValue()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.auth.modular.sso.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* ticket单点登录登录参数
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/7/7 16:46
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AuthSsoTicketLoginParam {
|
||||
|
||||
/** ticket */
|
||||
@Schema(description = "ticket", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "ticket不能为空")
|
||||
private String ticket;
|
||||
|
||||
/** 设备 */
|
||||
@Schema(description = "设备")
|
||||
private String device;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.auth.modular.sso.service;
|
||||
|
||||
import vip.xiaonuo.auth.modular.sso.param.AuthSsoTicketLoginParam;
|
||||
|
||||
/**
|
||||
* 单点登录Service接口
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/8/30 9:20
|
||||
**/
|
||||
public interface AuthSsoService {
|
||||
|
||||
/**
|
||||
* 根据ticket执行单点登录
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/8/30 9:36
|
||||
**/
|
||||
String doLogin(AuthSsoTicketLoginParam authAccountPasswordLoginParam, String value);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.auth.modular.sso.service.impl;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import vip.xiaonuo.auth.modular.login.service.AuthService;
|
||||
import vip.xiaonuo.auth.modular.sso.param.AuthSsoTicketLoginParam;
|
||||
import vip.xiaonuo.auth.modular.sso.service.AuthSsoService;
|
||||
|
||||
/**
|
||||
* 单点登录Service接口实现类
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/8/30 9:21
|
||||
**/
|
||||
@Service
|
||||
public class AuthSsoServiceImpl implements AuthSsoService {
|
||||
|
||||
@Resource
|
||||
private AuthService authService;
|
||||
|
||||
@Override
|
||||
public String doLogin(AuthSsoTicketLoginParam authAccountPasswordLoginParam, String device) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -13,10 +13,11 @@
|
|||
package vip.xiaonuo.auth.modular.third.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import me.zhyd.oauth.model.AuthCallback;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
@ -29,6 +30,8 @@ import vip.xiaonuo.auth.modular.third.result.AuthThirdRenderResult;
|
|||
import vip.xiaonuo.auth.modular.third.service.AuthThirdService;
|
||||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 第三方登录控制器
|
||||
*
|
||||
|
@ -36,6 +39,7 @@ import vip.xiaonuo.common.pojo.CommonResult;
|
|||
* @date 2022/7/8 16:18
|
||||
**/
|
||||
@Tag(name = "三方登录控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 5)
|
||||
@RestController
|
||||
@Validated
|
||||
public class AuthThirdController {
|
||||
|
@ -49,6 +53,7 @@ public class AuthThirdController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/7/8 16:19
|
||||
**/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "第三方登录页面渲染")
|
||||
@GetMapping("/auth/third/render")
|
||||
public CommonResult<AuthThirdRenderResult> render(@Valid AuthThirdRenderParam authThirdRenderParam) {
|
||||
|
@ -61,6 +66,7 @@ public class AuthThirdController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/7/8 16:42
|
||||
**/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "第三方登录授权回调")
|
||||
@GetMapping("/auth/third/callback")
|
||||
public CommonResult<String> callback(@Valid AuthThirdCallbackParam authThirdCallbackParam, AuthCallback authCallback) {
|
||||
|
@ -73,6 +79,7 @@ public class AuthThirdController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "获取三方用户分页")
|
||||
@GetMapping("/auth/third/page")
|
||||
public CommonResult<Page<AuthThirdUser>> page(AuthThirdUserPageParam authThirdUserPageParam) {
|
||||
|
|
|
@ -45,7 +45,7 @@ public class AuthThirdUser extends CommonEntity {
|
|||
|
||||
/** 头像 */
|
||||
@Schema(description = "头像")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String avatar;
|
||||
|
||||
/** 姓名 */
|
||||
|
@ -54,12 +54,12 @@ public class AuthThirdUser extends CommonEntity {
|
|||
|
||||
/** 昵称 */
|
||||
@Schema(description = "昵称")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String nickname;
|
||||
|
||||
/** 性别 */
|
||||
@Schema(description = "性别")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String gender;
|
||||
|
||||
/** 分类 */
|
||||
|
@ -68,6 +68,6 @@ public class AuthThirdUser extends CommonEntity {
|
|||
|
||||
/** 扩展信息 */
|
||||
@Schema(description = "扩展信息")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String extJson;
|
||||
}
|
||||
|
|
|
@ -39,4 +39,4 @@
|
|||
<artifactId>snowy-plugin-dev-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -23,7 +23,9 @@ import lombok.Getter;
|
|||
@Getter
|
||||
public enum BizBuildInEnum {
|
||||
|
||||
/** 超管用户账号 */
|
||||
/**
|
||||
* 超管用户账号
|
||||
*/
|
||||
BUILD_IN_USER_ACCOUNT("superAdmin", "超管");
|
||||
|
||||
private final String value;
|
||||
|
|
|
@ -15,10 +15,11 @@ package vip.xiaonuo.biz.modular.dict.controller;
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
@ -31,6 +32,7 @@ import vip.xiaonuo.biz.modular.dict.service.BizDictService;
|
|||
import vip.xiaonuo.common.annotation.CommonLog;
|
||||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +42,7 @@ import java.util.List;
|
|||
* @date 2022/6/21 14:58
|
||||
**/
|
||||
@Tag(name = "业务字典控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 4)
|
||||
@RestController
|
||||
@Validated
|
||||
public class BizDictController {
|
||||
|
@ -53,6 +56,7 @@ public class BizDictController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "获取业务字典分页")
|
||||
@SaCheckPermission("/biz/dict/page")
|
||||
@GetMapping("/biz/dict/page")
|
||||
|
@ -66,6 +70,7 @@ public class BizDictController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "获取业务字典树")
|
||||
@SaCheckPermission("/biz/dict/tree")
|
||||
@GetMapping("/biz/dict/tree")
|
||||
|
@ -79,6 +84,7 @@ public class BizDictController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "获取所有字典树")
|
||||
@GetMapping("/biz/dict/treeAll")
|
||||
public CommonResult<List<Tree<String>>> treeAll() {
|
||||
|
@ -91,6 +97,7 @@ public class BizDictController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "编辑业务字典")
|
||||
@CommonLog("编辑业务字典")
|
||||
@SaCheckPermission("/biz/dict/edit")
|
||||
|
|
|
@ -57,6 +57,6 @@ public class BizDict extends CommonEntity {
|
|||
|
||||
/** 扩展信息 */
|
||||
@Schema(description = "扩展信息")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String extJson;
|
||||
}
|
||||
|
|
|
@ -29,17 +29,17 @@ import lombok.Setter;
|
|||
public class BizDictEditParam {
|
||||
|
||||
/** id */
|
||||
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "id")
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
|
||||
/** 字典文字 */
|
||||
@Schema(description = "字典文字", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "字典文字")
|
||||
@NotBlank(message = "dictLabel不能为空")
|
||||
private String dictLabel;
|
||||
|
||||
/** 排序码 */
|
||||
@Schema(description = "排序码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "排序码")
|
||||
@NotNull(message = "sortCode不能为空")
|
||||
private Integer sortCode;
|
||||
|
||||
|
|
|
@ -15,23 +15,23 @@ package vip.xiaonuo.biz.modular.group.controller;
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import vip.xiaonuo.biz.modular.group.entity.BizGroup;
|
||||
import vip.xiaonuo.biz.modular.group.param.*;
|
||||
import vip.xiaonuo.biz.modular.group.service.BizGroupService;
|
||||
import vip.xiaonuo.biz.modular.user.entity.BizUser;
|
||||
import vip.xiaonuo.common.annotation.CommonLog;
|
||||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
import vip.xiaonuo.biz.modular.group.entity.BizGroup;
|
||||
import vip.xiaonuo.biz.modular.group.service.BizGroupService;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
*/
|
||||
package vip.xiaonuo.biz.modular.group.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="vip.xiaonuo.biz.modular.group.mapper.BizGroupMapper">
|
||||
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
package vip.xiaonuo.biz.modular.group.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 用户组添加参数
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
package vip.xiaonuo.biz.modular.group.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 用户组编辑参数
|
||||
|
|
|
@ -13,11 +13,10 @@
|
|||
package vip.xiaonuo.biz.modular.group.param;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* 用户组Id参数
|
||||
*
|
||||
|
|
|
@ -21,7 +21,6 @@ import cn.hutool.core.lang.tree.TreeUtil;
|
|||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
@ -29,17 +28,18 @@ import jakarta.annotation.Resource;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
|
||||
import vip.xiaonuo.biz.modular.group.entity.BizGroup;
|
||||
import vip.xiaonuo.biz.modular.group.mapper.BizGroupMapper;
|
||||
import vip.xiaonuo.biz.modular.group.param.*;
|
||||
import vip.xiaonuo.biz.modular.group.service.BizGroupService;
|
||||
import vip.xiaonuo.biz.modular.org.entity.BizOrg;
|
||||
import vip.xiaonuo.biz.modular.org.service.BizOrgService;
|
||||
import vip.xiaonuo.biz.modular.user.entity.BizUser;
|
||||
import vip.xiaonuo.biz.modular.user.enums.BizUserStatusEnum;
|
||||
import vip.xiaonuo.biz.modular.user.service.BizUserService;
|
||||
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
|
||||
import vip.xiaonuo.common.exception.CommonException;
|
||||
import vip.xiaonuo.common.page.CommonPageRequest;
|
||||
import vip.xiaonuo.biz.modular.group.entity.BizGroup;
|
||||
import vip.xiaonuo.biz.modular.group.mapper.BizGroupMapper;
|
||||
import vip.xiaonuo.biz.modular.group.service.BizGroupService;
|
||||
import vip.xiaonuo.sys.api.SysGroupApi;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -143,32 +143,34 @@ public class BizGroupServiceImpl extends ServiceImpl<BizGroupMapper, BizGroup> i
|
|||
|
||||
@Override
|
||||
public Page<BizUser> userSelector(BizGroupSelectorUserParam bizGroupSelectorUserParam) {
|
||||
LambdaQueryWrapper<BizUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
QueryWrapper<BizUser> queryWrapper = new QueryWrapper<BizUser>().checkSqlInjection();
|
||||
// 只查询状态为正常的
|
||||
queryWrapper.lambda().eq(BizUser::getUserStatus, BizUserStatusEnum.ENABLE.getValue());
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizUser::getOrgId, loginUserDataScope);
|
||||
queryWrapper.lambda().in(BizUser::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
// 只查询部分字段
|
||||
lambdaQueryWrapper.select(BizUser::getId, BizUser::getAvatar, BizUser::getOrgId, BizUser::getPositionId, BizUser::getAccount,
|
||||
queryWrapper.lambda().select(BizUser::getId, BizUser::getAvatar, BizUser::getOrgId, BizUser::getPositionId, BizUser::getAccount,
|
||||
BizUser::getName, BizUser::getSortCode, BizUser::getGender, BizUser::getEntryDate);
|
||||
if (ObjectUtil.isNotEmpty(bizGroupSelectorUserParam.getOrgId())) {
|
||||
// 如果机构id不为空,则查询该机构及其子机构下的所有人
|
||||
List<String> childOrgIdList = CollStreamUtil.toList(bizOrgService.getChildListById(bizOrgService
|
||||
.getAllOrgList(), bizGroupSelectorUserParam.getOrgId(), true), BizOrg::getId);
|
||||
if (ObjectUtil.isNotEmpty(childOrgIdList)) {
|
||||
lambdaQueryWrapper.in(BizUser::getOrgId, childOrgIdList);
|
||||
queryWrapper.lambda().in(BizUser::getOrgId, childOrgIdList);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizGroupSelectorUserParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizUser::getName, bizGroupSelectorUserParam.getSearchKey());
|
||||
queryWrapper.lambda().like(BizUser::getName, bizGroupSelectorUserParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizUser::getSortCode);
|
||||
return bizUserService.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
|
||||
queryWrapper.lambda().orderByAsc(BizUser::getSortCode);
|
||||
return bizUserService.page(CommonPageRequest.defaultPage(), queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,10 +15,11 @@ package vip.xiaonuo.biz.modular.org.controller;
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
@ -26,12 +27,14 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import vip.xiaonuo.biz.modular.org.entity.BizOrg;
|
||||
import vip.xiaonuo.biz.modular.org.enums.BizOrgSourceFromTypeEnum;
|
||||
import vip.xiaonuo.biz.modular.org.param.*;
|
||||
import vip.xiaonuo.biz.modular.org.service.BizOrgService;
|
||||
import vip.xiaonuo.biz.modular.user.entity.BizUser;
|
||||
import vip.xiaonuo.common.annotation.CommonLog;
|
||||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -41,6 +44,7 @@ import java.util.List;
|
|||
* @date 2022/4/24 19:55
|
||||
*/
|
||||
@Tag(name = "机构控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 1)
|
||||
@RestController
|
||||
@Validated
|
||||
public class BizOrgController {
|
||||
|
@ -54,6 +58,7 @@ public class BizOrgController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "获取机构分页")
|
||||
@SaCheckPermission("/biz/org/page")
|
||||
@GetMapping("/biz/org/page")
|
||||
|
@ -67,6 +72,7 @@ public class BizOrgController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "获取机构树")
|
||||
@SaCheckPermission("/biz/org/tree")
|
||||
@GetMapping("/biz/org/tree")
|
||||
|
@ -80,12 +86,13 @@ public class BizOrgController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "添加机构")
|
||||
@CommonLog("添加机构")
|
||||
@SaCheckPermission("/biz/org/add")
|
||||
@PostMapping("/biz/org/add")
|
||||
public CommonResult<String> add(@RequestBody @Valid BizOrgAddParam bizOrgAddParam) {
|
||||
bizOrgService.add(bizOrgAddParam);
|
||||
bizOrgService.add(bizOrgAddParam, BizOrgSourceFromTypeEnum.SYSTEM_ADD.getValue());
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
|
@ -95,6 +102,7 @@ public class BizOrgController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "编辑机构")
|
||||
@CommonLog("编辑机构")
|
||||
@SaCheckPermission("/biz/org/edit")
|
||||
|
@ -110,6 +118,7 @@ public class BizOrgController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "删除机构")
|
||||
@CommonLog("删除机构")
|
||||
@SaCheckPermission("/biz/org/delete")
|
||||
|
@ -126,6 +135,7 @@ public class BizOrgController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "获取机构详情")
|
||||
@SaCheckPermission("/biz/org/detail")
|
||||
@GetMapping("/biz/org/detail")
|
||||
|
@ -141,6 +151,7 @@ public class BizOrgController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 7)
|
||||
@Operation(summary = "获取机构树选择器")
|
||||
@SaCheckPermission("/biz/org/orgTreeSelector")
|
||||
@GetMapping("/biz/org/orgTreeSelector")
|
||||
|
@ -154,6 +165,7 @@ public class BizOrgController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 8)
|
||||
@Operation(summary = "获取人员选择器")
|
||||
@SaCheckPermission("/biz/org/userSelector")
|
||||
@GetMapping("/biz/org/userSelector")
|
||||
|
|
|
@ -44,7 +44,7 @@ public class BizOrg extends CommonEntity {
|
|||
|
||||
/** 主管id */
|
||||
@Schema(description = "主管id")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
@Trans(type = TransType.SIMPLE, target = BizUser.class, fields = "name", alias = "director", ref = "directorName")
|
||||
private String directorId;
|
||||
|
||||
|
@ -66,6 +66,6 @@ public class BizOrg extends CommonEntity {
|
|||
|
||||
/** 扩展信息 */
|
||||
@Schema(description = "扩展信息")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String extJson;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.biz.modular.org.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import vip.xiaonuo.common.pojo.CommonEntity;
|
||||
|
||||
/**
|
||||
* 机构扩展实体
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("SYS_ORG_EXT")
|
||||
public class BizOrgExt extends CommonEntity {
|
||||
|
||||
/** id */
|
||||
@TableId
|
||||
@Schema(description = "id")
|
||||
private String id;
|
||||
|
||||
/** 机构id */
|
||||
@Schema(description = "机构id")
|
||||
private String orgId;
|
||||
|
||||
/** 来源类别 */
|
||||
@Schema(description = "来源类别")
|
||||
private String sourceFromType;
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.biz.modular.org.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 机构来源类型枚举
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/21 19:56
|
||||
**/
|
||||
@Getter
|
||||
public enum BizOrgSourceFromTypeEnum {
|
||||
|
||||
/** 系统自建 */
|
||||
SYSTEM_ADD("SYSTEM_ADD"),
|
||||
|
||||
/** 身份源 */
|
||||
ID_SOURCE("ID_SOURCE");
|
||||
|
||||
private final String value;
|
||||
|
||||
BizOrgSourceFromTypeEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.biz.modular.org.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import vip.xiaonuo.biz.modular.org.entity.BizOrgExt;
|
||||
|
||||
/**
|
||||
* 机构扩展Mapper接口
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/21 18:37
|
||||
**/
|
||||
public interface BizOrgExtMapper extends BaseMapper<BizOrgExt> {
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<?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="vip.xiaonuo.biz.modular.org.mapper.BizOrgExtMapper">
|
||||
|
||||
</mapper>
|
|
@ -29,22 +29,22 @@ import lombok.Setter;
|
|||
public class BizOrgAddParam {
|
||||
|
||||
/** 父id */
|
||||
@Schema(description = "父id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "父id")
|
||||
@NotBlank(message = "parentId不能为空")
|
||||
private String parentId;
|
||||
|
||||
/** 名称 */
|
||||
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "名称")
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 分类 */
|
||||
@Schema(description = "分类", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "分类")
|
||||
@NotBlank(message = "category不能为空")
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@Schema(description = "排序码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "排序码")
|
||||
@NotNull(message = "sortCode不能为空")
|
||||
private Integer sortCode;
|
||||
|
||||
|
|
|
@ -29,27 +29,27 @@ import lombok.Setter;
|
|||
public class BizOrgEditParam {
|
||||
|
||||
/** id */
|
||||
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "id")
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
|
||||
/** 父id */
|
||||
@Schema(description = "父id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "父id")
|
||||
@NotBlank(message = "parentId不能为空")
|
||||
private String parentId;
|
||||
|
||||
/** 名称 */
|
||||
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "名称")
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 分类 */
|
||||
@Schema(description = "分类", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "分类")
|
||||
@NotBlank(message = "category不能为空")
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@Schema(description = "排序码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "排序码")
|
||||
@NotNull(message = "sortCode不能为空")
|
||||
private Integer sortCode;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import lombok.Setter;
|
|||
public class BizOrgIdParam {
|
||||
|
||||
/** id */
|
||||
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "id")
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.springframework.stereotype.Service;
|
|||
import vip.xiaonuo.biz.api.BizOrgApi;
|
||||
import vip.xiaonuo.biz.modular.org.param.BizOrgSelectorOrgListParam;
|
||||
import vip.xiaonuo.biz.modular.org.service.BizOrgService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.biz.modular.org.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import vip.xiaonuo.biz.modular.org.entity.BizOrgExt;
|
||||
|
||||
/**
|
||||
* 机构扩展Service接口
|
||||
*
|
||||
* @author yubaoshan
|
||||
* @date 2024/12/21 01:25
|
||||
**/
|
||||
public interface BizOrgExtService extends IService<BizOrgExt> {
|
||||
|
||||
/**
|
||||
* 插入扩展信息
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/27 21:38
|
||||
*/
|
||||
void createExtInfo(String orgId, String sourceFromType);
|
||||
}
|
|
@ -51,7 +51,7 @@ public interface BizOrgService extends IService<BizOrg> {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:48
|
||||
*/
|
||||
void add(BizOrgAddParam bizOrgAddParam);
|
||||
void add(BizOrgAddParam bizOrgAddParam, String sourceFromType);
|
||||
|
||||
/**
|
||||
* 编辑机构
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.biz.modular.org.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import vip.xiaonuo.biz.modular.org.entity.BizOrgExt;
|
||||
import vip.xiaonuo.biz.modular.org.mapper.BizOrgExtMapper;
|
||||
import vip.xiaonuo.biz.modular.org.service.BizOrgExtService;
|
||||
|
||||
/**
|
||||
* 机构扩展Service接口实现类
|
||||
*
|
||||
* @author yubaoshan
|
||||
* @date 2024/12/21 01:25
|
||||
**/
|
||||
@Service
|
||||
public class BizOrgExtServiceImpl extends ServiceImpl<BizOrgExtMapper, BizOrgExt> implements BizOrgExtService {
|
||||
|
||||
@Override
|
||||
public void createExtInfo(String orgId, String sourceFromType) {
|
||||
BizOrgExt bizOrgExt = new BizOrgExt();
|
||||
bizOrgExt.setOrgId(orgId);
|
||||
bizOrgExt.setSourceFromType(sourceFromType);
|
||||
this.save(bizOrgExt);
|
||||
}
|
||||
}
|
|
@ -36,18 +36,19 @@ import vip.xiaonuo.biz.modular.org.entity.BizOrg;
|
|||
import vip.xiaonuo.biz.modular.org.enums.BizOrgCategoryEnum;
|
||||
import vip.xiaonuo.biz.modular.org.mapper.BizOrgMapper;
|
||||
import vip.xiaonuo.biz.modular.org.param.*;
|
||||
import vip.xiaonuo.biz.modular.org.service.BizOrgExtService;
|
||||
import vip.xiaonuo.biz.modular.org.service.BizOrgService;
|
||||
import vip.xiaonuo.biz.modular.position.entity.BizPosition;
|
||||
import vip.xiaonuo.biz.modular.position.service.BizPositionService;
|
||||
import vip.xiaonuo.biz.modular.user.entity.BizUser;
|
||||
import vip.xiaonuo.biz.modular.user.service.BizUserService;
|
||||
import vip.xiaonuo.common.cache.CommonCacheOperator;
|
||||
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
|
||||
import vip.xiaonuo.common.exception.CommonException;
|
||||
import vip.xiaonuo.common.listener.CommonDataChangeEventCenter;
|
||||
import vip.xiaonuo.common.page.CommonPageRequest;
|
||||
import vip.xiaonuo.sys.api.SysRoleApi;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -62,14 +63,12 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> implements BizOrgService {
|
||||
|
||||
public static final String ORG_CACHE_ALL_KEY = "sys-org:all";
|
||||
|
||||
@Resource
|
||||
private CommonCacheOperator commonCacheOperator;
|
||||
|
||||
@Resource
|
||||
private SysRoleApi sysRoleApi;
|
||||
|
||||
@Resource
|
||||
private BizOrgExtService bizOrgExtService;
|
||||
|
||||
@Resource
|
||||
private BizPositionService bizPositionService;
|
||||
|
||||
|
@ -127,7 +126,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
|
|||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void add(BizOrgAddParam bizOrgAddParam) {
|
||||
public void add(BizOrgAddParam bizOrgAddParam, String sourceFromType) {
|
||||
BizOrgCategoryEnum.validate(bizOrgAddParam.getCategory());
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
|
@ -147,8 +146,10 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
|
|||
throw new CommonException("存在重复的同级机构,名称为:{}", bizOrg.getName());
|
||||
}
|
||||
bizOrg.setCode(RandomUtil.randomString(10));
|
||||
// 保存机构
|
||||
this.save(bizOrg);
|
||||
|
||||
// 插入扩展信息
|
||||
bizOrgExtService.createExtInfo(bizOrg.getId(), sourceFromType);
|
||||
// 发布增加事件
|
||||
CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
|
||||
}
|
||||
|
@ -182,8 +183,8 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
|
|||
if(errorLevel) {
|
||||
throw new CommonException("不可选择上级机构:{}", this.getById(originDataList, bizOrg.getParentId()).getName());
|
||||
}
|
||||
// 更新机构
|
||||
this.updateById(bizOrg);
|
||||
|
||||
// 发布更新事件
|
||||
CommonDataChangeEventCenter.doUpdateWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
|
||||
}
|
||||
|
@ -196,7 +197,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
|
|||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.containsAll(orgIdList)) {
|
||||
if(!new HashSet<>(loginUserDataScope).containsAll(orgIdList)) {
|
||||
throw new CommonException("您没有权限删除这些机构,机构id:{}", orgIdList);
|
||||
}
|
||||
} else {
|
||||
|
@ -219,7 +220,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
|
|||
List<String> positionOrgIdList = CollectionUtil.newArrayList();
|
||||
positionJsonList.forEach(positionJson -> JSONUtil.toList(JSONUtil.parseArray(positionJson), JSONObject.class)
|
||||
.forEach(jsonObject -> positionOrgIdList.add(jsonObject.getStr("orgId"))));
|
||||
boolean hasPositionUser = CollectionUtil.intersectionDistinct(toDeleteOrgIdList, CollectionUtil.removeNull(positionOrgIdList)).size() > 0;
|
||||
boolean hasPositionUser = !CollectionUtil.intersectionDistinct(toDeleteOrgIdList, CollectionUtil.removeNull(positionOrgIdList)).isEmpty();
|
||||
if(hasPositionUser) {
|
||||
throw new CommonException("请先删除机构下的人员");
|
||||
}
|
||||
|
@ -263,28 +264,28 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
|
|||
|
||||
@Override
|
||||
public String getOrgIdByOrgFullNameWithCreate(String orgFullName) {
|
||||
List<BizOrg> cachedAllOrgList = this.getAllOrgList();
|
||||
List<Tree<String>> treeList = TreeUtil.build(cachedAllOrgList.stream().map(bizOrg ->
|
||||
List<BizOrg> allOrgList = this.getAllOrgList();
|
||||
List<Tree<String>> treeList = TreeUtil.build(allOrgList.stream().map(bizOrg ->
|
||||
new TreeNode<>(bizOrg.getId(), bizOrg.getParentId(), bizOrg.getName(), bizOrg.getSortCode()))
|
||||
.collect(Collectors.toList()), "0");
|
||||
return findOrgIdByOrgName("0", StrUtil.split(orgFullName, StrUtil.DASHED).iterator(), cachedAllOrgList, treeList);
|
||||
return findOrgIdByOrgName("0", StrUtil.split(orgFullName, StrUtil.DASHED).iterator(), allOrgList, treeList);
|
||||
}
|
||||
|
||||
public String findOrgIdByOrgName(String parentId, Iterator<String> iterator, List<BizOrg> cachedAllOrgList, List<Tree<String>> treeList) {
|
||||
public String findOrgIdByOrgName(String parentId, Iterator<String> iterator, List<BizOrg> allOrgList, List<Tree<String>> treeList) {
|
||||
String orgName = iterator.next();
|
||||
if(ObjectUtil.isNotEmpty(treeList)) {
|
||||
List<Tree<String>> findList = treeList.stream().filter(tree -> tree.getName().equals(orgName)).collect(Collectors.toList());
|
||||
if(ObjectUtil.isNotEmpty(findList)) {
|
||||
if(iterator.hasNext()) {
|
||||
return findOrgIdByOrgName(findList.get(0).getId(), iterator, cachedAllOrgList, findList.get(0).getChildren());
|
||||
return findOrgIdByOrgName(findList.get(0).getId(), iterator, allOrgList, findList.get(0).getChildren());
|
||||
} else {
|
||||
return findList.get(0).getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
String orgId = this.doCreateOrg(parentId, orgName, cachedAllOrgList);
|
||||
String orgId = this.doCreateOrg(parentId, orgName, allOrgList);
|
||||
if(iterator.hasNext()) {
|
||||
return findOrgIdByOrgName(orgId, iterator, cachedAllOrgList, CollectionUtil.newArrayList());
|
||||
return findOrgIdByOrgName(orgId, iterator, allOrgList, CollectionUtil.newArrayList());
|
||||
} else {
|
||||
return orgId;
|
||||
}
|
||||
|
@ -296,7 +297,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
|
|||
* @author xuyuxiang
|
||||
* @date 2023/3/8 9:38
|
||||
**/
|
||||
public String doCreateOrg(String parentId, String orgName, List<BizOrg> cachedAllOrgList) {
|
||||
public String doCreateOrg(String parentId, String orgName, List<BizOrg> allOrgList) {
|
||||
//创建该机构
|
||||
BizOrg bizOrg = new BizOrg();
|
||||
bizOrg.setName(orgName);
|
||||
|
@ -307,10 +308,6 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
|
|||
this.save(bizOrg);
|
||||
// 发布增加事件
|
||||
CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.ORG.getValue(), JSONUtil.createArray().put(bizOrg));
|
||||
// 将该机构加入缓存
|
||||
cachedAllOrgList.add(bizOrg);
|
||||
// 更新缓存
|
||||
commonCacheOperator.put(ORG_CACHE_ALL_KEY, cachedAllOrgList);
|
||||
return bizOrg.getId();
|
||||
}
|
||||
|
||||
|
@ -342,55 +339,55 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
|
|||
|
||||
@Override
|
||||
public List<BizOrg> orgListSelector(BizOrgSelectorOrgListParam bizOrgSelectorOrgListParam) {
|
||||
LambdaQueryWrapper<BizOrg> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
QueryWrapper<BizOrg> queryWrapper = new QueryWrapper<BizOrg>().checkSqlInjection();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizOrg::getId, loginUserDataScope);
|
||||
queryWrapper.lambda().in(BizOrg::getId, loginUserDataScope);
|
||||
} else {
|
||||
return CollectionUtil.newArrayList();
|
||||
}
|
||||
// 查询部分字段
|
||||
lambdaQueryWrapper.select(BizOrg::getId, BizOrg::getParentId, BizOrg::getName,
|
||||
queryWrapper.lambda().select(BizOrg::getId, BizOrg::getParentId, BizOrg::getName,
|
||||
BizOrg::getCategory, BizOrg::getSortCode);
|
||||
if(ObjectUtil.isNotEmpty(bizOrgSelectorOrgListParam.getParentId())) {
|
||||
lambdaQueryWrapper.eq(BizOrg::getParentId, bizOrgSelectorOrgListParam.getParentId());
|
||||
queryWrapper.lambda().eq(BizOrg::getParentId, bizOrgSelectorOrgListParam.getParentId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizOrgSelectorOrgListParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizOrg::getName, bizOrgSelectorOrgListParam.getSearchKey());
|
||||
queryWrapper.lambda().like(BizOrg::getName, bizOrgSelectorOrgListParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizOrg::getSortCode);
|
||||
return this.list(lambdaQueryWrapper);
|
||||
queryWrapper.lambda().orderByAsc(BizOrg::getSortCode);
|
||||
return this.list(queryWrapper.lambda());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<BizUser> userSelector(BizOrgSelectorUserParam bizOrgSelectorUserParam) {
|
||||
LambdaQueryWrapper<BizUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
QueryWrapper<BizUser> queryWrapper = new QueryWrapper<BizUser>().checkSqlInjection();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizUser::getOrgId, loginUserDataScope);
|
||||
queryWrapper.lambda().in(BizUser::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
// 只查询部分字段
|
||||
lambdaQueryWrapper.select(BizUser::getId, BizUser::getAvatar, BizUser::getOrgId, BizUser::getPositionId, BizUser::getAccount,
|
||||
queryWrapper.lambda().select(BizUser::getId, BizUser::getAvatar, BizUser::getOrgId, BizUser::getPositionId, BizUser::getAccount,
|
||||
BizUser::getName, BizUser::getSortCode, BizUser::getGender, BizUser::getEntryDate);
|
||||
if (ObjectUtil.isNotEmpty(bizOrgSelectorUserParam.getOrgId())) {
|
||||
// 如果机构id不为空,则查询该机构及其子机构下的所有人
|
||||
List<String> childOrgIdList = CollStreamUtil.toList(this.getChildListById(this
|
||||
.getAllOrgList(), bizOrgSelectorUserParam.getOrgId(), true), BizOrg::getId);
|
||||
if (ObjectUtil.isNotEmpty(childOrgIdList)) {
|
||||
lambdaQueryWrapper.in(BizUser::getOrgId, childOrgIdList);
|
||||
queryWrapper.lambda().in(BizUser::getOrgId, childOrgIdList);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizOrgSelectorUserParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizUser::getName, bizOrgSelectorUserParam.getSearchKey());
|
||||
queryWrapper.lambda().like(BizUser::getName, bizOrgSelectorUserParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizUser::getSortCode);
|
||||
return bizUserService.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
|
||||
queryWrapper.lambda().orderByAsc(BizUser::getSortCode);
|
||||
return bizUserService.page(CommonPageRequest.defaultPage(), queryWrapper.lambda());
|
||||
}
|
||||
|
||||
/* ====以下为各种递归方法==== */
|
||||
|
|
|
@ -15,10 +15,11 @@ package vip.xiaonuo.biz.modular.position.controller;
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
@ -31,6 +32,7 @@ import vip.xiaonuo.biz.modular.position.service.BizPositionService;
|
|||
import vip.xiaonuo.common.annotation.CommonLog;
|
||||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +42,7 @@ import java.util.List;
|
|||
* @date 2022/4/25 20:40
|
||||
*/
|
||||
@Tag(name = "岗位控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 2)
|
||||
@RestController
|
||||
@Validated
|
||||
public class BizPositionController {
|
||||
|
@ -53,6 +56,7 @@ public class BizPositionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "获取岗位分页")
|
||||
@SaCheckPermission("/biz/position/page")
|
||||
@GetMapping("/biz/position/page")
|
||||
|
@ -66,6 +70,7 @@ public class BizPositionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "添加岗位")
|
||||
@CommonLog("添加岗位")
|
||||
@SaCheckPermission("/biz/position/add")
|
||||
|
@ -81,6 +86,7 @@ public class BizPositionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "编辑岗位")
|
||||
@CommonLog("编辑岗位")
|
||||
@SaCheckPermission("/biz/position/edit")
|
||||
|
@ -96,6 +102,7 @@ public class BizPositionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "删除岗位")
|
||||
@CommonLog("删除岗位")
|
||||
@SaCheckPermission("/biz/position/delete")
|
||||
|
@ -112,6 +119,7 @@ public class BizPositionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "获取岗位详情")
|
||||
@SaCheckPermission("/biz/position/detail")
|
||||
@GetMapping("/biz/position/detail")
|
||||
|
@ -127,6 +135,7 @@ public class BizPositionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "获取组织树选择器")
|
||||
@SaCheckPermission("/biz/position/orgTreeSelector")
|
||||
@GetMapping("/biz/position/orgTreeSelector")
|
||||
|
@ -140,6 +149,7 @@ public class BizPositionController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 7)
|
||||
@Operation(summary = "获取岗位选择器")
|
||||
@SaCheckPermission("/biz/position/positionSelector")
|
||||
@GetMapping("/biz/position/positionSelector")
|
||||
|
|
|
@ -57,6 +57,6 @@ public class BizPosition extends CommonEntity {
|
|||
|
||||
/** 扩展信息 */
|
||||
@Schema(description = "扩展信息")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String extJson;
|
||||
}
|
||||
|
|
|
@ -29,22 +29,22 @@ import lombok.Setter;
|
|||
public class BizPositionAddParam {
|
||||
|
||||
/** 机构id */
|
||||
@Schema(description = "机构id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "机构id")
|
||||
@NotBlank(message = "orgId不能为空")
|
||||
private String orgId;
|
||||
|
||||
/** 名称 */
|
||||
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "名称")
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 分类 */
|
||||
@Schema(description = "分类", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "分类")
|
||||
@NotBlank(message = "category不能为空")
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@Schema(description = "排序码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "排序码")
|
||||
@NotNull(message = "sortCode不能为空")
|
||||
private Integer sortCode;
|
||||
|
||||
|
|
|
@ -29,27 +29,27 @@ import lombok.Setter;
|
|||
public class BizPositionEditParam {
|
||||
|
||||
/** id */
|
||||
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "id")
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
|
||||
/** 机构id */
|
||||
@Schema(description = "机构id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "机构id")
|
||||
@NotBlank(message = "orgId不能为空")
|
||||
private String orgId;
|
||||
|
||||
/** 名称 */
|
||||
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "名称")
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 分类 */
|
||||
@Schema(description = "分类", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "分类")
|
||||
@NotBlank(message = "category不能为空")
|
||||
private String category;
|
||||
|
||||
/** 排序码 */
|
||||
@Schema(description = "排序码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "排序码")
|
||||
@NotNull(message = "sortCode不能为空")
|
||||
private Integer sortCode;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import lombok.Setter;
|
|||
public class BizPositionIdParam {
|
||||
|
||||
/** id */
|
||||
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "id")
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ import vip.xiaonuo.common.exception.CommonException;
|
|||
import vip.xiaonuo.common.listener.CommonDataChangeEventCenter;
|
||||
import vip.xiaonuo.common.page.CommonPageRequest;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -71,7 +72,7 @@ public class BizPositionServiceImpl extends ServiceImpl<BizPositionMapper, BizPo
|
|||
QueryWrapper<BizPosition> queryWrapper = new QueryWrapper<BizPosition>().checkSqlInjection();
|
||||
// 查询部分字段
|
||||
queryWrapper.lambda().select(BizPosition::getId, BizPosition::getOrgId, BizPosition::getName,
|
||||
BizPosition::getCategory, BizPosition::getSortCode);
|
||||
BizPosition::getCategory, BizPosition::getSortCode, BizPosition::getExtJson);
|
||||
if(ObjectUtil.isNotEmpty(bizPositionPageParam.getOrgId())) {
|
||||
queryWrapper.lambda().eq(BizPosition::getOrgId, bizPositionPageParam.getOrgId());
|
||||
}
|
||||
|
@ -162,7 +163,7 @@ public class BizPositionServiceImpl extends ServiceImpl<BizPositionMapper, BizPo
|
|||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.containsAll(positionOrgIdList)) {
|
||||
if(!new HashSet<>(loginUserDataScope).containsAll(positionOrgIdList)) {
|
||||
throw new CommonException("您没有权限删除这些机构下的岗位,机构id:{}", positionOrgIdList);
|
||||
}
|
||||
} else {
|
||||
|
@ -180,7 +181,7 @@ public class BizPositionServiceImpl extends ServiceImpl<BizPositionMapper, BizPo
|
|||
List<String> extPositionIdList = CollectionUtil.newArrayList();
|
||||
positionJsonList.forEach(positionJson -> JSONUtil.toList(JSONUtil.parseArray(positionJson), JSONObject.class)
|
||||
.forEach(jsonObject -> extPositionIdList.add(jsonObject.getStr("positionId"))));
|
||||
boolean hasPositionUser = CollectionUtil.intersectionDistinct(positionIdList, CollectionUtil.removeNull(extPositionIdList)).size() > 0;
|
||||
boolean hasPositionUser = !CollectionUtil.intersectionDistinct(positionIdList, CollectionUtil.removeNull(extPositionIdList)).isEmpty();
|
||||
if(hasPositionUser) {
|
||||
throw new CommonException("请先删除岗位下的用户");
|
||||
}
|
||||
|
@ -240,24 +241,24 @@ public class BizPositionServiceImpl extends ServiceImpl<BizPositionMapper, BizPo
|
|||
|
||||
@Override
|
||||
public Page<BizPosition> positionSelector(BizPositionSelectorPositionParam bizPositionSelectorPositionParam) {
|
||||
LambdaQueryWrapper<BizPosition> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
QueryWrapper<BizPosition> queryWrapper = new QueryWrapper<BizPosition>();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizPosition::getOrgId, loginUserDataScope);
|
||||
queryWrapper.lambda().in(BizPosition::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
// 查询部分字段
|
||||
lambdaQueryWrapper.select(BizPosition::getId, BizPosition::getOrgId, BizPosition::getName,
|
||||
queryWrapper.lambda().select(BizPosition::getId, BizPosition::getOrgId, BizPosition::getName,
|
||||
BizPosition::getCategory, BizPosition::getSortCode);
|
||||
if(ObjectUtil.isNotEmpty(bizPositionSelectorPositionParam.getOrgId())) {
|
||||
lambdaQueryWrapper.eq(BizPosition::getOrgId, bizPositionSelectorPositionParam.getOrgId());
|
||||
queryWrapper.lambda().eq(BizPosition::getOrgId, bizPositionSelectorPositionParam.getOrgId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizPositionSelectorPositionParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizPosition::getName, bizPositionSelectorPositionParam.getSearchKey());
|
||||
queryWrapper.lambda().like(BizPosition::getName, bizPositionSelectorPositionParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizPosition::getSortCode);
|
||||
return this.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
|
||||
queryWrapper.lambda().orderByAsc(BizPosition::getSortCode);
|
||||
return this.page(CommonPageRequest.defaultPage(), queryWrapper.lambda());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,12 @@ package vip.xiaonuo.biz.modular.user.controller;
|
|||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
@ -30,12 +31,14 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
import vip.xiaonuo.biz.modular.org.entity.BizOrg;
|
||||
import vip.xiaonuo.biz.modular.position.entity.BizPosition;
|
||||
import vip.xiaonuo.biz.modular.user.entity.BizUser;
|
||||
import vip.xiaonuo.biz.modular.user.enums.BizUserSourceFromTypeEnum;
|
||||
import vip.xiaonuo.biz.modular.user.param.*;
|
||||
import vip.xiaonuo.biz.modular.user.result.BizUserRoleResult;
|
||||
import vip.xiaonuo.biz.modular.user.service.BizUserService;
|
||||
import vip.xiaonuo.common.annotation.CommonLog;
|
||||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -46,6 +49,7 @@ import java.util.List;
|
|||
* @date 2022/4/22 9:34
|
||||
**/
|
||||
@Tag(name = "人员控制器")
|
||||
@ApiSupport(author = "SNOWY_TEAM", order = 9)
|
||||
@RestController
|
||||
@Validated
|
||||
public class BizUserController {
|
||||
|
@ -59,6 +63,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@Operation(summary = "获取人员分页")
|
||||
@SaCheckPermission("/biz/user/page")
|
||||
@GetMapping("/biz/user/page")
|
||||
|
@ -72,12 +77,13 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "添加人员")
|
||||
@CommonLog("添加人员")
|
||||
@SaCheckPermission("/biz/user/add")
|
||||
@PostMapping("/biz/user/add")
|
||||
public CommonResult<String> add(@RequestBody @Valid BizUserAddParam bizUserAddParam) {
|
||||
bizUserService.add(bizUserAddParam);
|
||||
bizUserService.add(bizUserAddParam, BizUserSourceFromTypeEnum.SYSTEM_ADD.getValue());
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
||||
|
@ -87,6 +93,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:47
|
||||
*/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "编辑人员")
|
||||
@CommonLog("编辑人员")
|
||||
@SaCheckPermission("/biz/user/edit")
|
||||
|
@ -102,6 +109,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "删除人员")
|
||||
@CommonLog("删除人员")
|
||||
@SaCheckPermission("/biz/user/delete")
|
||||
|
@ -118,6 +126,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "获取人员详情")
|
||||
@SaCheckPermission("/biz/user/detail")
|
||||
@GetMapping("/biz/user/detail")
|
||||
|
@ -131,6 +140,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/13 14:01
|
||||
**/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "禁用人员")
|
||||
@CommonLog("禁用人员")
|
||||
@SaCheckPermission("/biz/user/disableUser")
|
||||
|
@ -146,6 +156,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/13 14:01
|
||||
**/
|
||||
@ApiOperationSupport(order = 7)
|
||||
@Operation(summary = "启用人员")
|
||||
@CommonLog("启用人员")
|
||||
@SaCheckPermission("/biz/user/enableUser")
|
||||
|
@ -161,6 +172,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/13 14:01
|
||||
**/
|
||||
@ApiOperationSupport(order = 8)
|
||||
@Operation(summary = "重置人员密码")
|
||||
@CommonLog("重置人员密码")
|
||||
@SaCheckPermission("/biz/user/resetPassword")
|
||||
|
@ -176,6 +188,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 9)
|
||||
@Operation(summary = "获取人员拥有角色")
|
||||
@SaCheckPermission("/biz/user/ownRole")
|
||||
@GetMapping("/biz/user/ownRole")
|
||||
|
@ -189,6 +202,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 10)
|
||||
@Operation(summary = "给人员授权角色")
|
||||
@CommonLog("给人员授权角色")
|
||||
@SaCheckPermission("/biz/user/grantRole")
|
||||
|
@ -204,6 +218,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 11)
|
||||
@Operation(summary = "人员导出")
|
||||
@CommonLog("人员导出")
|
||||
@SaCheckPermission("/biz/user/export")
|
||||
|
@ -218,6 +233,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 12)
|
||||
@Operation(summary = "导出人员个人信息")
|
||||
@CommonLog("导出人员个人信息")
|
||||
@SaCheckPermission("/biz/user/exportUserInfo")
|
||||
|
@ -234,6 +250,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 13)
|
||||
@Operation(summary = "获取机构树选择器")
|
||||
@SaCheckPermission("/biz/user/orgTreeSelector")
|
||||
@GetMapping("/biz/user/orgTreeSelector")
|
||||
|
@ -247,6 +264,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 14)
|
||||
@Operation(summary = "获取机构列表选择器")
|
||||
@SaCheckPermission("/biz/user/orgListSelector")
|
||||
@GetMapping("/biz/user/orgListSelector")
|
||||
|
@ -260,6 +278,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 15)
|
||||
@Operation(summary = "获取岗位选择器")
|
||||
@SaCheckPermission("/biz/user/positionSelector")
|
||||
@GetMapping("/biz/user/positionSelector")
|
||||
|
@ -273,6 +292,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 16)
|
||||
@Operation(summary = "获取角色选择器")
|
||||
@SaCheckPermission("/biz/user/roleSelector")
|
||||
@GetMapping("/biz/user/roleSelector")
|
||||
|
@ -286,6 +306,7 @@ public class BizUserController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 17)
|
||||
@Operation(summary = "获取人员选择器")
|
||||
@SaCheckPermission("/biz/user/userSelector")
|
||||
@GetMapping("/biz/user/userSelector")
|
||||
|
|
|
@ -47,12 +47,12 @@ public class BizUser extends CommonEntity {
|
|||
|
||||
/** 头像 */
|
||||
@Schema(description = "头像")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String avatar;
|
||||
|
||||
/** 签名 */
|
||||
@Schema(description = "签名")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String signature;
|
||||
|
||||
/** 账号 */
|
||||
|
@ -70,156 +70,154 @@ public class BizUser extends CommonEntity {
|
|||
|
||||
/** 昵称 */
|
||||
@Schema(description = "昵称")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String nickname;
|
||||
|
||||
/** 性别 */
|
||||
@Schema(description = "性别")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
@Trans(type = TransType.DICTIONARY, key = "GENDER")
|
||||
private String gender;
|
||||
|
||||
/** 年龄 */
|
||||
@Schema(description = "年龄")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String age;
|
||||
|
||||
/** 出生日期 */
|
||||
@Schema(description = "出生日期")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String birthday;
|
||||
|
||||
/** 民族 */
|
||||
@Schema(description = "民族")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String nation;
|
||||
|
||||
/** 籍贯 */
|
||||
@Schema(description = "籍贯")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String nativePlace;
|
||||
|
||||
/** 家庭住址 */
|
||||
@Schema(description = "家庭住址")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String homeAddress;
|
||||
|
||||
/** 通信地址 */
|
||||
@Schema(description = "通信地址")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String mailingAddress;
|
||||
|
||||
/** 证件类型 */
|
||||
@Schema(description = "证件类型")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String idCardType;
|
||||
|
||||
/** 证件号码 */
|
||||
@Schema(description = "证件号码")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED, typeHandler = CommonSm4CbcTypeHandler.class)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS, typeHandler = CommonSm4CbcTypeHandler.class)
|
||||
private String idCardNumber;
|
||||
|
||||
/** 文化程度 */
|
||||
@Schema(description = "文化程度")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String cultureLevel;
|
||||
|
||||
/** 政治面貌 */
|
||||
@Schema(description = "政治面貌")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String politicalOutlook;
|
||||
|
||||
/** 毕业院校 */
|
||||
@Schema(description = "毕业院校")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String college;
|
||||
|
||||
/** 学历 */
|
||||
@Schema(description = "学历")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String education;
|
||||
|
||||
/** 学制 */
|
||||
@Schema(description = "学制")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String eduLength;
|
||||
|
||||
/** 学位 */
|
||||
@Schema(description = "学位")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String degree;
|
||||
|
||||
/** 手机 */
|
||||
@Schema(description = "手机")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED, typeHandler = CommonSm4CbcTypeHandler.class)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS, typeHandler = CommonSm4CbcTypeHandler.class)
|
||||
private String phone;
|
||||
|
||||
/** 邮箱 */
|
||||
@Schema(description = "邮箱")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String email;
|
||||
|
||||
/** 家庭电话 */
|
||||
@Schema(description = "家庭电话")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String homeTel;
|
||||
|
||||
/** 办公电话 */
|
||||
@Schema(description = "办公电话")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String officeTel;
|
||||
|
||||
/** 紧急联系人 */
|
||||
@Schema(description = "紧急联系人")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String emergencyContact;
|
||||
|
||||
/** 紧急联系人电话 */
|
||||
@Schema(description = "紧急联系人电话")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED, typeHandler = CommonSm4CbcTypeHandler.class)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS, typeHandler = CommonSm4CbcTypeHandler.class)
|
||||
private String emergencyPhone;
|
||||
|
||||
/** 紧急联系人地址 */
|
||||
@Schema(description = "紧急联系人地址")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String emergencyAddress;
|
||||
|
||||
/** 员工编号 */
|
||||
@Schema(description = "员工编号")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String empNo;
|
||||
|
||||
/** 入职日期 */
|
||||
@Schema(description = "入职日期")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String entryDate;
|
||||
|
||||
/** 机构id */
|
||||
@Schema(description = "机构id")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@Trans(type = TransType.SIMPLE, target = BizOrg.class, fields = "name", alias = "org", ref = "orgName")
|
||||
private String orgId;
|
||||
|
||||
/** 岗位id */
|
||||
@Schema(description = "岗位id")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@Trans(type = TransType.SIMPLE, target = BizPosition.class, fields = "name", alias = "position", ref = "positionName")
|
||||
private String positionId;
|
||||
|
||||
/** 职级 */
|
||||
@Schema(description = "职级")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String positionLevel;
|
||||
|
||||
/** 主管id */
|
||||
@Schema(description = "主管id")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
@Trans(type = TransType.SIMPLE, target = BizUser.class, fields = "name", alias = "director", ref = "directorName")
|
||||
private String directorId;
|
||||
|
||||
/** 兼任信息 */
|
||||
@Schema(description = "兼任信息")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String positionJson;
|
||||
|
||||
/** 上次登录ip */
|
||||
|
@ -264,7 +262,7 @@ public class BizUser extends CommonEntity {
|
|||
|
||||
/** 扩展信息 */
|
||||
@Schema(description = "扩展信息")
|
||||
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED)
|
||||
@TableField(insertStrategy = FieldStrategy.ALWAYS, updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String extJson;
|
||||
|
||||
@Schema(description = "机构名称")
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.biz.modular.user.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import vip.xiaonuo.common.pojo.CommonEntity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户扩展实体
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/21 16:13
|
||||
**/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("SYS_USER_EXT")
|
||||
public class BizUserExt extends CommonEntity {
|
||||
|
||||
/** id */
|
||||
@TableId
|
||||
@Schema(description = "id")
|
||||
private String id;
|
||||
|
||||
/** 用户id */
|
||||
@Schema(description = "用户id")
|
||||
private String userId;
|
||||
|
||||
/** 来源类别 */
|
||||
@Schema(description = "来源类别")
|
||||
private String sourceFromType;
|
||||
|
||||
/** 密码修改日期 */
|
||||
@Schema(description = "密码修改日期")
|
||||
private Date passwordUpdateTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.biz.modular.user.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 用户来源类型枚举
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/21 19:56
|
||||
**/
|
||||
@Getter
|
||||
public enum BizUserSourceFromTypeEnum {
|
||||
|
||||
/** 系统自建 */
|
||||
SYSTEM_ADD("SYSTEM_ADD"),
|
||||
|
||||
/** 用户注册 */
|
||||
SYSTEM_REGISTER("SYSTEM_REGISTER"),
|
||||
|
||||
/** 身份源 */
|
||||
ID_SOURCE("ID_SOURCE");
|
||||
|
||||
private final String value;
|
||||
|
||||
BizUserSourceFromTypeEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.biz.modular.user.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import vip.xiaonuo.biz.modular.user.entity.BizUserExt;
|
||||
|
||||
/**
|
||||
* 用户扩展Mapper接口
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/21 18:37
|
||||
**/
|
||||
public interface BizUserExtMapper extends BaseMapper<BizUserExt> {
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<?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="vip.xiaonuo.biz.modular.user.mapper.BizUserExtMapper">
|
||||
|
||||
</mapper>
|
|
@ -2,4 +2,4 @@
|
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="vip.xiaonuo.biz.modular.user.mapper.BizUserMapper">
|
||||
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
|
|
@ -28,22 +28,22 @@ import lombok.Setter;
|
|||
public class BizUserAddParam {
|
||||
|
||||
/** 账号 */
|
||||
@Schema(description = "账号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "账号")
|
||||
@NotBlank(message = "account不能为空")
|
||||
private String account;
|
||||
|
||||
/** 姓名 */
|
||||
@Schema(description = "姓名", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "姓名")
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 机构id */
|
||||
@Schema(description = "机构id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "机构id")
|
||||
@NotBlank(message = "orgId不能为空")
|
||||
private String orgId;
|
||||
|
||||
/** 岗位id */
|
||||
@Schema(description = "岗位id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "岗位id")
|
||||
@NotBlank(message = "positionId不能为空")
|
||||
private String positionId;
|
||||
|
||||
|
|
|
@ -28,27 +28,27 @@ import lombok.Setter;
|
|||
public class BizUserEditParam {
|
||||
|
||||
/** id */
|
||||
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "id")
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
|
||||
/** 账号 */
|
||||
@Schema(description = "账号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "账号")
|
||||
@NotBlank(message = "account不能为空")
|
||||
private String account;
|
||||
|
||||
/** 姓名 */
|
||||
@Schema(description = "姓名", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "姓名")
|
||||
@NotBlank(message = "name不能为空")
|
||||
private String name;
|
||||
|
||||
/** 机构id */
|
||||
@Schema(description = "机构id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "机构id")
|
||||
@NotBlank(message = "orgId不能为空")
|
||||
private String orgId;
|
||||
|
||||
/** 岗位id */
|
||||
@Schema(description = "岗位id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "岗位id")
|
||||
@NotBlank(message = "positionId不能为空")
|
||||
private String positionId;
|
||||
|
||||
|
|
|
@ -31,12 +31,12 @@ import java.util.List;
|
|||
public class BizUserGrantRoleParam {
|
||||
|
||||
/** id */
|
||||
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "id")
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
|
||||
/** 角色id集合 */
|
||||
@Schema(description = "角色id集合", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "角色id集合")
|
||||
@NotNull(message = "roleIdList不能为空")
|
||||
private List<String> roleIdList;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import lombok.Setter;
|
|||
public class BizUserIdParam {
|
||||
|
||||
/** id */
|
||||
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "id")
|
||||
@NotBlank(message = "id不能为空")
|
||||
private String id;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.biz.modular.user.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import vip.xiaonuo.biz.modular.user.entity.BizUserExt;
|
||||
|
||||
/**
|
||||
* 用户扩展Service接口
|
||||
*
|
||||
* @author yubaoshan
|
||||
* @date 2024/12/21 01:25
|
||||
**/
|
||||
public interface BizUserExtService extends IService<BizUserExt> {
|
||||
|
||||
/**
|
||||
* 更新用户最新修改密码时间
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/27 21:38
|
||||
*/
|
||||
void updatePasswordLastTime(String userId);
|
||||
|
||||
/**
|
||||
* 插入扩展信息
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/27 21:38
|
||||
*/
|
||||
void createExtInfo(String userId, String sourceFromType);
|
||||
}
|
|
@ -47,7 +47,7 @@ public interface BizUserService extends IService<BizUser> {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:48
|
||||
*/
|
||||
void add(BizUserAddParam bizUserAddParam);
|
||||
void add(BizUserAddParam bizUserAddParam, String sourceFromType);
|
||||
|
||||
/**
|
||||
* 编辑人员
|
||||
|
@ -83,7 +83,7 @@ public interface BizUserService extends IService<BizUser> {
|
|||
|
||||
/**
|
||||
* 禁用人员
|
||||
*
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/7/5 18:20
|
||||
**/
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.biz.modular.user.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import vip.xiaonuo.biz.modular.user.entity.BizUserExt;
|
||||
import vip.xiaonuo.biz.modular.user.mapper.BizUserExtMapper;
|
||||
import vip.xiaonuo.biz.modular.user.service.BizUserExtService;
|
||||
|
||||
/**
|
||||
* 用户扩展Service接口实现类
|
||||
*
|
||||
* @author yubaoshan
|
||||
* @date 2024/12/21 01:25
|
||||
**/
|
||||
@Service
|
||||
public class BizUserExtServiceImpl extends ServiceImpl<BizUserExtMapper, BizUserExt> implements BizUserExtService {
|
||||
|
||||
@Override
|
||||
public void updatePasswordLastTime(String userId) {
|
||||
BizUserExt bizUserExt = this.getOne(new LambdaQueryWrapper<BizUserExt>().eq(BizUserExt::getUserId, userId));
|
||||
if(ObjectUtil.isEmpty(bizUserExt)){
|
||||
bizUserExt = new BizUserExt();
|
||||
bizUserExt.setUserId(userId);
|
||||
bizUserExt.setPasswordUpdateTime(DateTime.now());
|
||||
this.save(bizUserExt);
|
||||
} else {
|
||||
bizUserExt.setPasswordUpdateTime(DateTime.now());
|
||||
this.updateById(bizUserExt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createExtInfo(String userId, String sourceFromType) {
|
||||
BizUserExt bizUserExt = new BizUserExt();
|
||||
bizUserExt.setUserId(userId);
|
||||
bizUserExt.setSourceFromType(sourceFromType);
|
||||
bizUserExt.setPasswordUpdateTime(DateTime.now());
|
||||
this.save(bizUserExt);
|
||||
}
|
||||
}
|
|
@ -61,12 +61,14 @@ import vip.xiaonuo.biz.modular.org.service.BizOrgService;
|
|||
import vip.xiaonuo.biz.modular.position.entity.BizPosition;
|
||||
import vip.xiaonuo.biz.modular.position.service.BizPositionService;
|
||||
import vip.xiaonuo.biz.modular.user.entity.BizUser;
|
||||
import vip.xiaonuo.biz.modular.user.entity.BizUserExt;
|
||||
import vip.xiaonuo.biz.modular.user.enums.BizRoleCategoryEnum;
|
||||
import vip.xiaonuo.biz.modular.user.enums.BizUserStatusEnum;
|
||||
import vip.xiaonuo.biz.modular.user.mapper.BizUserMapper;
|
||||
import vip.xiaonuo.biz.modular.user.param.*;
|
||||
import vip.xiaonuo.biz.modular.user.result.BizUserExportResult;
|
||||
import vip.xiaonuo.biz.modular.user.result.BizUserRoleResult;
|
||||
import vip.xiaonuo.biz.modular.user.service.BizUserExtService;
|
||||
import vip.xiaonuo.biz.modular.user.service.BizUserService;
|
||||
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
|
||||
import vip.xiaonuo.common.excel.CommonExcelCustomMergeStrategy;
|
||||
|
@ -74,7 +76,7 @@ import vip.xiaonuo.common.exception.CommonException;
|
|||
import vip.xiaonuo.common.listener.CommonDataChangeEventCenter;
|
||||
import vip.xiaonuo.common.page.CommonPageRequest;
|
||||
import vip.xiaonuo.common.util.*;
|
||||
import vip.xiaonuo.dev.api.DevConfigApi;
|
||||
import vip.xiaonuo.sys.api.SysApi;
|
||||
import vip.xiaonuo.sys.api.SysRoleApi;
|
||||
import vip.xiaonuo.sys.api.SysUserApi;
|
||||
|
||||
|
@ -82,10 +84,7 @@ import java.io.BufferedOutputStream;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -97,13 +96,11 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> implements BizUserService {
|
||||
|
||||
private static final String SNOWY_SYS_DEFAULT_PASSWORD_KEY = "SNOWY_SYS_DEFAULT_PASSWORD";
|
||||
|
||||
@Resource
|
||||
private TransService transService;
|
||||
|
||||
@Resource
|
||||
private DevConfigApi devConfigApi;
|
||||
private SysApi sysApi;
|
||||
|
||||
@Resource
|
||||
private SysUserApi sysUserApi;
|
||||
|
@ -111,6 +108,9 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
@Resource
|
||||
private SysRoleApi sysRoleApi;
|
||||
|
||||
@Resource
|
||||
private BizUserExtService bizUserExtService;
|
||||
|
||||
@Resource
|
||||
private BizOrgService bizOrgService;
|
||||
|
||||
|
@ -151,7 +151,7 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void add(BizUserAddParam bizUserAddParam) {
|
||||
public void add(BizUserAddParam bizUserAddParam, String sourceFromType) {
|
||||
checkParam(bizUserAddParam);
|
||||
BizUser bizUser = BeanUtil.toBean(bizUserAddParam, BizUser.class);
|
||||
if(ObjectUtil.isEmpty(bizUser.getAvatar())) {
|
||||
|
@ -159,11 +159,13 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
bizUser.setAvatar(CommonAvatarUtil.generateImg(bizUser.getName()));
|
||||
}
|
||||
// 设置密码
|
||||
bizUser.setPassword(CommonCryptogramUtil.doHashValue(devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_PASSWORD_KEY)));
|
||||
bizUser.setPassword(CommonCryptogramUtil.doHashValue(sysApi.getDefaultPassword()));
|
||||
// 设置状态
|
||||
bizUser.setUserStatus(BizUserStatusEnum.ENABLE.getValue());
|
||||
// 保存用户
|
||||
this.save(bizUser);
|
||||
|
||||
// 插入扩展信息
|
||||
bizUserExtService.createExtInfo(bizUser.getId(), sourceFromType);
|
||||
// 发布增加事件
|
||||
CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.USER.getValue(), JSONUtil.createArray().put(bizUser));
|
||||
}
|
||||
|
@ -192,7 +194,7 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
}
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserAddParam.getEmail())) {
|
||||
if(!CommonEmailUtil.isEmail(bizUserAddParam.getEmail())) {
|
||||
if(CommonEmailUtil.isNotEmail(bizUserAddParam.getEmail())) {
|
||||
throw new CommonException("邮箱:{}格式错误", bizUserAddParam.getEmail());
|
||||
}
|
||||
if (this.count(new LambdaQueryWrapper<BizUser>()
|
||||
|
@ -213,8 +215,8 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
throw new CommonException("不可修改系统内置超管人员账号");
|
||||
}
|
||||
BeanUtil.copyProperties(bizUserEditParam, bizUser);
|
||||
// 更新用户
|
||||
this.updateById(bizUser);
|
||||
|
||||
// 发布更新事件
|
||||
CommonDataChangeEventCenter.doUpdateWithData(BizDataTypeEnum.USER.getValue(), JSONUtil.createArray().put(bizUser));
|
||||
}
|
||||
|
@ -247,7 +249,7 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
}
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserEditParam.getEmail())) {
|
||||
if(!CommonEmailUtil.isEmail(bizUserEditParam.getEmail())) {
|
||||
if(CommonEmailUtil.isNotEmail(bizUserEditParam.getEmail())) {
|
||||
throw new CommonException("邮箱:{}格式错误", bizUserEditParam.getEmail());
|
||||
}
|
||||
if (this.count(new LambdaQueryWrapper<BizUser>()
|
||||
|
@ -273,7 +275,7 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
if(!loginUserDataScope.containsAll(userOrgIdList)) {
|
||||
if(!new HashSet<>(loginUserDataScope).containsAll(userOrgIdList)) {
|
||||
throw new CommonException("您没有权限删除这些机构下的人员,机构id:{}",
|
||||
CollectionUtil.subtract(userOrgIdList, loginUserDataScope));
|
||||
}
|
||||
|
@ -304,6 +306,9 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
// 执行删除
|
||||
this.removeByIds(bizUserIdList);
|
||||
|
||||
// 删除扩展信息
|
||||
bizUserExtService.remove(new LambdaQueryWrapper<BizUserExt>().in(BizUserExt::getUserId, bizUserIdList));
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(BizDataTypeEnum.USER.getValue(), bizUserIdList);
|
||||
}
|
||||
|
@ -369,7 +374,7 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
}
|
||||
this.update(new LambdaUpdateWrapper<BizUser>().eq(BizUser::getId,
|
||||
bizUserIdParam.getId()).set(BizUser::getPassword,
|
||||
CommonCryptogramUtil.doHashValue(devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_PASSWORD_KEY))));
|
||||
CommonCryptogramUtil.doHashValue(sysApi.getDefaultPassword())));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -563,7 +568,7 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
if(ObjectUtil.isNotEmpty(bizUser.getBirthday())) {
|
||||
try {
|
||||
// 年龄
|
||||
long age = cn.hutool.core.date.DateUtil.betweenYear(cn.hutool.core.date.DateUtil.parseDate(bizUser.getBirthday()), DateTime.now(), true);
|
||||
long age = DateUtil.betweenYear(DateUtil.parseDate(bizUser.getBirthday()), DateTime.now(), true);
|
||||
if(age != 0) {
|
||||
map.put("age", age + "岁");
|
||||
}
|
||||
|
@ -633,48 +638,48 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
|
||||
@Override
|
||||
public Page<BizOrg> orgListSelector(BizUserSelectorOrgListParam bizUserSelectorOrgListParam) {
|
||||
LambdaQueryWrapper<BizOrg> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
QueryWrapper<BizOrg> queryWrapper = new QueryWrapper<BizOrg>().checkSqlInjection();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizOrg::getId, loginUserDataScope);
|
||||
queryWrapper.lambda().in(BizOrg::getId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
// 查询部分字段
|
||||
lambdaQueryWrapper.select(BizOrg::getId, BizOrg::getParentId, BizOrg::getName,
|
||||
queryWrapper.lambda().select(BizOrg::getId, BizOrg::getParentId, BizOrg::getName,
|
||||
BizOrg::getCategory, BizOrg::getSortCode);
|
||||
if(ObjectUtil.isNotEmpty(bizUserSelectorOrgListParam.getParentId())) {
|
||||
lambdaQueryWrapper.eq(BizOrg::getParentId, bizUserSelectorOrgListParam.getParentId());
|
||||
queryWrapper.lambda().eq(BizOrg::getParentId, bizUserSelectorOrgListParam.getParentId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserSelectorOrgListParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizOrg::getName, bizUserSelectorOrgListParam.getSearchKey());
|
||||
queryWrapper.lambda().like(BizOrg::getName, bizUserSelectorOrgListParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizOrg::getSortCode);
|
||||
return bizOrgService.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
|
||||
queryWrapper.lambda().orderByAsc(BizOrg::getSortCode);
|
||||
return bizOrgService.page(CommonPageRequest.defaultPage(), queryWrapper.lambda());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<BizPosition> positionSelector(BizUserSelectorPositionParam bizUserSelectorPositionParam) {
|
||||
LambdaQueryWrapper<BizPosition> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
QueryWrapper<BizPosition> queryWrapper = new QueryWrapper<BizPosition>().checkSqlInjection();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizPosition::getOrgId, loginUserDataScope);
|
||||
queryWrapper.lambda().in(BizPosition::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
// 查询部分字段
|
||||
lambdaQueryWrapper.select(BizPosition::getId, BizPosition::getOrgId, BizPosition::getName,
|
||||
queryWrapper.lambda().select(BizPosition::getId, BizPosition::getOrgId, BizPosition::getName,
|
||||
BizPosition::getCategory, BizPosition::getSortCode);
|
||||
if(ObjectUtil.isNotEmpty(bizUserSelectorPositionParam.getOrgId())) {
|
||||
lambdaQueryWrapper.eq(BizPosition::getOrgId, bizUserSelectorPositionParam.getOrgId());
|
||||
queryWrapper.lambda().eq(BizPosition::getOrgId, bizUserSelectorPositionParam.getOrgId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserSelectorPositionParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizPosition::getName, bizUserSelectorPositionParam.getSearchKey());
|
||||
queryWrapper.lambda().like(BizPosition::getName, bizUserSelectorPositionParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizPosition::getSortCode);
|
||||
return bizPositionService.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
|
||||
queryWrapper.lambda().orderByAsc(BizPosition::getSortCode);
|
||||
return bizPositionService.page(CommonPageRequest.defaultPage(), queryWrapper.lambda());
|
||||
}
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
|
@ -707,31 +712,31 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
|
||||
@Override
|
||||
public Page<BizUser> userSelector(BizUserSelectorUserParam bizUserSelectorUserParam) {
|
||||
LambdaQueryWrapper<BizUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
QueryWrapper<BizUser> queryWrapper = new QueryWrapper<BizUser>().checkSqlInjection();
|
||||
// 校验数据范围
|
||||
List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
|
||||
if(ObjectUtil.isNotEmpty(loginUserDataScope)) {
|
||||
lambdaQueryWrapper.in(BizUser::getOrgId, loginUserDataScope);
|
||||
queryWrapper.lambda().in(BizUser::getOrgId, loginUserDataScope);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
// 只查询部分字段
|
||||
lambdaQueryWrapper.select(BizUser::getId, BizUser::getAvatar, BizUser::getOrgId, BizUser::getPositionId, BizUser::getAccount,
|
||||
queryWrapper.lambda().select(BizUser::getId, BizUser::getAvatar, BizUser::getOrgId, BizUser::getPositionId, BizUser::getAccount,
|
||||
BizUser::getName, BizUser::getSortCode, BizUser::getGender, BizUser::getEntryDate);
|
||||
if (ObjectUtil.isNotEmpty(bizUserSelectorUserParam.getOrgId())) {
|
||||
// 如果机构id不为空,则查询该机构及其子机构下的所有人
|
||||
List<String> childOrgIdList = CollStreamUtil.toList(bizOrgService.getChildListById(bizOrgService
|
||||
.getAllOrgList(), bizUserSelectorUserParam.getOrgId(), true), BizOrg::getId);
|
||||
if (ObjectUtil.isNotEmpty(childOrgIdList)) {
|
||||
lambdaQueryWrapper.in(BizUser::getOrgId, childOrgIdList);
|
||||
queryWrapper.lambda().in(BizUser::getOrgId, childOrgIdList);
|
||||
} else {
|
||||
return new Page<>();
|
||||
}
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(bizUserSelectorUserParam.getSearchKey())) {
|
||||
lambdaQueryWrapper.like(BizUser::getName, bizUserSelectorUserParam.getSearchKey());
|
||||
queryWrapper.lambda().like(BizUser::getName, bizUserSelectorUserParam.getSearchKey());
|
||||
}
|
||||
lambdaQueryWrapper.orderByAsc(BizUser::getSortCode);
|
||||
return this.page(CommonPageRequest.defaultPage(), lambdaQueryWrapper);
|
||||
queryWrapper.lambda().orderByAsc(BizUser::getSortCode);
|
||||
return this.page(CommonPageRequest.defaultPage(), queryWrapper.lambda());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.client.core.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 密码复杂度类型枚举
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2023/3/3 10:40
|
||||
**/
|
||||
@Getter
|
||||
public enum ClientPasswordComplexityEnum {
|
||||
|
||||
/**
|
||||
* 无限制
|
||||
*/
|
||||
REG0("REG0", "无限制"),
|
||||
|
||||
/**
|
||||
* 必须包含数字和字母
|
||||
*/
|
||||
REG1("REG1", "必须包含数字和字母"),
|
||||
|
||||
/**
|
||||
* 必须包含数字和大写字母
|
||||
*/
|
||||
REG2("REG2", "必须包含数字和大写字母"),
|
||||
|
||||
/**
|
||||
* 必须包含数字、大写字母、小写字母和特殊字符
|
||||
*/
|
||||
REG3("REG3", "必须包含数字、大写字母、小写字母和特殊字符"),
|
||||
|
||||
/**
|
||||
* 至少包含数字、字母和特殊字符中的两种
|
||||
*/
|
||||
REG4("REG4", "至少包含数字、字母和特殊字符中的两种"),
|
||||
|
||||
/**
|
||||
* 至少包含数字、大写字母、小写字母和特殊字符的三种
|
||||
*/
|
||||
REG5("REG5", "至少包含数字、大写字母、小写字母和特殊字符的三种");
|
||||
|
||||
private final String value;
|
||||
|
||||
private final String message;
|
||||
|
||||
ClientPasswordComplexityEnum(String value, String message) {
|
||||
this.value = value;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.client.core.timer;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import vip.xiaonuo.client.modular.user.service.ClientUserService;
|
||||
import vip.xiaonuo.common.timer.CommonTimerTaskRunner;
|
||||
|
||||
/**
|
||||
* 通知用户密码即将到期定时类
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/8/5 15:52
|
||||
**/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ClientUserPasswordExpiredNoticeTimerTaskRunner implements CommonTimerTaskRunner {
|
||||
|
||||
@Resource
|
||||
private ClientUserService clientUserService;
|
||||
|
||||
@Override
|
||||
public void action(String extJson) {
|
||||
// 通知用户密码即将到期
|
||||
clientUserService.noticeUserPasswordAboutToExpired();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue