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

039模块记录(数据)的权限设计(4)


  下面显示一下上几节讲的数据权限的具体例子,这些都是我在开发过程中用于测试的数据。首先加入二个权限的数据,代码如下:
    // 加入几个模拟的的全局条件

    UserGlobalFilter globalFilter = new UserGlobalFilter();
    globalFilter.setBaseModule(SystemAndLoginInfoService.getModuleWithName("Orders"));<span style="white-space:pre">	// 基准模块
    globalFilter.setFilterModule(SystemAndLoginInfoService.getModuleWithName("Province")); // 加入权限的模块
    globalFilter.setFieldAhead("tf_Customer.tf_City.tf_Province"); // 从基准模块到加入权限的模块的路径
    List<String> ids = new ArrayList<String>();
    ids.add("06");
    ids.add("07");
    ids.add("08");<span style="white-space:pre">	// 限定的三个值
    globalFilter.setKeys(ids);

    userSession.getUserGlobalFilters().add(globalFilter);

    UserGlobalFilter globalFilter2 = new UserGlobalFilter();
    globalFilter2.setBaseModule(SystemAndLoginInfoService.getModuleWithName("Customer"));// 基准模块
    globalFilter2.setFilterModule(SystemAndLoginInfoService.getModuleWithName("Rate"));// 加入权限的模块
    globalFilter2.setFieldAhead("tf_Rate");// 路径
    List<String> ids2 = new ArrayList<String>();
    ids2.add("10");
    globalFilter2.setKeys(ids2);
    userSession.getUserGlobalFilters().add(globalFilter2);<span style="white-space:pre">	// 模块的权限放在用户session中
    
  在上面加入了二个权限的设置,第一个是加在“订单”模块的父模块“省份”之上的,其路径为:客户单位--市--省,第二是加在“客户”的“等级“模块之上,其路径为tf_Rate,这二个同件同时满足。生成的“订单”查询语句如下:

SELECT 
    (SELECT 
            COUNT(*)
        FROM
            _Attachment
        WHERE
            tf_moduleId = '6040'
                AND tf_moduleIdValue = _this.tf_ordersId) AS `tf_attachmentCount`,// 附件张数
    GETATTACHMENTNAMES('6040', _this.tf_ordersId) AS `tf_attachmentTooltip`, //附件tooltip
    _this.tf_ordersId AS `tf_ordersId`,
    _this.tf_ordersNumber AS `tf_ordersNumber`,
    (DATE_FORMAT(_this.tf_date, '%Y年%m月')) AS `tf_yearmonth`, // 自定义的计算字段
    _this.tf_finished AS `tf_finished`,
    _this.tf_remark AS `tf_remark`,
    _this_14.tf_cityId AS `tf_FromCity.tf_cityId`,<span style="white-space:pre">	</span>//始发地市id
    _this_14.tf_name AS `tf_FromCity.tf_name`,<span style="white-space:pre">		</span>//始发地市名称<span style="white-space:pre">	</span>
    _this_12.tf_salesmanId AS `tf_Salesman.tf_salesmanId`,<span style="white-space:pre">	</span>//销售人员id
    _this_12.tf_name AS `tf_Salesman.tf_name`,<span style="white-space:pre">			</span>//销售人员名称
    _this_13.tf_storageId AS `tf_Storage.tf_storageId`,<span style="white-space:pre">	</span>//商品仓库id
    _this_13.tf_name AS `tf_Storage.tf_name`,<span style="white-space:pre">	</span>//商品仓库名称
    _this_11.tf_customerId AS `tf_Customer.tf_customerId`,<span style="white-space:pre">	</span>//客户id
    _this_11.tf_name AS `tf_Customer.tf_name`,<span style="white-space:pre">			</span>//客户名称
