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 repositoryPermission = service.GetRepository>(); 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(); } /// /// 管理员口径:该谱系下此用户存在 ManagerIndc=Y 且已生效的权限行(谱级操作专属)。 /// 注意与 HasPermission 区分:成员若绑始祖或始祖在其上溯两代内,HasPermission(始祖) 也会为真, /// 不能拿它当谱级闸,否则这些成员能改谱/删谱 /// public bool IsManager(string treeId) { IRepository repositoryPermission = service.GetRepository>(); return repositoryPermission.DetachedEntities .Where(x => x.UserName == service.UserId && x.TreeId == treeId && x.ManagerIndc == YesNoPolicy.YES && x.ValidIndc == YesNoPolicy.YES) .Any(); } /// /// 成员口径:该谱系下此用户存在已生效权限行(不分管理员/成员档), /// 供「往谱里新增人」这类无既有 PersonId 可校验的操作做最小闸门 /// public bool IsMember(string treeId) { IRepository repositoryPermission = service.GetRepository>(); return repositoryPermission.DetachedEntities .Where(x => x.UserName == service.UserId && x.TreeId == treeId && x.ValidIndc == YesNoPolicy.YES) .Any(); } /// /// 当前用户在本谱可编的族员集合(家支主线,口径与 HasPermission 完全同源); /// 供详情接口下发给前端做「逐个目标人」的编辑/删除钮判定(锚点级 IsCanAmend 盖不住关系行里的旁支) /// public List GetAmendablePersonIds(string treeId) { IRepository repositoryPermission = service.GetRepository>(); FamilyTreePermissionEntity[] permissions = repositoryPermission.DetachedEntities.Where(x => x.TreeId == treeId && x.UserName == service.UserId && x.ValidIndc == YesNoPolicy.YES).ToArray(); return GetPersonId(permissions, treeId); } public List GetPersonId(FamilyTreePermissionEntity[] permissions, string treeId) { List ps = new List(); if (permissions == null || permissions.Length == 0) return ps; IRepository repositoryChildrenMap = service.GetRepository>(); if (childrens == null || childrens.Length == 0) childrens = repositoryChildrenMap.DetachedEntities.Where(x => x.TreeId == treeId).ToArray(); IRepository repositorySpouseMap = service.GetRepository>(); 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 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 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); } } } } }