2024-11-13 09:19:06 +08:00
using System.Text ;
using Infrastructure ;
using OpenAuth.App.Base ;
2025-04-18 13:23:18 +08:00
using OpenAuth.App ;
2024-11-13 09:19:06 +08:00
using OpenAuth.App.Interface ;
using OpenAuth.App.Permission.Request ;
using OpenAuth.Repository ;
using OpenAuth.Repository.Domain ;
using SqlSugar ;
namespace OpenAuth.App.Permission ;
/// <summary>
/// 数据权限业务类
/// </summary>
public class BaseDataAuthorizeApp : SqlSugarBaseApp < BaseDataAuth , SugarDbContext >
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="unitWork"></param>
/// <param name="repository"></param>
/// <param name="auth"></param>
public BaseDataAuthorizeApp ( ISugarUnitOfWork < SugarDbContext > unitWork , ISimpleClient < BaseDataAuth > repository ,
IAuth auth ) : base ( unitWork , repository , auth )
{
}
#region 获取数据
/// <summary>
/// 获取数据权限对应关系数据列表
/// </summary>
/// <param name="code">编码</param>
/// <param name="objectIds">用户或角色主键</param>
/// <returns></returns>
public Task < List < BaseDataAuth > > GetList ( string code , string [ ] objectIds )
{
return Repository . AsQueryable ( )
. Where ( t = > t . Code . Equals ( code )
& & ( objectIds . Contains ( t . ObjectId ) | | t . ObjectType = = 3 )
) . ToListAsync ( ) ;
}
/// <summary>
/// 获取数据权限列表(分页)
/// </summary>
public async Task < Response < PageInfo < List < BaseDataAuth > > > > GetPageList ( BaseDataAuthListReq req )
{
RefAsync < int > totalCount = 0 ;
// 实现查询及分页
var result = await Repository . AsQueryable ( )
. WhereIF ( req . Type ! = null , t = > t . Type = = req . Type )
. WhereIF ( ! string . IsNullOrEmpty ( req . ObjectId ) , t = > t . ObjectId = = req . ObjectId )
. WhereIF ( ! string . IsNullOrEmpty ( req . key ) , t = > t . Name . Contains ( req . key ) | | t . Code . Contains ( req . key ) )
. ToPageListAsync ( req . page , req . limit , totalCount ) ;
return new Response < PageInfo < List < BaseDataAuth > > >
{
Result = new PageInfo < List < BaseDataAuth > >
{
Items = result ,
Total = totalCount
}
} ;
}
/// <summary>
/// 获取实体
/// </summary>
/// <param name="keyValue">主键</param>
/// <returns></returns>
public Task < BaseDataAuth > GetEntity ( string keyValue )
{
return Repository . GetByIdAsync ( keyValue ) ;
}
# endregion
#region 提交数据
/// <summary>
/// 删除实体数据
/// </summary>
/// <param name="keyValue">主键</param>
/// <returns></returns>
public async Task DeleteEntity ( string keyValue )
{
await Repository . DeleteByIdAsync ( keyValue ) ;
}
/// <summary>
/// 保存实体数据(新增、修改)
/// </summary>
/// <param name="keyValue">主键</param>
/// <param name="entity">实体</param>
/// <returns></returns>
public async Task SaveEntity ( string keyValue , BaseDataAuthReq record )
{
var user = _auth . GetCurrentUser ( ) ;
var entity = record . MapTo < BaseDataAuth > ( ) ;
entity . Formula = record . Formula . ToJson ( ) ;
if ( string . IsNullOrEmpty ( keyValue ) )
{
entity . Id = Guid . NewGuid ( ) . ToString ( ) ;
entity . CreateDate = DateTime . Now ;
entity . CreateUserId = user . User . Id . ToString ( ) ;
entity . CreateUserName = user . User . Name ;
}
else
{
entity . Id = keyValue ;
entity . ModifyDate = DateTime . Now ;
entity . ModifyUserId = user . User . Id . ToString ( ) ;
entity . ModifyUserName = user . User . Name ;
}
// 全部值都更新了
await Repository . InsertOrUpdateAsync ( entity ) ;
}
# endregion
#region 扩展方法
/// <summary>
/// 获取自定义表单数据权限查询条件
/// </summary>
/// <param name="code">自定义表单功能主键</param>
/// <returns></returns>
/// todo 可以优化,使代码逻辑清晰,减少代码量,比如有无公式,可以合并部分逻辑
/// 逻辑: 1. 超级用户不做过滤 2. 先看有无公式( 默认条件使用and连接) , 再看有无分组公式( 分组公式使用and连接)
public async Task < string > GetWhereSql ( string code )
{
// 取得当前用户信息
var userInfo = _auth . GetCurrentUser ( ) ;
// 超级用户不做过滤 todo 暂时注释
/ * if ( userInfo . User . Id . Equals ( - 1 ) )
{
return "" ;
} * /
// 26个字母干嘛用的? 别名?
var numIndex = new [ ]
{
"A" , "B" , "C" , "D" , "E" , "F" , "G" , "H" , "I" , "J" , "K" , "L" , "M" , "N" ,
"O" , "P" , "Q" , "R" , "S" , "T" , "U" , "V" , "W" , "X" , "Y" , "Z"
} ;
// 获取数据权限配置信息
// 查询当前用户所拥有的角色或者岗位
var roleIds = userInfo . Roles . Select ( t = > t . Id ) . MapToList < string > ( ) ;
var objectIds = new List < string > { userInfo . User . Id + "" , } ;
objectIds . AddRange ( roleIds ) ;
// code 自定义表单功能主键 查询当前用户或者用户所属角色是否有设置的权限规则
var baseDataAuths = await GetList ( code , objectIds . ToArray ( ) ) ;
// 保存拼接的sql
var whereSqlSb = new StringBuilder ( ) ;
var sqlNum = 0 ;
foreach ( var auth in baseDataAuths )
{
//{"formula":"A and B",
//"conditions":[
//{"f_FieldId":"F_text0","f_Symbol":1,"f_FieldValueType":1,"f_FieldValue":"xxx","group":"","type":"","table":"","cfield":"","field":"","relationField":""}],
//"formulas":[1 or 2]}
// 判断是否是开头
// 先运行这里
// 不同数据权限规则使用or ,很可能只有一条吧
whereSqlSb . Append ( sqlNum > 0 ? " AND ( " : " ( " ) ;
var strSql = "" ;
// 反序列化数据权限公式
var itemFormula = auth . Formula . ToObject < FormulaObject > ( ) ;
// formula 不存在时, 直接使用and连接
if ( string . IsNullOrEmpty ( itemFormula . Formula ) )
{
// Conditions
// 默认公式
for ( var i = 1 ; i < itemFormula . Conditions . Count + 1 ; i + + )
{
var conditionItem = itemFormula . Conditions [ i - 1 ] ;
conditionItem . index = i ; // 赋值索引, 后面应该会用到, 从1开始
// 这里的Group是字符串, 大概是字母 A B 之类 , 如何没有Group, 条件之间用 and 连接
if ( ! string . IsNullOrEmpty ( conditionItem . Group ) )
{
continue ;
}
if ( strSql ! = "" )
{
strSql + = " AND " ;
}
strSql + = " {@hopetry" + i + "hopetry@} " ;
}
// 公式为空,分组公式不为空
if ( itemFormula . Formulas ! = null & & itemFormula . Formulas . Count > 0 )
{
// 假设分组公式只有1个 【{“value”: "1 or 2"}】 多个分组公式之间, 使用and连接
for ( var i = 0 ; i < itemFormula . Formulas . Count ; i + + )
{
if ( itemFormula . Conditions . FindIndex ( t = > t . Group = = numIndex [ i ] ) ! = - 1 )
{
if ( strSql ! = "" )
{
strSql + = " AND " ;
}
strSql + = " {@hopetry" + numIndex [ i ] + "hopetry@} " ;
}
}
}
}
// 存在公式
else
{
// 当分组公式存在时,公式含有分组信息,如: A and B
strSql = itemFormula . Formula ;
// 为什么从1开头
for ( var i = 1 ; i < itemFormula . Conditions . Count + 1 ; i + + )
{
var conditionItem = itemFormula . Conditions [ i - 1 ] ;
// 取了条件没有使用
conditionItem . index = i ;
strSql = strSql . Replace ( "" + i , "{@hopetry" + i + "hopetry@}" ) ;
}
if ( itemFormula . Formulas ! = null & & itemFormula . Formulas . Count > 0 )
{
for ( var i = 0 ; i < itemFormula . Formulas . Count ; i + + )
{
strSql = strSql . Replace ( numIndex [ i ] , "{@hopetry" + numIndex [ i ] + "hopetry@}" ) ;
}
}
}
// 针对公组公式存在, 再做部分处理, todo 暂时可以忽略,不实现分组
if ( itemFormula . Formulas ! = null & & itemFormula . Formulas . Count > 0 )
{
// 分组公式
for ( var i = 0 ; i < itemFormula . Formulas . Count ; i + + )
{
var groupSql = new StringBuilder ( ) ;
var groupList = itemFormula . Conditions . FindAll ( t = > t . Group = = numIndex [ i ] ) ;
if ( groupList . Count > 0 )
{
groupSql . Append (
// relationField 关联字段(外键) 这里的Table应该是子表吧
$" {groupList[0].RelationField} in ( SELECT {groupList[0].Field} FROM {groupList[0].Table} WHERE " ) ;
// 初始化分组公式
var groupSqlWhere = "" ;
if ( string . IsNullOrEmpty ( itemFormula . Formulas [ i ] . Value ) )
{
foreach ( var groupItem in groupList )
{
if ( groupSqlWhere ! = "" )
{
groupSqlWhere + = " AND " ;
}
groupSqlWhere + = " {@hopetry" + groupItem . index + "hopetry@} " ;
}
}
else
{
groupSqlWhere = itemFormula . Formulas [ i ] . Value ;
foreach ( var groupItem in groupList )
{
groupSqlWhere = groupSqlWhere . Replace ( "" + groupItem . index ,
"{@hopetry" + groupItem . index + "hopetry@}" ) ;
}
}
foreach ( var groupItem in groupList )
{
var strone = new StringBuilder ( ) ;
if ( groupItem . F_Symbol . Equals ( "8" ) )
{
strone . Append ( $" ({groupItem.Cfield} " ) ;
}
else
{
strone . Append ( $" {groupItem.Cfield} " ) ;
}
var value = await GetValue ( int . Parse ( groupItem . F_FieldValueType ) , groupItem . F_FieldValue ) ;
switch ( int . Parse ( groupItem . F_Symbol ) )
{
case 1 : // 等于
strone . Append ( $" = {value}" ) ;
break ;
case 2 : // 大于
strone . Append ( $" > {value}" ) ;
break ;
case 3 : // 大于等于
strone . Append ( $" >= {value}" ) ;
break ;
case 4 : // 小于
strone . Append ( $" < {value}" ) ;
break ;
case 5 : // 小于等于
strone . Append ( $" <= {value}" ) ;
break ;
case 6 : // 包含
value = value . Replace ( "'" , "" ) ;
strone . Append ( $" like '%{value}%'" ) ;
break ;
case 7 : // 包含于
value = value . Replace ( "," , "','" ) ;
strone . Append ( $" in ({value})" ) ;
break ;
case 8 : // 不等于
strone . Append ( $" != {value} or {groupItem.Cfield} is null ) " ) ;
break ;
case 9 : // 不包含
value = value . Replace ( "'" , "" ) ;
strone . Append ( $" not like '%{value}%'" ) ;
break ;
case 10 : // 不包含于
value = value . Replace ( "," , "','" ) ;
strone . Append ( $" not in ({value})" ) ;
break ;
default :
break ;
}
groupSqlWhere = groupSqlWhere . Replace ( "{@hopetry" + groupItem . index + "hopetry@}" ,
strone . ToString ( ) ) ;
}
groupSql . Append ( groupSqlWhere ) ;
groupSql . Append ( " ) " ) ;
strSql = strSql . Replace ( "{@hopetry" + numIndex [ i ] + "hopetry@}" , groupSql . ToString ( ) ) ;
}
}
}
// 填充占位符, 生成实际wheresql
var num = 1 ;
foreach ( var conditionItem in itemFormula . Conditions )
{
// 这里的group应该是 A B C 之类的字母
if ( string . IsNullOrEmpty ( conditionItem . Group ) )
{
var strone = new StringBuilder ( ) ;
if ( conditionItem . Type = = "glbd" ) // 未使用
{
strone . Append (
$" {conditionItem.RelationField} in ( SELECT {conditionItem.Field} FROM {conditionItem.Table} WHERE {conditionItem.Cfield} " ) ;
}
else
{
// 8 不等于
if ( conditionItem . F_Symbol . Equals ( "8" ) )
{
strone . Append ( $" ( {conditionItem.F_FieldId}" ) ;
}
else
{
strone . Append ( $" {conditionItem.F_FieldId}" ) ;
}
}
var value = await GetValue ( int . Parse ( conditionItem . F_FieldValueType ) , conditionItem . F_FieldValue ) ;
// 如果 value 值是 userId
switch ( int . Parse ( conditionItem . F_Symbol ) )
{
case 1 : // 等于
strone . Append ( $" = {value}" ) ;
break ;
case 2 : // 大于
strone . Append ( $" > {value}" ) ;
break ;
case 3 : // 大于等于
strone . Append ( $" >= {value}" ) ;
break ;
case 4 : // 小于
strone . Append ( $" < {value}" ) ;
break ;
case 5 : // 小于等于
strone . Append ( $" <= {value}" ) ;
break ;
case 6 : // 包含
value = value . Replace ( "'" , "" ) ;
strone . Append ( $" like '%{value}%'" ) ;
break ;
case 7 : // 包含于
value = value . Replace ( "," , "','" ) ;
value = value . Replace ( "#" , "," ) ;
strone . Append ( $" in ({value})" ) ;
break ;
case 8 : // 不等于
strone . Append ( $" != {value}" ) ;
if ( conditionItem . Type = = "glbd" )
{
strone . Append ( $" or {conditionItem.Cfield} is null " ) ;
}
else
{
strone . Append ( $" or {conditionItem.F_FieldId} is null ) " ) ;
}
break ;
case 9 : // 不包含
value = value . Replace ( "'" , "" ) ;
strone . Append ( $" not like '%{value}%'" ) ;
break ;
case 10 : // 不包含于
value = value . Replace ( "," , "','" ) ;
strone . Append ( $" not in ({value})" ) ;
break ;
default :
break ;
}
strone . Append ( conditionItem . Type = = "glbd" ? " ) " : " " ) ;
strSql = strSql . Replace ( "{@hopetry" + num + "hopetry@}" , strone . ToString ( ) ) ;
}
num + + ;
}
whereSqlSb . Append ( strSql ) ;
whereSqlSb . Append ( " ) " ) ;
sqlNum + + ;
}
Console . WriteLine ( "strRes:" + whereSqlSb . ToString ( ) ) ;
return whereSqlSb . ToString ( ) ;
}
/// <summary>
/// 获取数据 where 值部分
/// </summary>
/// <param name="type">数据类型</param>
/// <param name="value">数据值</param>
/// <returns></returns>
///
// todo 扩展改造
private async Task < string > GetValue ( int? type , string value )
{
var userInfo = _auth . GetCurrentUser ( ) ;
//1.文本(string) 2.登录者ID 3.登录者账号 4.登录者部门 5. 登录者部门及下属部门 6.登录者岗位 7.登录者角色 10. 文本( int)
string text ;
switch ( type )
{
case 1 : // 文本(string)
text = $"'{value}'" ;
break ;
case 10 : // 文本( int)
text = value ;
break ;
case 2 : // 登录者ID(本地创建数据)
text = userInfo . User . Id + "" ;
break ;
case 3 : // 登录者账号
text = $"'{userInfo.User.Account}'" ;
break ;
// todo 扩展实现
case 4 : // 本部门
text =
$"( SELECT CAST ( \" OrgId \ " AS VARCHAR ) AS \"OrgId\" FROM sys_userorg WHERE \"UserId\" = '{userInfo.User.Id}' )" ;
break ;
case 5 : // 本部门及子部门
text =
$"select CAST(\" Id \ " AS VARCHAR) from sys_org where string_to_array(\"CascadeId\"#'.') && ARRAY['{string.Join(" , ", userInfo.Orgs.Select(t => t.Id).MapToList<string>())}']" ;
break ;
case 6 :
text = "" ;
break ;
case 7 :
text = $"'{string.Join(" , ", userInfo.Roles.Select(t => t.Id).MapToList<string>())}'" ;
break ;
default :
text = $"'{value}'" ;
break ;
}
return text ;
}
# endregion
public async Task < Response < Repository . Domain . FormScheme > > GetEntityByCode ( string code )
{
var formModuleEntity = await Repository
. ChangeRepository < SugarRepositiry < FormModuleEntity > > ( )
. GetFirstAsync ( r = > r . Id = = code ) ;
if ( formModuleEntity ! = null )
{
var formScheme = await base . Repository . ChangeRepository < SugarRepositiry < Repository . Domain . FormScheme > > ( )
. GetFirstAsync ( r = > r . Id = = formModuleEntity . FormVerison ) ;
return new Response < Repository . Domain . FormScheme > ( )
{
Result = formScheme ,
Message = "查询成功"
} ;
}
throw new Exception ( "code无效" ) ;
}
}