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.TokenDto; 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.common.token.util.CpUserDetailRedis; import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.utils.Result; import com.epmet.dao.CustomerUserDao; import com.epmet.entity.CustomerUserEntity; import com.epmet.jwt.JwtTokenProperties; import com.epmet.jwt.JwtTokenUtils; 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 CustomerUserDao customerUserDao; @Autowired private WxMaServiceUtils wxMaServiceUtils; @Autowired private JwtTokenUtils jwtTokenUtils; @Autowired private JwtTokenProperties jwtTokenProperties; @Autowired private CpUserDetailRedis cpUserDetailRedis; /** * 微信小程序登录 * * @param formDTO * @return com.epmet.commons.tools.utils.Result * @author yinzuomei * @since 2020/3/14 19:34 */ @Override public Result 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().ok(userTokenResultDTO); } return new Result().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) { String userId = ""; if (LoginConstant.APP_GOV.equals(formDTO.getApp())) { //查询customer_staff待完善 } else if (LoginConstant.APP_OPER.equals(formDTO.getApp())) { //查询oper_staff待完善 } else if (LoginConstant.APP_RESI.equals(formDTO.getApp())) { //查询customer_user userId = customerUserDao.selectByWxOpenId(wxMaJscode2SessionResult.getOpenid()); if (StringUtils.isBlank(userId)) { WxMaUserInfo wxMaUserInfo = wxMaServiceUtils.resiWxMaService().getUserService() .getUserInfo(wxMaJscode2SessionResult.getSessionKey(), formDTO.getEncryptedData(), formDTO.getIv()); CustomerUserEntity customerUserEntity = new CustomerUserEntity(); customerUserEntity.setCity(wxMaUserInfo.getCity()); customerUserEntity.setWxOpenId(wxMaUserInfo.getOpenId()); customerUserEntity.setNickname(wxMaUserInfo.getNickName()); customerUserEntity.setCountry(wxMaUserInfo.getCountry()); customerUserEntity.setHeadImgUrl(wxMaUserInfo.getAvatarUrl()); customerUserEntity.setCountry(wxMaUserInfo.getCountry()); customerUserEntity.setProvince(wxMaUserInfo.getProvince()); customerUserEntity.setSex(Integer.valueOf(wxMaUserInfo.getGender())); customerUserDao.insert(customerUserEntity); userId = customerUserEntity.getId(); } } return userId; } /** * 封装用户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 map = new HashMap<>(); map.put("app", formDTO.getApp()); map.put("client", formDTO.getClient()); map.put("userId", userId); String token = jwtTokenUtils.createToken(map); 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()); cpUserDetailRedis.set(tokenDto, expire); return token; } /** * 手机号+密码登录接口 * * @param formDTO * @return com.epmet.commons.tools.utils.Result * @author yinzuomei * @since 2020/3/14 19:34 */ @Override public Result loginByPassword(LoginByPassWordFormDTO formDTO) { //1、账号是否存在 //2、密码是否正确 //3、生成token返回,且将TokenDto存到redis return null; } }