forked from rongchao/epmet-cloud-rizhao
23 changed files with 692 additions and 3 deletions
@ -0,0 +1,170 @@ |
|||
package com.epmet.controller; |
|||
|
|||
import cn.hutool.core.bean.BeanUtil; |
|||
import com.epmet.commons.tools.constant.AppClientConstant; |
|||
import com.epmet.commons.tools.constant.ServiceConstant; |
|||
import com.epmet.commons.tools.exception.EpmetErrorCode; |
|||
import com.epmet.commons.tools.exception.RenException; |
|||
import com.epmet.commons.tools.feign.ResultDataResolver; |
|||
import com.epmet.commons.tools.redis.RedisKeys; |
|||
import com.epmet.commons.tools.redis.RedisUtils; |
|||
import com.epmet.commons.tools.security.password.PasswordUtils; |
|||
import com.epmet.commons.tools.utils.ConvertUtils; |
|||
import com.epmet.commons.tools.utils.Result; |
|||
import com.epmet.commons.tools.validator.ValidatorUtils; |
|||
import com.epmet.dto.CustomerStaffDTO; |
|||
import com.epmet.dto.form.LoginByPassWordFormDTO; |
|||
import com.epmet.dto.form.RootOrgListByStaffIdFormDTO; |
|||
import com.epmet.dto.form.StaffBasicInfoByMobileFromDTO; |
|||
import com.epmet.dto.result.BasicInfoResultDTO; |
|||
import com.epmet.dto.result.StaffOrgsResultDTO; |
|||
import com.epmet.dto.result.UserTokenResultDTO; |
|||
import com.epmet.feign.EpmetUserFeignClient; |
|||
import com.epmet.feign.EpmetUserOpenFeignClient; |
|||
import com.epmet.feign.GovOrgOpenFeignClient; |
|||
import com.epmet.redis.CaptchaRedis; |
|||
import com.epmet.redis.IcLoginTicketCacheBean; |
|||
import com.epmet.service.IcLoginService; |
|||
import org.apache.commons.collections4.CollectionUtils; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.springframework.beans.BeanUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.RequestBody; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
import javax.validation.constraints.NotBlank; |
|||
import java.beans.IntrospectionException; |
|||
import java.lang.reflect.InvocationTargetException; |
|||
import java.util.*; |
|||
|
|||
@RestController |
|||
@RequestMapping("ic") |
|||
public class IcLoinController implements ResultDataResolver { |
|||
|
|||
public static final long IC_LOGIN_TICKET_EXPIRE_SECONDS = 2 * 60l; |
|||
|
|||
@Autowired |
|||
private EpmetUserFeignClient epmetUserFeignClient; |
|||
|
|||
@Autowired |
|||
private GovOrgOpenFeignClient govOrgOpenFeignClient; |
|||
|
|||
@Autowired |
|||
private CaptchaRedis captchaRedis; |
|||
|
|||
@Autowired |
|||
private IcLoginService icLoginService; |
|||
|
|||
@Autowired |
|||
private RedisUtils redisUtils; |
|||
|
|||
/** |
|||
* @description 基层治理赋能平台-根据手机号密码获取组织列表 |
|||
* |
|||
* @param input |
|||
* @return |
|||
* @author wxz |
|||
* @date 2021.10.25 09:56:33 |
|||
*/ |
|||
@PostMapping("getmyorgsbypassword") |
|||
public Result<HashMap<String, Object>> getMyOrgsByPassword(@RequestBody LoginByPassWordFormDTO input) { |
|||
ValidatorUtils.validateEntity(input, LoginByPassWordFormDTO.IcGetOrgsByPwdGroup.class); |
|||
String captcha = input.getCaptcha(); |
|||
String mobile = input.getMobile(); |
|||
String password = input.getPassword(); |
|||
String uuid = input.getUuid(); |
|||
|
|||
// 图片验证码
|
|||
String captchaInCache = captchaRedis.getIcLoginCaptcha(uuid); |
|||
if (StringUtils.isBlank(captchaInCache) || !captcha.equals(captchaInCache)) { |
|||
throw new RenException(EpmetErrorCode.ERR10019.getCode()); |
|||
} |
|||
|
|||
// 获取用户信息
|
|||
Result<List<CustomerStaffDTO>> staffResult = epmetUserFeignClient.checkCustomerStaff(mobile); |
|||
List<CustomerStaffDTO> staffList = getResultDataOrThrowsException(staffResult, ServiceConstant.EPMET_USER_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "【基层治理平台登录】获取用户信息失败"); |
|||
if (CollectionUtils.isEmpty(staffList)) { |
|||
throw new RenException(EpmetErrorCode.ERR10003.getCode()); |
|||
} |
|||
|
|||
CustomerStaffDTO staffInfo = staffList.get(0); |
|||
|
|||
if (!PasswordUtils.matches(password, staffInfo.getPassword())) { |
|||
throw new RenException(EpmetErrorCode.ERR10004.getCode()); |
|||
} |
|||
|
|||
String staffId = staffInfo.getUserId(); |
|||
|
|||
// 查询跟组织列表
|
|||
RootOrgListByStaffIdFormDTO orgListForm = new RootOrgListByStaffIdFormDTO(); |
|||
orgListForm.setStaffId(staffId); |
|||
Result<List<StaffOrgsResultDTO>> orgListResult = govOrgOpenFeignClient.getStaffOrgListByStaffId(orgListForm); |
|||
List<StaffOrgsResultDTO> orgs = getResultDataOrThrowsException(orgListResult, ServiceConstant.GOV_ORG_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "【基层治理平台登录】根据staffId查询所属客户跟组织列表失败"); |
|||
|
|||
// 生成登录票据
|
|||
String ticket = UUID.randomUUID().toString().replace("-", ""); |
|||
IcLoginTicketCacheBean ticketCacheBean = new IcLoginTicketCacheBean(); |
|||
ticketCacheBean.setMobile(mobile); |
|||
ticketCacheBean.setStaffId(staffId); |
|||
cacheTicket(ticket, ticketCacheBean); |
|||
|
|||
HashMap<String, Object> resultMap = new HashMap<>(); |
|||
resultMap.put("staffId", staffId); |
|||
resultMap.put("ticket", ticket); |
|||
resultMap.put("orgs", orgs); |
|||
|
|||
return new Result<HashMap<String, Object>>().ok(resultMap); |
|||
} |
|||
|
|||
/** |
|||
* @description IC登录 |
|||
* |
|||
* @param input |
|||
* @return |
|||
* @author wxz |
|||
* @date 2021.10.25 21:14:22 |
|||
*/ |
|||
@PostMapping("login") |
|||
public Result<UserTokenResultDTO> login(@RequestBody LoginByPassWordFormDTO input) { |
|||
ValidatorUtils.validateEntity(input, LoginByPassWordFormDTO.IcLoginGroup.class); |
|||
String ticket = input.getTicket(); |
|||
String orgId = input.getOrgId(); |
|||
String staffId = input.getStaffId(); |
|||
|
|||
// ticket校验
|
|||
IcLoginTicketCacheBean ticketCache = getTicketCache(ticket); |
|||
if (ticketCache == null || !ticketCache.getStaffId().equals(staffId)) { |
|||
// ticket&userId不对应
|
|||
throw new RenException(EpmetErrorCode.ERR10008.getCode()); |
|||
} |
|||
|
|||
UserTokenResultDTO tokenInfo = icLoginService.login(staffId, orgId); |
|||
return new Result<UserTokenResultDTO>().ok(tokenInfo); |
|||
} |
|||
|
|||
private void cacheTicket(String ticket, IcLoginTicketCacheBean cacheBean) { |
|||
Map<String, Object> stringObjectMap = BeanUtil.beanToMap(cacheBean, false, true); |
|||
redisUtils.hMSet(RedisKeys.loginTicket(AppClientConstant.APP_IC, ticket), stringObjectMap, IC_LOGIN_TICKET_EXPIRE_SECONDS); |
|||
} |
|||
|
|||
/** |
|||
* @description 从缓存中取出ticket,并删除 |
|||
* |
|||
* @param ticket |
|||
* @return |
|||
* @author wxz |
|||
* @date 2021.10.26 08:58:27 |
|||
*/ |
|||
private IcLoginTicketCacheBean getTicketCache(String ticket) { |
|||
String key = RedisKeys.loginTicket(AppClientConstant.APP_IC, ticket); |
|||
Map<String, Object> map = redisUtils.hGetAll(key); |
|||
if (CollectionUtils.sizeIsEmpty(map)) { |
|||
return null; |
|||
} |
|||
redisUtils.expire(key, 0); |
|||
return BeanUtil.mapToBean(map, IcLoginTicketCacheBean.class, false); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,9 @@ |
|||
package com.epmet.redis; |
|||
|
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
public class IcLoginTicketCacheBean { |
|||
private String staffId; |
|||
private String mobile; |
|||
} |
@ -0,0 +1,9 @@ |
|||
package com.epmet.service; |
|||
|
|||
import com.epmet.dto.result.UserTokenResultDTO; |
|||
|
|||
public interface IcLoginService { |
|||
|
|||
|
|||
UserTokenResultDTO login(String staffId, String orgId); |
|||
} |
@ -0,0 +1,183 @@ |
|||
package com.epmet.service.impl; |
|||
|
|||
import cn.hutool.core.bean.BeanUtil; |
|||
import com.epmet.auth.constants.AuthOperationConstants; |
|||
import com.epmet.common.token.constant.LoginConstant; |
|||
import com.epmet.commons.rocketmq.messages.LoginMQMsg; |
|||
import com.epmet.commons.tools.constant.AppClientConstant; |
|||
import com.epmet.commons.tools.constant.ServiceConstant; |
|||
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.feign.ResultDataResolver; |
|||
import com.epmet.commons.tools.redis.RedisKeys; |
|||
import com.epmet.commons.tools.redis.RedisUtils; |
|||
import com.epmet.commons.tools.security.dto.IcTokenDto; |
|||
import com.epmet.commons.tools.utils.CpUserDetailRedis; |
|||
import com.epmet.commons.tools.utils.IpUtils; |
|||
import com.epmet.commons.tools.utils.Result; |
|||
import com.epmet.dto.CustomerAgencyDTO; |
|||
import com.epmet.dto.form.SystemMsgFormDTO; |
|||
import com.epmet.dto.result.DepartmentListResultDTO; |
|||
import com.epmet.dto.result.GridByStaffResultDTO; |
|||
import com.epmet.dto.result.UserTokenResultDTO; |
|||
import com.epmet.feign.EpmetMessageOpenFeignClient; |
|||
import com.epmet.feign.GovOrgOpenFeignClient; |
|||
import com.epmet.jwt.JwtTokenProperties; |
|||
import com.epmet.jwt.JwtTokenUtils; |
|||
import com.epmet.service.IcLoginService; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.util.CollectionUtils; |
|||
import org.springframework.web.context.request.RequestContextHolder; |
|||
import org.springframework.web.context.request.ServletRequestAttributes; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import java.util.*; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@Service |
|||
@Slf4j |
|||
public class IcLoginServiceImpl implements IcLoginService, ResultDataResolver { |
|||
|
|||
@Autowired |
|||
private JwtTokenUtils jwtTokenUtils; |
|||
|
|||
@Autowired |
|||
private RedisUtils redisUtils; |
|||
|
|||
@Autowired |
|||
private CpUserDetailRedis cpUserDetailRedis; |
|||
|
|||
@Autowired |
|||
private JwtTokenProperties jwtTokenProperties; |
|||
|
|||
@Autowired |
|||
private EpmetMessageOpenFeignClient messageOpenFeignClient; |
|||
|
|||
@Autowired |
|||
private GovOrgOpenFeignClient govOrgOpenFeignClient; |
|||
|
|||
@Autowired |
|||
private ThirdLoginServiceImpl thirdLoginService; |
|||
|
|||
@Override |
|||
public UserTokenResultDTO login(String staffId, String orgId) { |
|||
String app = AppClientConstant.APP_IC; |
|||
String client = AppClientConstant.CLIENT_WEB; |
|||
|
|||
// 1.获取用户token
|
|||
String token = this.generateIcToken(staffId, app, client); |
|||
|
|||
Result<CustomerAgencyDTO> agencyResult = govOrgOpenFeignClient.getAgencyById(orgId); |
|||
CustomerAgencyDTO agencyInfo = getResultDataOrThrowsException(agencyResult, ServiceConstant.GOV_ORG_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "【IC平台登录】获取组织信息失败"); |
|||
|
|||
// 2.缓存token
|
|||
cacheToken(app, client, staffId, token, orgId, agencyInfo.getCustomerId()); |
|||
|
|||
UserTokenResultDTO userTokenResultDTO = new UserTokenResultDTO(); |
|||
userTokenResultDTO.setToken(token); |
|||
userTokenResultDTO.setCustomerId(agencyInfo.getCustomerId()); |
|||
|
|||
//7.发送登录事件
|
|||
try { |
|||
sendLoginEvent(staffId, app, client); |
|||
} catch (RenException e) { |
|||
log.error(e.getInternalMsg()); |
|||
} catch (Exception e) { |
|||
log.error("【工作端workLogin登录】发送登录事件失败,程序继续执行。"); |
|||
} |
|||
|
|||
return userTokenResultDTO; |
|||
} |
|||
|
|||
/** |
|||
* @param staffId |
|||
* @return |
|||
* @description 生成Ic平台的Token |
|||
* @author wxz |
|||
* @date 2021.10.26 13:42:36 |
|||
*/ |
|||
private String generateIcToken(String staffId, String app, String client) { |
|||
Map<String, Object> map = new HashMap<>(); |
|||
map.put("app", app); |
|||
map.put("client", client); |
|||
map.put("userId", staffId); |
|||
String token = jwtTokenUtils.createToken(map); |
|||
return token; |
|||
} |
|||
|
|||
/** |
|||
* @param userId |
|||
* @param fromApp |
|||
* @param fromClient |
|||
* @return |
|||
* @description 发布登录时间 |
|||
* @author wxz |
|||
* @date 2021.10.26 13:45:59 |
|||
*/ |
|||
private void sendLoginEvent(String userId, String fromApp, String fromClient) { |
|||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); |
|||
|
|||
LoginMQMsg loginMQMsg = new LoginMQMsg(); |
|||
loginMQMsg.setUserId(userId); |
|||
loginMQMsg.setLoginTime(new Date()); |
|||
loginMQMsg.setIp(IpUtils.getIpAddr(request)); |
|||
loginMQMsg.setFromApp(fromApp); |
|||
loginMQMsg.setFromClient(fromClient); |
|||
|
|||
SystemMsgFormDTO form = new SystemMsgFormDTO(); |
|||
form.setMessageType(AuthOperationConstants.LOGIN); |
|||
form.setContent(loginMQMsg); |
|||
messageOpenFeignClient.sendSystemMsgByMQ(form); |
|||
} |
|||
|
|||
/** |
|||
* @description 缓存token到redis |
|||
* |
|||
* @param app |
|||
* @param client |
|||
* @param userId |
|||
* @param token |
|||
* @param rootAgencyId |
|||
* @return |
|||
* @author wxz |
|||
* @date 2021.10.26 14:19:07 |
|||
*/ |
|||
private void cacheToken(String app, |
|||
String client, |
|||
String userId, |
|||
String token, |
|||
String rootAgencyId, |
|||
String customerId) { |
|||
|
|||
IcTokenDto tokenDto = new IcTokenDto(); |
|||
int expire = jwtTokenProperties.getExpire(); |
|||
long expireTime = jwtTokenUtils.getExpiration(token).getTime(); |
|||
|
|||
tokenDto.setApp(app); |
|||
tokenDto.setClient(client); |
|||
tokenDto.setUserId(userId); |
|||
tokenDto.setToken(token); |
|||
tokenDto.setExpireTime(expireTime); |
|||
tokenDto.setRootAgencyId(rootAgencyId); |
|||
tokenDto.setCustomerId(customerId); |
|||
|
|||
//设置部门,网格,角色列表
|
|||
tokenDto.setDeptIdList(thirdLoginService.getDeptartmentIdList(userId)); |
|||
tokenDto.setGridIdList(thirdLoginService.getGridIdList(userId)); |
|||
CustomerAgencyDTO agency = thirdLoginService.getAgencyByStaffId(userId); |
|||
if (agency != null) { |
|||
tokenDto.setAgencyId(agency.getId()); |
|||
tokenDto.setRoleList(thirdLoginService.queryGovStaffRoles(userId, agency.getId())); |
|||
} |
|||
tokenDto.setOrgIdPath(thirdLoginService.getOrgIdPath(userId)); |
|||
|
|||
String key = RedisKeys.getCpUserKey(app, client, userId); |
|||
Map<String, Object> map = BeanUtil.beanToMap(tokenDto, false, true); |
|||
redisUtils.hMSet(key, map, expire); |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,81 @@ |
|||
package com.epmet.commons.tools.security.dto; |
|||
|
|||
import com.alibaba.fastjson.JSON; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.util.List; |
|||
import java.util.Set; |
|||
|
|||
/** |
|||
* @Description ic平台token |
|||
* @author wxz |
|||
* @date 2021.10.26 13:58:03 |
|||
*/ |
|||
@Data |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class IcTokenDto extends BaseTokenDto { |
|||
|
|||
/** |
|||
* 当前登录的组织id(顶级) |
|||
*/ |
|||
private String rootAgencyId; |
|||
|
|||
/** |
|||
* 当前用户所属的机关单位id |
|||
*/ |
|||
private String agencyId; |
|||
|
|||
/** |
|||
* 当前网格对应的组织结构id的全路径用:隔开 |
|||
*/ |
|||
private String orgIdPath; |
|||
|
|||
/** |
|||
* 当前所在网格id |
|||
*/ |
|||
private String gridId; |
|||
|
|||
/*** |
|||
* 所在网格列表 |
|||
*/ |
|||
private Set<String> gridIdList; |
|||
|
|||
/** |
|||
* 部门id列表 |
|||
*/ |
|||
private Set<String> deptIdList; |
|||
|
|||
/** |
|||
* 功能权限列表,实际上是gov_staff => staff_role => role_operation查询到的operationKey |
|||
*/ |
|||
private Set<String> permissions; |
|||
|
|||
/** |
|||
* 角色ID列表 |
|||
*/ |
|||
private List<GovTokenDto.Role> roleList; |
|||
|
|||
/** |
|||
* 过期时间戳 |
|||
*/ |
|||
private Long expireTime; |
|||
|
|||
@Data |
|||
public static class Role { |
|||
|
|||
private String id; |
|||
private String roleKey; |
|||
private String roleName; |
|||
|
|||
public Role() { |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public String toString() { |
|||
return JSON.toJSONString(this); |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
package com.epmet.dto.form; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
/** |
|||
* @Description 客户id查询跟组织列表 |
|||
* @author wxz |
|||
* @date 2021.10.25 14:53:09 |
|||
*/ |
|||
@Data |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
public class RootOrgListByStaffIdFormDTO { |
|||
|
|||
private String staffId; |
|||
|
|||
} |
@ -0,0 +1,18 @@ |
|||
diff a/epmet-module/gov-org/gov-org-server/src/main/resources/mapper/CustomerAgencyDao.xml b/epmet-module/gov-org/gov-org-server/src/main/resources/mapper/CustomerAgencyDao.xml (rejected hunks) |
|||
@@ -539,4 +539,15 @@ |
|||
AND CUSTOMER_ID = #{customerId} |
|||
</select> |
|||
|
|||
+ <select id="getStaffOrgListByStaffId" resultType="com.epmet.dto.result.StaffOrgsResultDTO"> |
|||
+ select ca.id AS rootAgencyId, |
|||
+ ca.ORGANIZATION_NAME AS rootAgencyName, |
|||
+ ca.CUSTOMER_ID AS customerId |
|||
+ from customer_staff_agency csa |
|||
+ inner join customer_agency ca |
|||
+ on (csa.DEL_FLAG = 0 and ca.DEL_FLAG = 0 and csa.AGENCY_ID = ca.ID) |
|||
+ inner join customer_agency root on (root.DEL_FLAG = 0 and ca.CUSTOMER_ID = root.CUSTOMER_ID and root.PID = '0') |
|||
+ where csa.USER_ID = #{staffId} |
|||
+ </select> |
|||
+ |
|||
</mapper> |
|||
\ No newline at end of file |
@ -0,0 +1,23 @@ |
|||
package com.epmet.dto.form; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import javax.validation.constraints.NotBlank; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* @Description |
|||
* @author wxz |
|||
* @date 2021.10.25 14:00:11 |
|||
*/ |
|||
@Data |
|||
public class StaffBasicInfoByMobileFromDTO implements Serializable { |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
@NotBlank(message = "缺少手机号码信息") |
|||
private String mobile; |
|||
|
|||
@NotBlank(message = "缺少密码") |
|||
private String password; |
|||
|
|||
} |
Loading…
Reference in new issue