package com.mzl.flower.web.login;
|
|
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
|
import cn.hutool.core.util.StrUtil;
|
import com.mzl.flower.base.BaseController;
|
import com.mzl.flower.base.R;
|
import com.mzl.flower.base.ReturnDataDTO;
|
import com.mzl.flower.base.cache.StringCacheClient;
|
import com.mzl.flower.config.exception.BaseException;
|
import com.mzl.flower.config.exception.ValidationException;
|
import com.mzl.flower.config.security.SecurityUtils;
|
import com.mzl.flower.config.security.token.PhoneAuthenticationToken;
|
import com.mzl.flower.config.security.token.UserIdAuthenticationToken;
|
import com.mzl.flower.config.security.token.WebAuthenticationToken;
|
import com.mzl.flower.constant.Constants;
|
import com.mzl.flower.dto.request.CreateWechatUserDTO;
|
import com.mzl.flower.dto.request.UserLoginDTO;
|
import com.mzl.flower.dto.request.UserPhoneLoginDTO;
|
import com.mzl.flower.dto.response.customer.CustomerDTO;
|
import com.mzl.flower.dto.response.wx.WxUserVO;
|
import com.mzl.flower.dto.security.UserDTO;
|
import com.mzl.flower.entity.customer.Customer;
|
import com.mzl.flower.entity.system.User;
|
import com.mzl.flower.mapper.customer.CustomerMapper;
|
import com.mzl.flower.service.customer.CustomerService;
|
import com.mzl.flower.service.impl.WechatUserDetailsService;
|
import com.mzl.flower.service.login.LoginService;
|
import com.mzl.flower.service.system.UserService;
|
import com.mzl.flower.service.system.WeChatService;
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiOperation;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.http.ResponseEntity;
|
import org.springframework.security.authentication.AuthenticationDetailsSource;
|
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.BadCredentialsException;
|
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
|
import org.springframework.security.oauth2.provider.token.TokenStore;
|
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
import org.springframework.util.ObjectUtils;
|
import org.springframework.web.bind.annotation.*;
|
|
import javax.servlet.http.HttpServletRequest;
|
import javax.validation.constraints.NotBlank;
|
import java.util.Map;
|
|
@Slf4j
|
@RestController
|
@RequestMapping("/api")
|
@Api(value = "会员登录", tags = "会员登录")
|
public class CustomerLoginController extends BaseController {
|
|
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
|
|
@Autowired
|
private AuthenticationManager authenticationManager;
|
|
@Autowired
|
private LoginService loginService;
|
|
@Autowired
|
private StringCacheClient stringCacheClient;
|
|
@Autowired
|
private WeChatService weChatService;
|
|
@Autowired
|
private UserService userService;
|
|
@Autowired
|
private CustomerMapper customerMapper;
|
|
@Autowired
|
private CustomerService customerService;
|
|
|
@Autowired
|
private TokenStore tokenStore;
|
public static final String SMS_CODE_KEY = "SMS-CODE-KEY";
|
public static final String TOKEN_KEY = "TOKEN-KEY";
|
|
public static final String SEPARATOR = ":";
|
|
|
@PostMapping("/login/wechat")
|
@ApiOperation(value = "微信小程序登录", notes = "微信小程序登录")
|
public ResponseEntity<ReturnDataDTO<OAuth2AccessToken>> loginWeChat(
|
HttpServletRequest request,@RequestBody CreateWechatUserDTO dto) throws Exception {
|
WxMaJscode2SessionResult session = weChatService.getWxMaSessionInfo(dto.getCode());
|
String openId = session.getOpenid();
|
String sessionKey = session.getSessionKey();
|
String unionId = session.getUnionid();
|
// 判断当前用户账号是否存在
|
dto.setOpenId(openId);
|
dto.setSessionKey(sessionKey);
|
dto.setUnionId(unionId);
|
dto.setUserType(Constants.USER_TYPE.customer.name());
|
|
User existUserByOpenId = userService.getExistUserByOpenId(openId, sessionKey, unionId, Constants.USER_TYPE.customer.name());
|
if(ObjectUtils.isEmpty(existUserByOpenId)){
|
userService.registWxUser(dto);
|
}
|
|
User user = userService.findUserByOpenId(openId, sessionKey, unionId
|
, dto.getImgUrl(), dto.getNickname(),Constants.USER_TYPE.customer.name());
|
String tokenCache = stringCacheClient.get(TOKEN_KEY + SEPARATOR + user.getId());
|
if (StringUtils.isNotBlank(tokenCache)) {
|
//强制删除token,下线
|
removeToken(tokenCache,user.getId());
|
}
|
try {
|
UserIdAuthenticationToken authRequest = new UserIdAuthenticationToken(user.getId(), null);
|
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
|
Authentication authentication = authenticationManager.authenticate(authRequest);
|
OAuth2AccessToken token = loginService.getAccessToken(authentication, Constants.USER_TYPE.customer.name());
|
stringCacheClient.set(TOKEN_KEY + SEPARATOR + user.getId(),token.getValue());
|
return returnData(R.SUCCESS.getCode(), token);
|
} catch (BadCredentialsException e) {
|
throw new ValidationException("用户名或密码错误");
|
} catch (UsernameNotFoundException e) {
|
throw new ValidationException("用户不存在");
|
} catch (Exception e) {
|
log.error(e.getMessage(), e);
|
throw new BaseException(R.RUNTIME_EXCEPTION.getCode(), "登录错误");
|
}
|
}
|
|
@PostMapping("/wx/getuserphonenumber")
|
@ApiOperation(value = "获取当前授权的手机号")
|
public ResponseEntity<ReturnDataDTO> getuserphonenumber(@RequestBody CreateWechatUserDTO dto) throws Exception{
|
return returnData(R.SUCCESS.getCode(), weChatService.getuserphonenumber(dto));
|
}
|
|
@PostMapping("/wx/getExistUserByOpenId")
|
@ApiOperation(value = "查看当前微信号是否已经绑定了用户")
|
public ResponseEntity<ReturnDataDTO> getExistUserByOpenId(@RequestBody CreateWechatUserDTO dto) throws Exception{
|
WxMaJscode2SessionResult session = weChatService.getWxMaSessionInfo(dto.getCode());
|
String openId = session.getOpenid();
|
String sessionKey = session.getSessionKey();
|
String unionId = session.getUnionid();
|
User user=userService.getExistUserByOpenId(openId, sessionKey, unionId,dto.getUserType());
|
return returnData(R.SUCCESS.getCode(), new WxUserVO(openId,sessionKey,unionId,user));
|
}
|
|
@GetMapping("/wx/jscode2session")
|
@ApiOperation(value = "微信小程序授权")
|
public ResponseEntity<ReturnDataDTO> jscode2session(@NotBlank(message = "授权码不能为空") String jsCode,String userType) throws Exception{
|
return returnData(R.SUCCESS.getCode(), weChatService.getWechatOpenId(jsCode,userType));
|
}
|
|
|
@PostMapping("/login/customer")
|
@ApiOperation(value = "商户账号密码登录", notes = "商户账号密码登录")
|
public ResponseEntity<ReturnDataDTO<OAuth2AccessToken>> loginPerson(HttpServletRequest request
|
, @RequestBody UserLoginDTO loginDTO) {
|
String username = loginDTO.getUsername();
|
String password = loginDTO.getPassword();
|
if (StringUtils.isBlank(username)) {
|
throw new ValidationException("用户名不能为空");
|
}
|
if (StringUtils.isBlank(password)) {
|
throw new ValidationException("密码不能为空");
|
}
|
|
User user = userService.findByTel(username, Constants.USER_TYPE.customer.name());
|
if(user == null){
|
throw new ValidationException("用户不存在");
|
}
|
CustomerDTO currentCustomer = customerMapper.getCurrentCustomer(user.getId());
|
if (ObjectUtils.isEmpty(currentCustomer)) {
|
throw new ValidationException("用户不存在");
|
}
|
if (currentCustomer.getIsEnabled() == false) {
|
throw new ValidationException("用户已禁用,请联系管理员");
|
}
|
String tokenCache = stringCacheClient.get(TOKEN_KEY + SEPARATOR + user.getId());
|
if (StringUtils.isNotBlank(tokenCache)) {
|
//强制删除token,下线
|
removeToken(tokenCache,user.getId());
|
}
|
|
try {
|
WebAuthenticationToken authRequest = new WebAuthenticationToken(username, password);
|
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
|
Authentication authentication = authenticationManager.authenticate(authRequest);
|
OAuth2AccessToken token = loginService.getAccessToken(authentication,Constants.USER_TYPE.customer.name());
|
stringCacheClient.set(TOKEN_KEY + SEPARATOR + user.getId(),token.getValue());
|
return returnData(R.SUCCESS.getCode(),token);
|
}catch (BadCredentialsException e){
|
throw new ValidationException("用户名或密码错误");
|
}catch (UsernameNotFoundException e){
|
throw new ValidationException("用户不存在");
|
}catch (Exception e) {
|
log.error(e.getMessage(), e);
|
throw new BaseException(R.RUNTIME_EXCEPTION.getCode(),"登录错误");
|
}
|
}
|
|
|
@PostMapping("/login/customer/phone")
|
@ApiOperation(value = "手机验证码登录系统", notes = "手机验证码登录系统")
|
public ResponseEntity<ReturnDataDTO<OAuth2AccessToken>> loginPhone(HttpServletRequest request,
|
@RequestBody UserLoginDTO loginDTO) {
|
String tel = loginDTO.getUsername();
|
String smsCode = loginDTO.getSmsCode();
|
if (StringUtils.isBlank(tel)) {
|
throw new ValidationException("手机号码不能为空");
|
}
|
if (StringUtils.isBlank(smsCode)) {
|
throw new ValidationException("手机验证码不能为空");
|
}
|
//从缓存中获取验证码
|
String smsCacheCode = stringCacheClient.get(SMS_CODE_KEY + SEPARATOR + Constants.USER_TYPE.customer.name() + SEPARATOR + tel);
|
if (!StringUtils.equals(smsCode, smsCacheCode)) {
|
throw new ValidationException("手机验证码不正确");
|
}
|
|
User user = userService.findByTel(tel, Constants.USER_TYPE.customer.name());
|
if(user == null){
|
throw new ValidationException("用户不存在");
|
}
|
CustomerDTO currentCustomer = customerMapper.getCurrentCustomer(user.getId());
|
if (ObjectUtils.isEmpty(currentCustomer)) {
|
throw new ValidationException("用户不存在");
|
}
|
if (currentCustomer.getIsEnabled() == false) {
|
throw new ValidationException("用户已禁用,请联系管理员");
|
}
|
String tokenCache = stringCacheClient.get(TOKEN_KEY + SEPARATOR + user.getId());
|
if (StringUtils.isNotBlank(tokenCache)) {
|
//强制删除token,下线
|
removeToken(tokenCache,user.getId());
|
}
|
|
try {
|
PhoneAuthenticationToken authRequest = new PhoneAuthenticationToken(tel, smsCode, Constants.USER_TYPE.customer.name());
|
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
|
Authentication authentication = authenticationManager.authenticate(authRequest);
|
OAuth2AccessToken token = loginService.getAccessToken(authentication, Constants.USER_TYPE.customer.name());
|
//删除缓存中的验证码
|
stringCacheClient.delete(SMS_CODE_KEY + SEPARATOR + Constants.USER_TYPE.customer.name() + SEPARATOR + tel);
|
stringCacheClient.set(TOKEN_KEY + SEPARATOR + user.getId(),token.getValue());
|
return returnData(R.SUCCESS.getCode(),token);
|
}catch (UsernameNotFoundException e){
|
throw new ValidationException("手机号未注册");
|
}catch (Exception e) {
|
log.error(e.getMessage(), e);
|
throw new BaseException(R.RUNTIME_EXCEPTION.getCode(),"登录错误");
|
}
|
}
|
|
public void removeToken(String token,String userId) {
|
if (StringUtils.isNotBlank(token) && StringUtils.isNotBlank(userId)) {
|
stringCacheClient.delete(TOKEN_KEY + SEPARATOR + userId);
|
String tokenValue = token.replace(OAuth2AccessToken.BEARER_TYPE, StrUtil.EMPTY).trim();
|
OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
|
if (accessToken != null && StringUtils.isNotBlank(accessToken.getValue())) {
|
tokenStore.removeAccessToken(accessToken);
|
OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
|
tokenStore.removeRefreshToken(refreshToken);
|
}
|
}
|
}
|
|
@PostMapping("/login/customer/phone/v2")
|
@ApiOperation(value = "手机验证码登录系统", notes = "手机验证码登录系统")
|
public ResponseEntity<ReturnDataDTO<OAuth2AccessToken>> loginPhoneV2(HttpServletRequest request,
|
@RequestBody UserPhoneLoginDTO loginDTO) {
|
String tel = loginDTO.getUsername();
|
String smsCode = loginDTO.getSmsCode();
|
if (StringUtils.isBlank(tel)) {
|
throw new ValidationException("手机号码不能为空");
|
}
|
if (StringUtils.isBlank(smsCode)) {
|
throw new ValidationException("手机验证码不能为空");
|
}
|
//从缓存中获取验证码
|
String smsCacheCode = stringCacheClient.get(SMS_CODE_KEY + SEPARATOR + Constants.USER_TYPE.customer.name() + SEPARATOR + tel);
|
if (!StringUtils.equals(smsCode, smsCacheCode)) {
|
throw new ValidationException("手机验证码不正确");
|
}
|
|
User user = userService.findByTel(tel, Constants.USER_TYPE.customer.name());
|
User user1 = null;
|
String tokenCache ="";
|
if(user == null){
|
loginDTO.setUserType(Constants.USER_TYPE.customer.name());
|
user1 = userService.registPhoneUser(loginDTO);
|
if(org.springframework.util.StringUtils.isEmpty(user1)){
|
throw new ValidationException("注册用户信息报错");
|
}
|
tokenCache = stringCacheClient.get(TOKEN_KEY + SEPARATOR + user1.getId());
|
CustomerDTO currentCustomer = customerMapper.getCurrentCustomer(user1.getId());
|
if (ObjectUtils.isEmpty(currentCustomer)) {
|
throw new ValidationException("用户不存在");
|
}
|
if (currentCustomer.getIsEnabled() == false) {
|
throw new ValidationException("用户已禁用,请联系管理员");
|
}
|
tokenCache = stringCacheClient.get(TOKEN_KEY + SEPARATOR + user1.getId());
|
if (StringUtils.isNotBlank(tokenCache)) {
|
//强制删除token,下线
|
removeToken(tokenCache,user.getId());
|
}
|
}else{
|
CustomerDTO currentCustomer = customerMapper.getCurrentCustomer(user.getId());
|
if (ObjectUtils.isEmpty(currentCustomer)) {
|
throw new ValidationException("用户不存在");
|
}
|
if (currentCustomer.getIsEnabled() == false) {
|
throw new ValidationException("用户已禁用,请联系管理员");
|
}
|
|
//验证邀请码
|
if (StringUtils.isNotEmpty(loginDTO.getIntevailCode())) {
|
throw new ValidationException("非新用户注册无法填写邀请码,请删除后重新登陆");
|
}
|
|
tokenCache = stringCacheClient.get(TOKEN_KEY + SEPARATOR + user.getId());
|
if (StringUtils.isNotBlank(tokenCache)) {
|
//强制删除token,下线
|
removeToken(tokenCache,user.getId());
|
}
|
}
|
try {
|
PhoneAuthenticationToken authRequest = new PhoneAuthenticationToken(tel, smsCode, Constants.USER_TYPE.customer.name());
|
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
|
Authentication authentication = authenticationManager.authenticate(authRequest);
|
OAuth2AccessToken token = loginService.getAccessToken(authentication, Constants.USER_TYPE.customer.name());
|
//删除缓存中的验证码
|
stringCacheClient.delete(SMS_CODE_KEY + SEPARATOR + Constants.USER_TYPE.customer.name() + SEPARATOR + tel);
|
if(user == null){
|
stringCacheClient.set(TOKEN_KEY + SEPARATOR + user1.getId(),token.getValue());
|
}else {
|
stringCacheClient.set(TOKEN_KEY + SEPARATOR + user.getId(), token.getValue());
|
}
|
return returnData(R.SUCCESS.getCode(),token);
|
}catch (UsernameNotFoundException e){
|
throw new ValidationException("用户不存在");
|
}catch (Exception e) {
|
log.error(e.getMessage(), e);
|
throw new BaseException(R.RUNTIME_EXCEPTION.getCode(),"登录错误");
|
}
|
}
|
|
|
@PostMapping("/account/close")
|
@ApiOperation(value = "账户注销", notes = "账户注销")
|
public ResponseEntity<ReturnDataDTO<Boolean>> accountClose() {
|
|
String userId = SecurityUtils.getUserId();
|
|
if(StringUtils.isNotBlank(userId)){
|
//
|
CustomerDTO currentCustomer = customerMapper.getCurrentCustomer(userId);
|
if(null==currentCustomer){
|
throw new BaseException(R.RUNTIME_EXCEPTION.getCode(),"用户不存在");
|
}
|
|
currentCustomer.setIsClosed(true);
|
|
User user=userService.getUserById(userId);
|
|
|
if (StringUtils.isNotBlank(user.getLoginName())) {
|
currentCustomer.setName("智信-" + user.getLoginName().substring(user.getLoginName().length() - 4));
|
|
}
|
currentCustomer.setCover("https://hmy-flower.oss-cn-shanghai.aliyuncs.com/8f/8f205ea4618b4ce48d5bd204ae73f075tmp_f0c47a66148245dc17d74563c5939e764273ba583619664d.jpg");
|
|
Customer customer=new Customer();
|
BeanUtils.copyProperties(currentCustomer,customer);
|
|
// 会员注销
|
customer.setIsMember(false);
|
// 会员过期时间设置为空
|
customer.setMemberOvertime(null);
|
|
customerMapper.updateById(customer);
|
|
return returnData(R.SUCCESS.getCode(),true);
|
|
}else{
|
throw new BaseException(R.RUNTIME_EXCEPTION.getCode(),"用户ID不能为空");
|
}
|
|
|
}
|
|
|
}
|