package com.epmet.service.impl; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import com.epmet.common.token.constant.LoginConstant; import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.RenException; import com.epmet.commons.tools.security.dto.GovTokenDto; import com.epmet.commons.tools.security.dto.TokenDto; import com.epmet.commons.tools.utils.CpUserDetailRedis; import com.epmet.commons.tools.utils.DateUtils; import com.epmet.commons.tools.utils.Result; import com.epmet.commons.tools.validator.PhoneValidatorUtils; import com.epmet.dto.CustomerStaffDTO; import com.epmet.dto.form.*; import com.epmet.dto.result.StaffLatestAgencyResultDTO; import com.epmet.dto.result.StaffOrgsResultDTO; import com.epmet.dto.result.UserTokenResultDTO; import com.epmet.feign.EpmetUserFeignClient; import com.epmet.feign.GovOrgFeignClient; import com.epmet.feign.MessageFeignClient; import com.epmet.jwt.JwtTokenProperties; import com.epmet.jwt.JwtTokenUtils; import com.epmet.redis.CaptchaRedis; import com.epmet.service.GovLoginService; import com.epmet.service.LoginService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @Description 政府端登录服务 * @Author yinzuomei * @Date 2020/4/20 10:56 */ @Service public class GovLoginServiceImpl implements GovLoginService { private static final Logger logger = LoggerFactory.getLogger(GovLoginServiceImpl.class); private static final String SEND_SMS_CODE_ERROR = "发送短信验证码异常,手机号[%s],code[%s],msg[%s]"; @Autowired private LoginService loginService; @Autowired private EpmetUserFeignClient epmetUserFeignClient; @Autowired private CaptchaRedis captchaRedis; @Autowired private MessageFeignClient messageFeignClient; @Autowired private JwtTokenUtils jwtTokenUtils; @Autowired private JwtTokenProperties jwtTokenProperties; @Autowired private CpUserDetailRedis cpUserDetailRedis; @Autowired private GovOrgFeignClient govOrgFeignClient; /** * @param formDTO * @return com.epmet.commons.tools.utils.Result * @Author yinzuomei * @Description 政府端微信小程序登录-发送验证码 * @Date 2020/4/18 10:59 **/ @Override public Result sendSmsCode(SendSmsCodeFormDTO formDTO) { //1、校验手机号是否符合规范 if (!PhoneValidatorUtils.isMobile(formDTO.getMobile())) { logger.error(String.format(SEND_SMS_CODE_ERROR, formDTO.getMobile(), EpmetErrorCode.ERROR_PHONE.getCode(), EpmetErrorCode.ERROR_PHONE.getMsg())); return new Result().error(EpmetErrorCode.ERROR_PHONE.getCode()); } //2、根据手机号校验用户是否存在 Result> customerStaffResult = epmetUserFeignClient.checkCustomerStaff(formDTO.getMobile()); if (!customerStaffResult.success()) { logger.error(String.format(SEND_SMS_CODE_ERROR, formDTO.getMobile(), customerStaffResult.getCode(), customerStaffResult.getMsg())); return new Result().error(customerStaffResult.getCode()); } //3、发送短信验证码 Result> smsCodeResult = messageFeignClient.sendSmsCaptcha(formDTO.getMobile()); if (!smsCodeResult.success()) { logger.error(String.format(SEND_SMS_CODE_ERROR, formDTO.getMobile(), smsCodeResult.getCode(), smsCodeResult.getMsg())); return new Result().error(smsCodeResult.getCode()); } //4、保存短信验证码(删除现有短信验证码、将新的短信验证码存入Redis) captchaRedis.saveSmsCode(formDTO, smsCodeResult.getData().get("code")); logger.info(String.format("发送短信验证码成功,手机号[%s]", formDTO.getMobile())); return new Result(); } /** * @param formDTO * @return com.epmet.commons.tools.utils.Result * @Author yinzuomei * @Description 3、手机验证码获取组织 * @Date 2020/4/18 21:11 **/ @Override public Result> getMyOrg(StaffOrgsFormDTO formDTO) { //1、根据手机号查询到用户信息 Result> customerStaffResult = epmetUserFeignClient.checkCustomerStaff(formDTO.getMobile()); if (!customerStaffResult.success()) { logger.error(String.format("手机验证码登录异常,手机号[%s],code[%s],msg[%s]", formDTO.getMobile(), customerStaffResult.getCode(), customerStaffResult.getMsg())); return new Result().error(customerStaffResult.getCode()); } //2、验证码是否正确 String rightSmsCode = captchaRedis.getSmsCode(formDTO.getMobile()); if (!formDTO.getSmsCode().equals(rightSmsCode)) { logger.error(String.format("验证码错误code[%s],msg[%s]",EpmetErrorCode.MOBILE_CODE_ERROR.getCode(),EpmetErrorCode.MOBILE_CODE_ERROR.getMsg())); return new Result>().error(EpmetErrorCode.MOBILE_CODE_ERROR.getCode()); } //3、查询用户所有的组织信息 List customerIdList = new ArrayList<>(); for (CustomerStaffDTO customerStaffDTO : customerStaffResult.getData()) { customerIdList.add(customerStaffDTO.getCustomerId()); } StaffOrgFormDTO staffOrgFormDTO = new StaffOrgFormDTO(); staffOrgFormDTO.setCustomerIdList(customerIdList); Result> result = govOrgFeignClient.getStaffOrgList(staffOrgFormDTO); return result; } @Override public Result loginByWxCode(GovWxmpFormDTO formDTO) { //1、解析微信用户 WxMaJscode2SessionResult wxMaJscode2SessionResult = loginService.getWxMaUser(formDTO.getApp(), formDTO.getWxCode()); Result latestStaffWechat = epmetUserFeignClient.getLatestStaffWechatLoginRecord(wxMaJscode2SessionResult.getOpenid()); if (!latestStaffWechat.success() || null == latestStaffWechat.getData()) { logger.error(String.format("没有获取到用户最近一次登录账户信息,code[%s],msg[%s]", EpmetErrorCode.PLEASE_LOGIN.getCode(), EpmetErrorCode.PLEASE_LOGIN.getMsg())); return new Result().error(EpmetErrorCode.PLEASE_LOGIN.getCode()); } StaffLatestAgencyResultDTO staffLatestAgencyResultDTO = latestStaffWechat.getData(); //2、记录staff_wechat this.savestaffwechat(staffLatestAgencyResultDTO.getStaffId(), wxMaJscode2SessionResult.getOpenid()); //3、记录登录日志 this.saveStaffLoginRecord(staffLatestAgencyResultDTO); //4、获取用户token String token = this.generateGovWxmpToken(staffLatestAgencyResultDTO.getStaffId()); //5、保存到redis this.saveLatestGovTokenDto(staffLatestAgencyResultDTO, wxMaJscode2SessionResult, token); UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO(); userTokenResultDTO.setToken(token); return new Result().ok(userTokenResultDTO); } //保存tokenDto到redis private void saveLatestGovTokenDto(StaffLatestAgencyResultDTO staffLatestAgency, WxMaJscode2SessionResult wxMaJscode2SessionResult, String token) { int expire = jwtTokenProperties.getExpire(); GovTokenDto govTokenDto = new GovTokenDto(); govTokenDto.setApp(LoginConstant.APP_GOV); govTokenDto.setClient(LoginConstant.CLIENT_WXMP); govTokenDto.setUserId(staffLatestAgency.getStaffId()); govTokenDto.setOpenId(wxMaJscode2SessionResult.getOpenid()); govTokenDto.setSessionKey(wxMaJscode2SessionResult.getSessionKey()); govTokenDto.setUnionId(wxMaJscode2SessionResult.getUnionid()); govTokenDto.setToken(token); govTokenDto.setUpdateTime(System.currentTimeMillis()); govTokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime()); govTokenDto.setAgencyId(staffLatestAgency.getAgencyId()); govTokenDto.setCustomerId(staffLatestAgency.getCustomerId()); cpUserDetailRedis.set(govTokenDto, expire); logger.info("截止时间:" + DateUtils.format(jwtTokenUtils.getExpiration(token), "yyyy-MM-dd HH:mm:ss")); } //保存登录日志 private Result saveStaffLoginRecord(StaffLatestAgencyResultDTO latestStaffWechatLoginDTO) { StaffLoginAgencyRecordFormDTO staffLoginAgencyRecordFormDTO = new StaffLoginAgencyRecordFormDTO(); staffLoginAgencyRecordFormDTO.setCustomerId(latestStaffWechatLoginDTO.getCustomerId()); staffLoginAgencyRecordFormDTO.setStaffId(latestStaffWechatLoginDTO.getStaffId()); staffLoginAgencyRecordFormDTO.setWxOpenId(latestStaffWechatLoginDTO.getWxOpenId()); staffLoginAgencyRecordFormDTO.setMobile(latestStaffWechatLoginDTO.getMobile()); staffLoginAgencyRecordFormDTO.setAgencyId(latestStaffWechatLoginDTO.getAgencyId()); Result staffLoginRecordResult = epmetUserFeignClient.saveStaffLoginRecord(staffLoginAgencyRecordFormDTO); return staffLoginRecordResult; } @Override public Result enterOrg(GovWxmpEnteOrgFormDTO formDTO) { //1、需要校验要登录的客户,是否被禁用 CustomerStaffFormDTO customerStaffFormDTO = new CustomerStaffFormDTO(); customerStaffFormDTO.setCustomerId(formDTO.getCustomerId()); customerStaffFormDTO.setMobile(formDTO.getMobile()); Result customerStaffDTOResult = epmetUserFeignClient.getCustomerStaffInfo(customerStaffFormDTO); if (!customerStaffDTOResult.success() || null == customerStaffDTOResult.getData()) { logger.error(String.format("获取工作人员信息失败,手机号[%s],客户id:[%s],code[%s],msg[%s]", formDTO.getMobile(), formDTO.getCustomerId(), customerStaffDTOResult.getCode(), customerStaffDTOResult.getMsg())); return new Result().error(customerStaffDTOResult.getCode()); } CustomerStaffDTO customerStaff = customerStaffDTOResult.getData(); //2、解析微信用户 WxMaJscode2SessionResult wxMaJscode2SessionResult = loginService.getWxMaUser(LoginConstant.APP_GOV, formDTO.getWxCode()); //3、记录staff_wechat this.savestaffwechat(customerStaff.getUserId(), wxMaJscode2SessionResult.getOpenid()); //5、记录登录日志 this.saveStaffLoginRecord(formDTO, customerStaff.getUserId(), wxMaJscode2SessionResult.getOpenid()); //1、获取用户token String token = this.generateGovWxmpToken(customerStaff.getUserId()); //2、保存到redis this.saveGovTokenDto(formDTO.getAgencyId(), formDTO.getCustomerId(), customerStaff.getUserId(), wxMaJscode2SessionResult, token); UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO(); userTokenResultDTO.setToken(token); return new Result().ok(userTokenResultDTO); } @Override public Result loginOut(TokenDto tokenDto) { if(null == tokenDto){ logger.error("token解析失败,直接跳转重新登录即可"); throw new RenException("当前用户信息获取失败"); } cpUserDetailRedis.logout(tokenDto.getApp() , tokenDto.getClient() , tokenDto.getUserId()); return new Result(); } //保存登录日志 private Result saveStaffLoginRecord(GovWxmpEnteOrgFormDTO formDTO, String staffId, String openId) { StaffLoginAgencyRecordFormDTO staffLoginAgencyRecordFormDTO = new StaffLoginAgencyRecordFormDTO(); staffLoginAgencyRecordFormDTO.setCustomerId(formDTO.getCustomerId()); staffLoginAgencyRecordFormDTO.setStaffId(staffId); staffLoginAgencyRecordFormDTO.setWxOpenId(openId); staffLoginAgencyRecordFormDTO.setMobile(formDTO.getMobile()); staffLoginAgencyRecordFormDTO.setAgencyId(formDTO.getAgencyId()); Result staffLoginRecordResult = epmetUserFeignClient.saveStaffLoginRecord(staffLoginAgencyRecordFormDTO); return staffLoginRecordResult; } /** * @param userId * @param openid * @return com.epmet.commons.tools.utils.Result * @Author yinzuomei * @Description 保存微信和当前登录用户关系 * @Date 2020/4/18 22:54 **/ private Result savestaffwechat(String userId, String openid) { StaffWechatFormDTO staffWechatFormDTO = new StaffWechatFormDTO(); staffWechatFormDTO.setUserId(userId); staffWechatFormDTO.setWxOpenId(openid); return epmetUserFeignClient.saveStaffWechat(staffWechatFormDTO); } /** * @Description 生成token * @Date 2020/4/18 23:04 **/ private String generateGovWxmpToken(String staffId) { Map map = new HashMap<>(); map.put("app", LoginConstant.APP_GOV); map.put("client", LoginConstant.CLIENT_WXMP); map.put("staffId", staffId); String token = jwtTokenUtils.createToken(map); logger.info("app:" + LoginConstant.APP_GOV + ";client:" + LoginConstant.CLIENT_WXMP + ";staffId:" + staffId + ";生成token[" + token + "]"); return token; } /** * @Description 生成token * @Date 2020/4/18 23:04 **/ private void saveGovTokenDto(String orgId, String customerId, String staffId, WxMaJscode2SessionResult wxMaJscode2SessionResult, String token) { int expire = jwtTokenProperties.getExpire(); GovTokenDto govTokenDto = new GovTokenDto(); govTokenDto.setApp(LoginConstant.APP_GOV); govTokenDto.setClient(LoginConstant.CLIENT_WXMP); govTokenDto.setUserId(staffId); govTokenDto.setOpenId(wxMaJscode2SessionResult.getOpenid()); govTokenDto.setSessionKey(wxMaJscode2SessionResult.getSessionKey()); govTokenDto.setUnionId(wxMaJscode2SessionResult.getUnionid()); govTokenDto.setToken(token); govTokenDto.setUpdateTime(System.currentTimeMillis()); govTokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime()); govTokenDto.setAgencyId(orgId); govTokenDto.setCustomerId(customerId); cpUserDetailRedis.set(govTokenDto, expire); logger.info("截止时间:" + DateUtils.format(jwtTokenUtils.getExpiration(token), "yyyy-MM-dd HH:mm:ss")); } }