package com.chinasnow.framework.interrector;/*
类名称:UsersDataFilter
功能描述:
作者:
创建时间:2021/4/14 16:07
*/
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chinasnow.framework.annotation.FilterData;
import com.chinasnow.framework.auth.jwt.JWTUtil;
import com.chinasnow.framework.protocal.DataResponse;
import com.chinasnow.framework.util.HttpSSOUtil;
import com.chinasnow.framework.util.SpringContextUtil1;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 公共切面,根据登录人过滤有效信息
*/
@Component
@Aspect
public class UsersDataFilter {
/**
* 切面表达式,切到各个控制层的get方法中;
*/
@Pointcut("execution( * com.chinasnow.sal.controller.*.get(..))")
public void getPoint() {
}
// /**
// * 环绕切面,在方法执行前后进行操做;
// * @param proceedingJoinPoint 操做元素
// * @return
// * @throws Throwable
// */
// @Around("@annotation(filterData)")
// public Object globalAround(ProceedingJoinPoint proceedingJoinPoint, FilterData filterData) throws Throwable {
// //获取过滤字符串
// String filterCode = filterData.filterCode();
// //过滤后符合条件的数据
// List<Map> resultData=new LinkedList<>();
// //切面切入的方法对应的参数
// Object[] args = proceedingJoinPoint.getArgs();
// // 由于切入的切点是list,所以第一个参数为page
// Page argPage = (Page) args[0];
//
// // 获取list执行后的结果
// Object proceed = proceedingJoinPoint.proceed();
//
// // 将list的结果按照DataResponse进行拆分;并且格式化日期
// Map requestDataMap = JSON.parseObject(JSON.toJSONStringWithDateFormat(proceed, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat), Map.class);
//
// Map dataMap = JSON.parseObject(requestDataMap.get("data").toString(), Map.class);
// // 放入过滤函数进行过滤
// resultData = filterUserDataMap(argPage, proceedingJoinPoint, filterCode, dataMap);
//
// // 将过滤后的数据封装到record中;
// dataMap.put("records", resultData);
// //将data封装到返回类型中
// requestDataMap.put("data", dataMap);
// DataResponse dataResponse = JSON.parseObject(JSON.toJSONString(requestDataMap), DataResponse.class);
// return dataResponse;
// }
/**
*
* @param page 分页条件
* @param proceedingJoinPoint 切点
* @param filterCode 过滤字符串
* @param paramMap 传入需要过滤的数据
* @return
* @throws Throwable
*/
public List<Map> filterUserDataMap(Page page,ProceedingJoinPoint proceedingJoinPoint, String filterCode,Map paramMap) throws Throwable {
long size = page.getSize();
long current = page.getCurrent();
//过滤数据集合
List<Map> resultData=new LinkedList<>();
boolean requestFlag=true;
while (requestFlag){
// 拿取到list数据
List<Map> mapList = JSON.parseArray(paramMap.get("records").toString(), Map.class);
// 如果过滤数据集合小于分页页码并且查询出来的数据不为空,就进行过滤并且将数据加入到过滤数据集合中
if (resultData.size()<size&&mapList.size()>0){
// 获取登录用户的信息
Map<String, Object> userInfo = getUserInfoBySSO();
// 获取登录用户的userid
String userId = userInfo.get("name").toString();
//获取登录用户角色
String roles = userInfo.get("roles").toString();
// 利用stream流对数据进行过滤:如果该数据有责任人这个选项并且登录用户不为销售管理员,则对数据进行过滤;
// 过滤规则: 数据的责任人和登录用户相同;
List<Map> filterData = mapList.stream().filter(map -> {
boolean flag = true;
// 如果登录用户的角色是销售管理员则给予放行;如果查看客户线索平台给予放行;
if (StringUtils.contains(roles, "销售管理员") || map.get("leadsSourceId") != null) {
return true;
}
// 如果查看的list中拥有负责人的字段并且负责人的字段为空,则过滤掉
if (map.get(filterCode)==null){
flag=false;
}
if (map.get(filterCode)!=null && !(StringUtils.contains(roles, "销售管理员"))) {
if ( !StringUtils.equals(map.get(filterCode).toString(), userId)) {
flag = false;
}
}
return flag;
}).collect(Collectors.toList());
resultData.addAll(filterData);
}else {
break;
}
//分页自增
current++;
Page argPage = (Page) proceedingJoinPoint.getArgs()[0];
argPage.setCurrent(current);
// 获取list执行后的结果
Object proceed = proceedingJoinPoint.proceed();
// 将list的结果按照DataResponse进行拆分;并且格式化日期
Map requestDataMap = JSON.parseObject(JSON.toJSONStringWithDateFormat(proceed, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat), Map.class);
paramMap = JSON.parseObject(requestDataMap.get("data").toString(), Map.class);
}
return resultData;
}
/**
* get方法公共切面,去掉mybatisplus自动填充的字段信息,解决mybatisplus修改自动填充不生效
* @param proceedingJoinPoint
* @return 1
* @throws Throwable
*/
@Around("getPoint()")
public Object globalGetAround(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
Object proceed = proceedingJoinPoint.proceed();
Map getMap = JSON.parseObject(JSON.toJSONStringWithDateFormat(proceed,"yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat), Map.class);
Map dataMap = JSON.parseObject(getMap.get("data").toString(), Map.class);
dataMap.remove("assignedBy");
dataMap.remove("assignedUserId");
dataMap.remove("modifyBy");
dataMap.remove("modifiedBy");
dataMap.remove("dateModified");
dataMap.remove("modifyDate");
getMap.put("data",dataMap);
DataResponse dataResponse = JSON.parseObject(JSON.toJSONString(getMap), DataResponse.class);
return dataResponse;
}
/**
* 从sso获取登录用户的信息
*
* @return 人员信息
*/
private Map<String, Object> getUserInfoBySSO() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest(); // 获取到http请求
//从request请求中获取到token
String token = request.getHeader("Cool-SSO-Token");
//获取登录用户信息
Map<String, Object> userInfo = HttpSSOUtil.getUserInfo(token);
return userInfo;
}
}
自定义注解
@Retention(RetentionPolicy.RUNTIME) //运行时作用域,会存在jvm中运行
@Target(value = {ElementType.METHOD}) // 用来描述方法
@Documented // 用来做为标识;是否生成javadoc
public @interface FilterData {
//用来过滤的字段
String filterCode() default "assignedUserId" ;
}