package com.epmet.service.impl; import com.epmet.common.token.constant.LoginConstant; import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.ExceptionUtils; 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.ConvertUtils; import com.epmet.commons.tools.utils.CpUserDetailRedis; import com.epmet.commons.tools.utils.DateUtils; import com.epmet.commons.tools.utils.Result; import com.epmet.dto.CustomerAgencyDTO; import com.epmet.dto.GovStaffRoleDTO; import com.epmet.dto.UserDTO; import com.epmet.dto.UserWechatDTO; import com.epmet.dto.form.*; import com.epmet.dto.result.DepartmentListResultDTO; import com.epmet.dto.result.GridByStaffResultDTO; import com.epmet.dto.result.StaffLatestAgencyResultDTO; import com.epmet.dto.result.UserTokenResultDTO; import com.epmet.feign.EpmetThirdFeignClient; import com.epmet.feign.EpmetUserOpenFeignClient; import com.epmet.feign.GovOrgOpenFeignClient; import com.epmet.jwt.JwtTokenProperties; import com.epmet.jwt.JwtTokenUtils; import com.epmet.service.ThirdLoginService; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** * @author sun * @Description 第三方-居民端、政府端登陆服务 */ @Slf4j @Service public class ThirdLoginServiceImpl implements ThirdLoginService { private static final Logger logger = LoggerFactory.getLogger(ThirdLoginServiceImpl.class); @Autowired private JwtTokenUtils jwtTokenUtils; @Autowired private JwtTokenProperties jwtTokenProperties; @Autowired private CpUserDetailRedis cpUserDetailRedis; @Autowired private EpmetThirdFeignClient epmetThirdFeignClient; @Autowired private EpmetUserOpenFeignClient epmetUserOpenFeignClient; @Autowired private GovOrgOpenFeignClient govOrgOpenFeignClient; /** * @param formDTO * @return * @Author sun * @Description 单客户-居民端微信小程序登录 **/ @Override public UserTokenResultDTO resiLogin(LoginFormDTO formDTO) { //1.调用epmet_third服务,校验appId是否有效以及是否授权,校验通过的调用微信API获取用户基本信息 WxLoginFormDTO resiLoginFormDTO = new WxLoginFormDTO(); resiLoginFormDTO.setAppId(formDTO.getAppId()); resiLoginFormDTO.setWxCode(formDTO.getWxCode()); Result result = epmetThirdFeignClient.resiAndWorkLogin(resiLoginFormDTO); if (!result.success()) { logger.error("居民端小程序登陆,调用epmet_third服务获取数据失败"); throw new RenException(result.getCode()); } UserWechatDTO userWechatDTO = result.getData(); //2.调用epmet-user服务,新增用户信息(先判断用户是否存在,不存在则新增存在则更新) WxUserFormDTO wxUserFormDTO = new WxUserFormDTO(); wxUserFormDTO.setWechatDTO(userWechatDTO); wxUserFormDTO.setApp(formDTO.getApp()); Result userResult = epmetUserOpenFeignClient.saveWxUser(wxUserFormDTO); if (!userResult.success()) { throw new RenException(result.getCode()); } UserDTO userDTO = userResult.getData(); //3.生成业务token String userId = userDTO.getId(); String token = this.generateToken(formDTO, userId); //4.存放Redis this.saveTokenDto(formDTO, userId, userWechatDTO, token); //5.接口返参 UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO(); userTokenResultDTO.setToken(token); return userTokenResultDTO; } /** * @Description 居民端登陆生成业务token的key **/ private String generateToken(LoginCommonFormDTO formDTO, String userId) { Map 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 + "]"); return token; } /** * @Description 将token存入redis **/ private String saveTokenDto(LoginCommonFormDTO formDTO, String userId, UserWechatDTO userWechatDTO, String token) { int expire = jwtTokenProperties.getExpire(); TokenDto tokenDto = new TokenDto(); tokenDto.setApp(formDTO.getApp()); tokenDto.setClient(formDTO.getClient()); tokenDto.setUserId(userId); tokenDto.setOpenId(userWechatDTO.getWxOpenId()); tokenDto.setSessionKey(userWechatDTO.getSessionKey()); tokenDto.setUnionId(userWechatDTO.getUnionId()); tokenDto.setToken(token); tokenDto.setUpdateTime(System.currentTimeMillis()); tokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime()); cpUserDetailRedis.set(tokenDto, expire); logger.info("截止时间:" + DateUtils.format(jwtTokenUtils.getExpiration(token), "yyyy-MM-dd HH:mm:ss")); return token; } /** * @param formDTO * @return * @Author sun * @Description 单客户-政府端微信小程序登录 **/ @Override public UserTokenResultDTO workLogin(LoginFormDTO formDTO) { //1.调用epmet_third服务,校验appId是否有效以及是否授权,校验通过的调用微信API获取用户基本信息 WxLoginFormDTO resiLoginFormDTO = new WxLoginFormDTO(); resiLoginFormDTO.setAppId(formDTO.getAppId()); resiLoginFormDTO.setWxCode(formDTO.getWxCode()); Result result = epmetThirdFeignClient.resiAndWorkLogin(resiLoginFormDTO); if (!result.success()) { logger.error("工作端小程序登陆,调用epmet_third服务获取数据失败"); throw new RenException(result.getCode()); } UserWechatDTO userWechatDTO = result.getData(); //2.根据openid查询用户是否存在历史登陆信息 Result latestStaffWechat = epmetUserOpenFeignClient.getLatestStaffWechatLoginRecord(userWechatDTO.getWxOpenId()); if (!latestStaffWechat.success() || null == latestStaffWechat.getData()) { logger.error(String.format("没有获取到用户最近一次登录账户信息,code[%s],msg[%s]", EpmetErrorCode.PLEASE_LOGIN.getCode(), EpmetErrorCode.PLEASE_LOGIN.getMsg())); throw new RenException(EpmetErrorCode.PLEASE_LOGIN.getCode()); } StaffLatestAgencyResultDTO staffLatestAgencyResultDTO = latestStaffWechat.getData(); //3.记录staff_wechat this.savestaffwechat(staffLatestAgencyResultDTO.getStaffId(), userWechatDTO.getWxOpenId()); //4.记录登录日志 this.saveStaffLoginRecord(staffLatestAgencyResultDTO); //5.获取用户token String token = this.generateGovWxmpToken(staffLatestAgencyResultDTO.getStaffId()); //6.保存到redis this.saveLatestGovTokenDto(staffLatestAgencyResultDTO, userWechatDTO, token); UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO(); userTokenResultDTO.setToken(token); return userTokenResultDTO; } /** * @param userId openid * @return * @Author sun * @Description 保存微信和当前登录用户关系 **/ private Result savestaffwechat(String userId, String openid) { StaffWechatFormDTO staffWechatFormDTO = new StaffWechatFormDTO(); staffWechatFormDTO.setUserId(userId); staffWechatFormDTO.setWxOpenId(openid); return epmetUserOpenFeignClient.saveStaffWechat(staffWechatFormDTO); } /** * @param latestStaffWechatLoginDTO * @return * @Author sun * @Description 保存登录日志 **/ 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 = epmetUserOpenFeignClient.saveStaffLoginRecord(staffLoginAgencyRecordFormDTO); return staffLoginRecordResult; } /** * @Description 生成政府端小程序业务token Key * @Author sun **/ private String generateGovWxmpToken(String staffId) { Map map = new HashMap<>(); map.put("app", LoginConstant.APP_GOV); map.put("client", LoginConstant.CLIENT_WXMP); map.put("userId", staffId); String token = jwtTokenUtils.createToken(map); logger.info("app:" + LoginConstant.APP_GOV + ";client:" + LoginConstant.CLIENT_WXMP + ";userId:" + staffId + ";生成token[" + token + "]"); return token; } /** * @Description 保存tokenDto到redis * @Author sun **/ private void saveLatestGovTokenDto(StaffLatestAgencyResultDTO staffLatestAgency, UserWechatDTO userWechatDTO, 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(userWechatDTO.getWxOpenId()); govTokenDto.setSessionKey(userWechatDTO.getSessionKey()); govTokenDto.setUnionId(userWechatDTO.getUnionId()); govTokenDto.setToken(token); govTokenDto.setUpdateTime(System.currentTimeMillis()); govTokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime()); govTokenDto.setRootAgencyId(staffLatestAgency.getAgencyId()); govTokenDto.setCustomerId(staffLatestAgency.getCustomerId()); //设置部门,网格,角色列表 govTokenDto.setDeptIdList(getDeptartmentIdList(staffLatestAgency.getStaffId())); govTokenDto.setGridIdList(getGridIdList(staffLatestAgency.getStaffId())); CustomerAgencyDTO agency = getAgencyByStaffId(staffLatestAgency.getStaffId()); if (agency != null) { govTokenDto.setAgencyId(agency.getId()); govTokenDto.setRoleList(queryGovStaffRoles(staffLatestAgency.getStaffId(), agency.getId())); } govTokenDto.setOrgIdPath(getOrgIdPath(staffLatestAgency.getStaffId())); cpUserDetailRedis.set(govTokenDto, expire); logger.info("截止时间:" + DateUtils.format(jwtTokenUtils.getExpiration(token), "yyyy-MM-dd HH:mm:ss")); } public Set getDeptartmentIdList(String staffId) { try { Result> deptListResult = govOrgOpenFeignClient.getDepartmentListByStaffId(staffId); if (deptListResult.success()) { if (!CollectionUtils.isEmpty(deptListResult.getData())) { Set deptIdLists = deptListResult.getData().stream().map(dept -> dept.getDepartmentId()).collect(Collectors.toSet()); return deptIdLists; } } else { logger.error("登录:查询部门列表,远程调用返回错误:{}", deptListResult.getMsg()); } } catch (Exception e) { String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); logger.error("登录:查询部门列表异常:{}", errorStackTrace); } return null; } /** * 根据工作人员ID查询网格ID列表 * * @param staffId * @return */ public Set getGridIdList(String staffId) { Result> result = govOrgOpenFeignClient.listGridsbystaffid(staffId); if (!result.success()) { logger.error("登录:查询网格列表,远程调用返回错误:{}", result.getMsg()); return null; } else { List grids = result.getData(); return grids.stream().map(grid -> grid.getGridId()).collect(Collectors.toSet()); } } /** * 根据staffId查询所属的组织机构 * * @param staffId */ public CustomerAgencyDTO getAgencyByStaffId(String staffId) { Result result = govOrgOpenFeignClient.getAgencyByStaff(staffId); if (!result.success()) { logger.error("登录:查询登录人所属的机关OrgIdPath失败:{}", result.getMsg()); return null; } return result.getData(); } /** * 查询人员在某机关单位下的角色列表 * * @param staffId orgId */ public List queryGovStaffRoles(String staffId, String orgId) { StaffRoleFormDTO formDTO = new StaffRoleFormDTO(); formDTO.setStaffId(staffId); formDTO.setOrgId(orgId); Result> gridResult = epmetUserOpenFeignClient.getRolesOfStaff(formDTO); if (!CollectionUtils.isEmpty(gridResult.getData())) { //return gridResult.getData().stream().map(role -> role.getId()).collect(Collectors.toSet()); return ConvertUtils.sourceToTarget(gridResult.getData(), GovTokenDto.Role.class); } return null; } /** * 查询工作人员的OrgIdPath * * @param staffId * @return */ public String getOrgIdPath(String staffId) { Result result = govOrgOpenFeignClient.getAgencyByStaff(staffId); if (!result.success()) { logger.error("登录:查询登录人所属的机关OrgIdPath失败:{}", result.getMsg()); return null; } CustomerAgencyDTO agency = result.getData(); if (agency != null) { if ("0".equals(agency.getPid())) { // 顶级 return agency.getId(); } else { return agency.getPids().concat(":").concat(agency.getId()); } } return null; } }