<span style="white-space:pre">	</span>//以上8个字段是当前模块的直接父模块,必须要加入。
	//下面的字段都是对于当前基准模块的附加字段,这些字段可以直接显示在grid中或者form中。<pre name="code" class="sql">    (IF(_this_14_21.tf_gdp > 1000,
        'gdp大于1000',
        'gdp小于1000')) AS `tf_FromCity.tf_Province.tf_calcGDPmap`,<span style="white-space:pre">	</span>//父模块的计算字段
    _this_14_21.tf_shortname AS `tf_FromCity.tf_Province.tf_shortname`,<span style="white-space:pre">	</span>//始发地省的简称
    _this_14_21.tf_provinceId AS `tf_FromCity.tf_Province.tf_provinceId`, //始地地省id
    _this_14_21.tf_name AS `tf_FromCity.tf_Province.tf_name`,    //始发地省名称
    _this_13_21_31.tf_provinceId AS `tf_Storage.tf_City.tf_Province.tf_provinceId`, //仓库所在省份id
    _this_13_21_31.tf_name AS `tf_Storage.tf_City.tf_Province.tf_name`   //仓库所在省份名称
FROM
    `Orders` AS _this
        LEFT OUTER JOIN
    `City` `_this_14` ON `_this_14`.tf_cityId = `_this`.tf_fromCityId<span style="white-space:pre">	</span>// 始发地市
        LEFT OUTER JOIN
    `Province` `_this_14_21` ON `_this_14_21`.tf_provinceId = `_this_14`.tf_provinceId //始发地省
        LEFT OUTER JOIN
    `Salesman` `_this_12` ON `_this_12`.tf_salesmanId = `_this`.tf_salesmanId  // 销售员
        LEFT OUTER JOIN
    `Storage` `_this_13` ON `_this_13`.tf_storageId = `_this`.tf_storageId   // 仓库
        LEFT OUTER JOIN
    `City` `_this_13_21` ON `_this_13_21`.tf_cityId = `_this_13`.tf_cityId   //仓库所在市
        LEFT OUTER JOIN
    `Province` `_this_13_21_31` ON `_this_13_21_31`.tf_provinceId = `_this_13_21`.tf_provinceId  // 仓库所在省
        LEFT OUTER JOIN
    `Customer` `_this_11` ON `_this_11`.tf_customerId = `_this`.tf_customerId  // 客户单位
        LEFT OUTER JOIN
    `City` `_this_11_21` ON `_this_11_21`.tf_cityId = `_this_11`.tf_cityId   //客户单位所在市
        LEFT OUTER JOIN
    `Province` `_this_11_21_31` ON `_this_11_21_31`.tf_provinceId = `_this_11_21`.tf_provinceId   //客户单位所在省
        LEFT OUTER JOIN
    `Rate` `_this_11_23` ON `_this_11_23`.tf_rateId = `_this_11`.tf_rateId   //客户单位等级
        LEFT OUTER JOIN
    `City` `_this_15` ON `_this_15`.tf_cityId = `_this`.tf_toCityId    //目的地市
WHERE
    (_this_11_21_31.tf_provinceId IN ('06' , '07', '08'))<span style="white-space:pre">	</span>//加在客户单位的省上面的条件
        AND (_this_11_23.tf_rateId IN ('10'))     //加在客户单位的等级上面的条件


 
 
  在上面的sql语中,只加入了必要的表,这些表中有的是有需要的字段,有的有附加字段,还有的是有限定的条件。所有不需要加入的表都不加入。这些sql语句应该是动态生成的,每次请求都有可能是不一样的。例如如果在查询或导航中,需要限定  “目的地省”,那么就又要在from中加入目的地省的模块。但是字段的部分还是不变的。
  下面来看一下延展性,在查询订单明细的时候,会是如下的语句:
SELECT 
    _this.tf_ordersDetailId AS `tf_ordersDetailId`,
    _this.tf_name AS `tf_name`,
    _this.tf_number AS `tf_number`,
    _this.tf_unitPrice AS `tf_unitPrice`,
    _this.tf_subtotalPrice AS `tf_subtotalPrice`,
    _this.tf_remark AS `tf_remark`,
    _this_12.tf_productId AS `tf_Product.tf_productId`,<span style="white-space:pre">	</span>//商品id
    _this_12.tf_name AS `tf_Product.tf_name`,<span style="white-space:pre">	</span>//商品名称
    _this_11.tf_ordersId AS `tf_Orders.tf_ordersId`,<span style="white-space:pre">	</span>//订单id
    _this_11.tf_ordersNumber AS `tf_Orders.tf_ordersNumber`<span style="white-space:pre">	</span>//订单名称 
