package com.huaxu.service.impl; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.metadata.IPage; import com.huaxu.dao.LoginLogMapper; import com.huaxu.dao.UserMapper; import com.huaxu.dto.UserAuthDto; import com.huaxu.dto.UserDto; import com.huaxu.entity.LoginLog; import com.huaxu.entity.MenuEntity; import com.huaxu.entity.Org; import com.huaxu.entity.User; import com.huaxu.exception.ServiceException; import com.huaxu.model.LoginUser; import com.huaxu.model.Permission; import com.huaxu.model.ProgramItem; import com.huaxu.model.ResultStatus; import com.huaxu.security.mobile.MobileLoginAuthenticationToken; import com.huaxu.service.UserService; import com.huaxu.util.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.stereotype.Service; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import sun.misc.BASE64Encoder; import javax.servlet.http.HttpServletRequest; import java.util.*; import java.util.stream.Collectors; /** * 用户(User表)服务实现类 * * @author makejava * @since 2020-10-21 15:23:52 */ @Service("userService") @Slf4j public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Autowired private ConsumerTokenServices consumerTokenServices; @Autowired private RedisUtil redisUtil; @Autowired private HttpServletRequest request; @Autowired private ClientDetailsService clientDetailsService; @Autowired private AuthorizationServerTokenServices authorizationServerTokenServices; @Autowired private LoginLogMapper loginLogMapper; @Autowired private TokenStore tokenStore; @Value("${iot.url}") private String iotUrl; /** * 通过ID查询单条数据 * * @param id 主键 * @return 实例对象 */ @Override public User selectById(Integer id) { return this.userMapper.selectById(id); } /** * 查询所有 * * @return 实例对象的集合 */ @Override public List selectAll() { return this.userMapper.selectAll(); } /** * 根据条件查询 * * @return 实例对象的集合 */ @Override public List selectList(User user) { return this.userMapper.selectList(user); } /** * 新增数据 * * @param user 实例对象 * @return 实例对象 */ @Override public int insert(User user) { return this.userMapper.insert(user); } /** * 批量新增 * * @param users 实例对象的集合 * @return 生效的条数 */ @Override public int batchInsert(List users) { return this.userMapper.batchInsert(users); } /** * 修改数据 * * @param user 实例对象 * @return 实例对象 */ @Override public int update(User user) { return this.userMapper.update(user); } /** * 通过主键删除数据 * * @param id 主键 * @return 是否成功 */ @Override public int deleteById(Integer id) { return this.userMapper.deleteById(id); } /** * 查询总数据数 * * @return 数据总数 */ @Override public int count() { return this.userMapper.count(); } /** * 分页查询 * * @return 对象列表 */ @Override public IPage selectPage(User user, IPage page) { return this.userMapper.selectPage(page, user); } @Override public User findUser(User user) { List users = userMapper.selectList(user); if(users!=null&&users.size()>0){ return users.get(0); } return null; } public void offline(String clientId, Integer userId, Integer status) { Collection c = tokenStore.findTokensByClientIdAndUserName(clientId, String.valueOf(userId)); System.out.println(c.size()); for (OAuth2AccessToken oAuth2AccessToken : c) { String accessToken = oAuth2AccessToken.getValue(); String tokenKey = "offlineStatus:" + accessToken; redisUtil.setExpire(tokenKey.getBytes(), ByteArrayUtils.objectToBytes(status).get(), 1800);//15分钟过期 tokenStore.removeAccessToken(oAuth2AccessToken); } } @Override public String getRangeCode(String appId) { UserAuthDto userAuthDto = new UserAuthDto(); LoginUser currentUser = UserUtil.getCurrentUser(); Integer id = currentUser.getId(); String appSecret=userMapper.getAppSecret(appId); String uniqueUserID=userMapper.getUniqueUserID(id); if(uniqueUserID==null){ uniqueUserID=UUID.randomUUID().toString(); userMapper.updateUniqueUserID(id,uniqueUserID); } Random random = new Random(); String code=""; if(uniqueUserID!=null){ userAuthDto.setUniqId(uniqueUserID); userAuthDto.setMobile(currentUser.getPhoneNumber()); for (int i=0;i<6;i++) { code+=random.nextInt(10); } String key=code+"_"+appId+"_"+appSecret; redisUtil.set(key, JSONObject.toJSONString(userAuthDto)); redisUtil.setExpire(key,300); } return code; } @Override public String getUniqId(String appId, String appSecret, String code) { String key=code+"_"+appId+"_"+appSecret; return redisUtil.get(key); } @Override public UserAuthDto getUniqId(String appId, String encryptValue) { String appSecret = userMapper.getAppSecret(appId); if (StringUtils.isEmpty(appSecret)){ throw new ServiceException(ResultStatus.USER_AUTH_APPID_NOT_FOUND); } String key = null; try { // 验证加密的内容是否正确 key = DESUtil.decrypt(encryptValue,appSecret); // 截取里面的时间 String date = key.substring(key.lastIndexOf("_") + 1, key.length()); // 验证在5分钟之内是否是有效的加密 if (!DESUtil.verifyTime(Long.parseLong(date), 5)){ throw new ServiceException(ResultStatus.USER_AUTH_ENCRYPT_VALUE_VERIFY_ERROR); } } catch (Exception e) { throw new ServiceException(ResultStatus.USER_AUTH_ENCRYPT_VALUE_VERIFY_ERROR); } String value = redisUtil.get(key.substring(0, key.lastIndexOf("_"))); if (StringUtils.isEmpty(value)){ throw new ServiceException(ResultStatus.USER_AUTH_UNIQID_OR_CODE_ISNULL); } UserAuthDto dto = JSONObject.parseObject(value,UserAuthDto.class); dto.setMessage(key); return dto; } @Override public User chooseUser(User user) { LoginUser currentUser = UserUtil.getCurrentUser(); if(currentUser.getTenantId()!=null){ user.setPhone(currentUser.getPhoneNumber()); user.setTenantId(currentUser.getTenantId()); } user=findUser(user); UserDto userDto=new UserDto(); userDto.setPhone(user.getPhone()); ListprogramItems=new ArrayList<>(); Permission permission= findPermission(user); boolean returnFlag=false; if((permission!=null&&permission.getRoleState()==0)){ user.setEnableState("0"); returnFlag=true; } if((user.getTenantState()!=null&&user.getTenantState()==0)){ user.setEnableState("0"); returnFlag=true; } if((user.getCompanyOrgState()!=null&&user.getCompanyOrgState()==0)){ user.setEnableState("0"); returnFlag=true; } if((user.getDepartmentOrgState()!=null&&user.getDepartmentOrgState()==0)){ user.setEnableState("0"); returnFlag=true; } if("0".equals(user.getEnableState())){ returnFlag=true; } if(returnFlag){ return user; } offline("smart-city-v2",user.getId(),1); getDataPermission(permission.getPermissionType(),user,programItems); //角色必须是ROLE_开头,其余的是用户功能权限 /* Integer permissionType = permissionList.get(0).getPermissionType(); List programItemList = newArrayList(); //获取数据权限 //分配功能权限 if (permissionList.size() > 0) { for (Permission permission : permissionList) { if(!StringUtils.equals("",permission.getPermission())){ GrantedAuthority authority1 = new SimpleGrantedAuthority(permission.getPermission()); grantedAuthorities.add(authority1); } } } */ Set grantedAuthorities = new HashSet<>(); OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication(); LoginUser loginUser = (LoginUser) oAuth2Authentication.getPrincipal(); //放置系统级菜单对应用户appid loginUser.setAppIds(findUserFirstMenu(user.getTenantId(),user.getId(),user.getUserType())); loginUser.setProgramItemList(programItems); loginUser.setName(user.getUsername()); loginUser.setId(user.getId()); loginUser.setUsername(user.getUsername()); loginUser.setCompanyId(user.getCompanyOrgId()); loginUser.setDepartmentId(user.getDeptOrgId()); loginUser.setTenantId(user.getTenantId()); loginUser.setType(user.getUserType()); loginUser.setPhoneNumber(user.getPhone()); loginUser.setAuthorities(grantedAuthorities); loginUser.setPermissonType(permission.getPermissionType()); loginUser.setRoleId(permission.getRoleId()); loginUser.setLoginToken(UUID.randomUUID().toString()); MobileLoginAuthenticationToken authenticationTokenReslut = new MobileLoginAuthenticationToken(loginUser,oAuth2Authentication.getCredentials(),loginUser.getAuthorities()); authenticationTokenReslut.setDetails(oAuth2Authentication.getDetails()); OAuth2Authentication oAuth2AuthenticationNew = new OAuth2Authentication(oAuth2Authentication.getOAuth2Request(), authenticationTokenReslut); OAuth2AccessToken accessToken = authorizationServerTokenServices.createAccessToken(oAuth2AuthenticationNew); //可以加一个映射表 String iotToken=getLoginIotToken(user.getIotPhoneNumber()); if(iotToken!=null){ String iotTokenKey = "iotToken:" + accessToken.getValue(); redisUtil.set(iotTokenKey,iotToken); redisUtil.setExpire(iotTokenKey,60*30); } insertLoginLog(loginUser,"登录"); user.setToken(accessToken.getValue()); return user; } public String getLoginIotToken(String account){ log.info("begin IotService login account={}",account); String url = iotUrl + "/api/integration/auth/login"; RestTemplate restTemplate = new RestTemplate(); if(account==null){ return null; } MultiValueMap map= new LinkedMultiValueMap(); map.add("source","rmcp"); map.add("code",new BASE64Encoder().encode(account.getBytes())); HttpHeaders headers = new HttpHeaders(); HttpEntity> request = new HttpEntity<>(map,headers); ResponseEntity responseEntity = restTemplate.postForEntity(url, request, JSONObject.class); log.info("responseEntity ={}", JSONObject.toJSONString(responseEntity)); if(responseEntity !=null && responseEntity.getStatusCode() == HttpStatus.OK){ JSONObject jsonObject = responseEntity.getBody(); if(jsonObject != null){ if(jsonObject.getInteger("status")==0){ String token = jsonObject.getString("data"); log.info("IotService getLoginIotToken success res={}",token); return token; }else { log.info("IotService getLoginIotToken fail"); return null; } }else { return null; } } return null; } private void getDataPermission(int permissionType,User user, List programItemList){ ProgramItem defaultProgramItem=new ProgramItem(); defaultProgramItem.setOrgCompanyId(-999); defaultProgramItem.setOrgDeparmtmentId(-999); programItemList.add(defaultProgramItem); if(permissionType==1){ ProgramItem programItem=new ProgramItem(); programItem.setOrgId(user.getCompanyOrgId()); programItem.setOrgCompanyId(user.getCompanyOrgId()); programItemList.add(programItem); }else if(permissionType==2){ Map> allOrgs = getAllOrgs(null,user.getTenantId()); ProgramItem programItem=new ProgramItem(); programItem.setOrgId(user.getCompanyOrgId()); programItem.setOrgCompanyId(user.getCompanyOrgId()); getOrg(user.getCompanyOrgId(),allOrgs,programItemList); programItemList.add(programItem); }else if(permissionType==3&&user.getDeptOrgId()!=null){ ProgramItem programItem=new ProgramItem(); programItem.setOrgId(user.getDeptOrgId()); programItem.setOrgDeparmtmentId(user.getDeptOrgId()); programItemList.add(programItem); }else if(permissionType==4&&user.getDeptOrgId()!=null) { ProgramItem programItem=new ProgramItem(); programItem.setOrgId(user.getDeptOrgId()); programItem.setOrgDeparmtmentId(user.getDeptOrgId()); Map> allOrgs = getAllOrgs("department",user.getTenantId()); getOrg(user.getDeptOrgId(),allOrgs,programItemList); programItemList.add(programItem); }else if(permissionType==5){ programItemList.addAll( userMapper.findOrgRole(user)); programItemList.forEach(programItem -> { if("company".equals(programItem.getNewType())){ programItem.setOrgCompanyId(programItem.getOrgId()); }else if("department".equals(programItem.getNewType())){ programItem.setOrgDeparmtmentId(programItem.getOrgId()); } programItem.setCode(user.getTenantId()); }); } } private Map> getAllOrgs(String orgType,String tenantId){ Org org=new Org(); org.setOrgType(orgType); org.setTenantId(tenantId); List orgs = userMapper.findOrgs(org); Map> collect = orgs.stream(). collect(Collectors.groupingBy(d -> d.getParentOrgId())); return collect; }; public void getOrg(Integer id, Map> collect,ListprogramItemList){ List orgs = collect.get(id); if(orgs!=null){ orgs.forEach(org->{ ProgramItem item=new ProgramItem(); item.setOrgId(org.getId()); if("company".equals(org.getOrgType())){ item.setOrgCompanyId(org.getId()); }else if("department".equals(org.getOrgType())){ item.setOrgDeparmtmentId(org.getId()); } item.setCode(org.getTenantId()); programItemList.add(item); getOrg(org.getId(),collect,programItemList); }); } } private Permission findPermission(User user){ List permissionList = userMapper.findPermission(user); if(permissionList.size()==0){ return null; } return permissionList.get(0); } private List findUserFirstMenu(String tenantId, Integer userId,String userType){ List menuEntities = userMapper.findUserFirstMenu(tenantId, userId); switch (userType) { // case "1"://超级管理员查询所有系统菜单 // menuEntities = menuMapper.findAllFirstMenu(); // break; // case "2"://普通用户按角色查询租户菜单 // menuEntities = menuMapper.findUserFirstMenu(currentUser.getTenantId(),userId); // break; case "-9999"://超级管理员查询所有系统菜单 menuEntities = userMapper.findAllFirstMenu(); break; case "-999"://租户管理员查询租户菜单 menuEntities = userMapper.findTenantFirstMenu(tenantId); break; default: //其他租户用户暂时不区分类型 menuEntities = userMapper.findUserFirstMenu(tenantId,userId); break; } ListappIds=new ArrayList<>(); menuEntities.forEach(menuEntity -> { appIds.add(menuEntity.getAppId()); }); return appIds; } @Override public boolean logOut(String token) { boolean flag=consumerTokenServices.revokeToken(token); insertLoginLog(UserUtil.getCurrentUser(),"登出"); return flag; } /** * 新增注册数据 * @author yjy * @param user 实例对象 * @return 影响行数 */ @Override public int insertRegister(User user) { return this.userMapper.insertRegister(user); } private void insertLoginLog(LoginUser loginUser,String type){ LoginLog loginLog=new LoginLog(); loginLog.setName(loginUser.getName()); loginLog.setPhone(loginUser.getPhoneNumber()); loginLog.setTenantId(loginUser.getTenantId()); loginLog.setCompanyId(loginUser.getCompanyId()); loginLog.setDepartmentId(loginUser.getDepartmentId()); loginLog.setType(type); loginLog.setCreateTime(new Date()); loginLog.setLoginIp(Util.getIpAddr(request)); loginLogMapper.insert(loginLog); } }