增加短信登录 修改密码登录模式
parent
54da04ea1b
commit
55218a0baa
@ -0,0 +1,22 @@
|
||||
package com.baiye.service;
|
||||
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
|
||||
/**
|
||||
* 用户详细扩展
|
||||
* @author pangu
|
||||
*/
|
||||
public interface CdpUserDetailsService extends UserDetailsService {
|
||||
|
||||
/**
|
||||
* 根据手机号登录
|
||||
* @param mobile
|
||||
* @return UserDetails
|
||||
* @throws UsernameNotFoundException
|
||||
*/
|
||||
UserDetails loadUserByMobile(String mobile) throws UsernameNotFoundException;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2019-2020 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.baiye.auth.config.properties;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "sms")
|
||||
public class SmsProperties {
|
||||
|
||||
@ApiModelProperty(value = "accessKeyId")
|
||||
private String accessKeyId;
|
||||
|
||||
@ApiModelProperty(value = "accessKeySecret")
|
||||
private String accessKeySecret;
|
||||
|
||||
@ApiModelProperty(value = "signName")
|
||||
private String signName;
|
||||
|
||||
@ApiModelProperty(value = "templateCode")
|
||||
private String templateCode;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.baiye.auth.controller;
|
||||
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
import com.alibaba.nacos.common.utils.Md5Utils;
|
||||
import com.baiye.core.annotation.Log;
|
||||
import com.baiye.core.base.api.Result;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 自定义Oauth2自定义返回格式
|
||||
*
|
||||
* @author pangu
|
||||
* @link https://segmentfault.com/a/1190000020317220?utm_source=tag-newest
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/oauth")
|
||||
@AllArgsConstructor
|
||||
@Api(value = "Oauth2管理")
|
||||
public class OauthController {
|
||||
|
||||
private final TokenEndpoint tokenEndpoint;
|
||||
|
||||
|
||||
@Log(value = "用户登录", exception = "用户登录请求异常")
|
||||
@PostMapping("/token")
|
||||
@ApiOperation(value = "用户登录Post")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(value = "grant_type", required = true, name = "授权类型"),
|
||||
@ApiImplicitParam(value = "username", required = true, name = "用户名"),
|
||||
@ApiImplicitParam(value = "password", required = true, name = "密码"),
|
||||
@ApiImplicitParam(value = "scope", required = true, name = "使用范围"),
|
||||
})
|
||||
public Result<Map<String, Object>> postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
|
||||
OAuth2AccessToken body = tokenEndpoint.postAccessToken(principal, parameters).getBody();
|
||||
DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) body;
|
||||
Map<String, Object> data = new LinkedHashMap<>(token.getAdditionalInformation());
|
||||
data.put("accessToken", token.getValue());
|
||||
if (token.getRefreshToken() != null) {
|
||||
data.put("refreshToken", token.getRefreshToken().getValue());
|
||||
}
|
||||
return Result.data(data);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.baiye.auth.controller;
|
||||
|
||||
import com.baiye.auth.service.SmsService;
|
||||
import com.baiye.core.base.api.Result;
|
||||
import io.swagger.annotations.Api;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @author Enzo
|
||||
* @date : 2023/3/15
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sms")
|
||||
@Api(value = "阿里云短信服务")
|
||||
@RequiredArgsConstructor
|
||||
public class SmsController {
|
||||
|
||||
private final SmsService smsService;
|
||||
|
||||
@GetMapping("/getCode")
|
||||
@ResponseBody
|
||||
public Result<String> sendSMS(@RequestParam String mobile){
|
||||
if (StringUtils.isBlank(mobile)) {
|
||||
return Result.fail("发送短信失败");
|
||||
}
|
||||
return smsService.sendSms(mobile) ? Result.success() : Result.fail();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.baiye.auth.feign;
|
||||
|
||||
import com.baiye.core.constant.SecurityConstants;
|
||||
import com.baiye.core.constant.ServiceNameConstants;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* @author Enzo
|
||||
* @description 用户feign接口
|
||||
* @date 2020-08-12 16:50
|
||||
*/
|
||||
@FeignClient(contextId = "remoteMemberService", value = ServiceNameConstants.BACKSTAGE_SERVER)
|
||||
public interface IRemoteMemberService {
|
||||
|
||||
|
||||
/**
|
||||
* 号码查询会员
|
||||
*
|
||||
* @param username
|
||||
* @param from
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/member/createOrUpdate")
|
||||
Boolean createOrUpdate(@RequestParam("username") String username, @RequestHeader(SecurityConstants.FROM) String from);
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.baiye.auth.service;
|
||||
|
||||
/**
|
||||
* @author Enzo
|
||||
* @date : 2023/3/15
|
||||
*/
|
||||
public interface SmsService {
|
||||
|
||||
/**
|
||||
* 发送短信
|
||||
* @param mobile
|
||||
* @return
|
||||
*/
|
||||
Boolean sendSms(String mobile);
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.baiye.auth.service.impl;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyun.dysmsapi20170525.Client;
|
||||
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
|
||||
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
|
||||
import com.aliyun.teaopenapi.models.Config;
|
||||
import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import com.baiye.auth.config.properties.SmsProperties;
|
||||
import com.baiye.auth.service.SmsService;
|
||||
import com.baiye.core.constant.DefaultNumberConstants;
|
||||
import com.baiye.core.constant.Oauth2Constant;
|
||||
import com.baiye.core.util.RedisUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Enzo
|
||||
* @date : 2023/3/15
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SmsServiceImpl implements SmsService {
|
||||
|
||||
private final RedisUtils redisUtils;
|
||||
|
||||
private final SmsProperties smsProperties;
|
||||
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public Boolean sendSms(String mobile) {
|
||||
Config config = new Config()
|
||||
.setAccessKeyId(smsProperties.getAccessKeyId())
|
||||
.setAccessKeySecret(smsProperties.getAccessKeySecret());
|
||||
config.endpoint = "dysmsapi.aliyuncs.com";
|
||||
String code = RandomUtil.randomNumbers(DefaultNumberConstants.SIX_NUMBER);
|
||||
Client client = new Client(config);
|
||||
SendSmsRequest sendSmsRequest = new SendSmsRequest();
|
||||
sendSmsRequest
|
||||
.setSignName(smsProperties.getSignName())
|
||||
.setPhoneNumbers(mobile)
|
||||
.setTemplateCode(smsProperties.getTemplateCode());
|
||||
HashMap<String, Object> param = new HashMap<>(DefaultNumberConstants.EIGHT_NUMBER);
|
||||
param.put("code", code);
|
||||
sendSmsRequest.setTemplateParam(JSON.toJSONString(param));
|
||||
RuntimeOptions runtime = new RuntimeOptions();
|
||||
SendSmsResponse response = client.sendSmsWithOptions(sendSmsRequest, runtime);
|
||||
if ("OK".equals(response.body.code)) {
|
||||
redisUtils.set(Oauth2Constant.SMS_CODE_KEY.concat(mobile),
|
||||
code, DefaultNumberConstants.FIVE_NUMBER, TimeUnit.MINUTES);
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.baiye.auth.sms;
|
||||
|
||||
import com.baiye.core.constant.Oauth2Constant;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.swing.text.html.FormSubmitEvent;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 短信验证码验证过滤器
|
||||
*
|
||||
* @author pangu
|
||||
*/
|
||||
public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
|
||||
|
||||
/**
|
||||
* 请求中的参数
|
||||
*/
|
||||
private String mobileParameter = Oauth2Constant.DEFAULT_PARAMETER_NAME_MOBILE;
|
||||
|
||||
private boolean postOnly = true;
|
||||
|
||||
public SmsCodeAuthenticationFilter() {
|
||||
super(new AntPathRequestMatcher(Oauth2Constant.OAUTH_MOBILE, "POST"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
|
||||
if (postOnly && !FormSubmitEvent.MethodType.POST.name().equals(request.getMethod())) {
|
||||
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
|
||||
}
|
||||
|
||||
// 获取请求中的参数值
|
||||
String mobile = obtainMobile(request);
|
||||
|
||||
if (Objects.isNull(mobile)) {
|
||||
mobile = "";
|
||||
}
|
||||
|
||||
mobile = mobile.trim();
|
||||
|
||||
SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(mobile);
|
||||
|
||||
// Allow subclasses to set the "details" property
|
||||
setDetails(request, authRequest);
|
||||
|
||||
return this.getAuthenticationManager().authenticate(authRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取手机号
|
||||
*/
|
||||
protected String obtainMobile(HttpServletRequest request) {
|
||||
return request.getParameter(mobileParameter);
|
||||
}
|
||||
|
||||
protected void setDetails(HttpServletRequest request, SmsCodeAuthenticationToken authRequest) {
|
||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
|
||||
}
|
||||
|
||||
public void setMobileParameter(String mobileParameter) {
|
||||
Assert.hasText(mobileParameter, "Mobile parameter must not be empty or null");
|
||||
this.mobileParameter = mobileParameter;
|
||||
}
|
||||
|
||||
public void setPostOnly(boolean postOnly) {
|
||||
this.postOnly = postOnly;
|
||||
}
|
||||
|
||||
public final String getMobileParameter() {
|
||||
return mobileParameter;
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.baiye.auth.sms;
|
||||
|
||||
import com.baiye.service.CdpUserDetailsService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 短信验证码验证提供者
|
||||
*
|
||||
* @author pangu
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
private final CdpUserDetailsService userDetailsService;
|
||||
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;
|
||||
|
||||
/**
|
||||
* 调用 {@link UserDetailsService}
|
||||
*/
|
||||
UserDetails user = userDetailsService.loadUserByMobile((String) authenticationToken.getPrincipal());
|
||||
|
||||
if (Objects.isNull(user)) {
|
||||
throw new InternalAuthenticationServiceException("手机号或验证码错误");
|
||||
}
|
||||
|
||||
SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(user, user.getAuthorities());
|
||||
|
||||
authenticationResult.setDetails(authenticationToken.getDetails());
|
||||
|
||||
return authenticationResult;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> authentication) {
|
||||
return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package com.baiye.auth.sms.granter;
|
||||
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import com.baiye.auth.feign.IRemoteMemberService;
|
||||
import com.baiye.auth.sms.SmsCodeAuthenticationToken;
|
||||
import com.baiye.core.constant.Oauth2Constant;
|
||||
import com.baiye.core.constant.SecurityConstants;
|
||||
import com.baiye.core.util.RedisUtils;
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.authentication.AccountStatusException;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
|
||||
import org.springframework.security.oauth2.common.exceptions.UserDeniedAuthorizationException;
|
||||
import org.springframework.security.oauth2.provider.*;
|
||||
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
|
||||
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 手机号验证码登录TokenGranter
|
||||
*
|
||||
* @author pangu
|
||||
* @since 2020-7-21
|
||||
*/
|
||||
public class SmsCodeTokenGranter extends AbstractTokenGranter {
|
||||
|
||||
|
||||
private final AuthenticationManager authenticationManager;
|
||||
|
||||
private final IRemoteMemberService remoteMemberService;
|
||||
|
||||
private RedisUtils redisUtils;
|
||||
|
||||
public SmsCodeTokenGranter(AuthenticationManager authenticationManager,
|
||||
AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService,
|
||||
OAuth2RequestFactory requestFactory, RedisUtils redisUtils,IRemoteMemberService remoteMemberService) {
|
||||
this(authenticationManager, tokenServices, clientDetailsService, requestFactory, SecurityConstants.SMS_GRANT_TYPE, remoteMemberService);
|
||||
this.redisUtils = redisUtils;
|
||||
}
|
||||
|
||||
protected SmsCodeTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices,
|
||||
ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType, IRemoteMemberService remoteMemberService) {
|
||||
super(tokenServices, clientDetailsService, requestFactory, grantType);
|
||||
this.authenticationManager = authenticationManager;
|
||||
this.remoteMemberService = remoteMemberService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
|
||||
Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
|
||||
String mobile = parameters.get("mobile");
|
||||
String code = parameters.get("code");
|
||||
|
||||
if (CharSequenceUtil.isBlank(code)) {
|
||||
throw new UserDeniedAuthorizationException("请输入验证码!");
|
||||
}
|
||||
|
||||
String codeFromRedis;
|
||||
// 从Redis里读取存储的验证码信息
|
||||
try {
|
||||
codeFromRedis = redisUtils.get(Oauth2Constant.SMS_CODE_KEY + mobile).toString();
|
||||
} catch (Exception e) {
|
||||
throw new UserDeniedAuthorizationException("验证码不存在!");
|
||||
}
|
||||
|
||||
if (codeFromRedis == null) {
|
||||
throw new UserDeniedAuthorizationException("验证码已过期!");
|
||||
}
|
||||
// 比较输入的验证码是否正确
|
||||
if (!CharSequenceUtil.equalsIgnoreCase(code, codeFromRedis)) {
|
||||
throw new UserDeniedAuthorizationException("验证码不正确!");
|
||||
}
|
||||
|
||||
redisUtils.del(Oauth2Constant.SMS_CODE_KEY + mobile);
|
||||
// 创建或修改账号
|
||||
remoteMemberService.createOrUpdate(mobile, SecurityConstants.FROM_IN);
|
||||
|
||||
Authentication userAuth = new SmsCodeAuthenticationToken(mobile);
|
||||
((AbstractAuthenticationToken) userAuth).setDetails(parameters);
|
||||
try {
|
||||
userAuth = authenticationManager.authenticate(userAuth);
|
||||
} catch (AccountStatusException | BadCredentialsException ase) {
|
||||
//covers expired, locked, disabled cases (mentioned in section 5.2, draft 31)
|
||||
throw new InvalidGrantException(ase.getMessage());
|
||||
}
|
||||
// If the username/password are wrong the spec says we should send 400/invalid grant
|
||||
|
||||
if (userAuth == null || !userAuth.isAuthenticated()) {
|
||||
throw new InvalidGrantException("Could not authenticate user: " + mobile);
|
||||
}
|
||||
|
||||
OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
|
||||
return new OAuth2Authentication(storedOAuth2Request, userAuth);
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package com.baiye;
|
||||
|
||||
import com.baiye.core.base.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
* @date 2019-03-25
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@TableName("tb_member")
|
||||
public class Member extends BaseEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3797115638759597781L;
|
||||
|
||||
@NotNull(groups = {Update.class})
|
||||
@TableId(value = "member_id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "ID", hidden = true)
|
||||
private Long id;
|
||||
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "用户名称")
|
||||
private String username;
|
||||
|
||||
@Email
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "邮箱")
|
||||
private String email;
|
||||
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "电话号码")
|
||||
private String phone;
|
||||
|
||||
@ApiModelProperty(value = "用户性别")
|
||||
private String gender;
|
||||
|
||||
@ApiModelProperty(value = "头像真实名称", hidden = true)
|
||||
private String avatarName;
|
||||
|
||||
@ApiModelProperty(value = "头像存储的路径", hidden = true)
|
||||
private String avatarPath;
|
||||
|
||||
@ApiModelProperty(value = "密码")
|
||||
private String password;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "是否启用")
|
||||
private Boolean enabled;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Member user = (Member) o;
|
||||
return Objects.equals(id, user.id) &&
|
||||
Objects.equals(username, user.username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, username);
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2019-2020 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.baiye.dto;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.baiye.core.base.BaseDTO;
|
||||
import com.baiye.core.excel.BoolCustomConverter;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 部门传输对象
|
||||
* @author Enzo
|
||||
* @date 2022-05-14
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ExcelIgnoreUnannotated
|
||||
public class MemberDto extends BaseDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 967234921171721967L;
|
||||
private Long id;
|
||||
|
||||
private Set<RoleSmallDto> roles;
|
||||
|
||||
private Set<JobSmallDto> jobs;
|
||||
|
||||
private DeptSmallDto dept;
|
||||
|
||||
private Long deptId;
|
||||
|
||||
@ExcelProperty("用户名")
|
||||
private String username;
|
||||
|
||||
@ExcelProperty("昵称")
|
||||
private String nickName;
|
||||
|
||||
@ExcelProperty("邮箱")
|
||||
private String email;
|
||||
|
||||
@ExcelProperty("手机号")
|
||||
private String phone;
|
||||
|
||||
@ExcelProperty("性别")
|
||||
private String gender;
|
||||
|
||||
private String avatarName;
|
||||
|
||||
private String avatarPath;
|
||||
|
||||
@JsonIgnore
|
||||
private String password;
|
||||
|
||||
@ExcelProperty(value = "是否启用",converter = BoolCustomConverter.class)
|
||||
private Boolean enabled;
|
||||
|
||||
@ExcelProperty(value = "是否为管理员",converter = BoolCustomConverter.class)
|
||||
@JsonIgnore
|
||||
private Boolean isAdmin = false;
|
||||
|
||||
private Date pwdResetTime;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2019-2020 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.baiye.mapstruct;
|
||||
|
||||
import com.baiye.Member;
|
||||
import com.baiye.core.base.BaseMapStruct;
|
||||
import com.baiye.dto.MemberDto;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
* @date 2018-11-23
|
||||
*/
|
||||
|
||||
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
public interface MemberMapStruct extends BaseMapStruct<MemberDto, Member> {
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2019-2020 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.baiye.query;
|
||||
|
||||
import com.baiye.annotation.Query;
|
||||
import com.baiye.annotation.type.SelectType;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
* @date 2018-11-23
|
||||
*/
|
||||
@Data
|
||||
public class MemberQueryCriteria implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8942145971476050045L;
|
||||
|
||||
@Query(blurry = {"email", "username", "nickName"})
|
||||
private String blurry;
|
||||
|
||||
@Query
|
||||
private Boolean enabled;
|
||||
|
||||
|
||||
@Query(type = SelectType.BETWEEN)
|
||||
private List<Timestamp> createTime;
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package com.baiye.controller;
|
||||
|
||||
import com.baiye.Member;
|
||||
import com.baiye.User;
|
||||
import com.baiye.annotation.Inner;
|
||||
import com.baiye.core.page.PageResult;
|
||||
import com.baiye.dto.UserDto;
|
||||
import com.baiye.dto.UserSmallDto;
|
||||
import com.baiye.query.MemberQueryCriteria;
|
||||
import com.baiye.query.UserQueryCriteria;
|
||||
import com.baiye.service.IMemberService;
|
||||
import com.baiye.service.IUserService;
|
||||
import com.baiye.util.SecurityUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Enzo
|
||||
* @date 2023-3-16
|
||||
*/
|
||||
@Api(tags = "系统: 会员管理")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/member")
|
||||
@RequiredArgsConstructor
|
||||
public class MemberController {
|
||||
|
||||
private final IMemberService memberService;
|
||||
|
||||
|
||||
@ApiOperation("通过用户id查询用户姓名")
|
||||
@GetMapping(value = "/id")
|
||||
public ResponseEntity<String> queryByUserId(@RequestParam Long id) {
|
||||
return ResponseEntity.ok(this.memberService.getById(id).getUsername());
|
||||
}
|
||||
|
||||
@ApiOperation("查询用户")
|
||||
@GetMapping
|
||||
@PreAuthorize("@el.check('member:list')")
|
||||
public ResponseEntity<PageResult> query(MemberQueryCriteria queryCriteria, Pageable pageable) {
|
||||
return new ResponseEntity<>(this.memberService.queryAll(queryCriteria, pageable), HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("修改用户")
|
||||
@PutMapping
|
||||
@PreAuthorize("@el.check('user:edit')")
|
||||
public ResponseEntity<Void> update(@Validated(Member.Update.class) @RequestBody Member resources) {
|
||||
this.memberService.updateMember(resources);
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("修改头像")
|
||||
@PostMapping(value = "/updateAvatar")
|
||||
public ResponseEntity<Map<String, String>> updateAvatar(@RequestParam MultipartFile avatar) {
|
||||
return new ResponseEntity<>(this.memberService.updateAvatar(avatar), HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
@Inner
|
||||
@ApiOperation("通过用户名查询用户")
|
||||
@GetMapping(value = "/createOrUpdate")
|
||||
public ResponseEntity<Boolean> getUserDetails(@RequestParam String mobile){
|
||||
return ResponseEntity.ok(this.memberService.createOrUpdate(mobile));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.baiye.mapper;
|
||||
|
||||
import com.baiye.Member;
|
||||
import com.baiye.User;
|
||||
import com.baiye.dto.UserSmallDto;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Enzo
|
||||
* @date : 2023/3/16
|
||||
*/
|
||||
public interface MemberMapper extends BaseMapper<Member> {
|
||||
|
||||
/**
|
||||
* 条件查询会员
|
||||
* @param wrapper
|
||||
* @return
|
||||
*/
|
||||
List<Member> queryAll(QueryWrapper<Member> wrapper);
|
||||
|
||||
/**
|
||||
* 条件查询分页
|
||||
* @param wrapper
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
Page<Member> queryAllWithPage(QueryWrapper<Member> wrapper, Page<Member> page);
|
||||
|
||||
/**
|
||||
* id查询会员
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
Member getById(Long id);
|
||||
|
||||
/**
|
||||
* 用户昵称查找
|
||||
* @param currentUsername
|
||||
* @return
|
||||
*/
|
||||
Member queryByUsername(String currentUsername);
|
||||
|
||||
/**
|
||||
* 会员会员查找
|
||||
* @param mobile
|
||||
* @return
|
||||
*/
|
||||
UserSmallDto getUserDetails(String mobile);
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.baiye.service;
|
||||
|
||||
import com.baiye.Member;
|
||||
import com.baiye.User;
|
||||
import com.baiye.core.page.PageResult;
|
||||
import com.baiye.dto.UserSmallDto;
|
||||
import com.baiye.query.MemberQueryCriteria;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Enzo
|
||||
* @date : 2023/3/16
|
||||
*/
|
||||
public interface IMemberService extends IService<Member> {
|
||||
|
||||
/**
|
||||
* 条件查询会员
|
||||
* @param queryCriteria
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
PageResult queryAll(MemberQueryCriteria queryCriteria, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 修改会员信息
|
||||
* @param resources
|
||||
*/
|
||||
void updateMember(Member resources);
|
||||
|
||||
/**
|
||||
* 修改头像
|
||||
* @param avatar
|
||||
* @return
|
||||
*/
|
||||
Map<String,String> updateAvatar(MultipartFile avatar);
|
||||
|
||||
/**
|
||||
* 号码获取会员详细信息
|
||||
* @param mobile
|
||||
* @return
|
||||
*/
|
||||
UserSmallDto getUserDetailsByMobile(String mobile);
|
||||
|
||||
/**
|
||||
* 创建或修改会员
|
||||
* @param mobile
|
||||
* @return
|
||||
*/
|
||||
Boolean createOrUpdate(String mobile);
|
||||
}
|
@ -0,0 +1,159 @@
|
||||
package com.baiye.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baiye.Member;
|
||||
import com.baiye.core.base.api.ResultCode;
|
||||
import com.baiye.core.constant.CacheKey;
|
||||
import com.baiye.core.page.PageResult;
|
||||
import com.baiye.core.util.RedisUtils;
|
||||
import com.baiye.dto.UserSmallDto;
|
||||
import com.baiye.exception.global.BadRequestException;
|
||||
import com.baiye.exception.global.UpdateFailException;
|
||||
import com.baiye.feign.IRemoteAuthService;
|
||||
import com.baiye.mapper.MemberMapper;
|
||||
import com.baiye.mapstruct.MemberMapStruct;
|
||||
import com.baiye.properties.FileProperties;
|
||||
import com.baiye.query.MemberQueryCriteria;
|
||||
import com.baiye.service.IMemberService;
|
||||
import com.baiye.util.FileUtil;
|
||||
import com.baiye.util.PageUtils;
|
||||
import com.baiye.util.QueryHelpUtils;
|
||||
import com.baiye.util.SecurityUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Enzo
|
||||
* @date : 2023/3/16
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements IMemberService {
|
||||
|
||||
private final RedisUtils redisUtils;
|
||||
|
||||
private final MemberMapper memberMapper;
|
||||
|
||||
private final FileProperties properties;
|
||||
|
||||
private final MemberMapStruct memberMapStruct;
|
||||
|
||||
private final IRemoteAuthService remoteAuthService;
|
||||
|
||||
@Override
|
||||
public PageResult queryAll(MemberQueryCriteria queryCriteria, Pageable pageable) {
|
||||
|
||||
QueryWrapper<Member> wrapper = null;
|
||||
if (BeanUtil.isNotEmpty(queryCriteria)) {
|
||||
wrapper = QueryHelpUtils.getWrapper(queryCriteria, Member.class);
|
||||
}
|
||||
Page<Member> page = PageUtils.startPageAndSort(pageable);
|
||||
Page<Member> memberPage = this.memberMapper.queryAllWithPage(wrapper, page);
|
||||
return PageResult.success(memberPage.getTotal(), memberPage.getPages(),
|
||||
this.memberMapStruct.toDto(memberPage.getRecords()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMember(Member resources) {
|
||||
// 如果用户被禁用,则清除用户登陆的信息
|
||||
if (Boolean.FALSE.equals(resources.getEnabled())) {
|
||||
try {
|
||||
this.remoteAuthService.delete(Collections.singleton(resources.getId()));
|
||||
} catch (Exception e) {
|
||||
throw new BadRequestException(ResultCode.FAILURE.getMsg());
|
||||
}
|
||||
}
|
||||
// 更新用户信息
|
||||
boolean result = this.updateById(resources);
|
||||
if (!result) {
|
||||
// 更新失败,全部回滚
|
||||
log.error("更新失败:{}", resources);
|
||||
throw new UpdateFailException("更新失败,请联系管理员");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Map<String, String> updateAvatar(MultipartFile avatar) {
|
||||
// 文件大小验证
|
||||
FileUtil.checkSize(properties.getAvatarMaxSize(), avatar.getSize());
|
||||
// 验证文件上传的格式
|
||||
String image = "gif jpg png jpeg";
|
||||
String fileType = FileUtil.getExtensionName(avatar.getOriginalFilename());
|
||||
if (fileType != null && !image.contains(fileType)) {
|
||||
throw new BadRequestException("文件格式错误!, 仅支持 " + image + " 格式");
|
||||
}
|
||||
Member member = memberMapper.queryByUsername(SecurityUtils.getCurrentUsername());
|
||||
String oldPath = member.getAvatarPath();
|
||||
File file = FileUtil.upload(avatar, properties.getPath().getAvatar());
|
||||
member.setAvatarPath(Objects.requireNonNull(file).getPath());
|
||||
member.setAvatarName(file.getName());
|
||||
memberMapper.updateById(member);
|
||||
if (CharSequenceUtil.isNotBlank(oldPath)) {
|
||||
FileUtil.del(oldPath);
|
||||
}
|
||||
@NotBlank String username = member.getUsername();
|
||||
this.delCaches(member.getId(), username);
|
||||
return ImmutableMap.of("avatar", file.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户名加载用户和角色基本信息
|
||||
*
|
||||
* @param mobile
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Cacheable(key = "'username:' + #p0")
|
||||
public UserSmallDto getUserDetailsByMobile(String mobile) {
|
||||
return this.memberMapper.getUserDetails(mobile);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean createOrUpdate(String mobile) {
|
||||
Member member = memberMapper.queryByUsername(mobile);
|
||||
if (ObjectUtil.isNull(member)) {
|
||||
member = new Member();
|
||||
member.setId(IdUtil.getSnowflake().nextId());
|
||||
member.setEnabled(Boolean.TRUE);
|
||||
member.setPhone(mobile);
|
||||
member.setUsername(mobile);
|
||||
return this.save(member);
|
||||
}
|
||||
// 清除缓存
|
||||
this.delCaches(member.getId(), member.getUsername());
|
||||
return updateById(member);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
*
|
||||
* @param id
|
||||
* @param username
|
||||
*/
|
||||
private void delCaches(Long id, String username) {
|
||||
this.redisUtils.del(CacheKey.USER_ID + id);
|
||||
this.redisUtils.del(CacheKey.USER_NAME + username);
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
<?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.baiye.mapper.MemberMapper">
|
||||
|
||||
<resultMap id="baseUserMap" type="com.baiye.Member">
|
||||
<id property="id" column="id"/>
|
||||
<result property="avatarName" column="avatar_name"/>
|
||||
<result property="avatarPath" column="avatar_path"/>
|
||||
<result property="email" column="email"/>
|
||||
<result property="gender" column="gender"/>
|
||||
<result property="enabled" column="enabled"/>
|
||||
<result property="password" column="password"/>
|
||||
<result property="phone" column="phone"/>
|
||||
<result property="username" column="username"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="userDetailsMap" type="com.baiye.dto.UserSmallDto">
|
||||
<id property="id" column="user_id"/>
|
||||
<result property="username" column="username"/>
|
||||
<result property="isAdmin" column="is_admin"/>
|
||||
<result property="password" column="password"/>
|
||||
<result property="enabled" column="enabled"/>
|
||||
<collection property="permissions" column="permissions" ofType="java.lang.String">
|
||||
<constructor>
|
||||
<arg column="permissions"/>
|
||||
</constructor>
|
||||
</collection>
|
||||
<collection property="roleNames" column="role_name" ofType="java.lang.String">
|
||||
<constructor>
|
||||
<arg column="role_name"/>
|
||||
</constructor>
|
||||
</collection>
|
||||
</resultMap>
|
||||
|
||||
<sql id="baseUserSql">
|
||||
${property}.member_id as id,
|
||||
${property}.username,
|
||||
${property}.password,
|
||||
${property}.gender,
|
||||
${property}.phone,
|
||||
${property}.email,
|
||||
${property}.avatar_name,
|
||||
${property}.avatar_path,
|
||||
${property}.password,
|
||||
${property}.enabled,
|
||||
${property}.create_by,
|
||||
${property}.update_by,
|
||||
${property}.create_time,
|
||||
${property}.update_time
|
||||
</sql>
|
||||
|
||||
<sql id="selectAllSql">
|
||||
<include refid="baseUserSql">
|
||||
<property name="property" value="sys_user"/>
|
||||
</include>
|
||||
FROM
|
||||
tb_member
|
||||
|
||||
</sql>
|
||||
|
||||
|
||||
|
||||
<select id="queryAll" resultMap="baseUserMap">
|
||||
select
|
||||
<include refid="selectAllSql"/>
|
||||
<if test="ew != null and ew.sqlSegment != ''">
|
||||
and ${ew.sqlSegment}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="queryAllWithPage" resultMap="baseUserMap">
|
||||
select
|
||||
<include refid="selectAllSql"/>
|
||||
<if test="ew != null and ew.sqlSegment != ''">
|
||||
and ${ew.sqlSegment}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getById" resultMap="baseUserMap">
|
||||
select
|
||||
<include refid="selectAllSql"/>
|
||||
and sys_user.user_id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="queryByUsername" resultMap="baseUserMap">
|
||||
select
|
||||
<include refid="selectAllSql"/>
|
||||
where tb_member.username = #{username}
|
||||
</select>
|
||||
|
||||
|
||||
|
||||
<select id="getUserDetails" resultMap="userDetailsMap">
|
||||
select me.user_id,
|
||||
me.username,
|
||||
me.password,
|
||||
me.enabled
|
||||
from tb_member me
|
||||
where me.username = #{username};
|
||||
</select>
|
||||
</mapper>
|
Loading…
Reference in New Issue