AppRegister

This commit is contained in:
2025-06-20 08:23:00 +08:00
parent 27aea7e20d
commit bcaf594145
29 changed files with 725 additions and 148 deletions

View File

@ -229,6 +229,7 @@ public class RedisUtils {
* @return 值 * @return 值
*/ */
public <T> T get(String key, Class<T> clazz) { public <T> T get(String key, Class<T> clazz) {
System.out.println("get:------------------------"+ key);
Object value = key == null ? null : redisTemplate.opsForValue().get(key); Object value = key == null ? null : redisTemplate.opsForValue().get(key);
if (value == null) { if (value == null) {
return null; return null;
@ -324,6 +325,8 @@ public class RedisUtils {
* @return true成功 false 失败 * @return true成功 false 失败
*/ */
public boolean set(String key, Object value, long time) { public boolean set(String key, Object value, long time) {
System.out.println("set:------------------------"+ key);
try { try {
if (time > 0) { if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);

View File

@ -27,23 +27,27 @@ import com.fuyuanshen.modules.security.config.LoginProperties;
import com.fuyuanshen.modules.security.config.SecurityProperties; import com.fuyuanshen.modules.security.config.SecurityProperties;
import com.fuyuanshen.modules.security.config.enums.LoginCodeEnum; import com.fuyuanshen.modules.security.config.enums.LoginCodeEnum;
import com.fuyuanshen.modules.security.security.TokenProvider; import com.fuyuanshen.modules.security.security.TokenProvider;
import com.fuyuanshen.modules.security.security.app.AppTokenProvider;
import com.fuyuanshen.modules.security.service.OnlineUserService; import com.fuyuanshen.modules.security.service.OnlineUserService;
import com.fuyuanshen.modules.security.service.UserDetailsServiceImpl; import com.fuyuanshen.modules.security.service.UserDetailsServiceImpl;
import com.fuyuanshen.modules.security.service.dto.app.AppAuthUserQuery; import com.fuyuanshen.modules.security.service.dto.app.AppAuthUserDto;
import com.fuyuanshen.modules.security.service.dto.app.AppRoleDto; import com.fuyuanshen.modules.security.service.dto.app.AppRoleDto;
import com.fuyuanshen.modules.security.service.dto.AuthUserDto; import com.fuyuanshen.modules.security.service.dto.AuthUserDto;
import com.fuyuanshen.modules.security.service.dto.JwtUserDto; import com.fuyuanshen.modules.security.service.dto.JwtUserDto;
import com.fuyuanshen.modules.system.domain.app.APPUser; import com.fuyuanshen.modules.system.domain.app.APPUser;
import com.fuyuanshen.modules.system.domain.query.APPUserDto; import com.fuyuanshen.modules.system.domain.query.APPUserQuery;
import com.fuyuanshen.modules.system.mapper.app.APPUserMapper; import com.fuyuanshen.modules.system.mapper.app.APPUserMapper;
import com.fuyuanshen.modules.utils.ResponseVO;
import com.fuyuanshen.utils.RedisUtils; import com.fuyuanshen.utils.RedisUtils;
import com.fuyuanshen.utils.SecurityUtils; import com.fuyuanshen.utils.SecurityUtils;
import com.fuyuanshen.utils.StringUtils; import com.fuyuanshen.utils.StringUtils;
import com.wf.captcha.base.Captcha; import com.wf.captcha.base.Captcha;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@ -57,7 +61,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -77,6 +81,7 @@ public class AuthController {
private final SecurityProperties properties; private final SecurityProperties properties;
private final RedisUtils redisUtils; private final RedisUtils redisUtils;
private final OnlineUserService onlineUserService; private final OnlineUserService onlineUserService;
private final AppTokenProvider appTokenProvider;
private final TokenProvider tokenProvider; private final TokenProvider tokenProvider;
private final CaptchaConfig captchaConfig; private final CaptchaConfig captchaConfig;
private final LoginProperties loginProperties; private final LoginProperties loginProperties;
@ -137,64 +142,24 @@ public class AuthController {
@Log("app用户注册")
@ApiOperation("app用户注册")
@AnonymousPostMapping(value = "/app/register")
public ResponseEntity<Boolean> APPRegister(@Validated @RequestBody AppAuthUserQuery authUser, HttpServletRequest request) throws Exception {
// 校验手机号是否为空
if (StringUtils.isBlank(authUser.getPhoneNumber())) {
throw new BadRequestException("手机号不能为空");
}
// 验证验证码(示例)
int verificationCode = 0000;
if (authUser.getVerificationCode() != verificationCode) {
throw new BadRequestException("验证码错误");
}
// 构建用户对象
APPUserDto appUserDTO = new APPUserDto();
appUserDTO.setUsername(authUser.getPhoneNumber());
appUserDTO.setPassword(authUser.getPassword());
appUserDTO.setPhoneNumber(authUser.getPhoneNumber());
LocalDateTime now = LocalDateTime.now();
appUserDTO.setCreateTime(now);
appUserDTO.setUpdateTime(now);
log.debug("注册参数: {}", appUserDTO);
// 检查手机号是否已注册
APPUser existingUser = appUserMapper.selectByQueryOne(appUserDTO);
if (existingUser != null) {
throw new BadRequestException("手机号已注册");
}
// 执行注册
boolean isRegistered = appUserMapper.createAppUser(appUserDTO);
if (!isRegistered) {
throw new BadRequestException("注册失败");
}
return ResponseEntity.ok(true);
}
@Log("app用户登录") @Log("app用户登录")
@ApiOperation("app用户登录") @ApiOperation("app用户登录")
@AnonymousPostMapping(value = "/app/login") @AnonymousPostMapping(value = "/app/login")
public ResponseEntity<Object> APPLogin(@Validated @RequestBody AppAuthUserQuery authUser, HttpServletRequest request) throws Exception { public ResponseEntity<Object> APPLogin(@Validated @RequestBody AppAuthUserDto authUser, HttpServletRequest request) throws Exception {
// 1. 构建查询参数 // 1. 构建查询参数
APPUserDto appUserDTO = new APPUserDto(); APPUserQuery appUserQuery = new APPUserQuery();
appUserDTO.setPhoneNumber(authUser.getPhoneNumber()); appUserQuery.setPhoneNumber(authUser.getPhoneNumber());
appUserDTO.setPassword(authUser.getPassword()); appUserQuery.setPassword(authUser.getPassword());
appUserQuery.setUsername(authUser.getPhoneNumber());
log.debug("登录参数: {}", appUserQuery);
log.debug("登录参数: {}", appUserDTO);
// 2. 查询用户 // 2. 查询用户
APPUser appUser = appUserMapper.selectByQueryOne(appUserDTO); APPUser appUser = appUserMapper.selectByQueryOne(appUserQuery);
log.debug("查询用户: {}", appUser);
if (appUser == null) { if (appUser == null) {
log.debug("手机号未注册: {}", authUser.getPhoneNumber()); log.debug("手机号未注册: {}", authUser.getPhoneNumber());
throw new BadRequestException("手机号未注册"); throw new BadRequestException("手机号未注册");
@ -205,24 +170,24 @@ public class AuthController {
throw new BadRequestException("登录密码错误"); throw new BadRequestException("登录密码错误");
} }
// 4. 加载用户详情 // 4. 加载用户详情
JwtUserDto jwtUser = userDetailsService.loadUserByUsername(appUser.getUsername()); JwtUserDto jwtUser = userDetailsService.apploadUserByUsername(appUser.getUsername());
// 5. 创建认证信息 // 5. 创建认证信息
Authentication authentication = new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities()); Authentication authentication = new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication); SecurityContextHolder.getContext().setAuthentication(authentication);
// 6. 生成 Token // 6. 生成 Token
String token = tokenProvider.createToken(jwtUser); String token = appTokenProvider.createToken(jwtUser);
// 7. 获取角色权限 // 7. 获取角色权限
AppRoleDto appRoleDto = appUserMapper.selectRoleByUserLevel(appUser.getUserLevel()); AppRoleDto appRoleDto = appUserMapper.selectRoleByUserLevel(appUser.getUserLevel());
// 8. 构建响应数据 // 8. 构建响应数据
Map<String, Object> authInfo = new HashMap<>(3) {{ Map<String, Object> authInfo = new HashMap<>(2) {{
put("token", properties.getTokenStartWith() + token); put("token", properties.getTokenStartWith() + token);
put("user", jwtUser); put("user", jwtUser);
put("role", appRoleDto);
}}; }};
// 9. 单点登录踢人 // 9. 单点登录踢人

View File

@ -0,0 +1,156 @@
/*
* Copyright 2019-2025 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fuyuanshen.modules.security.security.app;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.fuyuanshen.modules.security.config.SecurityProperties;
import com.fuyuanshen.modules.security.service.dto.JwtUserDto;
import com.fuyuanshen.modules.security.service.dto.app.AppJwtUserDto;
import com.fuyuanshen.utils.RedisUtils;
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.security.Key;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author /
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class AppTokenProvider implements InitializingBean {
private JwtParser jwtParser;
private JwtBuilder jwtBuilder;
private final RedisUtils redisUtils;
private final SecurityProperties properties;
public static final String AUTHORITIES_UUID_KEY = "uid";
public static final String AUTHORITIES_UID_KEY = "userId";
@Override
public void afterPropertiesSet() {
byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret());
Key key = Keys.hmacShaKeyFor(keyBytes);
jwtParser = Jwts.parserBuilder()
.setSigningKey(key)
.build();
jwtBuilder = Jwts.builder()
.signWith(key, SignatureAlgorithm.HS512);
}
/**
* 创建Token 设置永不过期,
* Token 的时间有效性转到Redis 维护
* @param user /
* @return /
*/
public String createToken(JwtUserDto user) {
// 设置参数
Map<String, Object> claims = new HashMap<>(6);
// 设置用户ID
// claims.put(AUTHORITIES_UID_KEY, user.getAppUser().getId());
if (user.getAppUser() != null){
claims.put(AUTHORITIES_UID_KEY, user.getAppUser().getId());
}else {
claims.put(AUTHORITIES_UID_KEY, 0);
}
// 设置UUID确保每次Token不一样
claims.put(AUTHORITIES_UUID_KEY, IdUtil.simpleUUID());
return jwtBuilder
.setClaims(claims)
.setSubject(user.getUsername())
.compact();
}
/**
* 依据Token 获取鉴权信息
*
* @param token /
* @return /
*/
Authentication getAuthentication(String token) {
Claims claims = getClaims(token);
User principal = new User(claims.getSubject(), "******", new ArrayList<>());
return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>());
}
public Claims getClaims(String token) {
return jwtParser
.parseClaimsJws(token)
.getBody();
}
/**
* @param token 需要检查的token
*/
public void checkRenewal(String token) {
// 判断是否续期token,计算token的过期时间
String loginKey = loginKey(token);
long time = redisUtils.getExpire(loginKey) * 1000;
Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
// 判断当前时间与过期时间的时间差
long differ = expireDate.getTime() - System.currentTimeMillis();
// 如果在续期检查的范围内,则续期
if (differ <= properties.getDetect()) {
long renew = time + properties.getRenew();
redisUtils.expire(loginKey, renew, TimeUnit.MILLISECONDS);
}
}
public String getToken(HttpServletRequest request) {
final String requestHeader = request.getHeader(properties.getHeader());
if (requestHeader != null && requestHeader.startsWith(properties.getTokenStartWith())) {
return requestHeader.substring(7);
}
return null;
}
/**
* 获取登录用户RedisKey
* @param token /
* @return key
*/
public String loginKey(String token) {
Claims claims = getClaims(token);
return properties.getOnlineKey() + claims.getSubject() + ":" + getId(token);
}
/**
* 获取会话编号
* @param token /
* @return /
*/
public String getId(String token) {
Claims claims = getClaims(token);
return claims.get(AUTHORITIES_UUID_KEY, String.class);
}
}

View File

@ -15,6 +15,7 @@
*/ */
package com.fuyuanshen.modules.security.service; package com.fuyuanshen.modules.security.service;
import com.fuyuanshen.modules.security.service.dto.app.AppJwtUserDto;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import com.fuyuanshen.modules.security.security.TokenProvider; import com.fuyuanshen.modules.security.security.TokenProvider;
@ -51,7 +52,17 @@ public class OnlineUserService {
* @param request / * @param request /
*/ */
public void save(JwtUserDto jwtUserDto, String token, HttpServletRequest request){ public void save(JwtUserDto jwtUserDto, String token, HttpServletRequest request){
String dept = jwtUserDto.getUser().getDept() == null ? null : jwtUserDto.getUser().getDept().getName(); // String dept = jwtUserDto.getUser().getDept() == null ? null : jwtUserDto.getUser().getDept().getName();
String dept = null;
if (jwtUserDto.getUser() != null) {
dept = jwtUserDto.getUser().getDept() == null ? null : jwtUserDto.getUser().getDept().getName();
}else {
dept="";
}
String ip = StringUtils.getIp(request); String ip = StringUtils.getIp(request);
String id = tokenProvider.getId(token); String id = tokenProvider.getId(token);
String browser = StringUtils.getBrowser(request); String browser = StringUtils.getBrowser(request);
@ -66,6 +77,7 @@ public class OnlineUserService {
redisUtils.set(loginKey, onlineUserDto, properties.getTokenValidityInSeconds(), TimeUnit.MILLISECONDS); redisUtils.set(loginKey, onlineUserDto, properties.getTokenValidityInSeconds(), TimeUnit.MILLISECONDS);
} }
/** /**
* 查询全部数据 * 查询全部数据
* @param username / * @param username /

View File

@ -48,8 +48,20 @@ public class UserCacheManager {
userName = StringUtils.lowerCase(userName); userName = StringUtils.lowerCase(userName);
if (StringUtils.isNotEmpty(userName)) { if (StringUtils.isNotEmpty(userName)) {
// 获取数据 // 获取数据
return redisUtils.get(LoginProperties.cacheKey + userName, JwtUserDto.class); try {
JwtUserDto jwtUserDto = redisUtils.get(LoginProperties.cacheKey + userName, JwtUserDto.class);
if (jwtUserDto != null){
jwtUserDto.getUsername();
} }
return jwtUserDto;
} catch (Exception e) {
// redisUtils.del(LoginProperties.cacheKey + userName);
cleanUserCache(userName);
return null;
}
}
return null; return null;
} }

View File

@ -15,6 +15,7 @@
*/ */
package com.fuyuanshen.modules.security.service; package com.fuyuanshen.modules.security.service;
import com.fuyuanshen.modules.system.domain.app.APPUser;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import com.fuyuanshen.exception.BadRequestException; import com.fuyuanshen.exception.BadRequestException;
@ -58,7 +59,31 @@ public class UserDetailsServiceImpl implements UserDetailsService {
// 获取用户的权限 // 获取用户的权限
List<AuthorityDto> authorities = roleService.buildPermissions(user); List<AuthorityDto> authorities = roleService.buildPermissions(user);
// 初始化JwtUserDto // 初始化JwtUserDto
jwtUserDto = new JwtUserDto(user, dataService.getDeptIds(user), authorities); jwtUserDto = new JwtUserDto(user, null,dataService.getDeptIds(user), authorities);
// 添加缓存数据
userCacheManager.addUserCache(username, jwtUserDto);
}
}
return jwtUserDto;
}
public JwtUserDto apploadUserByUsername(String username) {
JwtUserDto jwtUserDto = userCacheManager.getUserCache(username);
if (jwtUserDto == null) {
APPUser user = userService.appGetLoginData(username);
if (user == null) {
throw new BadRequestException("用户不存在");
} else {
if (!user.getEnabled()) {
throw new BadRequestException("账号未激活!");
}
// 获取用户的权限
List<AuthorityDto> authorities = roleService.appBuildPermissions(user);
// 初始化JwtUserDto
jwtUserDto = new JwtUserDto(null,user, dataService.getDeptIds(user), authorities);
// 添加缓存数据 // 添加缓存数据
userCacheManager.addUserCache(username, jwtUserDto); userCacheManager.addUserCache(username, jwtUserDto);
} }

View File

@ -16,12 +16,16 @@
package com.fuyuanshen.modules.security.service.dto; package com.fuyuanshen.modules.security.service.dto;
import com.alibaba.fastjson2.annotation.JSONField; import com.alibaba.fastjson2.annotation.JSONField;
import com.fuyuanshen.modules.system.domain.app.APPUser;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import com.fuyuanshen.modules.system.domain.User; import com.fuyuanshen.modules.system.domain.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -30,56 +34,98 @@ import java.util.stream.Collectors;
* @author Zheng Jie * @author Zheng Jie
* @date 2018-11-23 * @date 2018-11-23
*/ */
@NoArgsConstructor(force = true)
@Getter @Getter
@AllArgsConstructor @Setter
public class JwtUserDto implements UserDetails { public class JwtUserDto implements UserDetails, java.io.Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户") @ApiModelProperty(value = "用户")
private final User user; private final User user;
@ApiModelProperty(value = "用户")
private final APPUser appUser;
@ApiModelProperty(value = "数据权限") @ApiModelProperty(value = "数据权限")
private final List<Long> dataScopes; private final List<Long> dataScopes;
@ApiModelProperty(value = "角色") @ApiModelProperty(value = "角色")
private final List<AuthorityDto> authorities; private final List<AuthorityDto> authorities;
private String username;
private String password;
private boolean enabled = true;
public Set<String> getRoles() { public Set<String> getRoles() {
if (authorities== null){
return Collections.emptySet();
}
return authorities.stream().map(AuthorityDto::getAuthority).collect(Collectors.toSet()); return authorities.stream().map(AuthorityDto::getAuthority).collect(Collectors.toSet());
} }
@Override @Override
@JSONField(serialize = false) //@JSONField(serialize = false)
public String getPassword() { public String getPassword() {
if (appUser != null) {
return appUser.getPassword();
}
return user.getPassword(); return user.getPassword();
} }
public JwtUserDto(User user, APPUser appUser, List<Long> dataScopes, List<AuthorityDto> authorities) {
this.user = user;
this.appUser = appUser;
this.dataScopes = dataScopes;
this.authorities = authorities;
if (user != null) {
this.username = user.getUsername();
this.password = user.getPassword();
this.enabled = user.getEnabled();
} else if (appUser != null) {
this.username = appUser.getUsername();
this.password = appUser.getPassword();
this.enabled = appUser.getEnabled();
}
}
@Override @Override
@JSONField(serialize = false) //@JSONField(serialize = false)
public String getUsername() { public String getUsername() {
if (appUser != null) {
return appUser.getUsername();
}
return user.getUsername(); return user.getUsername();
} }
@JSONField(serialize = false)
//@JSONField(serialize = false)
public String appGetUsername() {
return appUser.getUsername();
}
//@JSONField(serialize = false)
@Override @Override
public boolean isAccountNonExpired() { public boolean isAccountNonExpired() {
return true; return true;
} }
@JSONField(serialize = false) //@JSONField(serialize = false)
@Override @Override
public boolean isAccountNonLocked() { public boolean isAccountNonLocked() {
return true; return true;
} }
@JSONField(serialize = false) //@JSONField(serialize = false)
@Override @Override
public boolean isCredentialsNonExpired() { public boolean isCredentialsNonExpired() {
return true; return true;
} }
@Override @Override
@JSONField(serialize = false) //@JSONField(serialize = false)
public boolean isEnabled() { public boolean isEnabled() {
return user.getEnabled();
return enabled;
} }
} }

View File

@ -26,7 +26,7 @@ import javax.validation.constraints.NotBlank;
* @date 2025-06-18 * @date 2025-06-18
*/ */
@Data @Data
public class AppAuthUserQuery { public class AppAuthUserDto {
@ApiModelProperty(value = "用户名") @ApiModelProperty(value = "用户名")
private String username; private String username;

View File

@ -0,0 +1,86 @@
/*
* Copyright 2019-2025 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fuyuanshen.modules.security.service.dto.app;
import com.alibaba.fastjson2.annotation.JSONField;
import com.fuyuanshen.modules.security.service.dto.AuthorityDto;
import com.fuyuanshen.modules.system.domain.app.APPUser;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author Zheng Jie
* @date 2018-11-23
*/
@Getter
@AllArgsConstructor
public class AppJwtUserDto implements UserDetails {
@ApiModelProperty(value = "用户")
private final APPUser appUser;
@ApiModelProperty(value = "数据权限")
private final List<Long> dataScopes;
@ApiModelProperty(value = "角色")
private final List<AuthorityDto> authorities;
public Set<String> getRoles() {
return authorities.stream().map(AuthorityDto::getAuthority).collect(Collectors.toSet());
}
@Override
@JSONField(serialize = false)
public String getPassword() {
return appUser.getPassword();
}
@Override
@JSONField(serialize = false)
public String getUsername() {
return appUser.getUsername();
}
@JSONField(serialize = false)
@Override
public boolean isAccountNonExpired() {
return true;
}
@JSONField(serialize = false)
@Override
public boolean isAccountNonLocked() {
return true;
}
@JSONField(serialize = false)
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
@JSONField(serialize = false)
public boolean isEnabled() {
return appUser.getEnabled();
}
}

View File

@ -0,0 +1,86 @@
/*
* Copyright 2019-2025 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.fuyuanshen.modules.security.service.dto.app;
import cn.hutool.core.util.RandomUtil;
import com.fuyuanshen.modules.security.config.LoginProperties;
import com.fuyuanshen.modules.security.service.dto.JwtUserDto;
import com.fuyuanshen.utils.RedisUtils;
import com.fuyuanshen.utils.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @author Zheng Jie
* @description 用户缓存管理
* @date 2022-05-26
**/
@Component
public class AppUserCacheManager {
@Resource
private RedisUtils redisUtils;
@Value("${login.user-cache.idle-time}")
private long idleTime;
/**
* 返回用户缓存
* @param userName 用户名
* @return JwtUserDto
*/
public AppJwtUserDto getUserCache(String userName) {
// 转小写
userName = StringUtils.lowerCase(userName);
if (StringUtils.isNotEmpty(userName)) {
// 获取数据
return redisUtils.get(LoginProperties.cacheKey + userName, AppJwtUserDto.class);
}
return null;
}
/**
* 添加缓存到Redis
* @param userName 用户名
*/
@Async
public void addUserCache(String userName, AppJwtUserDto user) {
// 转小写
userName = StringUtils.lowerCase(userName);
if (StringUtils.isNotEmpty(userName)) {
// 添加数据, 避免数据同时过期
long time = idleTime + RandomUtil.randomInt(900, 1800);
redisUtils.set(LoginProperties.cacheKey + "a" + userName, user, time);
}
}
/**
* 清理用户缓存信息
* 用户信息变更时
* @param userName 用户名
*/
@Async
public void cleanUserCache(String userName) {
// 转小写
userName = StringUtils.lowerCase(userName);
if (StringUtils.isNotEmpty(userName)) {
// 清除数据
redisUtils.del(LoginProperties.cacheKey + userName);
}
}
}

View File

@ -25,6 +25,7 @@ import com.fuyuanshen.modules.system.domain.Job;
import com.fuyuanshen.modules.system.domain.Role; import com.fuyuanshen.modules.system.domain.Role;
import com.fuyuanshen.modules.system.domain.User; import com.fuyuanshen.modules.system.domain.User;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -39,8 +40,7 @@ import java.util.Set;
* @author Zheng Jie * @author Zheng Jie
* @date 2018-11-22 * @date 2018-11-22
*/ */
@Getter @Data
@Setter
@TableName("app_user") @TableName("app_user")
public class APPUser extends BaseEntity implements Serializable { public class APPUser extends BaseEntity implements Serializable {
@ -53,6 +53,10 @@ public class APPUser extends BaseEntity implements Serializable {
@ApiModelProperty(hidden = true) @ApiModelProperty(hidden = true)
private Long deptId; private Long deptId;
@TableField(exist = false)
@ApiModelProperty(value = "用户角色")
private Set<Role> roles;
@ApiModelProperty(hidden = true) @ApiModelProperty(hidden = true)
private Long pid; private Long pid;

View File

@ -0,0 +1,37 @@
package com.fuyuanshen.modules.system.domain.dto.app;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @author: 默苍璃
* @date: 2025-06-1818:36
*/
@Data
public class APPUserDTO {
@ApiModelProperty(value = "用户名")
private String username;
@NotBlank(message = "手机号不能为空")
@ApiModelProperty(value = "手机号APP登录")
private String phoneNumber;
@NotBlank(message = "密码不能为空")
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "验证码")
private String verificationCode;
/*@ApiModelProperty(value = "验证码")
private String code;
@ApiModelProperty(value = "验证码的key")
private String uuid = "";*/
}

View File

@ -1,21 +1,17 @@
package com.fuyuanshen.modules.system.domain.query; package com.fuyuanshen.modules.system.domain.query;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date;
/** /**
* @author: 默苍璃 * @author: 默苍璃
* @date: 2025-06-1213:49 * @date: 2025-06-1213:49
*/ */
@Data @Data
public class APPUserDto implements Serializable { public class APPUserQuery implements Serializable {
@ApiModelProperty(value = "ID", hidden = true) @ApiModelProperty(value = "ID", hidden = true)
private Long id; private Long id;

View File

@ -18,11 +18,15 @@ package com.fuyuanshen.modules.system.mapper.app;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fuyuanshen.modules.security.service.dto.app.AppRoleDto; import com.fuyuanshen.modules.security.service.dto.app.AppRoleDto;
import com.fuyuanshen.modules.system.domain.User;
import com.fuyuanshen.modules.system.domain.app.APPUser; import com.fuyuanshen.modules.system.domain.app.APPUser;
import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria; import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria;
import com.fuyuanshen.modules.system.domain.query.APPUserDto; import com.fuyuanshen.modules.system.domain.query.APPUserQuery;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import javax.validation.constraints.NotBlank;
/** /**
* @author Zheng Jie * @author Zheng Jie
@ -44,14 +48,25 @@ public interface APPUserMapper extends BaseMapper<APPUser> {
/** /**
* 根据条件查询一个用户 * 根据条件查询一个用户
* *
* @param appUserDTO * @param appUserQuery
* @return * @return
*/ */
APPUser selectByQueryOne(@Param("userQuery") APPUserDto appUserDTO); APPUser selectByQueryOne(@Param("appUserQuery") APPUserQuery appUserQuery);
AppRoleDto selectRoleByUserLevel(Byte userLevel); AppRoleDto selectRoleByUserLevel(Byte userLevel);
boolean createAppUser(APPUserDto appUserDTO); APPUser findByUsername(@Param("username") String username);
void setUsername(String phoneNumber); void setUsername(String phoneNumber);
APPUser appFindByUsername(@Param("username") String username);
@Select("select * from app_user where username=#{username}")
APPUserQuery getByUsername(@Param("username") String username);
@Select("select * from user where username=#{username} and password=#{password}")
User getByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
} }

View File

@ -16,6 +16,8 @@
package com.fuyuanshen.modules.system.service; package com.fuyuanshen.modules.system.service;
import com.fuyuanshen.modules.system.domain.User; import com.fuyuanshen.modules.system.domain.User;
import com.fuyuanshen.modules.system.domain.app.APPUser;
import java.util.List; import java.util.List;
/** /**
@ -31,4 +33,12 @@ public interface DataService {
* @return / * @return /
*/ */
List<Long> getDeptIds(User user); List<Long> getDeptIds(User user);
/**
* 获取数据权限
* @param user /
* @return /
*/
List<Long> getDeptIds(APPUser user);
} }

View File

@ -20,6 +20,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.fuyuanshen.modules.security.service.dto.AuthorityDto; import com.fuyuanshen.modules.security.service.dto.AuthorityDto;
import com.fuyuanshen.modules.system.domain.Role; import com.fuyuanshen.modules.system.domain.Role;
import com.fuyuanshen.modules.system.domain.User; import com.fuyuanshen.modules.system.domain.User;
import com.fuyuanshen.modules.system.domain.app.APPUser;
import com.fuyuanshen.modules.system.domain.dto.RoleQueryCriteria; import com.fuyuanshen.modules.system.domain.dto.RoleQueryCriteria;
import com.fuyuanshen.utils.PageResult; import com.fuyuanshen.utils.PageResult;
@ -116,6 +117,14 @@ public interface RoleService extends IService<Role> {
*/ */
List<AuthorityDto> buildPermissions(User user); List<AuthorityDto> buildPermissions(User user);
/**
* 获取用户权限信息
* @param user 用户信息
* @return 权限信息
*/
List<AuthorityDto> appBuildPermissions(APPUser user);
/** /**
* 验证是否被用户关联 * 验证是否被用户关联
* @param ids / * @param ids /

View File

@ -18,6 +18,7 @@ package com.fuyuanshen.modules.system.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.fuyuanshen.modules.system.domain.User; import com.fuyuanshen.modules.system.domain.User;
import com.fuyuanshen.modules.system.domain.app.APPUser;
import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria; import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria;
import com.fuyuanshen.modules.system.domain.vo.ConsumerVo; import com.fuyuanshen.modules.system.domain.vo.ConsumerVo;
import com.fuyuanshen.utils.PageResult; import com.fuyuanshen.utils.PageResult;
@ -96,6 +97,8 @@ public interface UserService extends IService<User> {
*/ */
User getLoginData(String userName); User getLoginData(String userName);
APPUser appGetLoginData(String userName);
/** /**
* 修改密码 * 修改密码
* *

View File

@ -19,6 +19,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.fuyuanshen.modules.system.domain.app.APPUser; import com.fuyuanshen.modules.system.domain.app.APPUser;
import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria; import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria;
import com.fuyuanshen.modules.system.domain.dto.app.APPUserDTO;
import com.fuyuanshen.modules.utils.ResponseVO;
import com.fuyuanshen.utils.PageResult; import com.fuyuanshen.utils.PageResult;
/** /**
@ -36,5 +38,14 @@ public interface APPUserService extends IService<APPUser> {
*/ */
PageResult<APPUser> queryAPPUser(UserQueryCriteria criteria, Page<APPUser> page); PageResult<APPUser> queryAPPUser(UserQueryCriteria criteria, Page<APPUser> page);
/**
* 根据用户名查询
*
* @param userName /
* @return /
*/
APPUser getLoginData(String userName);
ResponseVO<Object> addUser(APPUserDTO user);
} }

View File

@ -16,6 +16,7 @@
package com.fuyuanshen.modules.system.service.impl; package com.fuyuanshen.modules.system.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import com.fuyuanshen.modules.system.domain.app.APPUser;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import com.fuyuanshen.modules.system.domain.Dept; import com.fuyuanshen.modules.system.domain.Dept;
import com.fuyuanshen.modules.system.domain.Role; import com.fuyuanshen.modules.system.domain.Role;
@ -93,4 +94,36 @@ public class DataServiceImpl implements DataService {
} }
return deptIds; return deptIds;
} }
/**
* 用户角色和用户部门改变时需清理缓存
* @param user /
* @return /
*/
@Override
public List<Long> getDeptIds(APPUser user) {
String key = CacheKey.DATA_USER + user.getId();
List<Long> ids = redisUtils.getList(key, Long.class);
if (CollUtil.isEmpty(ids)) {
Set<Long> deptIds = new HashSet<>();
// 查询用户角色
List<Role> roleList = roleService.findByUsersId(user.getId());
// 获取对应的部门ID
for (Role role : roleList) {
DataScopeEnum dataScopeEnum = DataScopeEnum.find(role.getDataScope());
switch (Objects.requireNonNull(dataScopeEnum)) {
case THIS_LEVEL:
deptIds.add(user.getDept().getId());
break;
case CUSTOMIZE:
deptIds.addAll(getCustomize(deptIds, role));
break;
default:
return new ArrayList<>();
}
}
ids = new ArrayList<>(deptIds);
redisUtils.set(key, ids, 1, TimeUnit.DAYS);
}
return ids;
}
} }

View File

@ -19,6 +19,7 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyuanshen.modules.system.domain.app.APPUser;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import com.fuyuanshen.exception.BadRequestException; import com.fuyuanshen.exception.BadRequestException;
import com.fuyuanshen.modules.security.service.UserCacheManager; import com.fuyuanshen.modules.security.service.UserCacheManager;
@ -193,6 +194,26 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
return authorityDtos; return authorityDtos;
} }
@Override
public List<AuthorityDto> appBuildPermissions(APPUser user) {
String key = CacheKey.ROLE_AUTH + user.getId();
List<AuthorityDto> authorityDtos = redisUtils.getList(key, AuthorityDto.class);
if (CollUtil.isEmpty(authorityDtos)) {
Set<String> permissions = new HashSet<>();
// 如果是管理员直接返回
if (user.getAdmin() == 1) {
permissions.add("admin");
return permissions.stream().map(AuthorityDto::new).collect(Collectors.toList());
}
List<Role> roles = roleMapper.findByUserId(user.getId());
permissions = roles.stream().flatMap(role -> role.getMenus().stream()).map(Menu::getPermission).filter(StringUtils::isNotBlank).collect(Collectors.toSet());
authorityDtos = permissions.stream().map(AuthorityDto::new).collect(Collectors.toList());
redisUtils.set(key, authorityDtos, 1, TimeUnit.HOURS);
}
return authorityDtos;
}
@Override @Override
public void download(List<Role> roles, HttpServletResponse response) throws IOException { public void download(List<Role> roles, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>(); List<Map<String, Object>> list = new ArrayList<>();

View File

@ -20,6 +20,8 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyuanshen.modules.system.domain.app.APPUser;
import com.fuyuanshen.modules.system.mapper.app.APPUserMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import com.fuyuanshen.config.properties.FileProperties; import com.fuyuanshen.config.properties.FileProperties;
import com.fuyuanshen.constants.RoleConstants; import com.fuyuanshen.constants.RoleConstants;
@ -69,6 +71,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
private final UserCacheManager userCacheManager; private final UserCacheManager userCacheManager;
private final OnlineUserService onlineUserService; private final OnlineUserService onlineUserService;
private final RoleMapper roleMapper; private final RoleMapper roleMapper;
private final APPUserMapper appUserMapper;
@Override @Override
@ -428,6 +431,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
return userMapper.findByUsername(userName); return userMapper.findByUsername(userName);
} }
@Override
public APPUser appGetLoginData(String userName) {
return appUserMapper.appFindByUsername(userName);
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updatePass(String username, String pass) { public void updatePass(String username, String pass) {

View File

@ -15,46 +15,18 @@
*/ */
package com.fuyuanshen.modules.system.service.impl.app; package com.fuyuanshen.modules.system.service.impl.app;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyuanshen.config.properties.FileProperties;
import com.fuyuanshen.constants.RoleConstants;
import com.fuyuanshen.exception.BadRequestException; import com.fuyuanshen.exception.BadRequestException;
import com.fuyuanshen.exception.EntityExistException;
import com.fuyuanshen.modules.security.service.OnlineUserService;
import com.fuyuanshen.modules.security.service.UserCacheManager;
import com.fuyuanshen.modules.system.constant.UserConstants;
import com.fuyuanshen.modules.system.domain.Job;
import com.fuyuanshen.modules.system.domain.Role;
import com.fuyuanshen.modules.system.domain.User;
import com.fuyuanshen.modules.system.domain.app.APPUser; import com.fuyuanshen.modules.system.domain.app.APPUser;
import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria; import com.fuyuanshen.modules.system.domain.dto.UserQueryCriteria;
import com.fuyuanshen.modules.system.domain.query.UserQuery; import com.fuyuanshen.modules.system.domain.dto.app.APPUserDTO;
import com.fuyuanshen.modules.system.domain.vo.ConsumerVo;
import com.fuyuanshen.modules.system.mapper.RoleMapper;
import com.fuyuanshen.modules.system.mapper.UserJobMapper;
import com.fuyuanshen.modules.system.mapper.UserMapper;
import com.fuyuanshen.modules.system.mapper.UserRoleMapper;
import com.fuyuanshen.modules.system.mapper.app.APPUserMapper; import com.fuyuanshen.modules.system.mapper.app.APPUserMapper;
import com.fuyuanshen.modules.system.service.UserService;
import com.fuyuanshen.modules.system.service.app.APPUserService; import com.fuyuanshen.modules.system.service.app.APPUserService;
import com.fuyuanshen.modules.utils.ResponseVO;
import com.fuyuanshen.utils.*; import com.fuyuanshen.utils.*;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/** /**
* @author Zheng Jie * @author Zheng Jie
@ -67,6 +39,7 @@ public class APPUserServiceImpl extends ServiceImpl<APPUserMapper, APPUser> impl
private final APPUserMapper appUserMapper; private final APPUserMapper appUserMapper;
/** /**
* 查询APP/小程序用户 * 查询APP/小程序用户
* *
@ -83,4 +56,33 @@ public class APPUserServiceImpl extends ServiceImpl<APPUserMapper, APPUser> impl
return pageResult ; return pageResult ;
} }
@Override
public APPUser getLoginData(String userName) {
return appUserMapper.appFindByUsername(userName);
}
@Override
public ResponseVO<Object> addUser(APPUserDTO user) {
String username = user.getPhoneNumber().toString();
if (appUserMapper.getByUsername(username) != null) {
throw new BadRequestException("该手机号已被注册");
}
APPUser appUser = new APPUser();
appUser.setUsername(user.getPhoneNumber().toString());
appUser.setPassword(user.getPassword());
appUser.setUserLevel((byte) 1);
appUser.setPhone(Long.valueOf(user.getPhoneNumber()));
appUser.setAdmin((byte) 1);
appUser.setEnabled(true);
appUser.setUserType(0);
System.out.println("--------------------"+appUser);
appUserMapper.insert(appUser);
return ResponseVO.success("注册成功");
}
} }

View File

@ -26,6 +26,18 @@
<result column="user_type" property="userType"/> <result column="user_type" property="userType"/>
</resultMap> </resultMap>
<sql id="Base_Column_List">
u1
.
app_user_id
as user_user_id, u1.dept_id as user_dept_id, u1.username as user_username,
u1.nick_name as user_nick_name, u1.email as user_email, u1.phone as user_phone,
u1.gender as user_gender, u1.avatar_name as user_avatar_name, u1.avatar_path as user_avatar_path,
u1.enabled as user_enabled, u1.pwd_reset_time as user_pwd_reset_time, u1.create_by as user_create_by,
u1.update_by as user_update_by, u1.create_time as user_create_time, u1.update_time as user_update_time,
u1.user_level, u1.pid as user_pid,u1.is_admin AS admin,
</sql>
<!-- 查询APP/小程序用户 --> <!-- 查询APP/小程序用户 -->
<select id="queryAPPUser" resultMap="BaseResultMap"> <select id="queryAPPUser" resultMap="BaseResultMap">
SELECT u.* SELECT u.*
@ -43,16 +55,13 @@
</select> </select>
<!-- 根据条件查询一个用户 --> <!-- 根据条件查询一个用户 -->
<select id="selectByQueryOne" resultType="com.fuyuanshen.modules.system.domain.app.APPUser"> <select id="selectByQueryOne" resultType="com.fuyuanshen.modules.system.domain.app.APPUser">
select select
u.* u.*
from app_user u from app_user u
<where> where u.username = #{appUserQuery.username}
<if test="userQuery.phoneNumber != null">
AND u.phone = #{userQuery.phoneNumber}
</if>
</where>
</select> </select>
@ -63,38 +72,13 @@
WHERE level = #{userLevel} WHERE level = #{userLevel}
</select> </select>
<!-- 插入用户(自动忽略空字段) --> <select id="findByUsername" resultMap="BaseResultMap">
<insert id="createAppUser"> select
INSERT INTO app_user u1.password user_password, u1.is_admin user_is_admin, u1.tenant_id,
<trim prefix="(" suffix=")" suffixOverrides=","> <include refid="Base_Column_List"/>
<if test="username != null and username != ''">username,</if> from app_user u1
<if test="password != null and password != ''">password,</if> where u1.username = #{username}
<if test="nickName != null and nickName != ''">nick_name,</if> </select>
<if test="phone != null and phone != ''">phone,</if>
<if test="email != null and email != ''">email,</if>
<if test="gender != null and gender != ''">gender,</if>
<if test="deptId != null">dept_id,</if>
<if test="pwdResetTime != null">pwd_reset_time,</if>
<if test="createTime != null">create_time,</if>
<if test="updateTime != null">update_time,</if>
<if test="tenantId != null">tenant_id,</if>
<if test="userType != null">user_type,</if>
</trim>
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
<if test="username != null and username != ''">#{username},</if>
<if test="password != null and password != ''">#{password},</if>
<if test="nickName != null and nickName != ''">#{nickName},</if>
<if test="phone != null and phone != ''">#{phone},</if>
<if test="email != null and email != ''">#{email},</if>
<if test="gender != null and gender != ''">#{gender},</if>
<if test="deptId != null">#{deptId},</if>
<if test="pwdResetTime != null">#{pwdResetTime},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="tenantId != null">#{tenantId},</if>
<if test="userType != null">#{userType},</if>
</trim>
</insert>
<update id="setUsername"> <update id="setUsername">
UPDATE app_user UPDATE app_user
@ -105,4 +89,57 @@
</set> </set>
WHERE phone = #{phoneNumber} WHERE phone = #{phoneNumber}
</update> </update>
<resultMap id="APPUserWithRoleMap" type="com.fuyuanshen.modules.system.domain.app.APPUser">
<!-- 用户字段 -->
<id property="id" column="app_user_id"/>
<result property="username" column="username"/>
<result property="nickName" column="nick_name"/>
<result property="email" column="email"/>
<result property="phone" column="phone"/>
<result property="enabled" column="enabled"/>
<result property="gender" column="gender"/>
<result property="avatarPath" column="avatar_path"/>
<result property="pwdResetTime" column="pwd_reset_time"/>
<result property="userLevel" column="user_level"/>
<result property="pid" column="pid"/>
<result property="admin" column="is_admin"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<!-- 角色字段 -->
<collection property="roles" ofType="com.fuyuanshen.modules.system.domain.Role">
<id column="role_id" property="id"/>
<result column="role_name" property="name"/>
<result column="role_level" property="level"/>
<result column="role_data_scope" property="dataScope"/>
</collection>
</resultMap>
<select id="appFindByUsername" resultMap="APPUserWithRoleMap">
SELECT
u1.app_user_id,
u1.username,
u1.nick_name,
u1.email,
u1.phone,
u1.enabled,
u1.gender,
u1.avatar_path,
u1.pwd_reset_time,
u1.user_level,
u1.pid,
u1.is_admin,
u1.create_time,
u1.update_time,
r.name AS role_name,
r.level AS role_level,
r.description AS role_description,
r.data_scope AS role_data_scope
FROM app_user u1
LEFT JOIN app_role r ON u1.user_level = r.level
WHERE u1.username = #{username}
</select>
</mapper> </mapper>