通用模块开发

This commit is contained in:
haoxin963
2021-06-23 20:58:11 +08:00
parent bc185f2fe9
commit df06ebb8f6
48 changed files with 1205 additions and 826 deletions

View File

@@ -60,6 +60,13 @@ public interface AuthConstants {
String SELECT_CLIENT_DETAILS_SQL = BASE_CLIENT_DETAILS_SQL + " where client_id = ?";
/**
* 认证地址
*/
String OAUTH_TOKEN = "/oauth/token";
/**
* 密码加密方式
*/
@@ -86,5 +93,18 @@ public interface AuthConstants {
String REFRESH_TOKEN = "refresh_token";
/**
* 密码
*/
String PASSWORD = "password";
/**
* 验证码
*/
String VALIDATE_CODE_CODE = "code";
/**
* 验证码 key
*/
String VALIDATE_CODE_KEY = "key";
}

View File

@@ -1,11 +1,14 @@
package com.xtoon.cloud.common.redis.util;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
@@ -14,95 +17,549 @@ import java.util.concurrent.TimeUnit;
* @author haoxin
* @date 2021-06-07
**/
@Slf4j
@Component
public class RedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private ValueOperations<String, String> valueOperations;
/**
* 默认过期时长,单位:秒
*/
public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
/**
* 不设置过期时长
*/
public final static long NOT_EXPIRE = -1;
private final static Gson gson = new Gson();
public void set(String key, Object value, long expire) {
valueOperations.set(key, toJson(value));
if (expire != NOT_EXPIRE) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
}
public void set(String key, Object value) {
set(key, value, DEFAULT_EXPIRE);
}
public <T> T get(String key, Class<T> clazz, long expire) {
String value = valueOperations.get(key);
if (expire != NOT_EXPIRE) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value == null ? null : fromJson(value, clazz);
}
public <T> T get(String key, Class<T> clazz) {
return get(key, clazz, NOT_EXPIRE);
}
public String get(String key, long expire) {
String value = valueOperations.get(key);
if (expire != NOT_EXPIRE) {
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
return value;
}
public String get(String key) {
return get(key, NOT_EXPIRE);
}
public void delete(String key) {
redisTemplate.delete(key);
}
/**
* Object转成JSON数据
*/
private String toJson(Object object) {
if (object instanceof Integer || object instanceof Long || object instanceof Float ||
object instanceof Double || object instanceof Boolean || object instanceof String) {
return String.valueOf(object);
}
return gson.toJson(object);
}
/**
* 判断key是否存在
* 指定缓存失效时间
*
* @param key 键
* @return true 存在 false不存在
* @param key
* @param time 时间(秒)
* @return Boolean
*/
public boolean hasKey(String key) {
public Boolean expire(String key, Long time) {
try {
return redisTemplate.hasKey(key);
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage(), e);
return false;
}
}
/**
* JSON数据转成Object
* 根据key获取过期时间
*
* @param key 键 不能为 null
* @return 时间(秒) 返回 0代表为永久有效
*/
private <T> T fromJson(String json, Class<T> clazz) {
return gson.fromJson(json, clazz);
public Long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断 key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public Boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(Arrays.asList(key));
}
}
}
/**
* 普通缓存获取
*
* @param key 键
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public Boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 普通缓存放入并设置时间
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public Boolean set(String key, Object value, Long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 递增
*
* @param key 键
* @param delta 要增加几(大于0)
* @return Long
*/
public Long incr(String key, Long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
*
* @param key 键
* @param delta 要减少几
* @return Long
*/
public Long decr(String key, Long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
/**
* HashGet
*
* @param key 键 不能为 null
* @param item 项 不能为 null
* @return 值
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取 hashKey对应的所有键值
*
* @param key 键
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
*
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public Boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* HashSet 并设置时间
*
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public Boolean hmset(String key, Map<String, Object> map, Long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public Boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public Boolean hset(String key, String item, Object value, Long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 删除hash表中的值
*
* @param key 键 不能为 null
* @param item 项 可以使多个不能为 null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
*
* @param key 键 不能为 null
* @param item 项 不能为 null
* @return true 存在 false不存在
*/
public Boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return Double
*/
public Double hincr(String key, String item, Double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return Double
*/
public Double hdecr(String key, String item, Double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
/**
* 根据 key获取 Set中的所有值
*
* @param key 键
* @return Set
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
*
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public Boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public Long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
log.error(e.getMessage(), e);
return 0L;
}
}
/**
* 将set数据放入缓存
*
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public Long sSetAndTime(String key, Long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time);
}
return count;
} catch (Exception e) {
log.error(e.getMessage(), e);
return 0L;
}
}
/**
* 获取set缓存的长度
*
* @param key 键
* @return Long
*/
public Long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
log.error(e.getMessage(), e);
return 0L;
}
}
/**
* 移除值为value的
*
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public Long setRemove(String key, Object... values) {
try {
return redisTemplate.opsForSet().remove(key, values);
} catch (Exception e) {
log.error(e.getMessage(), e);
return 0L;
}
}
/**
* 获取list缓存的内容
*
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return List
*/
public List<Object> lGet(String key, Long start, Long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}
/**
* 获取list缓存的长度
*
* @param key 键
* @return Long
*/
public Long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
log.error(e.getMessage(), e);
return 0L;
}
}
/**
* 通过索引 获取list中的值
*
* @param key 键
* @param index 索引 index>=0时 0 表头1 第二个元素,依次类推;
* index<0时-1表尾-2倒数第二个元素依次类推
* @return Object
*/
public Object lGetIndex(String key, Long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return Boolean
*/
public Boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return Boolean
*/
public Boolean lSet(String key, Object value, Long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return Boolean
*/
public Boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return Boolean
*/
public Boolean lSet(String key, List<Object> value, Long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 根据索引修改list中的某条数据
*
* @param key 键
* @param index 索引
* @param value 值
* @return Boolean
*/
public Boolean lUpdateIndex(String key, Long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 移除N个值为value
*
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public Long lRemove(String key, Long count, Object value) {
try {
return redisTemplate.opsForList().remove(key, count, value);
} catch (Exception e) {
log.error(e.getMessage(), e);
return 0L;
}
}
}

View File

@@ -2,6 +2,7 @@ package com.xtoon.cloud.common.web.util;
import com.xtoon.cloud.common.core.constant.CommonConstant;
import com.xtoon.cloud.common.core.util.TenantContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
@@ -21,7 +22,9 @@ public class TenantHandlerInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse response, Object handler) {
// 多租户支持
String tenantId = httpServletRequest.getHeader(CommonConstant.TENANT_ID);
TenantContext.setTenantId(tenantId);
if (StringUtils.isNoneBlank(tenantId)) {
TenantContext.setTenantId(tenantId);
}
return true;
}
}

View File

@@ -22,6 +22,16 @@
<artifactId>xtoon-common-core</artifactId>
<version>${xtoon-cloud.version}</version>
</dependency>
<dependency>
<groupId>com.xtoon.cloud</groupId>
<artifactId>xtoon-common-swagger</artifactId>
<version>${xtoon-cloud.version}</version>
</dependency>
<dependency>
<groupId>com.xtoon.cloud</groupId>
<artifactId>xtoon-common-redis</artifactId>
<version>${xtoon-cloud.version}</version>
</dependency>
<dependency>
<groupId>com.xtoon.cloud</groupId>
<artifactId>xtoon-common-web</artifactId>
@@ -32,6 +42,11 @@
<artifactId>xtoon-common-mybatis</artifactId>
<version>${xtoon-cloud.version}</version>
</dependency>
<dependency>
<groupId>com.xtoon.cloud</groupId>
<artifactId>xtoon-sys-interface</artifactId>
<version>${xtoon-cloud.version}</version>
</dependency>
<!--注册中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
@@ -58,5 +73,14 @@
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.8</version>
</dependency>
</dependencies>
</project>

View File

@@ -1,7 +1,13 @@
package com.xtoon.cloud.ops.auth.controller;
import com.xtoon.cloud.sys.service.AuthenticationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException;
@@ -19,6 +25,7 @@ import java.util.Map;
* @author haoxin
* @date 2021-05-29
**/
@Api(tags = "认证中心")
@RestController
@RequestMapping("/oauth")
@AllArgsConstructor
@@ -27,7 +34,19 @@ public class AuthController {
private TokenEndpoint tokenEndpoint;
@DubboReference
protected AuthenticationService authenticationService;
@PostMapping("/token")
@ApiOperation(value = "OAuth2认证", notes = "login")
@ApiImplicitParams({
@ApiImplicitParam(name = "grant_type", defaultValue = "password", value = "授权模式", required = true),
@ApiImplicitParam(name = "client_id", defaultValue = "client", value = "Oauth2客户端ID", required = true),
@ApiImplicitParam(name = "client_secret", defaultValue = "123456", value = "Oauth2客户端秘钥", required = true),
@ApiImplicitParam(name = "refresh_token", value = "刷新token"),
@ApiImplicitParam(name = "username", defaultValue = "admin", value = "登录用户名"),
@ApiImplicitParam(name = "password", defaultValue = "123456", value = "登录密码"),
})
public OAuth2AccessToken postAccessToken(
Principal principal,
@RequestParam Map<String, String> parameters

View File

@@ -0,0 +1,40 @@
package com.xtoon.cloud.ops.auth.controller;
import cn.hutool.json.JSONObject;
import com.xtoon.cloud.common.core.constant.AuthConstants;
import com.xtoon.cloud.common.core.util.RequestUtils;
import com.xtoon.cloud.common.redis.util.RedisService;
import com.xtoon.cloud.common.web.util.Result;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "注销")
@RestController
@RequestMapping("/oauth")
@AllArgsConstructor
@Slf4j
public class LogoutController {
private RedisService redisService;
@DeleteMapping("/logout")
public Result logout() {
JSONObject jsonObject = RequestUtils.getJwtPayload();
String jti = jsonObject.getStr(AuthConstants.JWT_JTI);
long exp = jsonObject.getLong(AuthConstants.JWT_EXP);
long currentTimeSeconds = System.currentTimeMillis() / 1000;
if (exp < currentTimeSeconds) {
return Result.ok();
}
redisService.set(AuthConstants.TOKEN_BLACKLIST_PREFIX + jti, null, (exp - currentTimeSeconds));
return Result.ok();
}
}

View File

@@ -2,6 +2,7 @@ package com.xtoon.cloud.ops.auth.controller;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
@@ -18,6 +19,7 @@ import java.util.Map;
* @author haoxin
* @date 2021-05-29
**/
@Api(tags = "获取公钥接口")
@RestController
@RequestMapping
@AllArgsConstructor

View File

@@ -1,32 +1,26 @@
package com.xtoon.cloud.ops.auth.domain;
import com.xtoon.cloud.common.core.constant.AuthConstants;
import com.xtoon.cloud.common.core.domain.StatusEnum;
import com.xtoon.cloud.sys.dto.AuthenticationDTO;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
/**
* 登录用户信息
*
* @author haoxin
* @date 2021-06-15
**/
*/
@Data
@NoArgsConstructor
public class User implements UserDetails {
public User(Long id, String username, String password, Boolean enabled, String clientId, Collection<? extends GrantedAuthority> authorities) {
this.id = id;
this.username = username;
this.password = password;
this.enabled = enabled;
this.clientId = clientId;
this.authorities = authorities;
}
private Long id;
private String id;
private String username;
@@ -36,7 +30,30 @@ public class User implements UserDetails {
private String clientId;
private Collection<? extends GrantedAuthority> authorities;
private Collection<GrantedAuthority> authorities;
public User(AuthenticationDTO authenticationDTO) {
this.setId(authenticationDTO.getUserId());
this.setUsername(authenticationDTO.getUserName());
this.setPassword(AuthConstants.BCRYPT + authenticationDTO.getPassword());
this.setEnabled(StatusEnum.ENABLE.getValue().equals(authenticationDTO.getStatus()));
this.authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils.join(authenticationDTO.getPermissionCodes(), ","));
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public String getPassword() {
return this.password;
}
@Override
public String getUsername() {
return this.username;
}
@Override
public boolean isAccountNonExpired() {

View File

@@ -0,0 +1,53 @@
package com.xtoon.cloud.ops.auth.filter;
import com.alibaba.fastjson.JSONObject;
import com.xtoon.cloud.common.core.constant.AuthConstants;
import com.xtoon.cloud.common.web.util.Result;
import com.xtoon.cloud.sys.service.AuthenticationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 验证码过滤器
*
* @author haoxin
* @date 2021-06-23
**/
@Slf4j
@Component
public class CaptchaFilter extends OncePerRequestFilter {
@DubboReference
protected AuthenticationService authenticationService;
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
RequestMatcher matcher = new AntPathRequestMatcher(AuthConstants.OAUTH_TOKEN, HttpMethod.POST.toString());
if (matcher.matches(httpServletRequest)
&& StringUtils.equalsIgnoreCase(httpServletRequest.getParameter(AuthConstants.GRANT_TYPE_KEY), AuthConstants.PASSWORD)) {
String code = httpServletRequest.getParameter(AuthConstants.VALIDATE_CODE_CODE);
String key = httpServletRequest.getParameter(AuthConstants.VALIDATE_CODE_KEY);
if (!authenticationService.validateCaptcha(key, code)) {
httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
httpServletResponse.getOutputStream().write(JSONObject.toJSONString(Result.error("验证码不正确")).getBytes());
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
} else {
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
}

View File

@@ -1,18 +1,14 @@
package com.xtoon.cloud.ops.auth.service;
import com.xtoon.cloud.common.core.constant.AuthConstants;
import com.xtoon.cloud.ops.auth.domain.User;
import lombok.AllArgsConstructor;
import com.xtoon.cloud.sys.dto.AuthenticationDTO;
import com.xtoon.cloud.sys.service.AuthenticationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 自定义用户认证和授权
*
@@ -20,15 +16,19 @@ import java.util.List;
* @date 2021-05-29
**/
@Service
@AllArgsConstructor
@Slf4j
public class UserDetailsServiceImpl implements UserDetailsService {
@DubboReference
protected AuthenticationService authenticationService;
@Override
public User loadUserByUsername(String s) throws UsernameNotFoundException {
String permissions = "log:list";
List<GrantedAuthority> grantedAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(permissions);
// TODO test
return new User(1L, "test", AuthConstants.BCRYPT + new BCryptPasswordEncoder().encode("123456"), true, "client", grantedAuthorities);
public User loadUserByUsername(String username) throws UsernameNotFoundException {
AuthenticationDTO authenticationDTO = authenticationService.loginByUserName(username);
if (authenticationDTO != null) {
return new User(authenticationDTO);
} else {
throw new UsernameNotFoundException("");
}
}
}

View File

@@ -6,8 +6,12 @@ import cn.hutool.json.JSONUtil;
import com.nimbusds.jose.JWSObject;
import com.xtoon.cloud.common.core.constant.AuthConstants;
import com.xtoon.cloud.common.core.constant.CommonConstant;
import com.xtoon.cloud.common.redis.util.RedisService;
import com.xtoon.cloud.common.web.constant.ResultCode;
import com.xtoon.cloud.ops.gateway.util.WebUtils;
import lombok.SneakyThrows;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
@@ -26,8 +30,8 @@ import reactor.core.publisher.Mono;
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
// @Autowired
// private RedisService redisService;
@Autowired
private RedisService redisService;
@SneakyThrows
@Override
@@ -47,11 +51,11 @@ public class AuthGlobalFilter implements GlobalFilter, Ordered {
JWSObject jwsObject = JWSObject.parse(token);
String payload = jwsObject.getPayload().toString();
JSONObject jsonObject = JSONUtil.parseObj(payload);
// String jti = jsonObject.getStr(AuthConstants.JWT_JTI);
// Boolean isBlack = redisService.hasKey(AuthConstants.TOKEN_BLACKLIST_PREFIX + jti);
// if (isBlack) {
// return WebUtils.getAuthFailResult(response, ResultCode.UNAUTHORIZED.getCode());
// }
String jti = jsonObject.getStr(AuthConstants.JWT_JTI);
Boolean isBlack = redisService.hasKey(AuthConstants.TOKEN_BLACKLIST_PREFIX + jti);
if (isBlack) {
return WebUtils.getAuthFailResult(response, ResultCode.UNAUTHORIZED.getCode());
}
// 存在token且不是黑名单request写入JWT的载体信息
String tenantId = request.getHeaders().getFirst(CommonConstant.TENANT_ID);

View File

@@ -0,0 +1,42 @@
package com.xtoon.cloud.sys.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.Set;
/**
* 认证信息DTO
*
* @author haoxin
* @date 2021-06-23
**/
@Data
public class AuthenticationDTO implements Serializable {
/**
* 用户ID
*/
private String userId;
/**
* 用户名
*/
private String userName;
/**
* password
*/
private String password;
/**
* status
*/
private String status;
/**
* 权限编码
*/
private Set<String> permissionCodes;
}

View File

@@ -0,0 +1,28 @@
package com.xtoon.cloud.sys.service;
import com.xtoon.cloud.sys.dto.AuthenticationDTO;
/**
* 认证服务接口
*
* @author haoxin
* @date 2021-06-23
**/
public interface AuthenticationService {
/**
* 验证验证码
*
* @param uuid
* @return
*/
boolean validateCaptcha(String uuid, String captchaCode);
/**
* 认证
*
* @param userName 用户名
* @return
*/
AuthenticationDTO loginByUserName(String userName);
}

View File

@@ -0,0 +1,39 @@
package com.xtoon.cloud.sys.api;
import com.xtoon.cloud.sys.application.CaptchaApplicationService;
import io.swagger.annotations.Api;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
/**
* 验证码Controller
*
* @author haoxin
* @date 2021-06-23
**/
@Api(tags = "验证码管理")
@RestController
public class CaptchaController {
@Autowired
private CaptchaApplicationService captchaApplicationService;
@GetMapping("/captcha")
public void captcha(HttpServletResponse response, String uuid) throws IOException {
response.setHeader("Cache-Control", "no-store, no-cache");
response.setContentType("image/jpeg");
//获取图片验证码
BufferedImage image = captchaApplicationService.getCaptcha(uuid);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(image, "jpg", out);
IOUtils.closeQuietly(out);
}
}

View File

@@ -1,5 +1,6 @@
package com.xtoon.cloud.sys.api;
import com.xtoon.cloud.common.core.util.RequestUtils;
import com.xtoon.cloud.common.log.SysLog;
import com.xtoon.cloud.common.web.util.Result;
import com.xtoon.cloud.common.web.util.validator.ValidatorUtils;
@@ -16,6 +17,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Set;
/**
* 权限Controller
@@ -40,10 +42,9 @@ public class PermissionController {
@ApiOperation("导航菜单")
@GetMapping("/nav")
public Result nav() {
// List<PermissionDTO> menuList = permissionQueryService.getUserMenuTree(getUser().getPermissionIds());
// Set<String> permissions = getUser().getPermissionCodes();
// return Result.ok().put("menuList", menuList).put("permissions", permissions);
return Result.ok();
List<PermissionDTO> menuList = permissionQueryService.getUserMenuTree(RequestUtils.getUserId());
Set<String> permissions = permissionQueryService.getPermissionCodes(RequestUtils.getUserId());
return Result.ok().put("menuList", menuList).put("permissions", permissions);
}
/**

View File

@@ -4,7 +4,7 @@ import com.xtoon.cloud.common.log.SysLog;
import com.xtoon.cloud.common.web.util.Result;
import com.xtoon.cloud.common.web.util.validator.ValidatorUtils;
import com.xtoon.cloud.common.web.util.validator.group.AddGroup;
import com.xtoon.cloud.sys.application.AuthenticationApplicationService;
import com.xtoon.cloud.sys.application.RegisterApplicationService;
import com.xtoon.cloud.sys.application.command.RegisterTenantCommand;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -24,7 +24,7 @@ import org.springframework.web.bind.annotation.RestController;
public class RegisterController {
@Autowired
private AuthenticationApplicationService authenticationApplicationService;
private RegisterApplicationService registerApplicationService;
/**
* 注册租户
@@ -34,7 +34,7 @@ public class RegisterController {
@PostMapping("/registerTenant")
public Result registerTenantAndUser(@RequestBody RegisterTenantCommand registerTenantCommand) {
ValidatorUtils.validateEntity(registerTenantCommand, AddGroup.class);
authenticationApplicationService.registerTenant(registerTenantCommand);
registerApplicationService.registerTenant(registerTenantCommand);
return Result.ok();
}
}

View File

@@ -1,5 +1,6 @@
package com.xtoon.cloud.sys.api;
import com.xtoon.cloud.common.core.util.RequestUtils;
import com.xtoon.cloud.common.log.SysLog;
import com.xtoon.cloud.common.mybatis.constant.PageConstant;
import com.xtoon.cloud.common.mybatis.util.Page;
@@ -54,8 +55,7 @@ public class UserController {
@ApiOperation("获取登录的用户信息")
@GetMapping("/info")
public Result info() {
// return Result.ok().put("user", getUser());
return Result.ok();
return Result.ok().put("user", userQueryService.find(RequestUtils.getUserId()));
}
/**
@@ -66,7 +66,7 @@ public class UserController {
@PostMapping("/password")
public Result changePassword(@RequestBody PasswordCommand passwordCommand) {
ValidatorUtils.validateEntity(passwordCommand);
// passwordCommand.setUserId(getUser().getId());
passwordCommand.setUserId(RequestUtils.getUserId());
userApplicationService.changePassword(passwordCommand);
return Result.ok();
}

View File

@@ -1,56 +0,0 @@
package com.xtoon.cloud.sys.application;
import com.xtoon.cloud.sys.application.command.AccountLoginCommand;
import com.xtoon.cloud.sys.application.command.MobileLoginCommand;
import com.xtoon.cloud.sys.application.command.RegisterTenantCommand;
import com.xtoon.cloud.sys.application.dto.LoginSuccessDTO;
import java.awt.image.BufferedImage;
/**
* 身份验证应用服务接口
*
* @author haoxin
* @date 2021-05-10
**/
public interface AuthenticationApplicationService {
/**
* 获取图片验证码
*
* @param uuid
* @return
*/
BufferedImage getCaptcha(String uuid);
/**
* 账号登录
*
* @param accountLoginCommand
* @return
*/
LoginSuccessDTO loginByAccount(AccountLoginCommand accountLoginCommand);
/**
* 手机号登录
*
* @param mobileLoginCommand
* @return
*/
LoginSuccessDTO loginByMobile(MobileLoginCommand mobileLoginCommand);
/**
* 登出
*
* @param userId
*/
void logout(String userId);
/**
* 注册租户
*
* @param registerTenantCommand
*/
void registerTenant(RegisterTenantCommand registerTenantCommand);
}

View File

@@ -0,0 +1,20 @@
package com.xtoon.cloud.sys.application;
import java.awt.image.BufferedImage;
/**
* 验证码应用服务
*
* @author haoxin
* @date 2021-06-23
**/
public interface CaptchaApplicationService {
/**
* 生成ø验证码
*
* @param uuid
* @return
*/
BufferedImage getCaptcha(String uuid);
}

View File

@@ -38,8 +38,25 @@ public interface PermissionQueryService {
/**
* 获取权限树
*
* @param permissionIds
* @param userId
* @return
*/
List<PermissionDTO> getUserMenuTree(Set<String> permissionIds);
List<PermissionDTO> getUserMenuTree(String userId);
/**
* 获取权限编码
*
* @param userId
* @return
*/
Set<String> getPermissionCodes(String userId);
/**
* 获取权限id
*
* @param userId
* @return
*/
Set<String> getPermissionIds(String userId);
}

View File

@@ -0,0 +1,19 @@
package com.xtoon.cloud.sys.application;
import com.xtoon.cloud.sys.application.command.RegisterTenantCommand;
/**
* 注册应用服务接口
*
* @author haoxin
* @date 2021-06-23
**/
public interface RegisterApplicationService {
/**
* 注册租户
*
* @param registerTenantCommand
*/
void registerTenant(RegisterTenantCommand registerTenantCommand);
}

View File

@@ -19,4 +19,6 @@ public interface TenantQueryService {
* @return
*/
Page queryPage(Map<String, Object> params);
}

View File

@@ -28,12 +28,4 @@ public interface UserQueryService {
* @return
*/
UserDTO find(String userId);
/**
* token查询用户
*
* @param token
* @return
*/
UserDTO queryByToken(String token);
}

View File

@@ -0,0 +1,22 @@
package com.xtoon.cloud.sys.application.assembler;
import com.xtoon.cloud.sys.domain.model.user.User;
import com.xtoon.cloud.sys.dto.AuthenticationDTO;
/**
* Assembler class for the AuthenticationDTOAssembler.
*
* @author haoxin
* @date 2021-02-09
**/
public class AuthenticationDTOAssembler {
public static AuthenticationDTO fromUser(final User user) {
AuthenticationDTO authenticationDTO = new AuthenticationDTO();
authenticationDTO.setUserId(user.getUserId().getId());
authenticationDTO.setUserName(user.getUserName().getName());
authenticationDTO.setPassword(user.getAccount().getPassword().getPassword());
authenticationDTO.setStatus(user.getStatus().getValue());
return authenticationDTO;
}
}

View File

@@ -1,21 +0,0 @@
package com.xtoon.cloud.sys.application.assembler;
import com.xtoon.cloud.sys.application.dto.LoginSuccessDTO;
import com.xtoon.cloud.sys.domain.model.user.User;
/**
* Assembler class for the LoginSuccessDTOAssembler.
*
* @author haoxin
* @date 2021-02-09
**/
public class LoginSuccessDTOAssembler {
public static LoginSuccessDTO toDTO(final User user) {
final LoginSuccessDTO dto = new LoginSuccessDTO(
user.getAccount().getToken().getToken(),
String.valueOf(user.getAccount().getToken().getExpirePeriod()),
user.getTenantId().getId());
return dto;
}
}

View File

@@ -1,46 +0,0 @@
package com.xtoon.cloud.sys.application.command;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 账号名登录Command
*
* @author haoxin
* @date 2021-02-08
**/
@Data
@ApiModel(value = "账号登录", description = "账号登录")
public class AccountLoginCommand {
/**
* 账号名
*/
@ApiModelProperty(value = "账号名")
@NotBlank(message = "账号名不能为空")
private String accountName;
/**
* 密码
*/
@ApiModelProperty(value = "密码")
@NotBlank(message = "密码不能为空")
private String password;
/**
* 验证码
*/
@ApiModelProperty(value = "验证码")
@NotBlank(message = "验证码不能为空")
private String captcha;
/**
* uuid
*/
@ApiModelProperty(value = "uuid")
@NotBlank(message = "uuid不能为空")
private String uuid;
}

View File

@@ -1,38 +0,0 @@
package com.xtoon.cloud.sys.application.command;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 手机号登录Command
*
* @author haoxin
* @date 2021-02-08
**/
@Data
@ApiModel(value = "手机号登录", description = "手机号登录")
public class MobileLoginCommand {
/**
* 手机号
*/
@ApiModelProperty(value = "手机号")
@NotBlank(message = "手机号不能为空")
private String mobile;
/**
* 验证码
*/
@ApiModelProperty(value = "验证码")
@NotBlank(message = "验证码不能为空")
private String verificationCode;
/**
* 正确的验证码
*/
private String correctVerificationCode;
}

View File

@@ -16,28 +16,28 @@ import java.util.List;
* @date 2021-02-18
**/
@Data
@ApiModel(value="角色",description="角色")
@ApiModel(value = "角色", description = "角色")
public class RoleCommand {
/**
* id
*/
@ApiModelProperty(value = "角色id")
@NotBlank(message="角色id不能为空", groups = UpdateGroup.class)
@NotBlank(message = "角色id不能为空", groups = UpdateGroup.class)
private String id;
/**
* 角色编码
*/
@ApiModelProperty(value = "角色编码")
@NotBlank(message="角色编码不能为空", groups = AddGroup.class)
@NotBlank(message = "角色编码不能为空", groups = AddGroup.class)
private String roleCode;
/**
* 角色名称
*/
@ApiModelProperty(value = "角色名称")
@NotBlank(message="角色名称不能为空", groups = AddGroup.class)
@NotBlank(message = "角色名称不能为空", groups = AddGroup.class)
private String roleName;
/**

View File

@@ -1,54 +0,0 @@
package com.xtoon.cloud.sys.application.dto;
import java.io.Serializable;
/**
* 登录成功DTO
*
* @author haoxin
* @date 2021-02-09
**/
public class LoginSuccessDTO implements Serializable {
public LoginSuccessDTO(String token, String expire, String tenantId) {
this.token = token;
this.expire = expire;
this.tenantId = tenantId;
}
/**
* token
*/
private String token;
/**
* 过去时间
*/
private String expire;
/**
* 当前租户id
*/
private String tenantId;
public String getToken() {
return token;
}
public String getExpire() {
return expire;
}
public String getTenantId() {
return tenantId;
}
@Override
public String toString() {
return "LoginSuccessDTO{" +
"token='" + token + '\'' +
", expire='" + expire + '\'' +
", tenantId='" + tenantId + '\'' +
'}';
}
}

View File

@@ -1,125 +0,0 @@
package com.xtoon.cloud.sys.application.impl;
import com.google.code.kaptcha.Producer;
import com.xtoon.cloud.sys.application.AuthenticationApplicationService;
import com.xtoon.cloud.sys.application.assembler.LoginSuccessDTOAssembler;
import com.xtoon.cloud.sys.application.command.AccountLoginCommand;
import com.xtoon.cloud.sys.application.command.MobileLoginCommand;
import com.xtoon.cloud.sys.application.command.RegisterTenantCommand;
import com.xtoon.cloud.sys.application.dto.LoginSuccessDTO;
import com.xtoon.cloud.sys.domain.external.TokenGeneratorExternalService;
import com.xtoon.cloud.sys.domain.model.captcha.Captcha;
import com.xtoon.cloud.sys.domain.model.captcha.CaptchaCode;
import com.xtoon.cloud.sys.domain.model.captcha.CaptchaRepository;
import com.xtoon.cloud.sys.domain.model.captcha.Uuid;
import com.xtoon.cloud.sys.domain.model.permission.PermissionRepository;
import com.xtoon.cloud.sys.domain.model.role.RoleRepository;
import com.xtoon.cloud.sys.domain.model.tenant.TenantCode;
import com.xtoon.cloud.sys.domain.model.tenant.TenantName;
import com.xtoon.cloud.sys.domain.model.tenant.TenantRepository;
import com.xtoon.cloud.sys.domain.model.user.*;
import com.xtoon.cloud.sys.domain.service.CaptchaValidateService;
import com.xtoon.cloud.sys.domain.service.TenantRegisterService;
import com.xtoon.cloud.sys.domain.specification.LoginByAccountSpecification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.awt.image.BufferedImage;
import java.util.List;
/**
* 身份验证应用服务实现类
*
* @author haoxin
* @date 2021-05-10
**/
@Service
public class AuthenticationApplicationServiceImpl implements AuthenticationApplicationService {
@Autowired
private Producer producer;
@Autowired
private CaptchaRepository captchaRepository;
@Autowired
private UserRepository userRepository;
@Autowired
private TokenGeneratorExternalService tokenGeneratorExternalService;
@Autowired
private TenantRepository tenantRepository;
@Autowired
private RoleRepository roleRepository;
@Autowired
private PermissionRepository permissionRepository;
@Override
@Transactional(rollbackFor = Exception.class)
public BufferedImage getCaptcha(String uuid) {
//生成文字验证码
String code = producer.createText();
captchaRepository.store(Captcha.createCaptcha(new Uuid(uuid), new CaptchaCode(code)));
return producer.createImage(code);
}
@Override
@Transactional(rollbackFor = Exception.class)
public LoginSuccessDTO loginByAccount(AccountLoginCommand accountLoginCommand) {
CaptchaValidateService captchaValidateService = new CaptchaValidateService(captchaRepository);
if (!captchaValidateService.validate(new Uuid(accountLoginCommand.getUuid()), new CaptchaCode(accountLoginCommand.getCaptcha()))) {
throw new RuntimeException("验证码不正确");
}
List<User> users = userRepository.find(new Mobile(accountLoginCommand.getAccountName()));
if (users == null || users.isEmpty()) {
throw new RuntimeException("用户或密码不正确");
}
User user = users.get(0);
LoginByAccountSpecification loginByUserNameSpecification = new LoginByAccountSpecification(accountLoginCommand.getPassword());
loginByUserNameSpecification.isSatisfiedBy(user);
user.refreshToken(tokenGeneratorExternalService.generateValue());
userRepository.store(user);
return LoginSuccessDTOAssembler.toDTO(user);
}
@Override
@Transactional(rollbackFor = Exception.class)
public LoginSuccessDTO loginByMobile(MobileLoginCommand mobileLoginCommand) {
if (!mobileLoginCommand.getVerificationCode().equals(mobileLoginCommand.getCorrectVerificationCode())) {
throw new RuntimeException("验证码不正确");
}
List<User> users = userRepository.find(new Mobile(mobileLoginCommand.getMobile()));
if (users == null || users.isEmpty()) {
throw new RuntimeException("用户不存在");
}
User user = users.get(0);
user.refreshToken(tokenGeneratorExternalService.generateValue());
userRepository.store(user);
return LoginSuccessDTOAssembler.toDTO(user);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void logout(String userId) {
User user = userRepository.find(new UserId(userId));
user.refreshToken(tokenGeneratorExternalService.generateValue());
userRepository.store(user);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void registerTenant(RegisterTenantCommand registerTenantCommand) {
CaptchaValidateService captchaValidateService = new CaptchaValidateService(captchaRepository);
if (!captchaValidateService.validate(new Uuid(registerTenantCommand.getUuid()), new CaptchaCode(registerTenantCommand.getCaptcha()))) {
throw new RuntimeException("验证码不正确");
}
TenantRegisterService tenantRegisterService = new TenantRegisterService(tenantRepository, roleRepository, permissionRepository, userRepository);
tenantRegisterService.registerTenant(new TenantName(registerTenantCommand.getTenantName()), new TenantCode(registerTenantCommand.getTenantCode()), new Mobile(registerTenantCommand.getMobile()),
Password.create(registerTenantCommand.getPassword()), new UserName(registerTenantCommand.getUserName()));
}
}

View File

@@ -0,0 +1,63 @@
package com.xtoon.cloud.sys.application.impl;
import com.google.code.kaptcha.Producer;
import com.xtoon.cloud.sys.application.PermissionQueryService;
import com.xtoon.cloud.sys.application.assembler.AuthenticationDTOAssembler;
import com.xtoon.cloud.sys.domain.model.captcha.Captcha;
import com.xtoon.cloud.sys.domain.model.captcha.CaptchaCode;
import com.xtoon.cloud.sys.domain.model.captcha.CaptchaRepository;
import com.xtoon.cloud.sys.domain.model.captcha.Uuid;
import com.xtoon.cloud.sys.domain.model.user.Mobile;
import com.xtoon.cloud.sys.domain.model.user.User;
import com.xtoon.cloud.sys.domain.model.user.UserRepository;
import com.xtoon.cloud.sys.domain.service.CaptchaValidateService;
import com.xtoon.cloud.sys.dto.AuthenticationDTO;
import com.xtoon.cloud.sys.service.AuthenticationService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.awt.image.BufferedImage;
import java.util.List;
/**
* 身份验证应用服务实现类
*
* @author haoxin
* @date 2021-05-10
**/
@Service
public class AuthenticationServiceImpl implements AuthenticationService {
@Autowired
private CaptchaRepository captchaRepository;
@Autowired
private UserRepository userRepository;
@Autowired
private PermissionQueryService permissionQueryService;
@Override
public boolean validateCaptcha(String uuid, String captchaCode) {
if (StringUtils.isBlank(uuid) || StringUtils.isBlank(captchaCode)) {
return false;
}
CaptchaValidateService captchaValidateService = new CaptchaValidateService(captchaRepository);
return captchaValidateService.validate(new Uuid(uuid), new CaptchaCode(captchaCode));
}
@Override
public AuthenticationDTO loginByUserName(String userName) {
List<User> users = userRepository.find(new Mobile(userName));
if (users == null || users.isEmpty()) {
throw new RuntimeException("用户或密码不正确");
}
User user = users.get(0);
AuthenticationDTO authenticationDTO = AuthenticationDTOAssembler.fromUser(user);
authenticationDTO.setPermissionCodes(permissionQueryService.getPermissionCodes(user.getUserId().getId()));
return authenticationDTO;
}
}

View File

@@ -0,0 +1,38 @@
package com.xtoon.cloud.sys.application.impl;
import com.google.code.kaptcha.Producer;
import com.xtoon.cloud.sys.application.CaptchaApplicationService;
import com.xtoon.cloud.sys.domain.model.captcha.Captcha;
import com.xtoon.cloud.sys.domain.model.captcha.CaptchaCode;
import com.xtoon.cloud.sys.domain.model.captcha.CaptchaRepository;
import com.xtoon.cloud.sys.domain.model.captcha.Uuid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.awt.image.BufferedImage;
/**
* 验证码应用服务实现类
*
* @author haoxin
* @date 2021-06-23
**/
@Service
public class CaptchaApplicationServiceImpl implements CaptchaApplicationService {
@Autowired
private Producer producer;
@Autowired
private CaptchaRepository captchaRepository;
@Override
@Transactional(rollbackFor = Exception.class)
public BufferedImage getCaptcha(String uuid) {
//生成文字验证码
String code = producer.createText();
captchaRepository.store(Captcha.createCaptcha(new Uuid(uuid), new CaptchaCode(code)));
return producer.createImage(code);
}
}

View File

@@ -1,5 +1,7 @@
package com.xtoon.cloud.sys.application.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xtoon.cloud.common.core.domain.StatusEnum;
import com.xtoon.cloud.common.core.util.TenantContext;
import com.xtoon.cloud.sys.application.PermissionQueryService;
import com.xtoon.cloud.sys.application.assembler.PermissionDTOAssembler;
@@ -10,10 +12,14 @@ import com.xtoon.cloud.sys.domain.model.permission.PermissionRepository;
import com.xtoon.cloud.sys.domain.model.permission.PermissionTypeEnum;
import com.xtoon.cloud.sys.domain.model.role.RoleCode;
import com.xtoon.cloud.sys.domain.model.tenant.TenantId;
import com.xtoon.cloud.sys.domain.model.user.UserId;
import com.xtoon.cloud.sys.infrastructure.persistence.entity.SysPermissionDO;
import com.xtoon.cloud.sys.infrastructure.persistence.mapper.SysPermissionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
* 权限查询服务实现类
@@ -27,6 +33,9 @@ public class PermissionQueryServiceImpl implements PermissionQueryService {
@Autowired
private PermissionRepository permissionRepository;
@Autowired
private SysPermissionMapper sysPermissionMapper;
@Override
public List<PermissionDTO> listAllPermission() {
List<Permission> permissionList;
@@ -56,13 +65,45 @@ public class PermissionQueryServiceImpl implements PermissionQueryService {
}
@Override
public List<PermissionDTO> getUserMenuTree(Set<String> permissionIds) {
public List<PermissionDTO> getUserMenuTree(String userId) {
Set<String> permissionIds = getPermissionIds(userId);
if (permissionIds == null) {
return null;
}
return getAllMenuList(permissionIds);
}
@Override
public Set<String> getPermissionCodes(String userId) {
List<SysPermissionDO> sysPermissionDOList = getSysPermissionDOList(userId);
Set<String> permissionCodes = sysPermissionDOList.stream().filter(p -> p.getPermissionCodes() != null).
flatMap(p -> Arrays.asList(p.getPermissionCodes().trim().split(",")).stream()).collect(Collectors.toSet());
return permissionCodes;
}
@Override
public Set<String> getPermissionIds(String userId) {
List<SysPermissionDO> sysPermissionDOList = getSysPermissionDOList(userId);
Set<String> permissionIds = sysPermissionDOList.stream().map(p -> p.getId()).collect(Collectors.toSet());
return permissionIds;
}
/**
* 获取用户权限
*
* @param userId
* @return
*/
private List<SysPermissionDO> getSysPermissionDOList(String userId) {
List<SysPermissionDO> sysPermissionDOList;
if (new UserId(userId).isSysAdmin()) {
sysPermissionDOList = sysPermissionMapper.selectList(new QueryWrapper<SysPermissionDO>().eq("status", StatusEnum.ENABLE.getValue()));
} else {
sysPermissionDOList = sysPermissionMapper.queryPermissionByUserId(userId);
}
return sysPermissionDOList;
}
/**
* 获取所有菜单列表
*/

View File

@@ -0,0 +1,56 @@
package com.xtoon.cloud.sys.application.impl;
import com.xtoon.cloud.sys.application.RegisterApplicationService;
import com.xtoon.cloud.sys.application.command.RegisterTenantCommand;
import com.xtoon.cloud.sys.domain.model.captcha.CaptchaCode;
import com.xtoon.cloud.sys.domain.model.captcha.CaptchaRepository;
import com.xtoon.cloud.sys.domain.model.captcha.Uuid;
import com.xtoon.cloud.sys.domain.model.permission.PermissionRepository;
import com.xtoon.cloud.sys.domain.model.role.RoleRepository;
import com.xtoon.cloud.sys.domain.model.tenant.TenantCode;
import com.xtoon.cloud.sys.domain.model.tenant.TenantName;
import com.xtoon.cloud.sys.domain.model.tenant.TenantRepository;
import com.xtoon.cloud.sys.domain.model.user.Mobile;
import com.xtoon.cloud.sys.domain.model.user.Password;
import com.xtoon.cloud.sys.domain.model.user.UserName;
import com.xtoon.cloud.sys.domain.model.user.UserRepository;
import com.xtoon.cloud.sys.domain.service.CaptchaValidateService;
import com.xtoon.cloud.sys.domain.service.TenantRegisterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 注册应用服务实现类
*
* @author haoxin
* @date 2021-06-23
**/
@Service
public class RegisterApplicationServiceImpl implements RegisterApplicationService {
@Autowired
private CaptchaRepository captchaRepository;
@Autowired
private UserRepository userRepository;
@Autowired
private TenantRepository tenantRepository;
@Autowired
private RoleRepository roleRepository;
@Autowired
private PermissionRepository permissionRepository;
@Override
public void registerTenant(RegisterTenantCommand registerTenantCommand) {
CaptchaValidateService captchaValidateService = new CaptchaValidateService(captchaRepository);
if (!captchaValidateService.validate(new Uuid(registerTenantCommand.getUuid()), new CaptchaCode(registerTenantCommand.getCaptcha()))) {
throw new RuntimeException("验证码不正确");
}
TenantRegisterService tenantRegisterService = new TenantRegisterService(tenantRepository, roleRepository, permissionRepository, userRepository);
tenantRegisterService.registerTenant(new TenantName(registerTenantCommand.getTenantName()), new TenantCode(registerTenantCommand.getTenantCode()), new Mobile(registerTenantCommand.getMobile()),
Password.create(registerTenantCommand.getPassword()), new UserName(registerTenantCommand.getUserName()));
}
}

View File

@@ -1,21 +1,17 @@
package com.xtoon.cloud.sys.application.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xtoon.cloud.common.core.domain.StatusEnum;
import com.xtoon.cloud.common.mybatis.util.Page;
import com.xtoon.cloud.common.mybatis.util.PageAssembler;
import com.xtoon.cloud.common.mybatis.util.Query;
import com.xtoon.cloud.sys.application.PermissionQueryService;
import com.xtoon.cloud.sys.application.UserQueryService;
import com.xtoon.cloud.sys.application.assembler.UserDTOAssembler;
import com.xtoon.cloud.sys.application.dto.TenantDTO;
import com.xtoon.cloud.sys.application.dto.UserDTO;
import com.xtoon.cloud.sys.domain.model.user.Token;
import com.xtoon.cloud.sys.domain.model.user.User;
import com.xtoon.cloud.sys.domain.model.user.UserId;
import com.xtoon.cloud.sys.domain.model.user.UserRepository;
import com.xtoon.cloud.sys.domain.specification.LoginByTokenSpecification;
import com.xtoon.cloud.sys.infrastructure.persistence.entity.SysPermissionDO;
import com.xtoon.cloud.sys.infrastructure.persistence.entity.SysTenantDO;
import com.xtoon.cloud.sys.infrastructure.persistence.entity.SysUserDO;
import com.xtoon.cloud.sys.infrastructure.persistence.mapper.SysPermissionMapper;
@@ -24,7 +20,10 @@ import com.xtoon.cloud.sys.infrastructure.persistence.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 用户查询服务实现类
@@ -42,10 +41,10 @@ public class UserQueryServiceImpl implements UserQueryService {
private UserRepository userRepository;
@Autowired
private SysPermissionMapper sysPermissionMapper;
private SysTenantMapper sysTenantMapper;
@Autowired
private SysTenantMapper sysTenantMapper;
private PermissionQueryService permissionQueryService;
@Override
public Page queryPage(Map<String, Object> params) {
@@ -55,34 +54,25 @@ public class UserQueryServiceImpl implements UserQueryService {
@Override
public UserDTO find(String userId) {
return UserDTOAssembler.fromUser(userRepository.find(new UserId(userId)));
}
@Override
public UserDTO queryByToken(String token) {
Token accountToken = new Token(token, null);
User user = userRepository.find(accountToken);
LoginByTokenSpecification loginByTokenSpecification = new LoginByTokenSpecification();
loginByTokenSpecification.isSatisfiedBy(user);
User user = userRepository.find(new UserId(userId));
UserDTO userDTO = UserDTOAssembler.fromUser(user);
SysTenantDO tenantDO = sysTenantMapper.selectById(user.getTenantId());
userDTO.setTenantName(tenantDO.getTenantName());
List<SysPermissionDO> sysPermissionDOList;
if (user.getUserId().isSysAdmin()) {
sysPermissionDOList = sysPermissionMapper.selectList(new QueryWrapper<SysPermissionDO>().eq("status", StatusEnum.ENABLE.getValue()));
} else {
sysPermissionDOList = sysPermissionMapper.queryPermissionByUserId(user.getUserId().getId());
}
Set<String> permissionIds = new HashSet<>();
Set<String> permsSet = new HashSet<>();
for (SysPermissionDO sysPermissionDO : sysPermissionDOList) {
permissionIds.add(sysPermissionDO.getId());
if (sysPermissionDO.getPermissionCodes() != null) {
permsSet.addAll(Arrays.asList(sysPermissionDO.getPermissionCodes().trim().split(",")));
}
}
userDTO.setPermissionCodes(permissionQueryService.getPermissionCodes(userId));
userDTO.setPermissionIds(permissionQueryService.getPermissionIds(userId));
userDTO.setTenants(getUserTenants(userId));
return userDTO;
}
/**
* 获取用户关联的租户
*
* @param userId
* @return
*/
private List<TenantDTO> getUserTenants(String userId) {
Map<String, Object> params = new HashMap<>();
params.put("token", token);
params.put("userId", userId);
List<SysUserDO> sysUserDOList = sysUserMapper.queryUserNoTenant(params);
List<TenantDTO> tenants = new ArrayList<>();
for (SysUserDO sysUserDO : sysUserDOList) {
@@ -92,9 +82,6 @@ public class UserQueryServiceImpl implements UserQueryService {
tenantDTO.setTenantName(sysUserDO.getTenantName());
tenants.add(tenantDTO);
}
userDTO.setPermissionCodes(permsSet);
userDTO.setPermissionIds(permissionIds);
userDTO.setTenants(tenants);
return userDTO;
return tenants;
}
}

View File

@@ -1,17 +0,0 @@
package com.xtoon.cloud.sys.domain.external;
/**
* 生成Token外部接口
*
* @author haoxin
* @date 2021-04-23
**/
public interface TokenGeneratorExternalService {
/**
* 生成token
*
* @return
*/
String generateValue();
}

View File

@@ -30,18 +30,12 @@ public class Account implements Entity<Account> {
*/
private Password password;
/**
* token
*/
private Token token;
public Account(AccountId accountId, Mobile mobile, Email email, Password password, Token token) {
public Account(AccountId accountId, Mobile mobile, Email email, Password password) {
this.accountId = accountId;
this.mobile = mobile;
this.email = email;
this.password = password;
this.token = token;
}
public Account(Mobile mobile, String password) {
@@ -67,7 +61,7 @@ public class Account implements Entity<Account> {
* @return
*/
public boolean checkPassword(String passwordStr) {
return password != null && this.password.sameValueAs(Password.create(passwordStr, password.getSalt()));
return password != null && this.password.sameValueAs(Password.create(passwordStr));
}
/**
@@ -81,25 +75,7 @@ public class Account implements Entity<Account> {
if (!checkPassword(oldPasswordStr)) {
throw new RuntimeException("原密码不正确");
}
this.password = Password.create(newPasswordStr, password.getSalt());
}
/**
* 检查token是否有效
*
* @return
*/
public boolean isTokenValid() {
return this.token != null && this.token.getExpireTime() != null &&
this.token.getExpireTime().getTime() >= System.currentTimeMillis();
}
/**
* 更新Token
*/
public Account updateToken(String tokenStr) {
this.token = Token.create(tokenStr);
return this;
this.password = Password.create(newPasswordStr);
}
public AccountId getAccountId() {
@@ -117,8 +93,4 @@ public class Account implements Entity<Account> {
public Password getPassword() {
return password;
}
public Token getToken() {
return token;
}
}

View File

@@ -1,7 +1,6 @@
package com.xtoon.cloud.sys.domain.model.user;
import com.xtoon.cloud.common.core.domain.ValueObject;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@@ -20,41 +19,22 @@ public class Password implements ValueObject<Password> {
*/
private String password;
/**
* 盐
*/
private String salt;
public Password(String password, String salt) {
public Password(String password) {
if (StringUtils.isEmpty(password)) {
throw new IllegalArgumentException("密码不能为空");
}
this.password = password;
this.salt = salt;
}
public static Password create(String passwordStr) {
String salt = RandomStringUtils.randomAlphanumeric(20);
String password = new BCryptPasswordEncoder().encode(passwordStr + salt);
return new Password(password, salt);
}
public static Password create(String passwordStr, String salt) {
if (passwordStr.length() < 6) {
throw new IllegalArgumentException("密码长度不能小于6");
}
String password = new BCryptPasswordEncoder().encode(passwordStr + salt);
return new Password(password, salt);
String password = new BCryptPasswordEncoder().encode(passwordStr);
return new Password(password);
}
public String getPassword() {
return password;
}
public String getSalt() {
return salt;
}
@Override
public boolean sameValueAs(Password other) {
return other != null && this.password.equals(other.password);
@@ -64,7 +44,6 @@ public class Password implements ValueObject<Password> {
public String toString() {
return "Password{" +
"password='" + password + '\'' +
", salt='" + salt + '\'' +
'}';
}
}

View File

@@ -1,87 +0,0 @@
package com.xtoon.cloud.sys.domain.model.user;
import com.xtoon.cloud.common.core.domain.ValueObject;
import org.apache.commons.lang3.StringUtils;
import java.util.Date;
/**
* token值对象
*
* @author haoxin
* @date 2021-02-02
**/
public final class Token implements ValueObject<Token> {
/**
* token
*/
private String token;
/**
* 有效周期
*/
private int expirePeriod;
/**
* 过期时间
*/
private Date expireTime;
public Token(String token, Date expireTime) {
if (StringUtils.isEmpty(token)) {
throw new IllegalArgumentException("token不能为空");
}
this.token = token;
this.expireTime = expireTime;
}
public Token(String token, Date expireTime, int expirePeriod) {
if (StringUtils.isEmpty(token)) {
throw new IllegalArgumentException("token不能为空");
}
this.token = token;
this.expireTime = expireTime;
this.expirePeriod = expirePeriod;
}
/**
* 创建Token
*/
public static Token create(String tokenStr) {
//12小时后过期
int expirePeriod = 3600 * 12;
//当前时间
Date now = new Date();
//过期时间
Date expireTime = new Date(now.getTime() + expirePeriod * 1000);
return new Token(tokenStr, expireTime, expirePeriod);
}
public String getToken() {
return token;
}
public Date getExpireTime() {
return expireTime;
}
public int getExpirePeriod() {
return expirePeriod;
}
@Override
public boolean sameValueAs(Token other) {
return other != null && this.token.equals(other.token);
}
@Override
public String toString() {
return "Token{" +
"token='" + token + '\'' +
", expirePeriod=" + expirePeriod +
", expireTime=" + expireTime +
'}';
}
}

View File

@@ -84,10 +84,6 @@ public class User implements Entity<User> {
this.status = status;
}
public void refreshToken(String tokenStr) {
account.updateToken(tokenStr);
}
public void changePassword(String oldPasswordStr, String newPasswordStr) {
account.changePassword(oldPasswordStr, newPasswordStr);
}

View File

@@ -18,14 +18,6 @@ public interface UserRepository {
*/
User find(UserId userId);
/**
* 根据token获取用户
*
* @param token
* @return
*/
User find(Token token);
/**
* 根据手机号获取账号
*

View File

@@ -1,27 +0,0 @@
package com.xtoon.cloud.sys.domain.specification;
import com.xtoon.cloud.common.core.domain.AbstractSpecification;
import com.xtoon.cloud.sys.domain.model.user.User;
/**
* token登录Specification
*
* @author haoxin
* @date 2021-02-20
**/
public class LoginByTokenSpecification extends AbstractSpecification<User> {
@Override
public boolean isSatisfiedBy(User user) {
if (user == null) {
throw new IllegalArgumentException("用户未登录");
}
if (!user.getAccount().isTokenValid()) {
throw new IllegalArgumentException("账号已过期,请重新登录");
}
if (!user.isEnable()) {
throw new IllegalArgumentException("账号已被锁定,请联系管理员");
}
return true;
}
}

View File

@@ -1,48 +0,0 @@
package com.xtoon.cloud.sys.infrastructure.external.impl;
import com.xtoon.cloud.sys.domain.external.TokenGeneratorExternalService;
import org.springframework.stereotype.Component;
import java.security.MessageDigest;
import java.util.UUID;
/**
* 生成Token外部实现类
*
* @author haoxin
* @date 2021-04-23
**/
@Component
public class TokenGeneratorExternalServiceImpl implements TokenGeneratorExternalService {
@Override
public String generateValue() {
return generateValue(UUID.randomUUID().toString());
}
private static final char[] hexCode = "0123456789abcdef".toCharArray();
public static String toHexString(byte[] data) {
if (data == null) {
return null;
}
StringBuilder r = new StringBuilder(data.length * 2);
for (byte b : data) {
r.append(hexCode[(b >> 4) & 0xF]);
r.append(hexCode[(b & 0xF)]);
}
return r.toString();
}
public static String generateValue(String param) {
try {
MessageDigest algorithm = MessageDigest.getInstance("MD5");
algorithm.reset();
algorithm.update(param.getBytes());
byte[] messageDigest = algorithm.digest();
return toHexString(messageDigest);
} catch (Exception e) {
throw new RuntimeException("生成Token失败", e);
}
}
}

View File

@@ -44,9 +44,6 @@ public class UserConverter {
sysAccountDO.setEmail(account.getEmail() == null ? null : account.getEmail().getEmail());
sysAccountDO.setMobile(account.getMobile() == null ? null : account.getMobile().getMobile());
sysAccountDO.setPassword(account.getPassword() == null ? null : account.getPassword().getPassword());
sysAccountDO.setSalt(account.getPassword() == null ? null : account.getPassword().getSalt());
sysAccountDO.setToken(account.getToken() == null ? null : account.getToken().getToken());
sysAccountDO.setExpireTime(account.getToken() == null ? null : account.getToken().getExpireTime());
return sysAccountDO;
}
@@ -64,13 +61,10 @@ public class UserConverter {
}
Password password = null;
if (sysAccountDO.getPassword() != null) {
password = new Password(sysAccountDO.getPassword(), sysAccountDO.getSalt());
password = new Password(sysAccountDO.getPassword());
}
Token token = null;
if (sysAccountDO.getToken() != null) {
token = new Token(sysAccountDO.getToken(), sysAccountDO.getExpireTime());
}
Account account = new Account(new AccountId(sysAccountDO.getId()), mobile, email, password, token);
Account account = new Account(new AccountId(sysAccountDO.getId()), mobile, email, password);
return account;
}
}

View File

@@ -4,8 +4,6 @@ import com.baomidou.mybatisplus.annotation.TableName;
import com.xtoon.cloud.common.mybatis.util.BaseDO;
import lombok.Data;
import java.util.Date;
/**
* 用户Token DO
*
@@ -31,18 +29,4 @@ public class SysAccountDO extends BaseDO {
*/
private String password;
/**
* 盐
*/
private String salt;
/**
* token
*/
private String token;
/**
* 过期时间
*/
private Date expireTime;
}

View File

@@ -1,15 +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">
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xtoon.cloud.sys.infrastructure.persistence.mapper.SysCaptchaMapper">
<!-- 根据key更新value -->
<update id="updateValueByKey" parameterType="map">
update sys_config set param_value = #{paramValue} where param_key = #{paramKey}
</update>
<!-- 根据key查询value -->
<select id="queryByKey" parameterType="string" resultType="com.xtoon.boot.sys.infrastructure.persistence.entity.SysCaptchaDO">
select * from sys_config where param_key = #{paramKey}
</select>
</mapper>

View File

@@ -2,7 +2,8 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xtoon.cloud.sys.infrastructure.persistence.mapper.SysUserMapper">
<select id="queryPage" parameterType="Map" resultType="com.xtoon.boot.sys.infrastructure.persistence.entity.SysUserDO">
<select id="queryPage" parameterType="Map"
resultType="com.xtoon.boot.sys.infrastructure.persistence.entity.SysUserDO">
SELECT
u.*,a.email,a.mobile
FROM
@@ -11,21 +12,22 @@
<where>
AND u.del_flag='0' AND a.del_flag = '0'
<if test="params.userName != null and params.userName !=''">
AND u.user_name=#{params.userName}
AND u.user_name=#{params.userName}
</if>
<if test="params.userType != null and params.userType !=''">
AND u.user_type=#{params.userType}
AND u.user_type=#{params.userType}
</if>
<if test="params.email != null and params.email !=''">
AND a.email=#{params.email}
AND a.email=#{params.email}
</if>
<if test="params.mobile != null and params.mobile !=''">
AND a.mobile=#{params.mobile}
AND a.mobile=#{params.mobile}
</if>
</where>
</select>
<select id="queryUser" parameterType="Map" resultType="com.xtoon.boot.sys.infrastructure.persistence.entity.SysUserDO">
<select id="queryUser" parameterType="Map"
resultType="com.xtoon.boot.sys.infrastructure.persistence.entity.SysUserDO">
SELECT
u.*,t.tenant_code,t.tenant_name
FROM
@@ -35,18 +37,16 @@
<where>
AND u.del_flag='0' AND a.del_flag = '0' and t.del_flag = '0'
<if test="params.userId != null and params.userId !=''">
AND u.id=#{params.userId}
</if>
<if test="params.token != null and params.token !=''">
AND a.token=#{params.token}
AND u.id=#{params.userId}
</if>
<if test="params.mobile != null and params.mobile !=''">
AND a.mobile=#{params.mobile}
AND a.mobile=#{params.mobile}
</if>
</where>
</select>
<select id="queryUserNoTenant" parameterType="Map" resultType="com.xtoon.boot.sys.infrastructure.persistence.entity.SysUserDO">
<select id="queryUserNoTenant" parameterType="Map"
resultType="com.xtoon.boot.sys.infrastructure.persistence.entity.SysUserDO">
SELECT
u.*,t.tenant_code,t.tenant_name
FROM
@@ -56,16 +56,13 @@
<where>
AND u.del_flag='0' AND a.del_flag = '0' AND t.del_flag = '0' AND u.status = '0' AND t.status = '0'
<if test="params.accountId != null and params.accountId !=''">
AND a.id=#{params.accountId}
AND a.id=#{params.accountId}
</if>
<if test="params.userId != null and params.userId !=''">
AND u.id=#{params.userId}
</if>
<if test="params.token != null and params.token !=''">
AND a.token=#{params.token}
AND u.id=#{params.userId}
</if>
<if test="params.mobile != null and params.mobile !=''">
AND a.mobile=#{params.mobile}
AND a.mobile=#{params.mobile}
</if>
</where>
</select>

View File

@@ -53,18 +53,6 @@ public class UserRepositoryImpl extends ServiceImpl<SysUserMapper, SysUserDO> im
return user;
}
@Override
public User find(Token token) {
Map<String, Object> params = new HashMap<>();
params.put("token", token.getToken());
SysUserDO sysUserDO = baseMapper.queryUser(params);
if (sysUserDO == null) {
return null;
}
User user = UserConverter.toUser(sysUserDO, getUserAccount(sysUserDO.getAccountId()), getUserRoleIds(sysUserDO.getId()));
return user;
}
@Override
public List<User> find(Mobile mobile) {
Map<String, Object> params = new HashMap<>();