using CloudBuilder.Core.DatabaseAccessor; using CloudBuilder.Core.DatabaseAccessor.Entity; using CloudBuilder.Core.Service; using CloudBuilder.Master.Data; using CloudBuilder.Master.Entity; using CloudBuilder.Master.Policy; using CloudBuilder.Master.SearchCriteria; using CloudBuilder.Security.Data; using CloudBuilder.Security.Entity; using CloudBuilder.Security.Service; using CloudBuilder.Security.Utility; using Microsoft.AspNetCore.Authorization; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; using Microsoft.Extensions.DependencyInjection; using System.Collections.Generic; namespace CloudBuilder.Master.Service { public class FamilyTreeService : IFamilyTreeService { private readonly IApplicationService service; private IRepository repository; public FamilyTreeService(IApplicationService service) { this.service = service; repository = service.GetRepository>(); } [PermissionOperate(name: MasterPermissionPolicy.FamilyTree, operate: Operate.Find)] public FamilyTreeData FindAllByTreeId(string treeId) { FamilyTreeData data = new FamilyTreeData(); if (string.IsNullOrEmpty(treeId)) return data; FamilyTreeEntity d = repository.DetachedEntities.Where(x => x.TreeId == treeId).FirstOrDefault(); if (d == null) return data; data.FamilyTree = new FamilyTreeDisplayData(d); data.CurrentPerson = new FamilyPersonData(); IRepository repositoryFamilyPerson = repository.GetRepository>(); var currentPerson = d.AncestorPersonId; data.CurrentPerson.FamilyPerson = new FamilyPersonDisplayData(repositoryFamilyPerson.DetachedEntities.Where(x => x.PersonId == currentPerson).FirstOrDefault()!); data.FamilyTree.AncestorPersonGenealogyName = data.CurrentPerson.FamilyPerson.GenealogyName; IRepository repositoryChildrenMap = repository.GetRepository>(); IRepository repositorySpouseMap = repository.GetRepository>(); data.CurrentPerson.FamilyTreeSpouseMaps = repositorySpouseMap.GetRepository>().DetachedEntities.Where(x => x.TreeId == treeId).OrderBy(x => x.Orderby).ToArray(); data.CurrentPerson.FamilyTreeChildrenMaps = repositoryChildrenMap.GetRepository>().DetachedEntities.Where(x => x.TreeId == treeId).OrderBy(x => x.Orderby).ToArray(); List ps = new List(); ps.Add(d.AncestorPersonId); if (data.CurrentPerson.FamilyTreeSpouseMaps != null && data.CurrentPerson.FamilyTreeSpouseMaps.Length > 0) { ps.AddRange(data.CurrentPerson.FamilyTreeSpouseMaps.Select(x => x.SpouseId).ToArray()); } if (data.CurrentPerson.FamilyTreeChildrenMaps != null && data.CurrentPerson.FamilyTreeChildrenMaps.Length > 0) { ps.AddRange(data.CurrentPerson.FamilyTreeChildrenMaps.Select(x => x.ChildrenId).ToArray()); } ps = ps.Distinct().ToList(); FamilyPersonEntity[] families = repositoryFamilyPerson.DetachedEntities.Where(x => ps.AsQueryable().Contains(x.PersonId)).ToArray(); if (families != null && families.Length > 0) { data.CurrentPerson.FamilyTreePersons = families.Select(x => new FamilyPersonDisplayData(x)).ToArray(); } return data; } [PermissionOperate(name: MasterPermissionPolicy.FamilyTree, operate: Operate.Find)] public FamilyTreeData FindByKey(string key) { return FindByCurrentPerson(key, null); } [PermissionOperate(name: MasterPermissionPolicy.FamilyTree, operate: Operate.Find)] public FamilyTreeData FindByCurrentPerson(string key, string personId) { FamilyTreeData data = new FamilyTreeData(); if (string.IsNullOrEmpty(key)) return data; FamilyTreeEntity d = repository.DetachedEntities.Where(x => x.TreeId == key).FirstOrDefault(); if (d == null) return data; data.FamilyTree = new FamilyTreeDisplayData(d); data.CurrentPerson = new FamilyPersonData(); IRepository repositoryFamilyPerson = repository.GetRepository>(); var currentPerson = personId; if (string.IsNullOrEmpty(personId)) { currentPerson = d.AncestorPersonId; data.CurrentPerson.FamilyPerson = new FamilyPersonDisplayData(repositoryFamilyPerson.DetachedEntities.Where(x => x.PersonId == currentPerson).FirstOrDefault()!); data.FamilyTree.AncestorPersonGenealogyName = data.CurrentPerson.FamilyPerson.GenealogyName; } else { data.CurrentPerson.FamilyPerson = new FamilyPersonDisplayData(repositoryFamilyPerson.DetachedEntities.Where(x => x.PersonId == d.AncestorPersonId).FirstOrDefault()!); data.FamilyTree.AncestorPersonGenealogyName = data.CurrentPerson.FamilyPerson.GenealogyName; data.CurrentPerson.FamilyPerson = new FamilyPersonDisplayData(repositoryFamilyPerson.DetachedEntities.Where(x => x.PersonId == personId).FirstOrDefault()!); } IRepository repositoryChildrenMap = repository.GetRepository>(); IRepository repositorySpouseMap = repository.GetRepository>(); data.CurrentPerson.FamilyTreeSpouseMaps = repositorySpouseMap.GetRepository>().DetachedEntities.Where(x => x.PersonId == currentPerson).OrderBy(x => x.Orderby).ToArray(); //data.CurrentPerson.FamilyTreeParentMaps = repositoryChildrenMap.GetRepository>().DetachedEntities.Where(x => x.ChildrenId == key).OrderBy(x => x.Orderby).ToArray(); data.CurrentPerson.FamilyTreeChildrenMaps = repositoryChildrenMap.GetRepository>().DetachedEntities.Where(x => x.PersonId == currentPerson).OrderBy(x => x.Orderby).ToArray(); return data; } [PermissionOperate(name: MasterPermissionPolicy.FamilyTree, operate: Operate.Find)] public FamilyTreeResultData FindBySearchCriteria(FamilyTreeSearchCriteria criteria) { FamilyTreeResultData data = new FamilyTreeResultData(); FamilyTreeViewEntity[] list = null; int count = 0; string sqlWhere = null; if (criteria.Filter != null && criteria.Filter.Length > 0) { sqlWhere = SearchFilter.ComposeWhereClause(criteria.Filter); } FamilyTreeViewEntity entity = FamilyTreeViewEntity.GetInstance(repository.GetDbContext().Database.ProviderName); string sql = entity.GetSelectTopFrom(criteria.limit, criteria.page, criteria.orderby.StringToDbField(), criteria.orderbytag, sqlWhere); IRepository repositoryView = repository.GetRepository>(); string err = null; try { list = repositoryView.FromSql(sql).ToArray(); } catch (System.Exception ex) { err = ex.Message; } if (list != null && list.Length > 0) { sql = entity.GetSelectCountFrom(sqlWhere); count = Convert.ToInt32(repository.ExecuteScalar(sql)); } data.Limit = criteria.limit; data.Page = criteria.page; data.Datas = list; data.Total = count; //data.Sql = sql; data.ErrorMessage = err; return data; } //[PermissionOperate(name: MasterPermissionPolicy.FamilyTree, operate: Operate.Print)] public dynamic PrintBySearchCriteria(FamilyTreeSearchCriteria criteria) { throw new NotImplementedException(); } [PermissionOperate(name: MasterPermissionPolicy.FamilyTree, operate: Operate.Insert)] [UnitOfWork] public FamilyTreeData Insert(FamilyTreeData data) { FamilyTreeEntity d = repository.DetachedEntities.Where(x => x.TreeName == data.FamilyTree.TreeName).FirstOrDefault(); if (d != null) { throw new ValidatedException("家族名称已存在."); } Validate(data.FamilyTree); d = new FamilyTreeEntity(); ObjectCopyHelper.Copy(data.FamilyTree, d); ISecurityGeneratorNumberService securityGeneratorNumberService = service.ServiceProvider.GetService()!; d.TreeId = securityGeneratorNumberService.GetNo(MasterPrefixPolicy.FAMILY_TREE, MasterPrefixPolicy.FAMILY_TREE_TREE_ID, MasterPrefixPolicy.FAMILY_TREE_PREFIX, YesNoPolicy.NO, MasterPrefixPolicy.FAMILY_TREE_FORMAT); repository.InsertNow(d); var currentPerson = d.AncestorPersonId; if (data.CurrentPerson != null && data.CurrentPerson.FamilyPerson != null && !string.IsNullOrEmpty(data.CurrentPerson.FamilyPerson.PersonId)) { currentPerson = data.CurrentPerson.FamilyPerson.PersonId; } if (data.CurrentPerson != null && data.CurrentPerson.FamilyTreeSpouseMaps != null && data.CurrentPerson.FamilyTreeSpouseMaps.Length > 0) data.CurrentPerson.FamilyTreeSpouseMaps.ToLookup(x => x.TreeId = d.TreeId); if (data.CurrentPerson != null && data.CurrentPerson.FamilyTreeChildrenMaps != null && data.CurrentPerson.FamilyTreeChildrenMaps.Length > 0) data.CurrentPerson.FamilyTreeChildrenMaps.ToLookup(x => x.TreeId = d.TreeId); SaveSpouseMaps(currentPerson, data.CurrentPerson.FamilyTreeSpouseMaps); //SaveParentMaps(data.CurrentPerson.FamilyPerson.PersonId, data.CurrentPerson.FamilyTreeParentMaps); SaveSonMaps(currentPerson, data.CurrentPerson.FamilyTreeChildrenMaps); return FindByCurrentPerson(d.TreeId, currentPerson); } private void SaveSpouseMaps(string personId, FamilyTreeSpouseMapViewEntity[] maps) { IRepository repositoryMapView = repository.GetRepository>(); IRepository repositoryMap = repository.GetRepository>(); FamilyTreeSpouseMapViewEntity[] olds = repositoryMapView.Entities.Where(x => x.PersonId == personId).ToArray(); if (olds != null && olds.Length > 0) { foreach (FamilyTreeSpouseMapViewEntity old in olds) { repositoryMap.DeleteNow(new FamilyTreeSpouseMapEntity() { TreeId = old.TreeId, PersonId = personId, SpouseId = old.SpouseId }); } } if (maps == null || maps.Length == 0) return; int i = 1; foreach (FamilyTreeSpouseMapViewEntity map in maps.OrderBy(x => x.Orderby).ToArray()) { repositoryMap.InsertNow(new FamilyTreeSpouseMapEntity() { TreeId = map.TreeId, PersonId = personId, SpouseId = map.SpouseId, MarryDateText = map.MarryDateText, MarryDate = map.MarryDate, DivorceDateText = map.DivorceDateText, DivorceDate = map.DivorceDate, MarryType = map.MarryType, IsCurrent = map.IsCurrent, Remark = map.Remark, Orderby = i++ }); } } private void SaveParentMaps(string personId, FamilyTreeChildrenMapViewEntity[] maps) { IRepository repositoryMapView = repository.GetRepository>(); IRepository repositoryMap = repository.GetRepository>(); FamilyTreeChildrenMapViewEntity[] olds = repositoryMapView.Entities.Where(x => x.ChildrenId == personId).ToArray(); if (olds != null && olds.Length > 0) { foreach (FamilyTreeChildrenMapViewEntity old in olds) { repositoryMap.DeleteNow(new FamilyTreeChildrenMapEntity() { TreeId = old.TreeId, ChildrenId = personId, PersonId = old.PersonId }); } } if (maps == null || maps.Length == 0) return; int maxOrderBy = 0; foreach (FamilyTreeChildrenMapViewEntity map in maps) { FamilyTreeChildrenMapViewEntity[] oldMaps = repositoryMapView.Entities.Where(x => x.PersonId == map.PersonId).ToArray(); if (oldMaps != null && oldMaps.Count() > 0) maxOrderBy = oldMaps.Max(x => x.Orderby); repositoryMap.InsertNow(new FamilyTreeChildrenMapEntity() { TreeId = map.TreeId, ChildrenId = personId, PersonId = map.PersonId, Orderby = oldMaps == null ? 1 : maxOrderBy + 1 }); } } private void SaveSonMaps(string personId, FamilyTreeChildrenMapViewEntity[] maps) { IRepository repositoryMapView = repository.GetRepository>(); IRepository repositoryMap = repository.GetRepository>(); FamilyTreeChildrenMapViewEntity[] olds = repositoryMapView.Entities.Where(x => x.PersonId == personId).ToArray(); if (olds != null && olds.Length > 0) { foreach (FamilyTreeChildrenMapViewEntity old in olds) { repositoryMap.DeleteNow(new FamilyTreeChildrenMapEntity() { TreeId = old.TreeId, PersonId = personId, ChildrenId = old.ChildrenId }); } } if (maps == null || maps.Length == 0) return; int i = 1; foreach (FamilyTreeChildrenMapViewEntity map in maps.OrderBy(x => x.Orderby).ToArray()) { repositoryMap.InsertNow(new FamilyTreeChildrenMapEntity() { TreeId = map.TreeId, PersonId = personId, SpouseId = map.SpouseId, ChildrenId = map.ChildrenId, RelationType = map.RelationType, Remark = map.Remark, Orderby = i++ }); } } private void Validate(FamilyTreeEntity d) { List sysTableSchemas = service.ServiceProvider.GetRequiredService().FindByTableName(FamilyTreeEntity.DB_NAME_FAMILY_TREE); ValidateHelper.ValidateString(d, sysTableSchemas.ToArray()); } [PermissionOperate(name: MasterPermissionPolicy.FamilyTree, operate: Operate.Update)] [UnitOfWork] public FamilyTreeData Update(FamilyTreeData data) { FamilyTreeEntity d = repository.DetachedEntities.Where(x => x.TreeName == data.FamilyTree.TreeName).FirstOrDefault(); if (d == null) { throw new ValidatedException("家族名称不存在."); } Validate(data.FamilyTree); ObjectCopyHelper.Copy(data.FamilyTree, d); repository.UpdateNow(d); var currentPerson = data.CurrentPerson != null ? data.CurrentPerson.FamilyPerson.PersonId : null; if (string.IsNullOrEmpty(currentPerson)) currentPerson = d.AncestorPersonId; if (data.CurrentPerson != null && data.CurrentPerson.FamilyTreeSpouseMaps != null && data.CurrentPerson.FamilyTreeSpouseMaps.Length > 0) data.CurrentPerson.FamilyTreeSpouseMaps.ToLookup(x => x.TreeId = d.TreeId); if (data.CurrentPerson != null && data.CurrentPerson.FamilyTreeChildrenMaps != null && data.CurrentPerson.FamilyTreeChildrenMaps.Length > 0) data.CurrentPerson.FamilyTreeChildrenMaps.ToLookup(x => x.TreeId = d.TreeId); SaveSpouseMaps(data.CurrentPerson.FamilyPerson.PersonId, data.CurrentPerson.FamilyTreeSpouseMaps); //SaveParentMaps(data.CurrentPerson.FamilyPerson.PersonId, data.CurrentPerson.FamilyTreeParentMaps); SaveSonMaps(data.CurrentPerson.FamilyPerson.PersonId, data.CurrentPerson.FamilyTreeChildrenMaps); return FindByCurrentPerson(data.FamilyTree.TreeId, currentPerson); } [PermissionOperate(name: MasterPermissionPolicy.FamilyTree, operate: Operate.Delete)] [UnitOfWork] public void Delete(string key) { var ent = repository.DetachedEntities.Where(x => x.TreeId == key).FirstOrDefault()!; if (ent == null) return; repository.DeleteNow(ent); DeleteSpouses(ent.AncestorPersonId); DeleteChildrens(ent.AncestorPersonId); } private void DeleteSpouses(string personId) { IRepository repositoryMap = repository.GetRepository>(); FamilyTreeSpouseMapEntity[] olds = repositoryMap.Entities.Where(x => x.PersonId == personId).ToArray(); if (olds != null && olds.Length > 0) { repositoryMap.DeleteNow(olds); } } private void DeleteChildrens(string personId) { IRepository repositoryMap = repository.GetRepository>(); FamilyTreeChildrenMapEntity[] olds = repositoryMap.Entities.Where(x => x.PersonId == personId).ToArray(); if (olds != null && olds.Length > 0) { repositoryMap.DeleteNow(olds); } foreach (FamilyTreeChildrenMapEntity old in olds) { DeleteChildrens(old.ChildrenId); DeleteSpouses(old.ChildrenId); } } [PermissionOperate(name: MasterPermissionPolicy.FamilyTree, operate: Operate.Delete)] [UnitOfWork] public void Deletes(string[] keys) { foreach (string key in keys) { Delete(key); } } } }