From fd3486865754d926eb91bc38564c13abea7ef0c1 Mon Sep 17 00:00:00 2001 From: FLYPHT <1035748121@qq.com> Date: Sun, 25 Sep 2022 18:15:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E:=E6=94=AF=E6=8C=81=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cc/smtweb/system/bpm/web/common/BpmConst.java | 4 + .../bpm/web/engine/dynPage/DynPageHelper.java | 175 ++++++++++------ .../dataRightGroup/AbsTreeDataRightHandler.java | 12 +- .../sys/user/dataRightGroup/DataRightGroup.java | 20 ++ .../user/dataRightGroup/DataRightGroupItem.java | 5 + .../sys/user/dataRightGroup/DataRightHelper.java | 32 ++- .../sys/user/dataRightGroup/IDataRightHandler.java | 2 +- .../user/dataRightGroup/IDataRightTreeFactory.java | 10 +- .../dataRightGroup/impl/PartyDataRightHandler.java | 233 ++++++++++++++++++++- .../system/bpm/web/sys/user/role/RoleHelper.java | 58 ++++- .../bpm/web/sys/user/role/RoleRightContent.java | 21 ++ .../cc/smtweb/framework/core/common/SwConsts.java | 2 + .../cc/smtweb/framework/core/common/SwEnum.java | 1 + .../controller/binder/body/SwMapBodyEditor.java | 22 +- .../framework/core/mvc/service/TreeHelper.java | 16 +- .../smtweb/framework/core/session/SessionUtil.java | 1 - 16 files changed, 538 insertions(+), 76 deletions(-) diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/common/BpmConst.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/common/BpmConst.java index 40217f5..bb80bc4 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/common/BpmConst.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/common/BpmConst.java @@ -12,5 +12,9 @@ public interface BpmConst { interface DataRight { public final static Long CUR_VALUE = 999L;//本机构,本部门 public final static Long ALL_DEPT = 998L;//全部门权限 + public final static int V_SELF = 0;//本级 + public final static int V_INCLUDE_CHILDREN = 1;//含下级 + public final static int V_INCLUDE = 0;//包含 + public final static int V_EXCEPT = 1;//排除 } } diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java index 5bb741b..8813be6 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/engine/dynPage/DynPageHelper.java @@ -12,11 +12,17 @@ import cc.smtweb.framework.core.db.vo.ModelTable; import cc.smtweb.framework.core.exception.BizException; import cc.smtweb.framework.core.exception.SwException; import cc.smtweb.framework.core.mvc.service.SqlNamedPara; +import cc.smtweb.framework.core.mvc.service.TreeHelper; import cc.smtweb.framework.core.util.MapUtil; import cc.smtweb.framework.core.util.NumberUtil; import cc.smtweb.framework.core.util.SqlUtil; import cc.smtweb.framework.core.util.StringUtil; import cc.smtweb.system.bpm.web.design.form.define.*; +import cc.smtweb.system.bpm.web.sys.user.dataRight.DataRightDefine; +import cc.smtweb.system.bpm.web.sys.user.dataRight.DataRightDefineCache; +import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.IDataRightHandler; +import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.IDataRightTreeFactory; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.lang.NonNull; @@ -31,6 +37,7 @@ import static cc.smtweb.framework.core.common.SwConsts.TOTAL_KEY; * Created by Akmm at 2022/4/23 10:01 * 动态页面辅助类 */ +@Slf4j public class DynPageHelper { /** * 新建bean @@ -138,28 +145,48 @@ public class DynPageHelper { return sqlNamedPara; } - /** - * 构建合计栏sql - * - * @param dataSet - * @param params - * @return - */ - public static SqlNamedPara buildSumSql(PageDataset dataSet, @NonNull SqlNamedPara sqlNamedPara) { - StringBuilder sql = new StringBuilder(256); - sql.append("select count(1) " + TOTAL_KEY); - for (PageDatasetField field : dataSet.fields) { - if (StringUtils.isEmpty(field.summary)) continue; - if (field.fieldIsCalc()) continue; - sql.append(","); - if (!SwEnum.SummaryType.instance.isText(field.summary)) { - sql.append(field.summary).append("(").append(field.name).append(") ").append(field.name); - } else { - sql.append("'").append(field.summary).append("' ").append(field.name); + static { + baseBuilder = (opt, field, name, value, args, filter) -> { + args.put(name, value); + return field + " " + opt + " :" + name; + }; + mapBuilder = new HashMap<>(); + mapBuilder.put(SwEnum.OptType.LIKE.value, (opt, field, name, value, args, filter) -> { + args.put(name, "%" + value + "%"); + return field + " like :" + name; + }); + + mapBuilder.put(SwEnum.OptType.PLIKE.value, (opt, field, name, value, args, filter) -> { + args.put(name, value + "%"); + return field + " like :" + name; + }); + + mapBuilder.put(SwEnum.OptType.BT.value, (opt, field, name, value, args, filter) -> { + String[] ss = value.toString().split(","); + if (ss.length != 2) throw new BizException("介于条件,参数值个数错误!"); + args.put(name + "_1", ss[0]); + args.put(name + "_2", ss[1]); + return "(" + field + ">=:" + name + "_1 and " + field + "<=:" + name + "_2)"; + }); + + mapBuilder.put(SwEnum.OptType.IN.value, (opt, field, name, value, args, filter) -> { + if (StringUtil.isEmpty(value.toString())) return ""; + args.put(name, value); + return field + " in (:" + name + ") "; + }); + + mapBuilder.put(SwEnum.OptType.NOT_IN.value, (opt, field, name, value, args, filter) -> { + if (StringUtil.isEmpty(value.toString())) return ""; + args.put(name, value); + return field + " not in (:" + name + ") "; + }); + mapBuilder.put(SwEnum.OptType.IN_CHILD.value, (opt, field, name, value, args, filter) -> { + ModelTable table = ModelTableCache.getInstance().get(filter.link); + if(table==null){ + return ""; } - } - sqlNamedPara.sql = sql.toString() + " from (" + sqlNamedPara.sql + ") xxxxa"; - return sqlNamedPara; + return TreeHelper.getTreeHelper(table.getName()).buildLikeFrSql(Long.parseLong(value.toString()),field); + }); } private static String buildSelFieldsSql(PageDataset dataSet, SqlNamedPara sqlNamedPara, IBuildSqlListener listener) { @@ -189,6 +216,30 @@ public class DynPageHelper { } /** + * 构建合计栏sql + * + * @param dataSet + * @param sqlNamedPara + * @return + */ + public static SqlNamedPara buildSumSql(PageDataset dataSet, @NonNull SqlNamedPara sqlNamedPara) { + StringBuilder sql = new StringBuilder(256); + sql.append("select count(1) " + TOTAL_KEY); + for (PageDatasetField field : dataSet.fields) { + if (StringUtils.isEmpty(field.summary)) continue; + if (field.fieldIsCalc()) continue; + sql.append(","); + if (!SwEnum.SummaryType.instance.isText(field.summary)) { + sql.append(field.summary).append("(").append(field.name).append(") ").append(field.name); + } else { + sql.append("'").append(field.summary).append("' ").append(field.name); + } + } + sqlNamedPara.sql = sql.toString() + " from (" + sqlNamedPara.sql + ") xxxxa"; + return sqlNamedPara; + } + + /** * 构建where条件:组合固定和动态条件 * * @param dataSet @@ -218,6 +269,12 @@ public class DynPageHelper { args.put(s, MapUtil.readString(params, s, "")); } if (listener != null) listener.buildWhere(dataSet, sql, args); + // 设置固定条件数据权限 + for (PageDatasetFilter filter : dataSet.filters) { + if(!setFixedFilter.contains(filter.name))break; + if(filter.dataRightType<=0L)break; + buildDataRight(filter.dataRightType,filter.sqlName,MapUtil.readString(params, filter.name, ""),sql,args); + } return new SqlNamedPara(sql.toString(), args); } @@ -265,6 +322,11 @@ public class DynPageHelper { value = params.get(filter.name); } if (value == null || StringUtils.isEmpty(value.toString())) { + if(filter.dataRightType>0L){ + StringBuilder frSql = new StringBuilder(); + buildDataRight(filter.dataRightType,filter.sqlName,value.toString(),frSql,args); + return frSql.toString(); + } if (filter.required) { throw new BizException("过滤条件不能为空(" + filter.name + ")!"); } @@ -272,9 +334,21 @@ public class DynPageHelper { } IBuilderExpr builder = getBuilder(dynCond.opt); String ns = isNameSelf ? filter.name: filter.name + "_" + dynCond.hashCode(); - return builder.build(dynCond.opt, filter.sqlName, ns, value, args); + String optWhere = builder.build(dynCond.opt, filter.sqlName, ns, value, args,filter); + // 添加数据权限 + if(filter.dataRightType>0L){ + StringBuilder frSql = new StringBuilder(); + buildDataRight(filter.dataRightType,filter.sqlName,value.toString(),frSql,args); + if(frSql.length()>0){ + if(StringUtil.isEmpty(optWhere)){ + optWhere = frSql.toString(); + }else { + optWhere+= " and "+ frSql.toString(); + } + } + } + return optWhere; } - /** * 处理计算字段 * @@ -292,41 +366,24 @@ public class DynPageHelper { private static Map mapBuilder; private static IBuilderExpr baseBuilder; - static { - baseBuilder = (opt, field, name, value, args) -> { - args.put(name, value); - return field + " " + opt + " :" + name; - }; - mapBuilder = new HashMap<>(); - mapBuilder.put(SwEnum.OptType.LIKE.value, (opt, field, name, value, args) -> { - args.put(name, "%" + value + "%"); - return field + " like :" + name; - }); - - mapBuilder.put(SwEnum.OptType.PLIKE.value, (opt, field, name, value, args) -> { - args.put(name, value + "%"); - return field + " like :" + name; - }); - - mapBuilder.put(SwEnum.OptType.BT.value, (opt, field, name, value, args) -> { - String[] ss = value.toString().split(","); - if (ss.length != 2) throw new BizException("介于条件,参数值个数错误!"); - args.put(name + "_1", ss[0]); - args.put(name + "_2", ss[1]); - return "(" + field + ">=:" + name + "_1 and " + field + "<=:" + name + "_2)"; - }); - - mapBuilder.put(SwEnum.OptType.IN.value, (opt, field, name, value, args) -> { - if (StringUtil.isEmpty(value.toString())) return ""; - args.put(name, value); - return field + " in (:" + name + ") "; - }); - - mapBuilder.put(SwEnum.OptType.NOT_IN.value, (opt, field, name, value, args) -> { - if (StringUtil.isEmpty(value.toString())) return ""; - args.put(name, value); - return field + " not in (:" + name + ") "; - }); + /** + * 构建数据权限 + * @param dsType 数据权限定义ID + * @param sqlField sql字段名 + * @param value 值 + * @param sql sql语句 + * @param args 参数 + */ + private static void buildDataRight(long dsType,String sqlField,String value,StringBuilder sql,SwMap args){ + DataRightDefine drd = DataRightDefineCache.getInstance().get(dsType); + if(drd==null){return;} + try{ + IDataRightHandler dataRightHandler = IDataRightTreeFactory.getInstance().getHandler(drd.getCode()); + dataRightHandler.buildSqlWhere(true,sqlField,value,sql,args); + }catch (Exception e){ + log.error("加载数据权限失败:",e); + throw new SwException(e); + } } private static IBuilderExpr getBuilder(String opt) { @@ -335,7 +392,7 @@ public class DynPageHelper { } interface IBuilderExpr { - String build(String opt, String field, String name, Object value, Map args); + String build(String opt, String field, String name, Object value, Map args,PageDatasetFilter filter); } } diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/AbsTreeDataRightHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/AbsTreeDataRightHandler.java index a546398..57bbfa7 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/AbsTreeDataRightHandler.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/AbsTreeDataRightHandler.java @@ -1,5 +1,6 @@ package cc.smtweb.system.bpm.web.sys.user.dataRightGroup; +import cc.smtweb.framework.core.common.SwConsts; import cc.smtweb.framework.core.common.SwMap; import cc.smtweb.framework.core.session.UserSession; import cc.smtweb.framework.core.util.StringUtil; @@ -12,7 +13,7 @@ import java.util.Map; * 数据权限计算处理抽象类 */ public abstract class AbsTreeDataRightHandler implements IDataRightHandler{ - protected final static String menuIdKey = "_menuId"; + protected final static String KEY_HEADER_MENU = "hmk"; //权限查找结果常量定义 protected final static int RIGHT_RET_NONE = 0; //未找到 protected final static int RIGHT_RET_IN_CHILD = 1;//找到,包含,且含下级 @@ -35,11 +36,16 @@ public abstract class AbsTreeDataRightHandler implements IDataRightHandler{ } @Override public void init(UserSession us,SwMap params) { - this.isByRight = true; this.us = us; this.params = params; - String menuId = params.readString("_menuId"); + // 获取header中的菜单ID + SwMap header = params.readMap(SwConsts.PARAMS_HEADER_KEY); + long menuId = 0L; + if(header!=null){ + menuId = header.readLong(KEY_HEADER_MENU); + } if (us == null) return; + this.isByRight = true; mapRight = DataRightHelper.getDataRightItemMap(getDataRightType(), menuId, us); if (mapRight == null) return; //将本单位处理下 diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightGroup.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightGroup.java index 1624e97..3fc3112 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightGroup.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightGroup.java @@ -2,6 +2,12 @@ package cc.smtweb.system.bpm.web.sys.user.dataRightGroup; import cc.smtweb.framework.core.annotation.SwTable; import cc.smtweb.framework.core.db.impl.DefaultEntity; +import cc.smtweb.framework.core.util.CommUtil; +import cc.smtweb.framework.core.util.JsonUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; /** * Created by 1 at 2022-08-04 17:45:35 @@ -98,4 +104,18 @@ public class DataRightGroup extends DefaultEntity { public void setSdrdId(long sdrg_sdrd_id) { put("sdrg_sdrd_id", sdrg_sdrd_id); } + // 获取权限明细集合 + public List getDataRightItemList(){ + List rtList = new ArrayList<>(); + List> listItem = data.readListMap("sdrg_content"); + if(!CommUtil.isEmpty(listItem)){ + listItem.forEach(map-> { + DataRightGroupItem item = JsonUtil.parse(map,DataRightGroupItem.class); + if(item!=null){ + rtList.add(item); + } + }); + } + return rtList; + } } diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightGroupItem.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightGroupItem.java index 6b0cb3e..21bfbb7 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightGroupItem.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightGroupItem.java @@ -1,6 +1,7 @@ package cc.smtweb.system.bpm.web.sys.user.dataRightGroup; import cc.smtweb.framework.core.db.impl.BaseBean; +import cc.smtweb.system.bpm.web.common.BpmConst; /** * @Author: tanghp @@ -31,4 +32,8 @@ public class DataRightGroupItem extends BaseBean { public void setType(int type) { put("type",type); } + // 包含 + public boolean isInclude(){ + return getKind() == BpmConst.DataRight.V_INCLUDE; + } } diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightHelper.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightHelper.java index 9fb97df..defb44b 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightHelper.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/DataRightHelper.java @@ -1,8 +1,13 @@ package cc.smtweb.system.bpm.web.sys.user.dataRightGroup; import cc.smtweb.framework.core.session.UserSession; +import cc.smtweb.system.bpm.web.common.BpmConst; +import cc.smtweb.system.bpm.web.sys.user.role.RoleHelper; +import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Set; /** * @Author: tanghp @@ -18,7 +23,30 @@ public class DataRightHelper { * @param us 用户session * @return */ - public static Map getDataRightItemMap(String dType, String menuId, UserSession us ){ - return null; + public static Map getDataRightItemMap(String dType, long menuId, UserSession us ){ + Set setGroup = RoleHelper.getDataRightGroup(us.getUserId(), us.getPartyId(), menuId,dType); + //以value作为key + Map map = new HashMap<>(); + for (DataRightGroup group : setGroup) { + List items = group.getDataRightItemList(); + for (DataRightGroupItem item : items) { + if (!map.containsKey(item.getValue())) { + map.put(item.getValue(), item); + } + DataRightGroupItem i = map.get(item.getValue()); + if ((!i.isInclude() && item.isInclude()) || (i.isInclude() == item.isInclude() && item.getType() == BpmConst.DataRight.V_INCLUDE_CHILDREN)) { + map.put(item.getValue(), item); + } + } + } + // 如果没有配置数据权限,默认设置个本级及下级 + if(map.size()==0){ + DataRightGroupItem drgi = new DataRightGroupItem(); + drgi.setKind(BpmConst.DataRight.V_INCLUDE); + drgi.setType(BpmConst.DataRight.V_INCLUDE_CHILDREN); + drgi.setValue(BpmConst.DataRight.CUR_VALUE.toString()); + map.put(drgi.getValue(),drgi); + } + return map; } } diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/IDataRightHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/IDataRightHandler.java index fbfbab3..897478e 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/IDataRightHandler.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/IDataRightHandler.java @@ -12,5 +12,5 @@ import java.util.List; public interface IDataRightHandler { void init(UserSession us,SwMap params); //构建sql - boolean buildSqlWhere(boolean where, String sqlField, String value, StringBuilder sql, List args); + boolean buildSqlWhere(boolean where, String sqlField, String value, StringBuilder sql, SwMap args); } diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/IDataRightTreeFactory.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/IDataRightTreeFactory.java index 1ed9369..3e65305 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/IDataRightTreeFactory.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/IDataRightTreeFactory.java @@ -3,6 +3,7 @@ package cc.smtweb.system.bpm.web.sys.user.dataRightGroup; import cc.smtweb.framework.core.exception.SwException; import cc.smtweb.system.bpm.web.common.BpmEnum; import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.impl.DeptDataRightTreeWork; +import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.impl.PartyDataRightHandler; import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.impl.PartyDataRightTreeWork; import java.util.HashMap; @@ -27,11 +28,13 @@ public class IDataRightTreeFactory { } private Map> mapWorks; - + private Map> mapHandlers; private IDataRightTreeFactory() { mapWorks = new HashMap<>(); + mapHandlers = new HashMap<>(); mapWorks.put(BpmEnum.DataRightType.PARTY.value, PartyDataRightTreeWork.class); + mapHandlers.put(BpmEnum.DataRightType.PARTY.value, PartyDataRightHandler.class); mapWorks.put(BpmEnum.DataRightType.DEPT.value, DeptDataRightTreeWork.class); } @@ -40,4 +43,9 @@ public class IDataRightTreeFactory { if (cls == null) throw new SwException("暂不支持[" + key + "]类型权限!"); return cls.newInstance(); } + public IDataRightHandler getHandler(String key) throws Exception { + Class cls = mapHandlers.get(key); + if (cls == null) throw new SwException("暂不支持[" + key + "]类型权限!"); + return cls.newInstance(); + } } diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/impl/PartyDataRightHandler.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/impl/PartyDataRightHandler.java index 70147cc..3d8d495 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/impl/PartyDataRightHandler.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/dataRightGroup/impl/PartyDataRightHandler.java @@ -1,13 +1,24 @@ package cc.smtweb.system.bpm.web.sys.user.dataRightGroup.impl; +import cc.smtweb.framework.core.common.SwConsts; +import cc.smtweb.framework.core.common.SwMap; +import cc.smtweb.framework.core.db.EntityHelper; +import cc.smtweb.framework.core.util.CommUtil; +import cc.smtweb.system.bpm.web.common.BpmConst; +import cc.smtweb.system.bpm.web.common.BpmEnum; import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.AbsTreeDataRightHandler; +import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.DataRightGroupItem; +import cc.smtweb.system.bpm.web.sys.user.party.Party; +import cc.smtweb.system.bpm.web.sys.user.party.PartyCache; -import java.util.*; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; /** * @Author: tanghp * @Date: 2022-09-22 15:17 - * @Desc: + * @Desc: 单位数据权限 */ public class PartyDataRightHandler extends AbsTreeDataRightHandler { @Override @@ -18,11 +29,225 @@ public class PartyDataRightHandler extends AbsTreeDataRightHandler { @Override protected String getDataRightType() { - return "partyId"; + return BpmEnum.DataRightType.PARTY.value; } @Override - public boolean buildSqlWhere(boolean where, String sqlField, String value, StringBuilder sql, List args) { + public boolean buildSqlWhere(boolean where, String sqlField, String value, StringBuilder sql, SwMap args) { return false; } + /** + * 根据菜单数据权限,找有权限的顶级机构列表 + * + * @return + */ + public Set getTopList() { + if (!isByRight || mapRight == null) { //不控制权限,直接取吧 + return PartyCache.getInstance().getChildren(SwConsts.DEF_ROOT_ID_LONG); + } + + Set list = new HashSet<>(); + if (mapRight.isEmpty()) return list; + Set setExists = new HashSet<>(); + for (DataRightGroupItem item : mapRight.values()) { + if (!item.isInclude()) continue; //不包含的对象,这里是计算根节点,不管就是了 + //本单位之类的已处理 + Party party = PartyCache.getInstance().get(item.getValue()); + if (party == null) continue; + boolean isParentExists = false; + //添加节点,注意:如果是已经添加了的单位的下级,则不要添加 + String[] pids = party.getLevelCode().split(SwConsts.SPLIT_CHAR); + for (String pid : pids) { + if (setExists.contains(pid)) { + isParentExists = true; + break; + } + } + if (!isParentExists) { + list.add(party); + setExists.add(String.valueOf(party.getEntityId())); + } + } + return list; + } + + /** + * 获取下级节点 + * + * @param parentId 上级机构id + * @return + */ + public Set getChildren(long parentId) { + Set children = PartyCache.getInstance().getChildren(parentId); + if (!isByRight || mapRight == null || CommUtil.isEmpty(children)) { //不控制权限,直接取吧 + return children; + } + + if (mapRight.isEmpty()) return null; + + children.removeIf(party -> !hasRight(party)); + return children; + } + + /** + * 是否拥有此单位权限 + * + * @param party + * @return + */ + private boolean hasRight(Party party) { + int nret = hasRight(party.getEntityId()); + if (nret != RIGHT_RET_NONE) return nret != RIGHT_RET_EX; + String[] pids = party.getLevelCode().split(SwConsts.SPLIT_CHAR); + for (String pid : pids) { + nret = hasRight(Long.parseLong(pid)); + if (nret == RIGHT_RET_IN_CHILD) return true; + if (nret == RIGHT_RET_IN_NOCHILD || nret == RIGHT_RET_EX) return false; + } + return false; + } + + private int hasRight(long id) { + if (mapRight == null || !mapRight.containsKey(String.valueOf(id))) return RIGHT_RET_NONE; + DataRightGroupItem item = mapRight.get(String.valueOf(id)); + if (item.isInclude()) { + if (item.getType()== BpmConst.DataRight.V_INCLUDE_CHILDREN) return RIGHT_RET_IN_CHILD; + return RIGHT_RET_IN_NOCHILD; + } + if (!item.isInclude()) return RIGHT_RET_EX; + return 0; + } + + + /** + * 判断childId是否是parentId的子孙 + * + * @param childId + * @param parentId + * @return + */ + public boolean isChild(long childId, long parentId) { + if (parentId<=0L) return true; + Party party = PartyCache.getInstance().get(childId); + if (party == null) return false; + String parentIdStr = SwConsts.SPLIT_CHAR+parentId+SwConsts.SPLIT_CHAR; + return (party.getLevelCode() + SwConsts.SPLIT_CHAR).contains(parentIdStr); + } + /** + * 获取查询语句,使用子查询的方式,数据权限越复杂,构建的语句就越复杂 + * + * @param where 是否带的有where了,确定是where还是and + * @param sqlField 查询的表的单位字段 + * @param partyId 查询条件机构的值,可以为空 + * @param qnext 是否带下级 注意:此方法仅单位管理使用。 + * @param includeSelf 是否包含自己 + * @param sql sql + * @param args 参数 + */ + public boolean buildSqlWhere(boolean where, String sqlField, long partyId, boolean qnext, + boolean includeSelf, StringBuilder sql, SwMap args) { + if (partyId>0L) {//前端页面传入了单位id + Party party = PartyCache.getInstance().get(partyId); + if (isByRight&&party==null) { + if (where) sql.append(" and "); + else sql.append(" where "); + sql.append(" 1 <> 1 "); + return true; + } + if (party != null) {//单位不存在,则默认查所有,押后 + int nret = hasRight(partyId); + if (nret == RIGHT_RET_IN_NOCHILD) {//不包含下级,则直接等于即可 + if (where) sql.append(" and "); + else sql.append(" where "); + sql.append(" ").append(sqlField).append(" =:_dr_partyId "); + args.put("_dr_partyId",partyId); + return true; + } + if (nret == RIGHT_RET_EX) {//不包含,直接用顶级单位的id来筛选,应该是无数据返回 + if (where) sql.append(" and "); + else sql.append(" where "); + sql.append(" 1 <> 1 "); + return true; + } + } else { + partyId = SwConsts.DEF_ROOT_ID_LONG; + } + } + + StringBuilder sqlAnd = new StringBuilder(128); + StringBuilder sqlOr = new StringBuilder(128); + + addPartySql(partyId, true, true, qnext, includeSelf, sqlAnd, sqlOr, args); + + if (mapRight != null) { + for (DataRightGroupItem item : mapRight.values()) { + long itemPartyId = Long.parseLong(item.getValue()); + if (item.getValue().equalsIgnoreCase(String.valueOf(partyId))) continue; + if (!isChild(itemPartyId, partyId)) continue; //非指定partyId的下级,不用搭理 + addPartySql(itemPartyId, item.isInclude(), item.getType() == BpmConst.DataRight.V_INCLUDE_CHILDREN, true, true, sqlAnd, sqlOr, args); + } + } + + if (sqlAnd.length() == 0 && sqlOr.length() == 0) { + return where; + } + + if (where) sql.append(" and "); + else sql.append(" where "); + + if (sqlOr.length() > 0) { + sql.append("\nEXISTS(\n" + + " SELECT pt_id FROM " + EntityHelper.getSchemaTableName(Party.ENTITY_NAME) + " r2 WHERE r2.party_id=" + sqlField); + sql.append(" and (").append(sqlOr.substring(4)).append("))"); + return true; + } + if (sqlAnd.length() > 0) { + sql.append("\nand not EXISTS(\n" + + " SELECT pt_id FROM " + EntityHelper.getSchemaTableName(Party.ENTITY_NAME)+ " r2 WHERE r2.party_id=" + sqlField); + sql.append(" and (").append(sqlAnd.substring(4)).append("))"); + return true; + } + return false; + + + } + private void addPartySql(long partyId, boolean isInclude, boolean hasChild, boolean qnext, boolean includeSelf, StringBuilder sqlAnd, StringBuilder sqlOr, SwMap args) { + if (partyId<=0L) return; + if (!hasChild && isInclude) {//不包含下级 + String p = String.format("_dr_pt_id_%s", new Random().nextInt(10)); + sqlOr.append(String.format(" or r2.pt_id=:%s",p)); + args.put(p,partyId); + return; + } + Party party = PartyCache.getInstance().get(partyId); + if (party == null) return; + if (isInclude) { + localBuildSqlPara(qnext, includeSelf, sqlOr, args, party); + } else { + localBuildSqlPara(qnext, includeSelf, sqlAnd, args, party); + } + } + + //构建子查询语句 + private void localBuildSqlPara(boolean qnext, boolean includeSelf, StringBuilder sqlOr, SwMap args, Party party) { + sqlOr.append(" or ( "); + if (includeSelf) { + String p = String.format("_dr_pt_id_%s", new Random().nextInt(10)); + sqlOr.append(String.format("(r2.pt_id=:%s or ",p)); + args.put(p,party.getId()); + } + if (qnext) { + String p = String.format("_dr_pt_level_code_%s", new Random().nextInt(10)); + sqlOr.append(String.format(" r2.pt_level_code like :%s",p)); + args.put(p,party.getLevelCode() + SwConsts.SPLIT_CHAR + party.getId() + "%"); + } else { + String p = String.format("_dr_pt_parent_id_%s", new Random().nextInt(10)); + sqlOr.append(String.format(" r2.pt_parent_id = :%s",p)); + args.put(p,party.getId()); + } + + if (includeSelf) sqlOr.append("))"); + else sqlOr.append(")"); + } + } diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleHelper.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleHelper.java index a468715..91289d2 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleHelper.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleHelper.java @@ -1,5 +1,9 @@ package cc.smtweb.system.bpm.web.sys.user.role; +import cc.smtweb.system.bpm.web.sys.user.dataRight.DataRightDefine; +import cc.smtweb.system.bpm.web.sys.user.dataRight.DataRightDefineCache; +import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.DataRightGroup; +import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.DataRightGroupCache; import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlan; import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlanCache; import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlanContent; @@ -8,9 +12,7 @@ import cc.smtweb.system.bpm.web.sys.user.user.User; import cc.smtweb.system.bpm.web.sys.user.user.UserCache; import cc.smtweb.system.bpm.web.sys.user.user.UserRoleCache; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @Author: tanghp @@ -127,4 +129,54 @@ public final class RoleHelper { }); return mpList; } + + /** + * 获取用户指定类型的数据权限组 + * @param userId 用户ID + * @param partyId 登录的单位 + * @param menuId 菜单ID + * @param dsType 数据权限类型编码 + * @return 数据权限组集合 + */ + public static Set getDataRightGroup(long userId,long partyId,long menuId,String dsType){ + Set mpIds = getMenuPlanIds(userId,partyId); + if(mpIds.size()==0){ + return new HashSet<>(); + } + // 没传菜单方案ID,随机取一个菜单方案 + return getDataRightGroup(userId,partyId,menuId,dsType,mpIds.iterator().next()); + } + + /** + * 获取用户指定类型的数据权限组 + * @param userId 用户ID + * @param partyId 登录单位 + * @param dsType 数据权限类型编码 参见 BpmEnum.DataRightType + * @param menuPlanId 菜单方案id + * @return 据权限组集合 + */ + public static Set getDataRightGroup(long userId,long partyId,long menuId,String dsType,long menuPlanId){ + Map mapGroup = new HashMap<>(); + //先看数据权限类型存在不 + DataRightDefine drd = DataRightDefineCache.getInstance().getByCode(dsType); + if(drd==null)return new HashSet<>(); + + Set roleIds = UserRoleCache.getInstance().getRoleIdByUP(userId,partyId); + RoleCache roleCache = RoleCache.getInstance(); + roleIds.forEach((roleId)-> { + Role role = roleCache.get(roleId); + if(role==null || role.getSmpId()!=menuPlanId){ + return; + } + RoleRightContent roleRightContent = new RoleRightContent(role.getPrivilege()); + long groupId =roleRightContent.getDataRightGroupId(menuId,drd.getEntityId()); + if(groupId>0L){ + DataRightGroup dataRightGroup = DataRightGroupCache.getInstance().get(groupId); + if(dataRightGroup!=null){ + mapGroup.put(groupId,dataRightGroup); + } + } + }); + return new HashSet<>(mapGroup.values()); + } } diff --git a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleRightContent.java b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleRightContent.java index b3b4cf3..cf10613 100644 --- a/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleRightContent.java +++ b/smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/user/role/RoleRightContent.java @@ -112,4 +112,25 @@ public class RoleRightContent { }); return cache; } + + /** + * 获取菜单的数据权限组ID + * @param menuId 菜单id + * @param dataRightId 数据权限定义id + * @return 数据权限组ID + */ + public long getDataRightGroupId(long menuId, long dataRightId){ + RoleRight right = getRoleRight(menuId); + List> list = right.getRightData(); + if(CommUtil.isEmpty(list))return 0L; + for(Map map :list){ + SwMap swMap = new SwMap(); + swMap.putAll(map); + long key = swMap.readLong("key"); + if(key ==dataRightId){ + return swMap.readLong("value"); + } + } + return 0L; + } } diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java index 8a191ff..b3f06be 100644 --- a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwConsts.java @@ -62,4 +62,6 @@ public interface SwConsts { //定时任务key String REDIS_KEY_BASE_JOB = "jobexe"; + // params 参数中的header key + String PARAMS_HEADER_KEY ="_header"; } diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwEnum.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwEnum.java index 795d691..375eb87 100644 --- a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwEnum.java +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/common/SwEnum.java @@ -314,6 +314,7 @@ public interface SwEnum { public static StrEnumBean LIKE = instance.addEnum("like", "包含"); public static StrEnumBean IN = instance.addEnum("in", "在列表"); public static StrEnumBean NOT_IN = instance.addEnum("not in", "不在列表"); + public static StrEnumBean IN_CHILD = instance.addEnum("inChild", "本级及下级"); } //合计栏类型 "summary": "COUNT/SUM/AVG/MAX/MIN/其他为文本" diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java index ae64f13..82f5b1c 100644 --- a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/controller/binder/body/SwMapBodyEditor.java @@ -8,6 +8,7 @@ import cc.smtweb.framework.core.util.JsonUtil; import org.apache.commons.lang3.StringUtils; import javax.servlet.http.HttpServletRequest; +import java.util.Enumeration; import java.util.Map; /** @@ -32,6 +33,10 @@ public class SwMapBodyEditor implements IEditor { private Object getGetValue(String paramName, Class paramType, Map params, HttpServletRequest request) { SwMap result = JsonUtil.parseSimple(params, SwMap.class); + if(result!=null){ + SwMap header = getHeaderMap(request); + result.put("_header",header); + } request.setAttribute(BODY_MAP, result); return getFieldValue(result, paramName); } @@ -42,10 +47,25 @@ public class SwMapBodyEditor implements IEditor { } SwMap result = JsonUtil.parse(body, SwMap.class); + if(result!=null){ + SwMap header = getHeaderMap(request); + result.put("_header",header); + } request.setAttribute(BODY_MAP, result); return getFieldValue(result, paramName); } - + private SwMap getHeaderMap( HttpServletRequest request){ + SwMap header = new SwMap(); + Enumeration headerNames = request.getHeaderNames(); + if (null != headerNames) { + while (headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + String headerValue = request.getHeader(headerName); + header.put(headerName,headerValue); + } + } + return header; + } private Object getFieldValue(SwMap result, String paramName) { if (paramName != null) { Object value = result.get(paramName); diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java index 029b469..2885fcb 100644 --- a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/mvc/service/TreeHelper.java @@ -6,6 +6,7 @@ import cc.smtweb.framework.core.common.SwConsts; import cc.smtweb.framework.core.common.SwEnum; import cc.smtweb.framework.core.db.DbEngine; import cc.smtweb.framework.core.db.EntityDao; +import cc.smtweb.framework.core.db.EntityHelper; import cc.smtweb.framework.core.db.cache.ModelTableCache; import cc.smtweb.framework.core.db.impl.DefaultEntity; import cc.smtweb.framework.core.db.vo.ModelTable; @@ -36,6 +37,7 @@ public class TreeHelper { private String fieldParent; private String fieldLevel; private String fieldLevelCode; + private String fieldId; public static TreeHelper getTreeHelper(String tableName) { @@ -69,6 +71,7 @@ public class TreeHelper { fieldParent = table.findFieldNameByType(SwEnum.FieldType.PARENT_ID.value); fieldLevelCode = table.findFieldNameByType(SwEnum.FieldType.LEVEL_CODE.value); fieldLevel = table.findFieldNameByType(SwEnum.FieldType.LEVEL.value); + fieldId = table.getIdField(); } public long getParentId(T bean) { @@ -125,13 +128,24 @@ public class TreeHelper { } return list; } + // 拼接查询本级及下级sql片段 + public String buildLikeFrSql(long id,String sqlField){ + T bean = cache.get(id); + if(bean==null){ + return "1<>1"; + } + String childStr = "'"+getLevelCode(bean)+ SwConsts.SPLIT_CHAR+ bean.getEntityId()+"'"; + String schemaTableName = EntityHelper.getSchemaTableName(tableName); + return String.format(" exists ( select %s from %s tt where tt.%s = %s and (tt.%s=%s or tt.%s like %s))", + fieldId,schemaTableName,fieldId,sqlField,fieldId,id,fieldLevelCode,childStr); + } private void resetParentChildren(T bean, List list) { T parent = cache.get(getParentId(bean)); if (parent != null) { bean.put(fieldLevelCode, getLevelCode(parent) + SwConsts.SPLIT_CHAR + parent.getEntityId()); bean.put(fieldLevel, getLevel(parent) + 1); - dao.updateEntity(bean, fieldLevelCode, fieldLevel); + dao.updateEntity(bean, fieldLevelCode+","+fieldLevel); list.add(bean); } Collection children = getChildren(bean); diff --git a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java index 5d96948..28b4c29 100644 --- a/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java +++ b/smtweb-framework/core/src/main/java/cc/smtweb/framework/core/session/SessionUtil.java @@ -37,7 +37,6 @@ public class SessionUtil { //url参数名 private final static String KEY_PARAM_FP_KEY = "fpk"; private final static String KEY_PARAM_FP_VAL = "fpv"; - //不需要校验登录的url public static List notLoginUrl = new ArrayList<>(); /*//不需要切换数据源的url,强制用主库