/**
* Copyright © 2015-2020 JeePlus All rights reserved.
*/
package com.jeeplus.common.service;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.jeeplus.common.persistence.BaseEntity;
import com.jeeplus.common.utils.JedisUtils;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.modules.sys.dao.OfficeDao;
import com.jeeplus.modules.sys.entity.Office;
import com.jeeplus.modules.sys.entity.Role;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.service.OfficeService;
import com.jeeplus.modules.sys.utils.UserUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Service基类
*
* @author jeeplus
* @version 2014-05-16
*/
@Transactional(readOnly = true)
public abstract class BaseService {
public static final String BRANCH_OFFICE_PREFIX = "BRANCH_OFFICE_";
public static final String CHILD_OFFICE_PREFIX = "CHILD_OFFICE_";
/**
* 日志对象
*/
protected Logger logger = LoggerFactory.getLogger(getClass());
/**
* 数据范围过滤
*
* @param user 当前用户对象,通过“entity.getCurrentUser()”获取
* @param officeAlias 机构表别名,多个用“,”逗号隔开。
* @param userAlias 用户表别名,多个用“,”逗号隔开,传递空,忽略此参数
* @return 标准连接条件对象
*/
public static String dataScopeFilter(User user, String officeAlias, String userAlias, String sAlias, String menuId) {
return genSqlString("menu1_",user, menuId,sAlias, "and");
}
public static String genSqlString(String prefix, User user, String menuId,String sAlias, String logic) {
if (user.isAdmin()) {
return "";
}
Jedis jedis = null;
try {
jedis = JedisUtils.getResource();
StringBuilder sqlString = new StringBuilder();
String sql = jedis.hget( prefix+ user.getCompany().getId() + "_" + user.getId(), menuId);
if (StringUtils.isNotBlank(sql)) {
//return sql;
}
// 进行权限过滤,多个岗位权限范围之间为或者关系。
List fnlRoleList = new ArrayList<>();
List selfRoleList = new ArrayList<>();
List roleList = UserUtils.getRolesByMenu(user, menuId);
if (roleList != null && roleList.size() > 0) {
for (Role role : roleList) {
if (Role.DATA_SCOPE_COMPANY_AND_CHILD.equals(role.getDataScope())) {
fnlRoleList.clear();
fnlRoleList.add(role);
break;
} else if (!Role.DATA_SCOPE_SELF.equals(role.getDataScope())) {
fnlRoleList.add(role);
} else {
selfRoleList.add(role);
}
}
}
Set officeSet = new HashSet<>();
for (Role r : fnlRoleList) {
if (Role.DATA_SCOPE_COMPANY_AND_CHILD.equals(r.getDataScope())) {
if(StringUtils.isBlank(sAlias)){
return logic + "1=1";
}
sqlString.append(logic + " a.company_id = '" + r.getCompany().getId() + "'");
return sqlString.toString();
}
if (Role.DATA_SCOPE_COMPANY.equals(r.getDataScope())) {
//查询分公司的所有部门
String key = BRANCH_OFFICE_PREFIX + r.getBranchCompany().getId();
String s = jedis.get(key);
List officeIds = null;
if (StringUtils.isBlank(s)) {
officeIds = UserUtils.findBranchOfficeId(r.getBranchCompany());
} else {
officeIds = JSON.parseArray(s, String.class);
}
if (officeIds != null && officeIds.size() > 0) {
jedis.set(key, JSON.toJSONString(officeIds));
jedis.expire(key, 60 * 60 * 8);
officeSet.addAll(officeIds);
}
continue;
}
if (Role.DATA_SCOPE_OFFICE_AND_CHILD.equals(r.getDataScope())) {
//查询当前部门的所有子部门
String key = CHILD_OFFICE_PREFIX + r.getOffice().getId();
String s = jedis.get(key);
List officeIds = new ArrayList<>();
if (StringUtils.isBlank(s)) {
officeIds = UserUtils.findChildOfficeId(r.getOffice());
} else {
officeIds = JSON.parseArray(s, String.class);
}
officeIds.add(r.getOffice().getId());
jedis.set(key, JSON.toJSONString(officeIds));
jedis.expire(key, 60 * 60 * 8);
officeSet.addAll(officeIds);
continue;
}
if (Role.DATA_SCOPE_OFFICE.equals(r.getDataScope())) {
officeSet.add(r.getOffice().getId());
continue;
}
}
//所有部门权限
if (officeSet != null) {
if (officeSet.size() > 1) {
sqlString.append("a.office_id in (");
for (String s : officeSet) {
sqlString.append("'" + s + "',");
}
sqlString.deleteCharAt(sqlString.length() - 1);
sqlString.append(")");
} else if (officeSet.size() == 1) {
for (String s : officeSet) {
sqlString.append("a.office_id ='" + s + "'");
}
}
}
//所有个人权限
for (int i = 0; i < selfRoleList.size(); i++) {
Role role = selfRoleList.get(i);
if (officeSet.contains(role.getOffice().getId())) {
continue;
}
if (i > 0 || sqlString.length() > 0) {
sqlString.append("or ");
}
sqlString.append("(a.office_id='" + role.getOffice().getId() + "' and a.create_by='" + user.getId() + "')");
}
if (StringUtils.isNotBlank(sqlString.toString())) {
sql = logic+" (" + sqlString.toString() + ")";
jedis.hset(prefix + user.getCompany().getId() + "_" + user.getId(), menuId, sql);
}
return sql;
} catch (Exception e) {
return "and a.company_id='" + user.getCompany().getId() + "' and a.create_by='" + user.getId() + "'";
} finally {
JedisUtils.returnResource(jedis);
}
}
/**
* 数据范围过滤
*
* @param user 当前用户对象,通过“entity.getCurrentUser()”获取
* @param officeAlias 机构表别名,多个用“,”逗号隔开。
* @param userAlias 用户表别名,多个用“,”逗号隔开,传递空,忽略此参数
* @return 标准连接条件对象
*/
public static String dataScopeFilterOR(User user, String officeAlias, String userAlias, String sAlias, String menuId) {
return genSqlString("menu2_",user, menuId, sAlias,"or");
}
/**
* 数据范围过滤 只显示当前企业下数据
*
* @param user 当前用户对象,通过“entity.getCurrentUser()”获取
* @param officeAlias 机构表别名,多个用“,”逗号隔开。
* @param userAlias 用户表别名,多个用“,”逗号隔开,传递空,忽略此参数
* @return 标准连接条件对象
*/
public static String dataScopeFilter2(User user, String officeAlias, String userAlias) {
StringBuilder sqlString = new StringBuilder();
// 进行权限过滤,多个岗位权限范围之间为或者关系。
List dataScope = Lists.newArrayList();
// 超级管理员,跳过权限过滤
if (!user.isAdmin()) {
boolean isDataScopeAll = false;
Role r = UserUtils.getSelectRole().get(0);
//for (Role r : user.getRoleList()){
user.setCompany(UserUtils.getSelectCompany());
user.setOffice(UserUtils.getSelectOffice());
for (String oa : StringUtils.split(officeAlias, ",")) {
if (!dataScope.contains(r.getDataScope()) && StringUtils.isNotBlank(oa)) {
if (Role.DATA_SCOPE_ALL.equals(r.getDataScope())) {
isDataScopeAll = true;
} else if (Role.DATA_SCOPE_COMPANY_AND_CHILD.equals(r.getDataScope())) {
sqlString.append(" OR " + oa + ".id = '" + user.getCompany().getId() + "'");
sqlString.append(" OR find_in_set( '" + user.getCompany().getId() + "'," + oa + ".parent_ids)");
} else if (Role.DATA_SCOPE_COMPANY.equals(r.getDataScope())) {
sqlString.append(" OR " + oa + ".id = '" + user.getCompany().getId() + "'");
// 包括本公司下的部门 (type=1:公司;type=2:部门)
sqlString.append(" OR (" + oa + ".parent_id = '" + user.getCompany().getId() + "' AND " + oa + ".type = '2')");
} else if (Role.DATA_SCOPE_OFFICE_AND_CHILD.equals(r.getDataScope())) {
sqlString.append(" OR " + oa + ".id = '" + user.getOffice().getId() + "'");
sqlString.append(" OR find_in_set( '" + user.getOffice().getId() + "'," + oa + ".parent_ids)");
} else if (Role.DATA_SCOPE_OFFICE.equals(r.getDataScope())) {
//查看分公司数据
sqlString.append(" OR " + oa + ".id = '" + user.getBranchOffice().getId() + "'");
sqlString.append(" OR find_in_set( '" + user.getBranchOffice().getId() + "'," + oa + ".parent_ids)");
/*sqlString.append(" OR " + oa + ".id = '" + user.getOffice().getId() + "'");*/
} else if (Role.DATA_SCOPE_CUSTOM.equals(r.getDataScope())) {
// String officeIds = StringUtils.join(r.getOfficeIdList(), "','");
// if (StringUtils.isNotEmpty(officeIds)){
// sqlString.append(" OR " + oa + ".id IN ('" + officeIds + "')");
// }
sqlString.append(" OR EXISTS (SELECT 1 FROM sys_role_office WHERE role_id = '" + r.getId() + "'");
sqlString.append(" AND office_id = " + oa + ".id)");
}
//else if (Role.DATA_SCOPE_SELF.equals(r.getDataScope())){
dataScope.add(r.getDataScope());
}
}
//}
// 如果没有全部数据权限,并设置了用户别名,则当前权限为本人;如果未设置别名,当前无权限为已植入权限
if (!isDataScopeAll) {
if (StringUtils.isNotBlank(userAlias)) {
for (String ua : StringUtils.split(userAlias, ",")) {
sqlString.append(" OR " + ua + ".id = '" + user.getId() + "'");
}
} else {
for (String oa : StringUtils.split(officeAlias, ",")) {
//sqlString.append(" OR " + oa + ".id = " + user.getOffice().getId());
sqlString.append(" OR " + oa + ".id IS NULL");
}
}
} else {
// 如果包含全部权限,则去掉之前添加的所有条件,并跳出循环。
sqlString = new StringBuilder();
}
}
if (StringUtils.isNotBlank(sqlString.toString())) {
return " AND (" + sqlString.substring(4) + ")";
}
return "";
}
/**
* 数据范围过滤(符合业务表字段不同的时候使用,采用exists方法)
*
* @param entity 当前过滤的实体类
* @param sqlMapKey sqlMap的键值,例如设置“dsf”时,调用方法:${sqlMap.sdf}
* @param officeWheres office表条件,组成:部门表字段=业务表的部门字段
* @param userWheres user表条件,组成:用户表字段=业务表的用户字段
* @example dataScopeFilter(user, " dsf ", " id = a.office_id ", " id = a.create_by ");
* dataScopeFilter(entity, "dsf", "code=a.jgdm", "no=a.cjr"); // 适应于业务表关联不同字段时使用,如果关联的不是机构id是code。
*/
public static void dataScopeFilter(BaseEntity> entity, String sqlMapKey, String officeWheres, String userWheres) {
User user = entity.getCurrentUser();
// 如果是超级管理员,则不过滤数据
if (user.isAdmin()) {
return;
}
// 数据范围(1:所有数据;2:所在公司及以下数据;3:所在公司数据;4:所在部门及以下数据;5:所在部门数据;8:仅本人数据;9:按明细设置)
StringBuilder sqlString = new StringBuilder();
// 获取到最大的数据权限范围
String roleId = "";
int dataScopeInteger = 8;
//for (Role r : user.getRoleList()){
Role r = UserUtils.getSelectRole().get(0);
//for (Role r : user.getRoleList()){
user.setCompany(UserUtils.getSelectCompany());
user.setOffice(UserUtils.getSelectOffice());
int ds = Integer.valueOf(r.getDataScope());
if (ds == 9) {
roleId = r.getId();
dataScopeInteger = ds;
//break;
} else if (ds < dataScopeInteger) {
roleId = r.getId();
dataScopeInteger = ds;
}
//}
String dataScopeString = String.valueOf(dataScopeInteger);
// 生成部门权限SQL语句
for (String where : StringUtils.split(officeWheres, ",")) {
if (Role.DATA_SCOPE_COMPANY_AND_CHILD.equals(dataScopeString)) {
// 包括本公司下的部门 (type=1:公司;type=2:部门)
sqlString.append(" AND EXISTS (SELECT 1 FROM SYS_OFFICE");
sqlString.append(" WHERE type='2'");
sqlString.append(" AND (id = '" + user.getCompany().getId() + "'");
sqlString.append(" OR parent_ids LIKE '" + user.getCompany().getParentIds() + user.getCompany().getId() + ",%')");
sqlString.append(" AND " + where + ")");
} else if (Role.DATA_SCOPE_COMPANY.equals(dataScopeString)) {
sqlString.append(" AND EXISTS (SELECT 1 FROM SYS_OFFICE");
sqlString.append(" WHERE type='2'");
sqlString.append(" AND id = '" + user.getCompany().getId() + "'");
sqlString.append(" AND " + where + ")");
} else if (Role.DATA_SCOPE_OFFICE_AND_CHILD.equals(dataScopeString)) {
sqlString.append(" AND EXISTS (SELECT 1 FROM SYS_OFFICE");
sqlString.append(" WHERE (id = '" + user.getOffice().getId() + "'");
sqlString.append(" OR parent_ids LIKE '" + user.getOffice().getParentIds() + user.getOffice().getId() + ",%')");
sqlString.append(" AND " + where + ")");
} else if (Role.DATA_SCOPE_OFFICE.equals(dataScopeString)) {
sqlString.append(" AND EXISTS (SELECT 1 FROM SYS_OFFICE");
sqlString.append(" WHERE id = '" + user.getOffice().getId() + "'");
sqlString.append(" AND " + where + ")");
} else if (Role.DATA_SCOPE_CUSTOM.equals(dataScopeString)) {
sqlString.append(" AND EXISTS (SELECT 1 FROM sys_role_office ro123456, sys_office o123456");
sqlString.append(" WHERE ro123456.office_id = o123456.id");
sqlString.append(" AND ro123456.role_id = '" + roleId + "'");
sqlString.append(" AND o123456." + where + ")");
}
}
// 生成个人权限SQL语句
for (String where : StringUtils.split(userWheres, ",")) {
if (Role.DATA_SCOPE_SELF.equals(dataScopeString)) {
sqlString.append(" AND EXISTS (SELECT 1 FROM sys_user");
sqlString.append(" WHERE id='" + user.getId() + "'");
sqlString.append(" AND " + where + ")");
}
}
// System.out.println("dataScopeFilter: " + sqlString.toString());
// 设置到自定义SQL对象
entity.getSqlMap().put(sqlMapKey, sqlString.toString());
}
/**
* @param user
* @param sAlias 分公司表别名
* @return
*/
public static String dataScopeBranchOfficeFilter(User user, String sAlias) {
if (user.isAdmin()) {
return "";
}
if (StringUtils.isBlank(sAlias)) {
return "";
}
List selectRoles = UserUtils.getSelectRole();
if (selectRoles == null || selectRoles.isEmpty()) {
return "";
}
Set branchIds = new HashSet<>();
for (Role role : selectRoles) {
branchIds.add(role.getBranchCompany() == null ? null : role.getBranchCompany().getId());
}
StringBuilder sql = new StringBuilder("and " + sAlias + ".id in (");
for (String branchId : branchIds) {
if (StringUtils.isBlank(branchId)) {
sql.append("'" + user.getComId() + "',");
} else {
sql.append("'" + branchId + "',");
}
}
sql.deleteCharAt(sql.length() - 1);
sql.append(")");
return sql.toString();
}
public static String dataScopeFilterOR(User user, String officeAlias,String menuId) {
Jedis jedis = null;
try {
jedis = JedisUtils.getResource();
StringBuilder sqlString = new StringBuilder();
String sql = jedis.hget("menu2_"+user.getCompany().getId()+"_"+user.getId(), menuId);
if (StringUtils.isNotBlank(sql)) {
return sql;
} else {
List roleList = UserUtils.getRolesByMenu(user, menuId);
// 超级管理员,跳过权限过滤
if (!user.isAdmin()) {
boolean isDataScopeAll = false;
if (UserUtils.getSelectRole() != null && UserUtils.getSelectRole().size() > 0) {
for (Role role : UserUtils.getSelectRole()) {
if (Role.DATA_SCOPE_COMPANY_AND_CHILD.equals(role.getDataScope())) {
roleList.clear();
roleList.add(role);
break;
} else if (!Role.DATA_SCOPE_SELF.equals(role.getDataScope()) || UserUtils.getSelectRole().size() == 1) {
roleList.add(role);
}
}
}
for (Role r : roleList) {
int count = 0;
sqlString.append(" ( (");
for (String oa : StringUtils.split(officeAlias, ",")) {
if (StringUtils.isNotBlank(oa)) {
if (Role.DATA_SCOPE_ALL.equals(r.getDataScope())) {
isDataScopeAll = true;
} else if (Role.DATA_SCOPE_COMPANY_AND_CHILD.equals(r.getDataScope())) {
sqlString.append(oa + ".id = '" + user.getCompany().getId() + "'");
sqlString.append(" OR " + oa + ".parent_ids LIKE '" + user.getCompany().getParentIds() + user.getCompany().getId() + ",%'");
} else if (Role.DATA_SCOPE_COMPANY.equals(r.getDataScope())) {
if (user.getBranchOffice() != null && StringUtils.isNotBlank(user.getBranchOffice().getId())) {
sqlString.append(oa + ".branch_office = '" + user.getBranchOffice().getId() + "'");
} else {
sqlString.append(oa + ".branch_office is null ");
}
sqlString.append("and (" + oa + ".id = '" + user.getCompany().getId() + "'");
sqlString.append(" OR " + oa + ".parent_ids LIKE '" + user.getCompany().getParentIds() + user.getCompany().getId() + ",%')");
/*sqlString.append(oa + ".id = '" + user.getCompany().getId() + "'");
// 包括本公司下的部门 (type=1:公司;type=2:部门)
sqlString.append(" OR (" + oa + ".parent_id = '" + user.getCompany().getId() + "' AND " + oa + ".type = '2')");
*/
} else if (Role.DATA_SCOPE_OFFICE_AND_CHILD.equals(r.getDataScope())) {
sqlString.append(oa + ".id = '" + user.getOffice().getId() + "'");
sqlString.append(" OR " + oa + ".parent_ids LIKE '" + user.getOffice().getParentIds() + user.getOffice().getId() + ",%'");
} else if (Role.DATA_SCOPE_OFFICE.equals(r.getDataScope())) {
/*sqlString.append(" OR " + oa + ".id = '" + user.getOffice().getId() + "'");*/
//查看分公司数据
sqlString.append(oa + ".id = '" + user.getBranchOffice().getId() + "'");
sqlString.append(" OR " + oa + ".parent_ids LIKE '" + user.getBranchOffice().getParentIds() + user.getBranchOffice().getId() + ",%'");
} else {
count = 1;
}
}
}
//}
// 如果没有全部数据权限,并设置了用户别名,则当前权限为本人;如果未设置别名,当前无权限为已植入权限
if (!isDataScopeAll) {
if (count == 1) {
sqlString.append("a.create_by IS NULL");
} else {
sqlString.append(" OR " + "a.create_by IS NULL");
}
} else {
// 如果包含全部权限,则去掉之前添加的所有条件,并跳出循环。
sqlString = new StringBuilder();
}
sqlString.append(") ) OR");
}
}
if (StringUtils.isNotBlank(sqlString.toString())) {
if (roleList.size() > 1) {
sql = "OR(" + sqlString.substring(0, sqlString.length() - 3) + ")";
} else {
sql = "OR" + sqlString.substring(0, sqlString.length() - 3);
}
jedis.hset("menu2_"+user.getCompany().getId()+"_"+user.getId(), menuId, sql);
return sql;
}
}
}catch (Exception e){
System.out.println("------------------dataScopeFilterOR Exception e:"+e);
}finally {
JedisUtils.returnResource(jedis);
}
//return "OR (s.id = '"+user.getCompany().getId()+"' AND a.create_by = '" + user.getId()+"')";
return "OR 1=1";
}
}