Files
Docker/CloudBuilder/CloudBuilder.Master.Service/FamilyTreeUtility/FamilyTreePermissionHelper.cs
T
2026-10-19 13:36:58 +08:00

138 lines
6.4 KiB
C#

using CloudBuilder.Core.DatabaseAccessor.Entity;
using CloudBuilder.Master.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudBuilder.Master.Service.FamilyTreeUtility
{
public class FamilyTreePermissionHelper
{
private readonly IApplicationService service;
public FamilyTreePermissionHelper(IApplicationService service)
{
this.service = service;
}
private FamilyTreeChildrenMapEntity[] childrens = null;
private FamilyTreeSpouseMapEntity[] spouses = null;
public bool HasPermission(string treeId, string personId)
{
IRepository<FamilyTreePermissionEntity> repositoryPermission = service.GetRepository<IRepository<FamilyTreePermissionEntity>>();
FamilyTreePermissionEntity[] permissions = repositoryPermission.DetachedEntities.Where(x => x.TreeId == treeId && x.UserName == service.UserId && x.ValidIndc == YesNoPolicy.YES).ToArray();
if (permissions != null && permissions.Where(x => x.ManagerIndc == YesNoPolicy.YES).Any()) return true;
return GetPersonId(permissions, treeId).Where(x => x == personId).Any();
}
/// <summary>
/// 管理员口径:该谱系下此用户存在 ManagerIndc=Y 且已生效的权限行(谱级操作专属)。
/// 注意与 HasPermission 区分:成员若绑始祖或始祖在其上溯两代内,HasPermission(始祖) 也会为真,
/// 不能拿它当谱级闸,否则这些成员能改谱/删谱
/// </summary>
public bool IsManager(string treeId)
{
IRepository<FamilyTreePermissionEntity> repositoryPermission = service.GetRepository<IRepository<FamilyTreePermissionEntity>>();
return repositoryPermission.DetachedEntities
.Where(x => x.UserName == service.UserId
&& x.TreeId == treeId
&& x.ManagerIndc == YesNoPolicy.YES
&& x.ValidIndc == YesNoPolicy.YES)
.Any();
}
/// <summary>
/// 成员口径:该谱系下此用户存在已生效权限行(不分管理员/成员档),
/// 供「往谱里新增人」这类无既有 PersonId 可校验的操作做最小闸门
/// </summary>
public bool IsMember(string treeId)
{
IRepository<FamilyTreePermissionEntity> repositoryPermission = service.GetRepository<IRepository<FamilyTreePermissionEntity>>();
return repositoryPermission.DetachedEntities
.Where(x => x.UserName == service.UserId
&& x.TreeId == treeId
&& x.ValidIndc == YesNoPolicy.YES)
.Any();
}
/// <summary>
/// 当前用户在本谱可编的族员集合(家支主线,口径与 HasPermission 完全同源);
/// 供详情接口下发给前端做「逐个目标人」的编辑/删除钮判定(锚点级 IsCanAmend 盖不住关系行里的旁支)
/// </summary>
public List<string> GetAmendablePersonIds(string treeId)
{
IRepository<FamilyTreePermissionEntity> repositoryPermission = service.GetRepository<IRepository<FamilyTreePermissionEntity>>();
FamilyTreePermissionEntity[] permissions = repositoryPermission.DetachedEntities.Where(x => x.TreeId == treeId && x.UserName == service.UserId && x.ValidIndc == YesNoPolicy.YES).ToArray();
return GetPersonId(permissions, treeId);
}
public List<string> GetPersonId(FamilyTreePermissionEntity[] permissions, string treeId)
{
List<string> ps = new List<string>();
if (permissions == null || permissions.Length == 0) return ps;
IRepository<FamilyTreeChildrenMapEntity> repositoryChildrenMap = service.GetRepository<IRepository<FamilyTreeChildrenMapEntity>>();
if (childrens == null || childrens.Length == 0)
childrens = repositoryChildrenMap.DetachedEntities.Where(x => x.TreeId == treeId).ToArray();
IRepository<FamilyTreeSpouseMapEntity> repositorySpouseMap = service.GetRepository<IRepository<FamilyTreeSpouseMapEntity>>();
if (spouses == null || spouses.Length == 0)
spouses = repositorySpouseMap.DetachedEntities.Where(x => x.TreeId == treeId).ToArray();
foreach (var permission in permissions)
{
PackPersonIdByChildrenMaps(childrens, spouses, permission.PersonId, ps);
}
return ps;
}
public void PackPersonIdByChildrenMaps(FamilyTreeChildrenMapEntity[] childrens, FamilyTreeSpouseMapEntity[] spouses, string personId, List<string> ps)
{
if (!ps.Contains(personId))
ps.Add(personId);
//所有下级都有权限
if (childrens != null && childrens.Where(x => x.PersonId == personId).Any())
{
foreach (FamilyTreeChildrenMapEntity child in childrens.Where(x => x.PersonId == personId))
PackPersonIdByChildrenMaps(childrens, spouses, child.ChildrenId, ps);
}
//向上延伸:最多两代(父、祖),含每一代配偶(家支口径;不含兄弟姐妹等旁支)
string cursor = personId;
for (int up = 0; up < 2 && childrens != null; up++)
{
string father = childrens.Where(x => x.ChildrenId == cursor).Select(x => x.PersonId).FirstOrDefault();
// ps 去重兼做环保护:父链成环或已收过即停
if (string.IsNullOrEmpty(father) || ps.Contains(father)) break;
ps.Add(father);
PackPersonIdBySpouseMaps(spouses, father, ps);
cursor = father;
}
//配偶都有权限
PackPersonIdBySpouseMaps(spouses, personId, ps);
}
public void PackPersonIdBySpouseMaps(FamilyTreeSpouseMapEntity[] spouses, string personId, List<string> ps)
{
if (spouses == null) return;
if (spouses.Where(x => x.PersonId == personId).Any())
{
foreach (FamilyTreeSpouseMapEntity s in spouses.Where(x => x.PersonId == personId))
{
if (!ps.Contains(s.SpouseId))
ps.Add(s.SpouseId);
}
}
}
}
}