FROM
    `OrdersDetail` AS _this
        LEFT OUTER JOIN
    `Product` `_this_12` ON `_this_12`.tf_productId = `_this`.tf_productId<span style="white-space:pre">	</span>//商品
        LEFT OUTER JOIN
    `Orders` `_this_11` ON `_this_11`.tf_ordersId = `_this`.tf_ordersId<span style="white-space:pre">		</span>//订单
        LEFT OUTER JOIN
    `Customer` `_this_11_21` ON `_this_11_21`.tf_customerId = `_this_11`.tf_customerId<span style="white-space:pre">	</span>//客户
        LEFT OUTER JOIN
    `City` `_this_11_21_31` ON `_this_11_21_31`.tf_cityId = `_this_11_21`.tf_cityId<span style="white-space:pre">	</span>//客户市
        LEFT OUTER JOIN
    `Province` `_this_11_21_31_41` ON `_this_11_21_31_41`.tf_provinceId = `_this_11_21_31`.tf_provinceId  //客户省
        LEFT OUTER JOIN
    `Rate` `_this_11_21_33` ON `_this_11_21_33`.tf_rateId = `_this_11_21`.tf_rateId<span style="white-space:pre">	</span>//客户等级
WHERE
    (_this_11_21_31_41.tf_provinceId IN ('06' , '07', '08'))   //附加在订单上的权限
        AND (_this_11_21_33.tf_rateId IN ('10'))<span style="white-space:pre">	</span><span style="font-family: Arial, Helvetica, sans-serif;">//附加在订单上的权限</span>

  在上面的sql语句中,由于没有加入附加字段,因此加入到form子句中的父模块会比较小,只加了必须的模块。

  下面看一下查询客户的语句:
SELECT 
    _this.tf_customerId AS `tf_customerId`,
    _this.tf_name AS `tf_name`,
    _this.tf_address AS `tf_address`,
    _this.tf_linkman AS `tf_linkman`,
    _this.tf_linkmanTel AS `tf_linkmanTel`,
    _this.tf_taxId AS `tf_taxId`,
    _this.tf_remark AS `tf_remark`,
    _this_12.tf_tradeId AS `tf_Trade.tf_tradeId`,
    _this_12.tf_name AS `tf_Trade.tf_name`,
    _this_11.tf_cityId AS `tf_City.tf_cityId`,
    _this_11.tf_name AS `tf_City.tf_name`,
    _this_13.tf_rateId AS `tf_Rate.tf_rateId`,
    _this_13.tf_name AS `tf_Rate.tf_name`
FROM
    `Customer` AS _this
        LEFT OUTER JOIN
    `Trade` `_this_12` ON `_this_12`.tf_tradeId = `_this`.tf_tradeId
        LEFT OUTER JOIN
    `City` `_this_11` ON `_this_11`.tf_cityId = `_this`.tf_cityId
        LEFT OUTER JOIN
    `Rate` `_this_13` ON `_this_13`.tf_rateId = `_this`.tf_rateId
WHERE
    (_this_13.tf_rateId IN ('10'))
  在这个语句中,只有限定了客户是金牌客户这个条件,并没有加入三个省份。因为这三个省份是加在基准模块是“订单”上的。如果将第一个条件的基准模块改为“客户”那么也会加入省份的限定条件。而这时订单也会继承客户的限定条件。

  在取得模块数据之前,先要编译一下满足当前条件记录数。在取得记录数的时候,只要加入有权限的父模块就行了。有附加字段的都不要加入。如要统计当前权限下的所有可以看到的订单个数:
select count(*)
 from 
`Orders` as _this
 left outer join `Customer` `_this_11` on `_this_11`.tf_customerId = `_this`.tf_customerId
 left outer join `City` `_this_11_21` on `_this_11_21`.tf_cityId = `_this_11`.tf_cityId
 left outer join `Province` `_this_11_21_31` on `_this_11_21_31`.tf_provinceId = `_this_11_21`.tf_provinceId
 left outer join `Rate` `_this_11_23` on `_this_11_23`.tf_rateId = `_this_11`.tf_rateId
 where 
 (_this_11_21_31.tf_provinceId in ('06' , '07' , '08')) 
 and 
 (_this_11_23.tf_rateId in ('10')) 



  以上即为本系统中关于模块记录权限的主要设计思想和实现的方法。我现在也正在想更加完善的方法,如果有建议或意见请跟贴回复,谢谢。



你可能感兴趣的:(开发经验,ExtJs6,cfcmms,常规功能和模块自定义系统)