日照智慧社区接口服务
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

353 lines
13 KiB

package com.epmet.service.impl;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.epmet.common.token.constant.LoginConstant;
import com.epmet.common.token.dto.form.LoginByPassWordFormDTO;
import com.epmet.common.token.dto.form.LoginByWxCodeFormDTO;
import com.epmet.common.token.dto.result.UserTokenResultDTO;
import com.epmet.commons.tools.exception.ErrorCode;
import com.epmet.commons.tools.exception.RenException;
import com.epmet.commons.tools.security.dto.TokenDto;
import com.epmet.commons.tools.security.password.PasswordUtils;
import com.epmet.commons.tools.utils.CpUserDetailRedis;
import com.epmet.commons.tools.utils.Result;
import com.epmet.dto.CustomerUserDTO;
import com.epmet.dto.form.PasswordLoginUserInfoFormDTO;
import com.epmet.dto.form.WxLoginUserInfoFormDTO;
import com.epmet.dto.result.PasswordLoginUserInfoResultDTO;
import com.epmet.feign.EpmetUserFeignClient;
import com.epmet.jwt.JwtTokenProperties;
import com.epmet.jwt.JwtTokenUtils;
import com.epmet.service.CaptchaService;
import com.epmet.service.LoginService;
import com.epmet.utils.WxMaServiceUtils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* @Description
* @Author yinzuomei
* @Date 2020/3/14 20:31
*/
@Slf4j
@Service
public class LoginServiceImpl implements LoginService {
private static final Logger logger = LoggerFactory.getLogger(AuthServiceImpl.class);
@Autowired
private EpmetUserFeignClient epmetUserFeignClient;
@Autowired
private WxMaServiceUtils wxMaServiceUtils;
@Autowired
private JwtTokenUtils jwtTokenUtils;
@Autowired
private JwtTokenProperties jwtTokenProperties;
@Autowired
private CpUserDetailRedis cpUserDetailRedis;
@Autowired
private CaptchaService captchaService;
/**
* 微信小程序登录
*
* @param formDTO
* @return com.epmet.commons.tools.utils.Result<com.epmet.dto.UserTokenResultDTO>
* @author yinzuomei
* @since 2020/3/14 19:34
*/
@Override
public Result<UserTokenResultDTO> loginByWxCode(LoginByWxCodeFormDTO formDTO) {
//1、根据wxCode获取微信信息
WxMaJscode2SessionResult wxMaJscode2SessionResult = this.getWxMaUser(formDTO);
logger.info("openId=[" + wxMaJscode2SessionResult.getOpenid() + "]unionId=[" + wxMaJscode2SessionResult.getUnionid() + "]");
//2、根据openId查询数据库,没有则直接插入一条记录
String userId = this.getUserId(formDTO, wxMaJscode2SessionResult);
if (StringUtils.isNotBlank(userId)) {
//3、封装token且存到redis
UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO();
userTokenResultDTO.setToken(this.packagingUserToken(formDTO, userId, wxMaJscode2SessionResult));
return new Result<UserTokenResultDTO>().ok(userTokenResultDTO);
}
return new Result<UserTokenResultDTO>().error("登录失败");
}
/**
* 解析微信code获取小程序用户信息
*
* @param formDTO
* @return cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult
* @author yinzuomei
* @date 2020/3/14 20:16
*/
private WxMaJscode2SessionResult getWxMaUser(LoginByWxCodeFormDTO formDTO) {
WxMaJscode2SessionResult wxMaJscode2SessionResult = null;
try {
if (LoginConstant.APP_GOV.equals(formDTO.getApp())) {
wxMaJscode2SessionResult = wxMaServiceUtils.govWxMaService().jsCode2SessionInfo(formDTO.getWxCode());
} else if (LoginConstant.APP_OPER.equals(formDTO.getApp())) {
wxMaJscode2SessionResult = wxMaServiceUtils.operWxMaService().jsCode2SessionInfo(formDTO.getWxCode());
} else if (LoginConstant.APP_RESI.equals(formDTO.getApp())) {
wxMaJscode2SessionResult = wxMaServiceUtils.resiWxMaService().jsCode2SessionInfo(formDTO.getWxCode());
}
} catch (WxErrorException e) {
log.error("->[getMaOpenId]::error[{}]", "解析微信code失败");
}
if (null == wxMaJscode2SessionResult) {
throw new RenException("解析微信用户信息失败");
} else if (StringUtils.isBlank(wxMaJscode2SessionResult.getOpenid())) {
throw new RenException("获取微信openid失败");
}
return wxMaJscode2SessionResult;
}
/**
* 根据openId查询用户id
*
* @param formDTO
* @param wxMaJscode2SessionResult
* @return java.lang.String
* @author yinzuomei
* @since 2020/3/14 19:34
*/
private String getUserId(LoginByWxCodeFormDTO formDTO, WxMaJscode2SessionResult wxMaJscode2SessionResult) {
WxLoginUserInfoFormDTO wxLoginUserInfoFormDTO = new WxLoginUserInfoFormDTO();
wxLoginUserInfoFormDTO.setApp(formDTO.getApp());
wxLoginUserInfoFormDTO.setOpenId(wxMaJscode2SessionResult.getOpenid());
//1、先根据app、client、openId查询
Result<String> userResult = epmetUserFeignClient.selecWxLoginUserInfo(wxLoginUserInfoFormDTO);
String userId = "";
if (!userResult.success()) {
throw new RenException("获取用户信息失败" + userResult.getMsg());
}
userId = userResult.getData();
//2、如果已经存在userId,则更新微信信息
if (StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(formDTO.getEncryptedData()) && StringUtils.isNotBlank(formDTO.getIv())) {
this.updateWxInfO(userId,formDTO,wxMaJscode2SessionResult);
}
//3、数据库不存在此用户则创建此用户
if (StringUtils.isBlank(userId)) {
userId = createEpmtUser(formDTO, wxMaJscode2SessionResult);
}
return userId;
}
/**
* @return com.epmet.commons.tools.utils.Result
* @param userId
* @param wxMaJscode2SessionResult
* @Author yinzuomei
* @Description 获取用户微信基本信息更新到本地
* @Date 2020/3/20 19:51
**/
private Result updateWxInfO(String userId,
LoginByWxCodeFormDTO formDTO,
WxMaJscode2SessionResult wxMaJscode2SessionResult) {
if (LoginConstant.APP_GOV.equals(formDTO.getApp())) {
//查询customer_staff待完善
} else if (LoginConstant.APP_OPER.equals(formDTO.getApp())) {
//查询oper_user待完善
} else if (LoginConstant.APP_RESI.equals(formDTO.getApp())) {
WxMaUserInfo wxMaUserInfo = wxMaServiceUtils.resiWxMaService().getUserService()
.getUserInfo(wxMaJscode2SessionResult.getSessionKey(),
formDTO.getEncryptedData(),
formDTO.getIv());
CustomerUserDTO customerUserDTO = this.packageCustomerUserDTO(wxMaUserInfo);
customerUserDTO.setId(userId);
epmetUserFeignClient.saveOrUpdateCustomerUser(customerUserDTO);
}
return new Result();
}
/**
* @param formDTO
* @param wxMaJscode2SessionResult
* @return java.lang.String
* @Author yinzuomei
* @Description 陌生人首次授权创建用户信息
* @Date 2020/3/20 19:42
**/
private String createEpmtUser(LoginByWxCodeFormDTO formDTO, WxMaJscode2SessionResult wxMaJscode2SessionResult) {
String userId = "";
if (LoginConstant.APP_GOV.equals(formDTO.getApp())) {
//查询customer_staff待完善
} else if (LoginConstant.APP_OPER.equals(formDTO.getApp())) {
//查询oper_user待完善
} else if (LoginConstant.APP_RESI.equals(formDTO.getApp())) {
//查询customer_user
CustomerUserDTO customerUserDTO = new CustomerUserDTO();
if (StringUtils.isNotBlank(formDTO.getIv()) && StringUtils.isNotBlank(formDTO.getEncryptedData())) {
WxMaUserInfo wxMaUserInfo = wxMaServiceUtils.resiWxMaService().getUserService()
.getUserInfo(wxMaJscode2SessionResult.getSessionKey(),
formDTO.getEncryptedData(),
formDTO.getIv());
customerUserDTO = this.packageCustomerUserDTO(wxMaUserInfo);
} else {
customerUserDTO.setWxOpenId(wxMaJscode2SessionResult.getOpenid());
customerUserDTO.setUnionId(wxMaJscode2SessionResult.getUnionid());
}
Result<String> saveCustomerUserResult = epmetUserFeignClient.saveOrUpdateCustomerUser(customerUserDTO);
if (!saveCustomerUserResult.success()) {
throw new RenException("创建用户失败" + saveCustomerUserResult.getMsg());
}
userId = saveCustomerUserResult.getData();
}
return userId;
}
/**
* @param wxMaUserInfo
* @return com.epmet.dto.CustomerUserDTO
* @Author yinzuomei
* @Description 微信信息封装为customer_user记录
* @Date 2020/3/17 18:22
**/
private CustomerUserDTO packageCustomerUserDTO(WxMaUserInfo wxMaUserInfo) {
CustomerUserDTO customerUserDTO = new CustomerUserDTO();
customerUserDTO.setCity(wxMaUserInfo.getCity());
customerUserDTO.setWxOpenId(wxMaUserInfo.getOpenId());
customerUserDTO.setNickname(wxMaUserInfo.getNickName());
customerUserDTO.setCountry(wxMaUserInfo.getCountry());
customerUserDTO.setHeadImgUrl(wxMaUserInfo.getAvatarUrl());
customerUserDTO.setCountry(wxMaUserInfo.getCountry());
customerUserDTO.setProvince(wxMaUserInfo.getProvince());
customerUserDTO.setSex(Integer.valueOf(wxMaUserInfo.getGender()));
return customerUserDTO;
}
/**
* 封装用户token值
*
* @param formDTO
* @param userId
* @param wxMaJscode2SessionResult
* @return java.lang.String
* @author yinzuomei
* @since 2020/3/14 19:34
*/
private String packagingUserToken(LoginByWxCodeFormDTO formDTO,
String userId,
WxMaJscode2SessionResult wxMaJscode2SessionResult) {
// 生成token
Map<String, Object> map = new HashMap<>();
map.put("app", formDTO.getApp());
map.put("client", formDTO.getClient());
map.put("userId", userId);
String token = jwtTokenUtils.createToken(map);
// logger.info("app:"+formDTO.getApp()+";client:"+formDTO.getClient()+";userId:"+userId+";生成token["+token+"]");
int expire = jwtTokenProperties.getExpire();
TokenDto tokenDto = new TokenDto();
tokenDto.setApp(formDTO.getApp());
tokenDto.setClient(formDTO.getClient());
tokenDto.setUserId(userId);
tokenDto.setOpenId(wxMaJscode2SessionResult.getOpenid());
tokenDto.setSessionKey(wxMaJscode2SessionResult.getSessionKey());
tokenDto.setUnionId(wxMaJscode2SessionResult.getUnionid());
tokenDto.setToken(token);
tokenDto.setUpdateTime(System.currentTimeMillis());
tokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime());
cpUserDetailRedis.set(tokenDto, expire);
// logger.info("token过期时间:"+tokenUtil.getExpire(tokenDto.getApp(),tokenDto.getClient(),tokenDto.getUserId()));
// logger.info("截止时间:"+ DateUtils.format(jwtTokenUtils.getExpiration(token),"yyyy-MM-dd HH:mm:ss"));
return token;
}
/**
* 手机号+密码登录接口
*
* @param formDTO
* @return com.epmet.commons.tools.utils.Result<com.epmet.dto.UserTokenResultDTO>
* @author yinzuomei
* @since 2020/3/14 19:34
*/
@Override
public Result<UserTokenResultDTO> loginByPassword(LoginByPassWordFormDTO formDTO) {
//1、验证码是否正确
6 years ago
boolean flag = captchaService.validate(formDTO.getUuid(), formDTO.getCaptcha());
if (!flag) {
return new Result<UserTokenResultDTO>().error(ErrorCode.CAPTCHA_ERROR);
6 years ago
}
//2、账号是否存在
//获取用户信息
PasswordLoginUserInfoFormDTO passwordLoginUserInfoFormDTO = new PasswordLoginUserInfoFormDTO();
passwordLoginUserInfoFormDTO.setApp(formDTO.getApp());
passwordLoginUserInfoFormDTO.setPhone(formDTO.getPhone());
Result<PasswordLoginUserInfoResultDTO> userInfoResult = epmetUserFeignClient.selectLoginUserInfoByPassword(passwordLoginUserInfoFormDTO);
logger.info(userInfoResult.getCode() + userInfoResult.getMsg());
if (!userInfoResult.success() || null == userInfoResult.getData()) {
return new Result<UserTokenResultDTO>().error("账号不存在");
}
//3、密码是否正确
//密码错误
if (!PasswordUtils.matches(formDTO.getPassword(), userInfoResult.getData().getPassWord())) {
throw new RenException(ErrorCode.ACCOUNT_PASSWORD_ERROR);
}
//4、生成token返回,且将TokenDto存到redis
UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO();
userTokenResultDTO.setToken(this.packagingUserToken(formDTO, userInfoResult.getData().getUserId()));
return new Result<UserTokenResultDTO>().ok(userTokenResultDTO);
}
/**
* 封装用户token值
*
* @param formDTO
* @param userId
* @return java.lang.String
* @author yinzuomei
* @since 2020/3/14 19:34
*/
private String packagingUserToken(LoginByPassWordFormDTO formDTO,
String userId) {
// 生成token
Map<String, Object> map = new HashMap<>();
map.put("app", formDTO.getApp());
map.put("client", formDTO.getClient());
map.put("userId", userId);
String token = jwtTokenUtils.createToken(map);
// logger.info("app:"+formDTO.getApp()+";client:"+formDTO.getClient()+";userId:"+userId+";生成token["+token+"]");
int expire = jwtTokenProperties.getExpire();
TokenDto tokenDto = new TokenDto();
tokenDto.setApp(formDTO.getApp());
tokenDto.setClient(formDTO.getClient());
tokenDto.setUserId(userId);
tokenDto.setToken(token);
tokenDto.setUpdateTime(System.currentTimeMillis());
tokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime());
cpUserDetailRedis.set(tokenDto, expire);
// logger.info("token过期时间:"+tokenUtil.getExpire(tokenDto.getApp(),tokenDto.getClient(),tokenDto.getUserId()));
// logger.info("截止时间:"+ DateUtils.format(jwtTokenUtils.getExpiration(token),"yyyy-MM-dd HH:mm:ss"));
return token;
}
@Override
6 years ago
public Result logoutByToken(TokenDto tokenDto) {
//记录登出日志
//删除redis
6 years ago
if(null == tokenDto){
return new Result().error("当前用户信息获取失败!");
}
cpUserDetailRedis.logout(tokenDto.getApp() , tokenDto.getClient() , tokenDto.getUserId());
//web端清空菜单栏和权限,小程序目前又
6 years ago
return new Result().ok("退出登录!");
}
}