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;
///
/// 数据权限业务类
///
public class BaseDataAuthorizeApp : SqlSugarBaseApp
{
///
/// 构造函数
///
///
///
///
public BaseDataAuthorizeApp(ISugarUnitOfWork unitWork, ISimpleClient repository,
IAuth auth) : base(unitWork, repository, auth)
{
}
#region 获取数据
///
/// 获取数据权限对应关系数据列表
///
/// 编码
/// 用户或角色主键
///
public Task> GetList(string code, string[] objectIds)
{
return Repository.AsQueryable()
.Where(t => t.Code.Equals(code)
&& (objectIds.Contains(t.ObjectId) || t.ObjectType == 3)
).ToListAsync();
}
///
/// 获取数据权限列表(分页)
///
public async Task>>> GetPageList(BaseDataAuthListReq req)
{
RefAsync 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>>
{
Result = new PageInfo>
{
Items = result,
Total = totalCount
}
};
}
///
/// 获取实体
///
/// 主键
///
public Task GetEntity(string keyValue)
{
return Repository.GetByIdAsync(keyValue);
}
#endregion
#region 提交数据
///
/// 删除实体数据
///
/// 主键
///
public async Task DeleteEntity(string keyValue)
{
await Repository.DeleteByIdAsync(keyValue);
}
///
/// 保存实体数据(新增、修改)
///
/// 主键
/// 实体
///
public async Task SaveEntity(string keyValue, BaseDataAuthReq record)
{
var user = _auth.GetCurrentUser();
var entity = record.MapTo();
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 扩展方法
///
/// 获取自定义表单数据权限查询条件
///
/// 自定义表单功能主键
///
/// todo 可以优化,使代码逻辑清晰,减少代码量,比如有无公式,可以合并部分逻辑
/// 逻辑:1. 超级用户不做过滤 2. 先看有无公式(默认条件使用and连接),再看有无分组公式(分组公式使用and连接)
public async Task 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();
var objectIds = new List { 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();
// 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();
}
///
/// 获取数据 where 值部分
///
/// 数据类型
/// 数据值
///
///
// todo 扩展改造
private async Task 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())}']";
break;
case 6:
text = "";
break;
case 7:
text = $"'{string.Join(",", userInfo.Roles.Select(t => t.Id).MapToList())}'";
break;
default:
text = $"'{value}'";
break;
}
return text;
}
#endregion
public async Task> GetEntityByCode(string code)
{
var formModuleEntity = await Repository
.ChangeRepository>()
.GetFirstAsync(r => r.Id == code);
if (formModuleEntity != null)
{
var formScheme = await base.Repository.ChangeRepository>()
.GetFirstAsync(r => r.Id == formModuleEntity.FormVerison);
return new Response()
{
Result = formScheme,
Message = "查询成功"
};
}
throw new Exception("code无效");
}
}