You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

507 lines
20 KiB
C#

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Text;
using Infrastructure;
using OpenAuth.App.Base;
using OpenAuth.App.BaseApp.Base;
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无效");
}
}