[置顶] 常规功能和模块自定义系统 (cfcmms)—038模块记录(数据)的权限设计(3)

038模块记录(数据)的权限设计(3)


  在有了模块的关联关系和定义在基准模块上的各种权限的基础上,我们就可以来生成查询数据的语句了。前面的博客里大多讲的是前台的一些技巧,其实本系统中最核心的还是这一块内容。如何根据模块的关联关系和用户权限以及附加字段和用户界面传过来的筛选、排序、分组条件来生成一个查询的select语句就是最关键的内容。现在就我自己开发的过程介绍一下生成select语句的一些内容:
  1、确定基准模块:大多数的模块功能中你得确定一个模块作为一个基准模块,比如我们用作例子的“订单”模块。
  2、根据基准模块生成关联关系图:确定了基准模块之后,得根据字段的ManyToOne的字义来生成所有的父模块的关联关系结构,由于父模块和祖父模块的个数和级数的未知性,因此需要一个类似链表的的数据结构来存放父模块,在父模块中也得生成这样的一个关联关系的结构,直到加入所有的父模块。为了实现这个功能,我做了一个类ParentModule.java来保存父模块。
public class ParentModule implements Serializable {

  private _Module module; // 父模块
  private _ModuleField moduleField; // 子模块中的ManyToOne的字段名,这个应该作为关键字

  private String asName; // as Name
  private Integer level; // 级数

  private String namePath; // 名称的路径,比如说 客户--市--省,承运商--市--省。

  private String modulePath; // 包括 模块名_字段名___父模块名—字段名___父模块名—字段名

  private String fieldAhead; // 放在id,name 和附加字段之前的前缀。tf_FromCity 或 tf_ToCity ,
                             // tf_FromCity__tf_Province__tf_name . 这样的

  private AdditionParentModuleField primarykeyField; // 主键的附加字段
  private AdditionParentModuleField nameField; // 名称字段的附加字段
  private Map<String, AdditionParentModuleField> additionFields; // BaseModule对于这个父模块的所有的附加字段
  private List<AdditionParentModuleField> tempField; // 临时的附加字段

  private List<UserGlobalFilter> userGlobalFilters; // 加在这个模块上的全局过滤条件,即用户权限

  private List<FieldFilter> fieldFilters; // 加在这个模块上的其他用户设定的条件
  private List<NavigateFilter> navigates; // 加在这个模块上的导航值

  private String leftoutterjoin; // leftoutterjoin 的语法 ,加在 sql语句里

  private Map<String, ParentModule> parents = new java.util.HashMap<String, ParentModule>();<span style="white-space:pre">	</span>//所有的父模块

  private boolean addToSQL; // 当前模块是否加入到sql中,如果是父模块,必须加入,如果是祖父模块,则根据附加字段的权限的设置来确定是否加入

  private Object sonModuleHierarchy; // 上级子模块的指针,其实是子模块的指针
}
  在上面的类中,设置了作为一个父模块所具有的各种字段属性。在BaseModule中生成这些父模块数据的时候用到了递归一级级的将生成父模块。
  3、确定哪些父模块需要加上权限设置。在生成每一个父模块的时候,都要对和当前用户的全局权限的设置进行比对。
  • 如果当前父模块上有权限设置,则要比对基准模块,如果基准模块相同,则要比较模块路径,这三个都对了,那么就把限定的条件加在这个父模块中。比如说当前父模块为“等级”,基准模块为“订单”,权限设置中的路径为:客户单位--等级。这三个条件都符合了,就说明这个权限是加在这里的。
  • 如果当前父模块上有权限设置,限定条件的基准模块不是当前基准模块的时候,就要判断当前限定条件的路径是不是 当前基准模块到此父模块的最后几级,如果是的话,那么就要根据模块权限延展性而把当前条件加进来。这个比较难懂,下面举一个例子说明:
    在系统中有一个权限:基准模块是“客户单位”,在其父模块“等级”上加了权限,那么在基准模块为“客户单位”的子模块“订单”的时候,这个权限也应该是有效的。
[置顶] 常规功能和模块自定义系统 (cfcmms)—038模块记录(数据)的权限设计(3)_第1张图片
  • 还有一种就是直接加在模块上的权限,只要遇到该模块作为基准模块或者父模块都把权限加进来。比如有个权限直接加在“省份”上,那么在所有出现的省份模块中都要加入这个权限。
  4、确定哪些父模块必须出现在查询语句中。一个稍大的系统中一个模块可能有数十个甚至上百个父模块,在生成查询语句的时候不可能将所有的父模块都关联进去。只能将那些必要的父模块才进行关联。下面来确定哪些父模块是必须加入的:
  • 当前基准模块的直接父模块。也就是说当前基准模块的所有的ManyToOne的模块都要加进去;(这个和我整个架构系统有关,是必须加入的)
  • 所有的有权限要加入的祖父模块都必须加到查询语句中。
  • 当前基准模块到有权限的祖父模块中间的连接模块也都要加进去。比如说在“订单”上有“等级”的权限,那么作为中间关联的模块“客户单位”也必须加进关联关系中。
  • 可以对基准模块设置一些父模块中的附加字段,有附加字段的父模块也要加入。
  • 可以在父模块的字段上设置一些查询条件,这包括前台传入的筛选条件或者是导航,也要求把这些关联关系加入。
  所有需要加入到查询语句中的把 addToSQL设置为true即可。

  5、生成查询语句的各个子句
  • 生成select的各个字段:包括当前基准模块的所有字段,和ManyToOne模块的id和name字段;以及所有的父模块和子模块中的附加字段;
  • 生成from子句:包括当前基准模块和所有的需要加入的父模块,form子句中基本是以 left outter join 来进行联接;
  • 生成where子句:加入当前基准模块的所有权限设置和用户指定的查询条件;
  • 生成order by子句:根据模块的默认设置或者用户的指定来生成排序字段;
  至此权限的从设置到查询数据过程基本完成。下面来根据这个模似的系统来看看加入了一些权限以后的具体的sql语句。

你可能感兴趣的:([置顶] 常规功能和模块自定义系统 (cfcmms)—038模块记录(数据)的权限设计(3))