ow
This commit is contained in:
1 parent
94d5fb2ec9
commit
6c86c59bdc
15 files changed
+429
-14
No files matched your search
@@ -1396,5 +1396,64 @@ namespace CloudBuilder.Master.Service
|
||||
}
|
||||
catch (Exception ex) { Console.WriteLine($"[FamilyTreeExchange] 审计写入失败: {ex.Message}"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 族谱「统计」 tab 的聚合查询:总数/男/女/世代层数 + 各世代人数分布。
|
||||
/// 世代 = 始祖起 BFS 深度(始祖=1 世);未连到始祖的旁支不入世代桶,只计入 Total。
|
||||
/// 与 ListExchangeFiles/SaveExchangeFile 同套成员闸:非本族成员不能拉本族聚合数据。
|
||||
/// </summary>
|
||||
[PermissionOperate(name: MasterPermissionPolicy.FamilyTree, operate: Operate.Find)]
|
||||
public FamilyTreeStatisticsData GetStatistics(string treeId)
|
||||
{
|
||||
FamilyTreeStatisticsData data = new FamilyTreeStatisticsData();
|
||||
if (string.IsNullOrEmpty(treeId)) return data;
|
||||
|
||||
FamilyTreeEntity d = repository.DetachedEntities.Where(x => x.TreeId == treeId).FirstOrDefault();
|
||||
if (d == null) throw new ValidatedException("族谱不存在.");
|
||||
|
||||
var helper = new FamilyTreePermissionHelper(service);
|
||||
if (!helper.IsMember(treeId) && !helper.IsManager(treeId))
|
||||
throw new ValidatedException("您不是该族谱成员.");
|
||||
|
||||
IRepository<FamilyPersonEntity> repositoryPerson = repository.GetRepository<IRepository<FamilyPersonEntity>>();
|
||||
IRepository<FamilyTreeChildrenMapEntity> repositoryChildrenMap = repository.GetRepository<IRepository<FamilyTreeChildrenMapEntity>>();
|
||||
|
||||
FamilyPersonEntity[] persons = repositoryPerson.DetachedEntities.Where(x => x.TreeId == treeId).ToArray();
|
||||
FamilyTreeChildrenMapEntity[] childrenMaps = repositoryChildrenMap.DetachedEntities.Where(x => x.TreeId == treeId).ToArray();
|
||||
|
||||
data.Total = persons.Length;
|
||||
data.Male = persons.Count(x => x.Gender == "M");
|
||||
data.Female = persons.Count(x => x.Gender == "W");
|
||||
|
||||
// BFS 从始祖起逐层下钻,记录每人世代号;genByPerson 去重兼做环保护
|
||||
Dictionary<string, int> genByPerson = new Dictionary<string, int>();
|
||||
if (!string.IsNullOrEmpty(d.AncestorPersonId))
|
||||
{
|
||||
Queue<KeyValuePair<string, int>> q = new Queue<KeyValuePair<string, int>>();
|
||||
q.Enqueue(new KeyValuePair<string, int>(d.AncestorPersonId, 1));
|
||||
genByPerson[d.AncestorPersonId] = 1;
|
||||
while (q.Count > 0)
|
||||
{
|
||||
var cur = q.Dequeue();
|
||||
foreach (var c in childrenMaps.Where(x => x.PersonId == cur.Key))
|
||||
{
|
||||
if (string.IsNullOrEmpty(c.ChildrenId) || genByPerson.ContainsKey(c.ChildrenId)) continue;
|
||||
genByPerson[c.ChildrenId] = cur.Value + 1;
|
||||
q.Enqueue(new KeyValuePair<string, int>(c.ChildrenId, cur.Value + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.GenerationCount = genByPerson.Count > 0 ? genByPerson.Values.Max() : 0;
|
||||
|
||||
// 按世代升序聚合;未入桶的旁支不入世代分布(仅计 Total)
|
||||
data.PerGeneration = genByPerson.Values
|
||||
.GroupBy(g => g)
|
||||
.OrderBy(grp => grp.Key)
|
||||
.Select(grp => new FamilyTreeGenerationCountData { Generation = grp.Key, Count = grp.Count() })
|
||||
.ToArray();
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user