From 4359903d9ca68a26b8a0651a99a373ecdb3ceac2 Mon Sep 17 00:00:00 2001 From: owenchen Date: Tue, 1 Sep 2026 15:26:40 +0800 Subject: [PATCH] ow --- .../FamilyTreeService.auto.cs | 284 ++++- .../Data/FamilyPersonData.cs | 7 + .../Data/FamilyTreeData.cs | 4 + .../Data/FamilyTreeDisplayData.cs | 7 +- .../Data/FamilyTreeResultData.cs | 2 +- .../CloudBuilderMasterRegistEntity.auto.cs | 12 +- .../FamilyTreeChildrenMapEntity.auto.cs | 85 +- .../FamilyTreeChildrenMapEntityKey.auto.cs | 12 +- .../FamilyTreeChildrenMapViewEntity.auto.cs | 208 ++++ .../Entity/FamilyTreeSpouseMapEntity.auto.cs | 115 +- .../FamilyTreeSpouseMapEntityKey.auto.cs | 8 +- .../FamilyTreeSpouseMapViewEntity.auto.cs | 228 ++++ .../Entity/FamilyTreeViewEntity.auto.cs | 178 ++++ .../Policy/MasterPrefixPolicy.cs | 6 + .../Service/IFamilyTreeService.auto.cs | 3 +- .../Master/FamilyTreeRequest.auto.cs | 108 +- .../Security/LocaleRequest.auto.cs | 126 +-- .../LocaleService.cs | 26 + .../Service/ILocaleService.auto.cs | 1 + .../Master/FamilyTreeController.auto.cs | 27 + .../Security/LocaleController.auto.cs | 27 + CloudBuilder/Data/insert_locale.sql | 22 + .../CloudBuilder.CodeGenerator.exe.lnk | Bin 2176 -> 2178 bytes .../CloudBuilder.CodeGenerator/Program.cs | 15 +- CodeGenerator/Lib/CloudBuilder.Core.dll | Bin 233472 -> 235520 bytes WebVue/src/hooks/useLocalePolicy.ts | 58 ++ .../security/operation-to-enquiry.ts | 6 + .../src/service/master/familyTreeService.ts | 10 + WebVue/src/service/security/localeService.ts | 11 + .../src/views/master/FamilyPersonEnquiry.vue | 6 +- .../views/master/FamilyPersonOperation.vue | 23 +- WebVue/src/views/master/FamilyTreeEnquiry.vue | 345 ++++++ .../src/views/master/FamilyTreeOperation.vue | 984 ++++++++++++++++++ 33 files changed, 2708 insertions(+), 246 deletions(-) create mode 100644 CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapViewEntity.auto.cs create mode 100644 CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapViewEntity.auto.cs create mode 100644 CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeViewEntity.auto.cs create mode 100644 CloudBuilder/Data/insert_locale.sql create mode 100644 WebVue/src/hooks/useLocalePolicy.ts create mode 100644 WebVue/src/views/master/FamilyTreeEnquiry.vue create mode 100644 WebVue/src/views/master/FamilyTreeOperation.vue diff --git a/CloudBuilder/CloudBuilder.Master.Service/FamilyTreeService.auto.cs b/CloudBuilder/CloudBuilder.Master.Service/FamilyTreeService.auto.cs index b4ba0d7..985c0e4 100644 --- a/CloudBuilder/CloudBuilder.Master.Service/FamilyTreeService.auto.cs +++ b/CloudBuilder/CloudBuilder.Master.Service/FamilyTreeService.auto.cs @@ -1,4 +1,4 @@ - + using CloudBuilder.Core.DatabaseAccessor; using CloudBuilder.Core.DatabaseAccessor.Entity; using CloudBuilder.Core.Service; @@ -6,7 +6,13 @@ 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; namespace CloudBuilder.Master.Service { public class FamilyTreeService : IFamilyTreeService @@ -19,19 +25,62 @@ namespace CloudBuilder.Master.Service this.service = service; repository = service.GetRepository>(); } - [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(); - return data;// repository.DetachedEntities.Where(x => x.TreeId == key).FirstOrDefault()!; + 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(); - FamilyTreeEntity[] list = null; + FamilyTreeViewEntity[] list = null; int count = 0; @@ -42,13 +91,15 @@ namespace CloudBuilder.Master.Service sqlWhere = SearchFilter.ComposeWhereClause(criteria.Filter); } - FamilyTreeEntity entity = FamilyTreeEntity.GetInstance(repository.GetDbContext().Database.ProviderName); + 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 = repository.FromSql(sql).ToArray(); + list = repositoryView.FromSql(sql).ToArray(); } catch (System.Exception ex) { @@ -81,14 +132,192 @@ namespace CloudBuilder.Master.Service [UnitOfWork] public FamilyTreeData Insert(FamilyTreeData data) { - throw new NotImplementedException(); + 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) { - throw new NotImplementedException(); + 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; + + 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); } @@ -96,8 +325,43 @@ namespace CloudBuilder.Master.Service [UnitOfWork] public void Delete(string key) { - var ent= repository.DetachedEntities.Where(x => x.TreeId == key).FirstOrDefault()!; - if (ent != null) { repository.DeleteNow(ent); } + 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)] diff --git a/CloudBuilder/CloudBuilder.Master/Data/FamilyPersonData.cs b/CloudBuilder/CloudBuilder.Master/Data/FamilyPersonData.cs index 901a3ee..713ffe0 100644 --- a/CloudBuilder/CloudBuilder.Master/Data/FamilyPersonData.cs +++ b/CloudBuilder/CloudBuilder.Master/Data/FamilyPersonData.cs @@ -1,4 +1,5 @@ using CloudBuilder.Core.Authorization; +using CloudBuilder.Master.Entity; using System; using System.Collections.Generic; using System.Linq; @@ -11,5 +12,11 @@ namespace CloudBuilder.Master.Data public class FamilyPersonData { public FamilyPersonDisplayData? FamilyPerson { get; set; } + + public FamilyTreeSpouseMapViewEntity[]? FamilyTreeSpouseMaps { get; set; } + + public FamilyTreeChildrenMapViewEntity[]? FamilyTreeParentMaps { get; set; } + + public FamilyTreeChildrenMapViewEntity[]? FamilyTreeChildrenMaps { get; set; } } } diff --git a/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeData.cs b/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeData.cs index 5792854..fbaa388 100644 --- a/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeData.cs +++ b/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeData.cs @@ -1,4 +1,5 @@ using CloudBuilder.Core.Authorization; +using CloudBuilder.Master.Entity; using System; using System.Collections.Generic; using System.Linq; @@ -12,5 +13,8 @@ namespace CloudBuilder.Master.Data public class FamilyTreeData { public FamilyTreeDisplayData? FamilyTree { get; set; } + + public FamilyPersonData? CurrentPerson { get; set; } + } } diff --git a/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeDisplayData.cs b/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeDisplayData.cs index a233786..67150fa 100644 --- a/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeDisplayData.cs +++ b/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeDisplayData.cs @@ -14,14 +14,17 @@ namespace CloudBuilder.Master.Data /// [NotMapped] [TypeScript] - public class FamilyTreeDisplayData : FamilyPersonEntity + public class FamilyTreeDisplayData : FamilyTreeEntity { public FamilyTreeDisplayData() { } - public FamilyTreeDisplayData(FamilyPersonEntity entity) + public FamilyTreeDisplayData(FamilyTreeEntity entity) { CopyFrom(entity); } + + public string? AncestorPersonGenealogyName { get; set; } + } } diff --git a/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeResultData.cs b/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeResultData.cs index 43e1639..3cd9140 100644 --- a/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeResultData.cs +++ b/CloudBuilder/CloudBuilder.Master/Data/FamilyTreeResultData.cs @@ -12,6 +12,6 @@ namespace CloudBuilder.Master.Data [TypeScript] public class FamilyTreeResultData : SearchCriteriaResultData { - public FamilyTreeEntity[]? Datas { get; set; } + public FamilyTreeViewEntity[]? Datas { get; set; } } } diff --git a/CloudBuilder/CloudBuilder.Master/Entity/CloudBuilderMasterRegistEntity.auto.cs b/CloudBuilder/CloudBuilder.Master/Entity/CloudBuilderMasterRegistEntity.auto.cs index fcbca47..60e53d6 100644 --- a/CloudBuilder/CloudBuilder.Master/Entity/CloudBuilderMasterRegistEntity.auto.cs +++ b/CloudBuilder/CloudBuilder.Master/Entity/CloudBuilderMasterRegistEntity.auto.cs @@ -41,7 +41,17 @@ builder.Entity().HasKey(c => new {c.TreeId,c.PersonId -//***END*** + +builder.Entity(eb => { eb.HasNoKey(); }); + +builder.Entity(eb => { eb.HasNoKey(); }); + +builder.Entity(eb => { eb.HasNoKey(); }); + +builder.Entity(eb => { eb.HasNoKey(); }); + +builder.Entity(eb => { eb.HasNoKey(); }); + //***END*** } } } diff --git a/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapEntity.auto.cs b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapEntity.auto.cs index b33f50a..5c0f02d 100644 --- a/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapEntity.auto.cs +++ b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapEntity.auto.cs @@ -14,51 +14,55 @@ namespace CloudBuilder.Master.Entity { } - [Column("created_datetime")] - public DateTime CreatedDatetime { get; set; } - [Column("created_by")] - public string CreatedBy { get; set; } - [Column("updated_datetime")] - public DateTime UpdatedDatetime { get; set; } - [Column("updated_by")] - public string UpdatedBy { get; set; } - [Column("tree_id")] - public string TreeId { get; set; } - [Column("person_id")] - public string PersonId { get; set; } - [Column("spouse_id")] - public string SpouseId { get; set; } [Column("children_id")] public string ChildrenId { get; set; } + [Column("created_by")] + public string CreatedBy { get; set; } + [Column("created_datetime")] + public DateTime CreatedDatetime { get; set; } + [Column("orderby")] + public int Orderby { get; set; } + [Column("person_id")] + public string PersonId { get; set; } [Column("relation_type")] public string? RelationType { get; set; } [Column("remark")] public string? Remark { get; set; } + [Column("spouse_id")] + public string? SpouseId { get; set; } + [Column("tree_id")] + public string TreeId { get; set; } + [Column("updated_by")] + public string UpdatedBy { get; set; } + [Column("updated_datetime")] + public DateTime UpdatedDatetime { get; set; } - public const string CREATED_DATETIME = "CreatedDatetime"; - public const string CREATED_BY = "CreatedBy"; - public const string UPDATED_DATETIME = "UpdatedDatetime"; - public const string UPDATED_BY = "UpdatedBy"; - public const string TREE_ID = "TreeId"; - public const string PERSON_ID = "PersonId"; - public const string SPOUSE_ID = "SpouseId"; public const string CHILDREN_ID = "ChildrenId"; + public const string CREATED_BY = "CreatedBy"; + public const string CREATED_DATETIME = "CreatedDatetime"; + public const string ORDERBY = "Orderby"; + public const string PERSON_ID = "PersonId"; public const string RELATION_TYPE = "RelationType"; public const string REMARK = "Remark"; + public const string SPOUSE_ID = "SpouseId"; + public const string TREE_ID = "TreeId"; + public const string UPDATED_BY = "UpdatedBy"; + public const string UPDATED_DATETIME = "UpdatedDatetime"; public const string DB_NAME_FAMILY_TREE_CHILDREN_MAP = "family_tree_children_map"; - public const string DB_NAME_FIELDS="created_datetime,created_by,updated_datetime,updated_by,tree_id,person_id,spouse_id,children_id,relation_type,remark"; + public const string DB_NAME_FIELDS="children_id,created_by,created_datetime,orderby,person_id,relation_type,remark,spouse_id,tree_id,updated_by,updated_datetime"; - public const string DB_CREATED_DATETIME = "created_datetime"; - public const string DB_CREATED_BY = "created_by"; - public const string DB_UPDATED_DATETIME = "updated_datetime"; - public const string DB_UPDATED_BY = "updated_by"; - public const string DB_TREE_ID = "tree_id"; - public const string DB_PERSON_ID = "person_id"; - public const string DB_SPOUSE_ID = "spouse_id"; public const string DB_CHILDREN_ID = "children_id"; + public const string DB_CREATED_BY = "created_by"; + public const string DB_CREATED_DATETIME = "created_datetime"; + public const string DB_ORDERBY = "orderby"; + public const string DB_PERSON_ID = "person_id"; public const string DB_RELATION_TYPE = "relation_type"; public const string DB_REMARK = "remark"; + public const string DB_SPOUSE_ID = "spouse_id"; + public const string DB_TREE_ID = "tree_id"; + public const string DB_UPDATED_BY = "updated_by"; + public const string DB_UPDATED_DATETIME = "updated_datetime"; private string ProviderName { get; set; } @@ -79,23 +83,24 @@ namespace CloudBuilder.Master.Entity throw new NullReferenceException("Source entity is null."); } - this.CreatedDatetime = source.CreatedDatetime; - this.CreatedBy = source.CreatedBy; - this.UpdatedDatetime = source.UpdatedDatetime; - this.UpdatedBy = source.UpdatedBy; - this.TreeId = source.TreeId; - this.PersonId = source.PersonId; - this.SpouseId = source.SpouseId; this.ChildrenId = source.ChildrenId; + this.CreatedBy = source.CreatedBy; + this.CreatedDatetime = source.CreatedDatetime; + this.Orderby = source.Orderby; + this.PersonId = source.PersonId; this.RelationType = source.RelationType; this.Remark = source.Remark; + this.SpouseId = source.SpouseId; + this.TreeId = source.TreeId; + this.UpdatedBy = source.UpdatedBy; + this.UpdatedDatetime = source.UpdatedDatetime; if (includeSystemFields) { - this.CreatedDatetime = source.CreatedDatetime; this.CreatedBy = source.CreatedBy; - this.UpdatedDatetime = source.UpdatedDatetime; + this.CreatedDatetime = source.CreatedDatetime; this.UpdatedBy = source.UpdatedBy; + this.UpdatedDatetime = source.UpdatedDatetime; } } @@ -167,7 +172,7 @@ namespace CloudBuilder.Master.Entity public string GetSelectTopFromByMySql(int limit, int start,string orderby,string orderbytag, string sqlWhere) { if (string.IsNullOrEmpty(orderbytag) || orderbytag.Trim() != "desc") orderbytag = "asc"; - if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_TREE_ID ; + if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_CHILDREN_ID ; int offset = limit * (start - 1); return $" select {DB_NAME_FIELDS} from (select {DB_NAME_FIELDS} ,row_number() over(order by {orderby} {orderbytag}) as num from { DB_NAME_FAMILY_TREE_CHILDREN_MAP} where 1=1 {sqlWhere} ) a where num> {offset} LIMIT {limit} "; } @@ -175,7 +180,7 @@ namespace CloudBuilder.Master.Entity public string GetSelectTopFromBySqlServer(int limit, int start,string orderby,string orderbytag, string sqlWhere) { if (string.IsNullOrEmpty(orderbytag) || orderbytag.Trim() != "desc") orderbytag = "asc"; - if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_TREE_ID ; + if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_CHILDREN_ID ; string top = limit > 0 ? $"top {limit}" : ""; return $" select {top} {DB_NAME_FIELDS} from (select {DB_NAME_FIELDS} ,row_number() over(order by {orderby} {orderbytag}) as num from { DB_NAME_FAMILY_TREE_CHILDREN_MAP} with(nolock) where 1=1 {sqlWhere} ) a where num> {limit * (start - 1)}"; } diff --git a/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapEntityKey.auto.cs b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapEntityKey.auto.cs index a6de04f..63a854f 100644 --- a/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapEntityKey.auto.cs +++ b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapEntityKey.auto.cs @@ -5,9 +5,9 @@ namespace CloudBuilder.Master [TypeScript] public class FamilyTreeChildrenMapEntityKey { - public string TreeId { get; set; } - public string PersonId { get; set; } public string ChildrenId { get; set; } + public string PersonId { get; set; } + public string TreeId { get; set; } public override bool Equals(object obj) { @@ -16,9 +16,9 @@ namespace CloudBuilder.Master FamilyTreeChildrenMapEntityKey pkey = obj as FamilyTreeChildrenMapEntityKey; if (pkey == null) return false; - if (TreeId != pkey.TreeId) return false; - if (PersonId != pkey.PersonId) return false; if (ChildrenId != pkey.ChildrenId) return false; + if (PersonId != pkey.PersonId) return false; + if (TreeId != pkey.TreeId) return false; return true; } @@ -27,9 +27,9 @@ namespace CloudBuilder.Master public override string ToString() { string declareSql=""; - declareSql=declareSql+$"declare @__tkey_TreeId_0 varchar(50) select @__tkey_TreeId_0 ='{TreeId}'; " ; declareSql=declareSql+$"declare @__tkey_PersonId_1 varchar(50) select @__tkey_PersonId_1 ='{PersonId}'; " ; declareSql=declareSql+$"declare @__tkey_ChildrenId_2 varchar(50) select @__tkey_ChildrenId_2 ='{ChildrenId}'; " ; + declareSql=declareSql+$"declare @__tkey_ChildrenId_0 varchar(50) select @__tkey_ChildrenId_0 ='{ChildrenId}'; " ; declareSql=declareSql+$"declare @__tkey_PersonId_1 varchar(50) select @__tkey_PersonId_1 ='{PersonId}'; " ; declareSql=declareSql+$"declare @__tkey_TreeId_2 varchar(50) select @__tkey_TreeId_2 ='{TreeId}'; " ; return declareSql; } } } - /* builder.Entity().HasKey(c => new { c.TreeId, c.PersonId, c.ChildrenId}); */ + /* builder.Entity().HasKey(c => new { c.ChildrenId, c.PersonId, c.TreeId}); */ diff --git a/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapViewEntity.auto.cs b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapViewEntity.auto.cs new file mode 100644 index 0000000..10dc533 --- /dev/null +++ b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeChildrenMapViewEntity.auto.cs @@ -0,0 +1,208 @@ + +using CloudBuilder.Core.Authorization; +using CloudBuilder.Core.DatabaseAccessor.Entity; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +namespace CloudBuilder.Master.Entity + { + [TypeScript] + [Table("family_tree_children_map_view")] + public class FamilyTreeChildrenMapViewEntity : ViewEntityBase + { + + public FamilyTreeChildrenMapViewEntity() + { + } + + [Column("children_common_name")] + public string? ChildrenCommonName { get; set; } + [Column("children_genealogy_name")] + public string? ChildrenGenealogyName { get; set; } + [Column("children_id")] + public string ChildrenId { get; set; } + [Column("children_surname")] + public string ChildrenSurname { get; set; } + [Column("common_name")] + public string? CommonName { get; set; } + [Column("gender")] + public string? Gender { get; set; } + [Column("genealogy_name")] + public string? GenealogyName { get; set; } + [Column("orderby")] + public int Orderby { get; set; } + [Column("person_id")] + public string PersonId { get; set; } + [Column("relation_type")] + public string? RelationType { get; set; } + [Column("remark")] + public string? Remark { get; set; } + [Column("spouse_id")] + public string? SpouseId { get; set; } + [Column("surname")] + public string Surname { get; set; } + [Column("tree_id")] + public string TreeId { get; set; } + + public const string CHILDREN_COMMON_NAME = "ChildrenCommonName"; + public const string CHILDREN_GENEALOGY_NAME = "ChildrenGenealogyName"; + public const string CHILDREN_ID = "ChildrenId"; + public const string CHILDREN_SURNAME = "ChildrenSurname"; + public const string COMMON_NAME = "CommonName"; + public const string GENDER = "Gender"; + public const string GENEALOGY_NAME = "GenealogyName"; + public const string ORDERBY = "Orderby"; + public const string PERSON_ID = "PersonId"; + public const string RELATION_TYPE = "RelationType"; + public const string REMARK = "Remark"; + public const string SPOUSE_ID = "SpouseId"; + public const string SURNAME = "Surname"; + public const string TREE_ID = "TreeId"; + + public const string DB_NAME_FAMILY_TREE_CHILDREN_MAP_VIEW = "family_tree_children_map_view"; + public const string DB_NAME_FIELDS="children_common_name,children_genealogy_name,children_id,children_surname,common_name,gender,genealogy_name,orderby,person_id,relation_type,remark,spouse_id,surname,tree_id"; + + public const string DB_CHILDREN_COMMON_NAME = "children_common_name"; + public const string DB_CHILDREN_GENEALOGY_NAME = "children_genealogy_name"; + public const string DB_CHILDREN_ID = "children_id"; + public const string DB_CHILDREN_SURNAME = "children_surname"; + public const string DB_COMMON_NAME = "common_name"; + public const string DB_GENDER = "gender"; + public const string DB_GENEALOGY_NAME = "genealogy_name"; + public const string DB_ORDERBY = "orderby"; + public const string DB_PERSON_ID = "person_id"; + public const string DB_RELATION_TYPE = "relation_type"; + public const string DB_REMARK = "remark"; + public const string DB_SPOUSE_ID = "spouse_id"; + public const string DB_SURNAME = "surname"; + public const string DB_TREE_ID = "tree_id"; + + private string ProviderName { get; set; } + + public static FamilyTreeChildrenMapViewEntity GetInstance(string providerName) + { + return new FamilyTreeChildrenMapViewEntity() { ProviderName = providerName }; + } + + public virtual void CopyFrom(FamilyTreeChildrenMapViewEntity source) + { + CopyFrom(source, true); + } + + public virtual void CopyFrom(FamilyTreeChildrenMapViewEntity source, bool includeSystemFields) + { + if (source == null) + { + throw new NullReferenceException("Source entity is null."); + } + + this.ChildrenCommonName = source.ChildrenCommonName; + this.ChildrenGenealogyName = source.ChildrenGenealogyName; + this.ChildrenId = source.ChildrenId; + this.ChildrenSurname = source.ChildrenSurname; + this.CommonName = source.CommonName; + this.Gender = source.Gender; + this.GenealogyName = source.GenealogyName; + this.Orderby = source.Orderby; + this.PersonId = source.PersonId; + this.RelationType = source.RelationType; + this.Remark = source.Remark; + this.SpouseId = source.SpouseId; + this.Surname = source.Surname; + this.TreeId = source.TreeId; + + if (includeSystemFields) + { + } + } + + public override string GetSelectFrom() + { + if (ProviderName.Contains("MySql")) + { + return GetSelectFromByMySql(); + } + else if (ProviderName.Contains("SqlServer")) + { + return GetSelectFromByBySqlServer(); + } + else + { + throw new NotSupportedException($"不支持的数据库提供程序:{ProviderName}"); + } + } + public string GetSelectFromByMySql() + { + return $" select {DB_NAME_FIELDS} from { DB_NAME_FAMILY_TREE_CHILDREN_MAP_VIEW} with(nolock) "; + } + public string GetSelectFromByBySqlServer() + { + return $" select {DB_NAME_FIELDS} from { DB_NAME_FAMILY_TREE_CHILDREN_MAP_VIEW} "; + } + + public override string GetSelectCountFrom(string sqlWhere) + { + if (ProviderName.Contains("MySql")) + { + return GetSelectCountFromByMySql(sqlWhere); + } + else if (ProviderName.Contains("SqlServer")) + { + return GetSelectCountFromBySqlServer(sqlWhere); + } + else + { + throw new NotSupportedException($"不支持的数据库提供程序:{ProviderName}"); + } + } + + public string GetSelectCountFromByMySql(string sqlWhere) + { + return $" select count(*) from { DB_NAME_FAMILY_TREE_CHILDREN_MAP_VIEW} where 1=1 {sqlWhere}"; + } + public string GetSelectCountFromBySqlServer(string sqlWhere) + { + return $" select count(*) from { DB_NAME_FAMILY_TREE_CHILDREN_MAP_VIEW} with(nolock) where 1=1 {sqlWhere}"; + } + + public override string GetSelectTopFrom(int limit, int start, string orderby, string orderbytag, string sqlWhere) + { + if (ProviderName.Contains("MySql")) + { + return GetSelectTopFromByMySql(limit, start, orderby, orderbytag, sqlWhere); + } + else if (ProviderName.Contains("SqlServer")) + { + return GetSelectTopFromBySqlServer(limit, start, orderby, orderbytag, sqlWhere); + } + else + { + throw new NotSupportedException($"不支持的数据库提供程序:{ProviderName}"); + } + } + + public string GetSelectTopFromByMySql(int limit, int start,string orderby,string orderbytag, string sqlWhere) + { + if (string.IsNullOrEmpty(orderbytag) || orderbytag.Trim() != "desc") orderbytag = "asc"; + + if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_CHILDREN_COMMON_NAME ; int offset = limit * (start - 1); + return $" select {DB_NAME_FIELDS} from (select {DB_NAME_FIELDS} ,row_number() over(order by {orderby} {orderbytag}) as num from { DB_NAME_FAMILY_TREE_CHILDREN_MAP_VIEW} where 1=1 {sqlWhere} ) a where num> {offset} LIMIT {limit} "; + } + + public string GetSelectTopFromBySqlServer(int limit, int start,string orderby,string orderbytag, string sqlWhere) + { + if (string.IsNullOrEmpty(orderbytag) || orderbytag.Trim() != "desc") orderbytag = "asc"; + + if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_CHILDREN_COMMON_NAME ; string top = limit > 0 ? $"top {limit}" : ""; + return $" select {top} {DB_NAME_FIELDS} from (select {DB_NAME_FIELDS} ,row_number() over(order by {orderby} {orderbytag}) as num from { DB_NAME_FAMILY_TREE_CHILDREN_MAP_VIEW} with(nolock) where 1=1 {sqlWhere} ) a where num> {limit * (start - 1)}"; + } + + public FamilyTreeChildrenMapViewEntity Clone() + { + FamilyTreeChildrenMapViewEntity result = new FamilyTreeChildrenMapViewEntity(); + result.CopyFrom(this); + + return result; + } + + } +} diff --git a/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapEntity.auto.cs b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapEntity.auto.cs index 878d0ab..6f923ec 100644 --- a/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapEntity.auto.cs +++ b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapEntity.auto.cs @@ -14,67 +14,71 @@ namespace CloudBuilder.Master.Entity { } - [Column("created_datetime")] - public DateTime CreatedDatetime { get; set; } [Column("created_by")] public string CreatedBy { get; set; } - [Column("updated_datetime")] - public DateTime UpdatedDatetime { get; set; } - [Column("updated_by")] - public string UpdatedBy { get; set; } - [Column("tree_id")] - public string TreeId { get; set; } - [Column("person_id")] - public string PersonId { get; set; } - [Column("spouse_id")] - public string SpouseId { get; set; } - [Column("marry_date_text")] - public string? MarryDateText { get; set; } - [Column("marry_date")] - public Nullable MarryDate { get; set; } - [Column("divorce_date_text")] - public string? DivorceDateText { get; set; } + [Column("created_datetime")] + public DateTime CreatedDatetime { get; set; } [Column("divorce_date")] public Nullable DivorceDate { get; set; } - [Column("marry_type")] - public string? MarryType { get; set; } + [Column("divorce_date_text")] + public string? DivorceDateText { get; set; } [Column("is_current")] public string? IsCurrent { get; set; } + [Column("marry_date")] + public Nullable MarryDate { get; set; } + [Column("marry_date_text")] + public string? MarryDateText { get; set; } + [Column("marry_type")] + public string? MarryType { get; set; } + [Column("orderby")] + public int Orderby { get; set; } + [Column("person_id")] + public string PersonId { get; set; } [Column("remark")] public string? Remark { get; set; } + [Column("spouse_id")] + public string SpouseId { get; set; } + [Column("tree_id")] + public string TreeId { get; set; } + [Column("updated_by")] + public string UpdatedBy { get; set; } + [Column("updated_datetime")] + public DateTime UpdatedDatetime { get; set; } - public const string CREATED_DATETIME = "CreatedDatetime"; public const string CREATED_BY = "CreatedBy"; - public const string UPDATED_DATETIME = "UpdatedDatetime"; - public const string UPDATED_BY = "UpdatedBy"; - public const string TREE_ID = "TreeId"; - public const string PERSON_ID = "PersonId"; - public const string SPOUSE_ID = "SpouseId"; - public const string MARRY_DATE_TEXT = "MarryDateText"; - public const string MARRY_DATE = "MarryDate"; - public const string DIVORCE_DATE_TEXT = "DivorceDateText"; + public const string CREATED_DATETIME = "CreatedDatetime"; public const string DIVORCE_DATE = "DivorceDate"; - public const string MARRY_TYPE = "MarryType"; + public const string DIVORCE_DATE_TEXT = "DivorceDateText"; public const string IS_CURRENT = "IsCurrent"; + public const string MARRY_DATE = "MarryDate"; + public const string MARRY_DATE_TEXT = "MarryDateText"; + public const string MARRY_TYPE = "MarryType"; + public const string ORDERBY = "Orderby"; + public const string PERSON_ID = "PersonId"; public const string REMARK = "Remark"; + public const string SPOUSE_ID = "SpouseId"; + public const string TREE_ID = "TreeId"; + public const string UPDATED_BY = "UpdatedBy"; + public const string UPDATED_DATETIME = "UpdatedDatetime"; public const string DB_NAME_FAMILY_TREE_SPOUSE_MAP = "family_tree_spouse_map"; - public const string DB_NAME_FIELDS="created_datetime,created_by,updated_datetime,updated_by,tree_id,person_id,spouse_id,marry_date_text,marry_date,divorce_date_text,divorce_date,marry_type,is_current,remark"; + public const string DB_NAME_FIELDS="created_by,created_datetime,divorce_date,divorce_date_text,is_current,marry_date,marry_date_text,marry_type,orderby,person_id,remark,spouse_id,tree_id,updated_by,updated_datetime"; - public const string DB_CREATED_DATETIME = "created_datetime"; public const string DB_CREATED_BY = "created_by"; - public const string DB_UPDATED_DATETIME = "updated_datetime"; - public const string DB_UPDATED_BY = "updated_by"; - public const string DB_TREE_ID = "tree_id"; - public const string DB_PERSON_ID = "person_id"; - public const string DB_SPOUSE_ID = "spouse_id"; - public const string DB_MARRY_DATE_TEXT = "marry_date_text"; - public const string DB_MARRY_DATE = "marry_date"; - public const string DB_DIVORCE_DATE_TEXT = "divorce_date_text"; + public const string DB_CREATED_DATETIME = "created_datetime"; public const string DB_DIVORCE_DATE = "divorce_date"; - public const string DB_MARRY_TYPE = "marry_type"; + public const string DB_DIVORCE_DATE_TEXT = "divorce_date_text"; public const string DB_IS_CURRENT = "is_current"; + public const string DB_MARRY_DATE = "marry_date"; + public const string DB_MARRY_DATE_TEXT = "marry_date_text"; + public const string DB_MARRY_TYPE = "marry_type"; + public const string DB_ORDERBY = "orderby"; + public const string DB_PERSON_ID = "person_id"; public const string DB_REMARK = "remark"; + public const string DB_SPOUSE_ID = "spouse_id"; + public const string DB_TREE_ID = "tree_id"; + public const string DB_UPDATED_BY = "updated_by"; + public const string DB_UPDATED_DATETIME = "updated_datetime"; private string ProviderName { get; set; } @@ -95,27 +99,28 @@ namespace CloudBuilder.Master.Entity throw new NullReferenceException("Source entity is null."); } - this.CreatedDatetime = source.CreatedDatetime; this.CreatedBy = source.CreatedBy; - this.UpdatedDatetime = source.UpdatedDatetime; - this.UpdatedBy = source.UpdatedBy; - this.TreeId = source.TreeId; - this.PersonId = source.PersonId; - this.SpouseId = source.SpouseId; - this.MarryDateText = source.MarryDateText; - this.MarryDate = source.MarryDate; - this.DivorceDateText = source.DivorceDateText; + this.CreatedDatetime = source.CreatedDatetime; this.DivorceDate = source.DivorceDate; - this.MarryType = source.MarryType; + this.DivorceDateText = source.DivorceDateText; this.IsCurrent = source.IsCurrent; + this.MarryDate = source.MarryDate; + this.MarryDateText = source.MarryDateText; + this.MarryType = source.MarryType; + this.Orderby = source.Orderby; + this.PersonId = source.PersonId; this.Remark = source.Remark; + this.SpouseId = source.SpouseId; + this.TreeId = source.TreeId; + this.UpdatedBy = source.UpdatedBy; + this.UpdatedDatetime = source.UpdatedDatetime; if (includeSystemFields) { - this.CreatedDatetime = source.CreatedDatetime; this.CreatedBy = source.CreatedBy; - this.UpdatedDatetime = source.UpdatedDatetime; + this.CreatedDatetime = source.CreatedDatetime; this.UpdatedBy = source.UpdatedBy; + this.UpdatedDatetime = source.UpdatedDatetime; } } @@ -187,7 +192,7 @@ namespace CloudBuilder.Master.Entity public string GetSelectTopFromByMySql(int limit, int start,string orderby,string orderbytag, string sqlWhere) { if (string.IsNullOrEmpty(orderbytag) || orderbytag.Trim() != "desc") orderbytag = "asc"; - if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_TREE_ID ; + if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_PERSON_ID ; int offset = limit * (start - 1); return $" select {DB_NAME_FIELDS} from (select {DB_NAME_FIELDS} ,row_number() over(order by {orderby} {orderbytag}) as num from { DB_NAME_FAMILY_TREE_SPOUSE_MAP} where 1=1 {sqlWhere} ) a where num> {offset} LIMIT {limit} "; } @@ -195,7 +200,7 @@ namespace CloudBuilder.Master.Entity public string GetSelectTopFromBySqlServer(int limit, int start,string orderby,string orderbytag, string sqlWhere) { if (string.IsNullOrEmpty(orderbytag) || orderbytag.Trim() != "desc") orderbytag = "asc"; - if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_TREE_ID ; + if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_PERSON_ID ; string top = limit > 0 ? $"top {limit}" : ""; return $" select {top} {DB_NAME_FIELDS} from (select {DB_NAME_FIELDS} ,row_number() over(order by {orderby} {orderbytag}) as num from { DB_NAME_FAMILY_TREE_SPOUSE_MAP} with(nolock) where 1=1 {sqlWhere} ) a where num> {limit * (start - 1)}"; } diff --git a/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapEntityKey.auto.cs b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapEntityKey.auto.cs index eb76a80..e96cd64 100644 --- a/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapEntityKey.auto.cs +++ b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapEntityKey.auto.cs @@ -5,9 +5,9 @@ namespace CloudBuilder.Master [TypeScript] public class FamilyTreeSpouseMapEntityKey { - public string TreeId { get; set; } public string PersonId { get; set; } public string SpouseId { get; set; } + public string TreeId { get; set; } public override bool Equals(object obj) { @@ -16,9 +16,9 @@ namespace CloudBuilder.Master FamilyTreeSpouseMapEntityKey pkey = obj as FamilyTreeSpouseMapEntityKey; if (pkey == null) return false; - if (TreeId != pkey.TreeId) return false; if (PersonId != pkey.PersonId) return false; if (SpouseId != pkey.SpouseId) return false; + if (TreeId != pkey.TreeId) return false; return true; } @@ -27,9 +27,9 @@ namespace CloudBuilder.Master public override string ToString() { string declareSql=""; - declareSql=declareSql+$"declare @__tkey_TreeId_0 varchar(50) select @__tkey_TreeId_0 ='{TreeId}'; " ; declareSql=declareSql+$"declare @__tkey_PersonId_1 varchar(50) select @__tkey_PersonId_1 ='{PersonId}'; " ; declareSql=declareSql+$"declare @__tkey_SpouseId_2 varchar(50) select @__tkey_SpouseId_2 ='{SpouseId}'; " ; + declareSql=declareSql+$"declare @__tkey_PersonId_0 varchar(50) select @__tkey_PersonId_0 ='{PersonId}'; " ; declareSql=declareSql+$"declare @__tkey_SpouseId_1 varchar(50) select @__tkey_SpouseId_1 ='{SpouseId}'; " ; declareSql=declareSql+$"declare @__tkey_TreeId_2 varchar(50) select @__tkey_TreeId_2 ='{TreeId}'; " ; return declareSql; } } } - /* builder.Entity().HasKey(c => new { c.TreeId, c.PersonId, c.SpouseId}); */ + /* builder.Entity().HasKey(c => new { c.PersonId, c.SpouseId, c.TreeId}); */ diff --git a/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapViewEntity.auto.cs b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapViewEntity.auto.cs new file mode 100644 index 0000000..5849d12 --- /dev/null +++ b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeSpouseMapViewEntity.auto.cs @@ -0,0 +1,228 @@ + +using CloudBuilder.Core.Authorization; +using CloudBuilder.Core.DatabaseAccessor.Entity; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +namespace CloudBuilder.Master.Entity + { + [TypeScript] + [Table("family_tree_spouse_map_view")] + public class FamilyTreeSpouseMapViewEntity : ViewEntityBase + { + + public FamilyTreeSpouseMapViewEntity() + { + } + + [Column("common_name")] + public string? CommonName { get; set; } + [Column("divorce_date")] + public Nullable DivorceDate { get; set; } + [Column("divorce_date_text")] + public string? DivorceDateText { get; set; } + [Column("gender")] + public string? Gender { get; set; } + [Column("genealogy_name")] + public string? GenealogyName { get; set; } + [Column("is_current")] + public string? IsCurrent { get; set; } + [Column("marry_date")] + public Nullable MarryDate { get; set; } + [Column("marry_date_text")] + public string? MarryDateText { get; set; } + [Column("marry_type")] + public string? MarryType { get; set; } + [Column("orderby")] + public int Orderby { get; set; } + [Column("person_id")] + public string PersonId { get; set; } + [Column("remark")] + public string? Remark { get; set; } + [Column("spouse_common_name")] + public string? SpouseCommonName { get; set; } + [Column("spouse_genealogy_name")] + public string? SpouseGenealogyName { get; set; } + [Column("spouse_id")] + public string SpouseId { get; set; } + [Column("spouse_surname")] + public string SpouseSurname { get; set; } + [Column("surname")] + public string Surname { get; set; } + [Column("tree_id")] + public string TreeId { get; set; } + + public const string COMMON_NAME = "CommonName"; + public const string DIVORCE_DATE = "DivorceDate"; + public const string DIVORCE_DATE_TEXT = "DivorceDateText"; + public const string GENDER = "Gender"; + public const string GENEALOGY_NAME = "GenealogyName"; + public const string IS_CURRENT = "IsCurrent"; + public const string MARRY_DATE = "MarryDate"; + public const string MARRY_DATE_TEXT = "MarryDateText"; + public const string MARRY_TYPE = "MarryType"; + public const string ORDERBY = "Orderby"; + public const string PERSON_ID = "PersonId"; + public const string REMARK = "Remark"; + public const string SPOUSE_COMMON_NAME = "SpouseCommonName"; + public const string SPOUSE_GENEALOGY_NAME = "SpouseGenealogyName"; + public const string SPOUSE_ID = "SpouseId"; + public const string SPOUSE_SURNAME = "SpouseSurname"; + public const string SURNAME = "Surname"; + public const string TREE_ID = "TreeId"; + + public const string DB_NAME_FAMILY_TREE_SPOUSE_MAP_VIEW = "family_tree_spouse_map_view"; + public const string DB_NAME_FIELDS="common_name,divorce_date,divorce_date_text,gender,genealogy_name,is_current,marry_date,marry_date_text,marry_type,orderby,person_id,remark,spouse_common_name,spouse_genealogy_name,spouse_id,spouse_surname,surname,tree_id"; + + public const string DB_COMMON_NAME = "common_name"; + public const string DB_DIVORCE_DATE = "divorce_date"; + public const string DB_DIVORCE_DATE_TEXT = "divorce_date_text"; + public const string DB_GENDER = "gender"; + public const string DB_GENEALOGY_NAME = "genealogy_name"; + public const string DB_IS_CURRENT = "is_current"; + public const string DB_MARRY_DATE = "marry_date"; + public const string DB_MARRY_DATE_TEXT = "marry_date_text"; + public const string DB_MARRY_TYPE = "marry_type"; + public const string DB_ORDERBY = "orderby"; + public const string DB_PERSON_ID = "person_id"; + public const string DB_REMARK = "remark"; + public const string DB_SPOUSE_COMMON_NAME = "spouse_common_name"; + public const string DB_SPOUSE_GENEALOGY_NAME = "spouse_genealogy_name"; + public const string DB_SPOUSE_ID = "spouse_id"; + public const string DB_SPOUSE_SURNAME = "spouse_surname"; + public const string DB_SURNAME = "surname"; + public const string DB_TREE_ID = "tree_id"; + + private string ProviderName { get; set; } + + public static FamilyTreeSpouseMapViewEntity GetInstance(string providerName) + { + return new FamilyTreeSpouseMapViewEntity() { ProviderName = providerName }; + } + + public virtual void CopyFrom(FamilyTreeSpouseMapViewEntity source) + { + CopyFrom(source, true); + } + + public virtual void CopyFrom(FamilyTreeSpouseMapViewEntity source, bool includeSystemFields) + { + if (source == null) + { + throw new NullReferenceException("Source entity is null."); + } + + this.CommonName = source.CommonName; + this.DivorceDate = source.DivorceDate; + this.DivorceDateText = source.DivorceDateText; + this.Gender = source.Gender; + this.GenealogyName = source.GenealogyName; + this.IsCurrent = source.IsCurrent; + this.MarryDate = source.MarryDate; + this.MarryDateText = source.MarryDateText; + this.MarryType = source.MarryType; + this.Orderby = source.Orderby; + this.PersonId = source.PersonId; + this.Remark = source.Remark; + this.SpouseCommonName = source.SpouseCommonName; + this.SpouseGenealogyName = source.SpouseGenealogyName; + this.SpouseId = source.SpouseId; + this.SpouseSurname = source.SpouseSurname; + this.Surname = source.Surname; + this.TreeId = source.TreeId; + + if (includeSystemFields) + { + } + } + + public override string GetSelectFrom() + { + if (ProviderName.Contains("MySql")) + { + return GetSelectFromByMySql(); + } + else if (ProviderName.Contains("SqlServer")) + { + return GetSelectFromByBySqlServer(); + } + else + { + throw new NotSupportedException($"不支持的数据库提供程序:{ProviderName}"); + } + } + public string GetSelectFromByMySql() + { + return $" select {DB_NAME_FIELDS} from { DB_NAME_FAMILY_TREE_SPOUSE_MAP_VIEW} with(nolock) "; + } + public string GetSelectFromByBySqlServer() + { + return $" select {DB_NAME_FIELDS} from { DB_NAME_FAMILY_TREE_SPOUSE_MAP_VIEW} "; + } + + public override string GetSelectCountFrom(string sqlWhere) + { + if (ProviderName.Contains("MySql")) + { + return GetSelectCountFromByMySql(sqlWhere); + } + else if (ProviderName.Contains("SqlServer")) + { + return GetSelectCountFromBySqlServer(sqlWhere); + } + else + { + throw new NotSupportedException($"不支持的数据库提供程序:{ProviderName}"); + } + } + + public string GetSelectCountFromByMySql(string sqlWhere) + { + return $" select count(*) from { DB_NAME_FAMILY_TREE_SPOUSE_MAP_VIEW} where 1=1 {sqlWhere}"; + } + public string GetSelectCountFromBySqlServer(string sqlWhere) + { + return $" select count(*) from { DB_NAME_FAMILY_TREE_SPOUSE_MAP_VIEW} with(nolock) where 1=1 {sqlWhere}"; + } + + public override string GetSelectTopFrom(int limit, int start, string orderby, string orderbytag, string sqlWhere) + { + if (ProviderName.Contains("MySql")) + { + return GetSelectTopFromByMySql(limit, start, orderby, orderbytag, sqlWhere); + } + else if (ProviderName.Contains("SqlServer")) + { + return GetSelectTopFromBySqlServer(limit, start, orderby, orderbytag, sqlWhere); + } + else + { + throw new NotSupportedException($"不支持的数据库提供程序:{ProviderName}"); + } + } + + public string GetSelectTopFromByMySql(int limit, int start,string orderby,string orderbytag, string sqlWhere) + { + if (string.IsNullOrEmpty(orderbytag) || orderbytag.Trim() != "desc") orderbytag = "asc"; + + if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_COMMON_NAME ; int offset = limit * (start - 1); + return $" select {DB_NAME_FIELDS} from (select {DB_NAME_FIELDS} ,row_number() over(order by {orderby} {orderbytag}) as num from { DB_NAME_FAMILY_TREE_SPOUSE_MAP_VIEW} where 1=1 {sqlWhere} ) a where num> {offset} LIMIT {limit} "; + } + + public string GetSelectTopFromBySqlServer(int limit, int start,string orderby,string orderbytag, string sqlWhere) + { + if (string.IsNullOrEmpty(orderbytag) || orderbytag.Trim() != "desc") orderbytag = "asc"; + + if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_COMMON_NAME ; string top = limit > 0 ? $"top {limit}" : ""; + return $" select {top} {DB_NAME_FIELDS} from (select {DB_NAME_FIELDS} ,row_number() over(order by {orderby} {orderbytag}) as num from { DB_NAME_FAMILY_TREE_SPOUSE_MAP_VIEW} with(nolock) where 1=1 {sqlWhere} ) a where num> {limit * (start - 1)}"; + } + + public FamilyTreeSpouseMapViewEntity Clone() + { + FamilyTreeSpouseMapViewEntity result = new FamilyTreeSpouseMapViewEntity(); + result.CopyFrom(this); + + return result; + } + + } +} diff --git a/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeViewEntity.auto.cs b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeViewEntity.auto.cs new file mode 100644 index 0000000..6632a95 --- /dev/null +++ b/CloudBuilder/CloudBuilder.Master/Entity/FamilyTreeViewEntity.auto.cs @@ -0,0 +1,178 @@ + +using CloudBuilder.Core.Authorization; +using CloudBuilder.Core.DatabaseAccessor.Entity; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +namespace CloudBuilder.Master.Entity + { + [TypeScript] + [Table("family_tree_view")] + public class FamilyTreeViewEntity : ViewEntityBase + { + + public FamilyTreeViewEntity() + { + } + + [Column("ancestor_person_id")] + public string AncestorPersonId { get; set; } + [Column("brief")] + public string? Brief { get; set; } + [Column("common_name")] + public string? CommonName { get; set; } + [Column("genealogy_name")] + public string? GenealogyName { get; set; } + [Column("public_indc")] + public string PublicIndc { get; set; } + [Column("surname")] + public string Surname { get; set; } + [Column("tree_id")] + public string TreeId { get; set; } + [Column("tree_name")] + public string TreeName { get; set; } + + public const string ANCESTOR_PERSON_ID = "AncestorPersonId"; + public const string BRIEF = "Brief"; + public const string COMMON_NAME = "CommonName"; + public const string GENEALOGY_NAME = "GenealogyName"; + public const string PUBLIC_INDC = "PublicIndc"; + public const string SURNAME = "Surname"; + public const string TREE_ID = "TreeId"; + public const string TREE_NAME = "TreeName"; + + public const string DB_NAME_FAMILY_TREE_VIEW = "family_tree_view"; + public const string DB_NAME_FIELDS="ancestor_person_id,brief,common_name,genealogy_name,public_indc,surname,tree_id,tree_name"; + + public const string DB_ANCESTOR_PERSON_ID = "ancestor_person_id"; + public const string DB_BRIEF = "brief"; + public const string DB_COMMON_NAME = "common_name"; + public const string DB_GENEALOGY_NAME = "genealogy_name"; + public const string DB_PUBLIC_INDC = "public_indc"; + public const string DB_SURNAME = "surname"; + public const string DB_TREE_ID = "tree_id"; + public const string DB_TREE_NAME = "tree_name"; + + private string ProviderName { get; set; } + + public static FamilyTreeViewEntity GetInstance(string providerName) + { + return new FamilyTreeViewEntity() { ProviderName = providerName }; + } + + public virtual void CopyFrom(FamilyTreeViewEntity source) + { + CopyFrom(source, true); + } + + public virtual void CopyFrom(FamilyTreeViewEntity source, bool includeSystemFields) + { + if (source == null) + { + throw new NullReferenceException("Source entity is null."); + } + + this.AncestorPersonId = source.AncestorPersonId; + this.Brief = source.Brief; + this.CommonName = source.CommonName; + this.GenealogyName = source.GenealogyName; + this.PublicIndc = source.PublicIndc; + this.Surname = source.Surname; + this.TreeId = source.TreeId; + this.TreeName = source.TreeName; + + if (includeSystemFields) + { + } + } + + public override string GetSelectFrom() + { + if (ProviderName.Contains("MySql")) + { + return GetSelectFromByMySql(); + } + else if (ProviderName.Contains("SqlServer")) + { + return GetSelectFromByBySqlServer(); + } + else + { + throw new NotSupportedException($"不支持的数据库提供程序:{ProviderName}"); + } + } + public string GetSelectFromByMySql() + { + return $" select {DB_NAME_FIELDS} from { DB_NAME_FAMILY_TREE_VIEW} with(nolock) "; + } + public string GetSelectFromByBySqlServer() + { + return $" select {DB_NAME_FIELDS} from { DB_NAME_FAMILY_TREE_VIEW} "; + } + + public override string GetSelectCountFrom(string sqlWhere) + { + if (ProviderName.Contains("MySql")) + { + return GetSelectCountFromByMySql(sqlWhere); + } + else if (ProviderName.Contains("SqlServer")) + { + return GetSelectCountFromBySqlServer(sqlWhere); + } + else + { + throw new NotSupportedException($"不支持的数据库提供程序:{ProviderName}"); + } + } + + public string GetSelectCountFromByMySql(string sqlWhere) + { + return $" select count(*) from { DB_NAME_FAMILY_TREE_VIEW} where 1=1 {sqlWhere}"; + } + public string GetSelectCountFromBySqlServer(string sqlWhere) + { + return $" select count(*) from { DB_NAME_FAMILY_TREE_VIEW} with(nolock) where 1=1 {sqlWhere}"; + } + + public override string GetSelectTopFrom(int limit, int start, string orderby, string orderbytag, string sqlWhere) + { + if (ProviderName.Contains("MySql")) + { + return GetSelectTopFromByMySql(limit, start, orderby, orderbytag, sqlWhere); + } + else if (ProviderName.Contains("SqlServer")) + { + return GetSelectTopFromBySqlServer(limit, start, orderby, orderbytag, sqlWhere); + } + else + { + throw new NotSupportedException($"不支持的数据库提供程序:{ProviderName}"); + } + } + + public string GetSelectTopFromByMySql(int limit, int start,string orderby,string orderbytag, string sqlWhere) + { + if (string.IsNullOrEmpty(orderbytag) || orderbytag.Trim() != "desc") orderbytag = "asc"; + + if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_ANCESTOR_PERSON_ID ; int offset = limit * (start - 1); + return $" select {DB_NAME_FIELDS} from (select {DB_NAME_FIELDS} ,row_number() over(order by {orderby} {orderbytag}) as num from { DB_NAME_FAMILY_TREE_VIEW} where 1=1 {sqlWhere} ) a where num> {offset} LIMIT {limit} "; + } + + public string GetSelectTopFromBySqlServer(int limit, int start,string orderby,string orderbytag, string sqlWhere) + { + if (string.IsNullOrEmpty(orderbytag) || orderbytag.Trim() != "desc") orderbytag = "asc"; + + if (string.IsNullOrEmpty(orderby) || !DB_NAME_FIELDS.Contains(orderby)) orderby = DB_ANCESTOR_PERSON_ID ; string top = limit > 0 ? $"top {limit}" : ""; + return $" select {top} {DB_NAME_FIELDS} from (select {DB_NAME_FIELDS} ,row_number() over(order by {orderby} {orderbytag}) as num from { DB_NAME_FAMILY_TREE_VIEW} with(nolock) where 1=1 {sqlWhere} ) a where num> {limit * (start - 1)}"; + } + + public FamilyTreeViewEntity Clone() + { + FamilyTreeViewEntity result = new FamilyTreeViewEntity(); + result.CopyFrom(this); + + return result; + } + + } +} diff --git a/CloudBuilder/CloudBuilder.Master/Policy/MasterPrefixPolicy.cs b/CloudBuilder/CloudBuilder.Master/Policy/MasterPrefixPolicy.cs index 04bcea3..095ab6a 100644 --- a/CloudBuilder/CloudBuilder.Master/Policy/MasterPrefixPolicy.cs +++ b/CloudBuilder/CloudBuilder.Master/Policy/MasterPrefixPolicy.cs @@ -13,5 +13,11 @@ namespace CloudBuilder.Master.Policy public const string FAMILY_PERSON_PREFIX = "P"; public const string FAMILY_PERSON_FORMAT = "0000000"; + public const string FAMILY_TREE = "FAMILY_TREE"; + public const string FAMILY_TREE_TREE_ID = "TREE_ID"; + public const string FAMILY_TREE_PREFIX = "T"; + public const string FAMILY_TREE_FORMAT = "0000000"; + + } } diff --git a/CloudBuilder/CloudBuilder.Master/Service/IFamilyTreeService.auto.cs b/CloudBuilder/CloudBuilder.Master/Service/IFamilyTreeService.auto.cs index 3bc7a7b..aae8e9d 100644 --- a/CloudBuilder/CloudBuilder.Master/Service/IFamilyTreeService.auto.cs +++ b/CloudBuilder/CloudBuilder.Master/Service/IFamilyTreeService.auto.cs @@ -7,8 +7,9 @@ using CloudBuilder.Master.SearchCriteria; namespace CloudBuilder.Master.Service { - public interface IFamilyTreeService :IServiceBase + public interface IFamilyTreeService : IServiceBase { + FamilyTreeData FindByCurrentPerson(string key, string personId); FamilyTreeResultData FindBySearchCriteria(FamilyTreeSearchCriteria tc); dynamic PrintBySearchCriteria(FamilyTreeSearchCriteria tc); void Deletes(string[] keys); diff --git a/CloudBuilder/CloudBuilder.Request/Master/FamilyTreeRequest.auto.cs b/CloudBuilder/CloudBuilder.Request/Master/FamilyTreeRequest.auto.cs index 73b8118..f846825 100644 --- a/CloudBuilder/CloudBuilder.Request/Master/FamilyTreeRequest.auto.cs +++ b/CloudBuilder/CloudBuilder.Request/Master/FamilyTreeRequest.auto.cs @@ -1,51 +1,61 @@ -using CloudBuilder.Core.DependencyInjection.Request; -using CloudBuilder.Core.Request; -using CloudBuilder.Core.Service; -using Microsoft.Extensions.DependencyInjection; -using CloudBuilder.Master.Service; - using CloudBuilder.Core.DatabaseAccessor.Entity; - using CloudBuilder.Master.Entity; - using CloudBuilder.Master.Data; - using System; - using CloudBuilder.Master.SearchCriteria; - -namespace CloudBuilder.Request.Master -{ - -public class FamilyTreeRequest : IRequest -{ - -private readonly IServiceRequest serviceRequest; -public FamilyTreeRequest(IServiceRequest serviceRequest) -{ -this.serviceRequest = serviceRequest; -} - - public FamilyTreeData FindByKey(string key) - { -return Task.Run(() => serviceRequest.PostAsJsonAsync("/FamilyTree/FindByKey?key=" + key.ToString())).GetAwaiter().GetResult(); } - - public FamilyTreeResultData FindBySearchCriteria(FamilyTreeSearchCriteria criteria) - { -return Task.Run(() => serviceRequest.PostAsJsonAsync("/FamilyTree/FindBySearchCriteria" , criteria)).GetAwaiter().GetResult(); } - - public FamilyTreeData Insert(FamilyTreeData data) - { -return Task.Run(() => serviceRequest.PostAsJsonAsync("/FamilyTree/Insert" , data)).GetAwaiter().GetResult(); } - - public FamilyTreeData Update(FamilyTreeData data) - { -return Task.Run(() => serviceRequest.PostAsJsonAsync("/FamilyTree/Update" , data)).GetAwaiter().GetResult(); } - - public void Delete(string key) - { - Task.Run(() => serviceRequest.PostAsync("/FamilyTree/Delete?key=" + key.ToString())).GetAwaiter().GetResult(); } - - public void Deletes(string[] keys) - { - Task.Run(() => serviceRequest.PostAsJsonAsync("/FamilyTree/Deletes" , keys)).GetAwaiter().GetResult(); } - - -} +using CloudBuilder.Core.DependencyInjection.Request; +using CloudBuilder.Core.Request; +using CloudBuilder.Core.Service; +using Microsoft.Extensions.DependencyInjection; +using CloudBuilder.Master.Service; + using CloudBuilder.Core.DatabaseAccessor.Entity; + using CloudBuilder.Master.Entity; + using CloudBuilder.Master.Data; + using System; + using CloudBuilder.Master.SearchCriteria; + +namespace CloudBuilder.Request.Master +{ + +public class FamilyTreeRequest : IRequest +{ + +private readonly IServiceRequest serviceRequest; +public FamilyTreeRequest(IServiceRequest serviceRequest) +{ +this.serviceRequest = serviceRequest; +} + + public FamilyTreeData FindByKey(string key) + { +return Task.Run(() => serviceRequest.PostAsJsonAsync("/FamilyTree/FindByKey?key=" + key.ToString())).GetAwaiter().GetResult(); } + + + public class FindByCurrentPersonCompositionData2 { + public string key { get; set; } + public string personId { get; set; } + + } + public FamilyTreeData FindByCurrentPerson(string key, string personId) + { +var compositionData = new FindByCurrentPersonCompositionData2{ key = key, personId = personId }; return Task.Run(() => serviceRequest.PostAsJsonAsync("/FamilyTree/FindByCurrentPerson", compositionData)).GetAwaiter().GetResult(); } + + public FamilyTreeResultData FindBySearchCriteria(FamilyTreeSearchCriteria criteria) + { +return Task.Run(() => serviceRequest.PostAsJsonAsync("/FamilyTree/FindBySearchCriteria" , criteria)).GetAwaiter().GetResult(); } + + public FamilyTreeData Insert(FamilyTreeData data) + { +return Task.Run(() => serviceRequest.PostAsJsonAsync("/FamilyTree/Insert" , data)).GetAwaiter().GetResult(); } + + public FamilyTreeData Update(FamilyTreeData data) + { +return Task.Run(() => serviceRequest.PostAsJsonAsync("/FamilyTree/Update" , data)).GetAwaiter().GetResult(); } + + public void Delete(string key) + { + Task.Run(() => serviceRequest.PostAsync("/FamilyTree/Delete?key=" + key.ToString())).GetAwaiter().GetResult(); } + + public void Deletes(string[] keys) + { + Task.Run(() => serviceRequest.PostAsJsonAsync("/FamilyTree/Deletes" , keys)).GetAwaiter().GetResult(); } + + +} } \ No newline at end of file diff --git a/CloudBuilder/CloudBuilder.Request/Security/LocaleRequest.auto.cs b/CloudBuilder/CloudBuilder.Request/Security/LocaleRequest.auto.cs index fac21cf..17821f0 100644 --- a/CloudBuilder/CloudBuilder.Request/Security/LocaleRequest.auto.cs +++ b/CloudBuilder/CloudBuilder.Request/Security/LocaleRequest.auto.cs @@ -1,60 +1,70 @@ -using CloudBuilder.Core.DependencyInjection.Request; -using CloudBuilder.Core.Request; -using CloudBuilder.Core.Service; -using Microsoft.Extensions.DependencyInjection; -using CloudBuilder.Security.Service; - using CloudBuilder.Core.DatabaseAccessor.Entity; - using Microsoft.AspNetCore.Http; - using CloudBuilder.Core.Policy; - using CloudBuilder.Core.DependencyInjection.Request; - using CloudBuilder.Security.Data; - using CloudBuilder.Core.Authorization; - using System; - using CloudBuilder.Security.Entity; - using CloudBuilder.Security.SearchCriteria; - using CloudBuilder.Security; - -namespace CloudBuilder.Request.Security -{ - -public class LocaleRequest : IRequest -{ - -private readonly IServiceRequest serviceRequest; -public LocaleRequest(IServiceRequest serviceRequest) -{ -this.serviceRequest = serviceRequest; -} - - public LocaleEntity[] FindAll() - { -return Task.Run(() => serviceRequest.GetAsync("/Locale/FindAll")).GetAwaiter().GetResult(); } - - public LocaleResultData FindBySearchCriteria(LocaleSearchCriteria criteria) - { -return Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/FindBySearchCriteria" , criteria)).GetAwaiter().GetResult(); } - - public LocaleEntity FindByKey(LocaleEntityKey key) - { -return Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/FindByKey" , key)).GetAwaiter().GetResult(); } - - public LocaleEntity Insert(LocaleEntity data) - { -return Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/Insert" , data)).GetAwaiter().GetResult(); } - - public LocaleEntity Update(LocaleEntity data) - { -return Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/Update" , data)).GetAwaiter().GetResult(); } - - public void UpdateLocaleData(LocaleData data) - { - Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/UpdateLocaleData" , data)).GetAwaiter().GetResult(); } - - public void Delete(LocaleEntityKey key) - { - Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/Delete" , key)).GetAwaiter().GetResult(); } - - -} +using CloudBuilder.Core.DependencyInjection.Request; +using CloudBuilder.Core.Request; +using CloudBuilder.Core.Service; +using Microsoft.Extensions.DependencyInjection; +using CloudBuilder.Security.Service; + using CloudBuilder.Core.DatabaseAccessor.Entity; + using Microsoft.AspNetCore.Http; + using CloudBuilder.Core.Policy; + using CloudBuilder.Core.DependencyInjection.Request; + using CloudBuilder.Security.Data; + using CloudBuilder.Core.Authorization; + using System; + using CloudBuilder.Security.Entity; + using CloudBuilder.Security.SearchCriteria; + using CloudBuilder.Security; + +namespace CloudBuilder.Request.Security +{ + +public class LocaleRequest : IRequest +{ + +private readonly IServiceRequest serviceRequest; +public LocaleRequest(IServiceRequest serviceRequest) +{ +this.serviceRequest = serviceRequest; +} + + public LocaleEntity[] FindAll() + { +return Task.Run(() => serviceRequest.GetAsync("/Locale/FindAll")).GetAwaiter().GetResult(); } + + + public class FindSelectOptionCompositionData2 { + public string groupName { get; set; } + public bool blank { get; set; } + + } + public SelectOption[] FindSelectOption(string groupName, bool blank) + { +var compositionData = new FindSelectOptionCompositionData2{ groupName = groupName, blank = blank }; return Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/FindSelectOption", compositionData)).GetAwaiter().GetResult(); } + + public LocaleResultData FindBySearchCriteria(LocaleSearchCriteria criteria) + { +return Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/FindBySearchCriteria" , criteria)).GetAwaiter().GetResult(); } + + public LocaleEntity FindByKey(LocaleEntityKey key) + { +return Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/FindByKey" , key)).GetAwaiter().GetResult(); } + + public LocaleEntity Insert(LocaleEntity data) + { +return Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/Insert" , data)).GetAwaiter().GetResult(); } + + public LocaleEntity Update(LocaleEntity data) + { +return Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/Update" , data)).GetAwaiter().GetResult(); } + + public void UpdateLocaleData(LocaleData data) + { + Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/UpdateLocaleData" , data)).GetAwaiter().GetResult(); } + + public void Delete(LocaleEntityKey key) + { + Task.Run(() => serviceRequest.PostAsJsonAsync("/Locale/Delete" , key)).GetAwaiter().GetResult(); } + + +} } \ No newline at end of file diff --git a/CloudBuilder/CloudBuilder.Security.Service/LocaleService.cs b/CloudBuilder/CloudBuilder.Security.Service/LocaleService.cs index 12c549e..d47c538 100644 --- a/CloudBuilder/CloudBuilder.Security.Service/LocaleService.cs +++ b/CloudBuilder/CloudBuilder.Security.Service/LocaleService.cs @@ -7,6 +7,7 @@ using CloudBuilder.Security.Policy; using CloudBuilder.Security.SearchCriteria; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; namespace CloudBuilder.Security.Service { public class LocaleService : ILocaleService @@ -27,6 +28,31 @@ namespace CloudBuilder.Security.Service return repository.DetachedEntities.ToArray(); } + [AllowAnonymous] + [HttpPost] + public SelectOption[] FindSelectOption(string groupName, bool blank = true) + { + LocaleEntity[] ents = repository.DetachedEntities.Where(x => x.GroupName == groupName && x.Lang == service.Locale).OrderBy(x => x.OrderBy).ToArray(); + + List l = new List(); + + SelectOption selectOption; + if (blank) + { + selectOption = new SelectOption(); + l.Add(selectOption); + } + + foreach (var ent in ents) + { + selectOption = new SelectOption(); + selectOption.BindValue = ent.Name; + selectOption.DisplayName = ent.Value; + l.Add(selectOption); + } + return l.ToArray(); + } + [AllowAnonymous] public LocaleResultData FindBySearchCriteria(LocaleSearchCriteria criteria) { diff --git a/CloudBuilder/CloudBuilder.Security/Service/ILocaleService.auto.cs b/CloudBuilder/CloudBuilder.Security/Service/ILocaleService.auto.cs index 29fe052..9d563e6 100644 --- a/CloudBuilder/CloudBuilder.Security/Service/ILocaleService.auto.cs +++ b/CloudBuilder/CloudBuilder.Security/Service/ILocaleService.auto.cs @@ -9,6 +9,7 @@ namespace CloudBuilder.Security.Service { public interface ILocaleService : IServiceBase { + SelectOption[] FindSelectOption(string groupName, bool blank); LocaleEntity[] FindAll(); LocaleResultData FindBySearchCriteria(LocaleSearchCriteria tc); diff --git a/CloudBuilder/CloudBuilder.Web.Entry/Controllers/Master/FamilyTreeController.auto.cs b/CloudBuilder/CloudBuilder.Web.Entry/Controllers/Master/FamilyTreeController.auto.cs index ba71c08..1b6ae4c 100644 --- a/CloudBuilder/CloudBuilder.Web.Entry/Controllers/Master/FamilyTreeController.auto.cs +++ b/CloudBuilder/CloudBuilder.Web.Entry/Controllers/Master/FamilyTreeController.auto.cs @@ -48,6 +48,33 @@ this.familyTreeService= familyTreeService; } } + + public class FindByCurrentPersonCompositionData + { + public string key { get; set; } + public string personId { get; set; } + + } + [PermissionOperate(name: "FamilyTree", operate: "Find")] + [HttpPost] + public dynamic FindByCurrentPerson(FindByCurrentPersonCompositionData compositionData) + { + try + { + + var result = familyTreeService.FindByCurrentPerson(compositionData.key,compositionData.personId); + return result; + } + catch (ValidatedException vex) + { + return vex; + } + catch (Exception ex) + { + return new ServiceErrorException(ex); + } + } + [PermissionOperate(name: "FamilyTree", operate: "Find")] [HttpPost] public dynamic FindBySearchCriteria(FamilyTreeSearchCriteria criteria) diff --git a/CloudBuilder/CloudBuilder.Web.Entry/Controllers/Security/LocaleController.auto.cs b/CloudBuilder/CloudBuilder.Web.Entry/Controllers/Security/LocaleController.auto.cs index 1dca1d1..e221849 100644 --- a/CloudBuilder/CloudBuilder.Web.Entry/Controllers/Security/LocaleController.auto.cs +++ b/CloudBuilder/CloudBuilder.Web.Entry/Controllers/Security/LocaleController.auto.cs @@ -53,6 +53,33 @@ this.localeService= localeService; } } + + public class FindSelectOptionCompositionData + { + public string groupName { get; set; } + public bool blank { get; set; } + + } + [AllowAnonymous] + [HttpPost] + public dynamic FindSelectOption(FindSelectOptionCompositionData compositionData) + { + try + { + + var result = localeService.FindSelectOption(compositionData.groupName,compositionData.blank); + return result; + } + catch (ValidatedException vex) + { + return vex; + } + catch (Exception ex) + { + return new ServiceErrorException(ex); + } + } + [AllowAnonymous] [HttpPost] public dynamic FindBySearchCriteria(LocaleSearchCriteria criteria) diff --git a/CloudBuilder/Data/insert_locale.sql b/CloudBuilder/Data/insert_locale.sql new file mode 100644 index 0000000..22dab4f --- /dev/null +++ b/CloudBuilder/Data/insert_locale.sql @@ -0,0 +1,22 @@ +INSERT INTO locale ( + created_datetime, + created_by, + updated_datetime, + updated_by, + group_name, + lang, + name, + value, + order_by +) +VALUES +(GETDATE(), 'system', GETDATE(), 'system', 'GenderPolicy', 'zh-cn', 'M', N'¨k', 1), +(GETDATE(), 'system', GETDATE(), 'system', 'GenderPolicy', 'zh-cn', 'W', N'¤k', 2), +(GETDATE(), 'system', GETDATE(), 'system', 'GenderPolicy', 'en', 'M', N'¨k', 1), +(GETDATE(), 'system', GETDATE(), 'system', 'GenderPolicy', 'en', 'W', N'¤k', 2) + +select * from locale +where group_name='RelationTypePolicy' and name in ('M','W') + +delete from locale +where group_name='RelationTypePolicy' and name in ('M','W') \ No newline at end of file diff --git a/CodeGenerator/CloudBuilder.CodeGenerator.exe.lnk b/CodeGenerator/CloudBuilder.CodeGenerator.exe.lnk index 83aea00493f5c5f3417c1f51ac6fdca506e0d36f..64905ee90062ce36cd35b7c40fc13e7ce5920ba7 100644 GIT binary patch delta 32 mcmZn=Y!ckCjz!p;!G*z!AqGh1GbA%)Go&&UZQjpvkQo4k83<7T delta 18 ZcmZn?Y!KYAj)l={G6(zA&2FqV%m6ng1x5e> diff --git a/CodeGenerator/CloudBuilder.CodeGenerator/Program.cs b/CodeGenerator/CloudBuilder.CodeGenerator/Program.cs index 2039e70..e9d6ed4 100644 --- a/CodeGenerator/CloudBuilder.CodeGenerator/Program.cs +++ b/CodeGenerator/CloudBuilder.CodeGenerator/Program.cs @@ -17,13 +17,20 @@ namespace WinFormsApp var services = new ServiceCollection(); - services.Initialize(); + try + { + services.Initialize(); - var serviceProvider = services.BuildServiceProvider(); + var serviceProvider = services.BuildServiceProvider(); - MainFunctionView mainFunctionView = serviceProvider.GetRequiredKeyedService(typeof(MainFunctionView).Name); + MainFunctionView mainFunctionView = serviceProvider.GetRequiredKeyedService(typeof(MainFunctionView).Name); - Application.Run(mainFunctionView); + Application.Run(mainFunctionView); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } } } } \ No newline at end of file diff --git a/CodeGenerator/Lib/CloudBuilder.Core.dll b/CodeGenerator/Lib/CloudBuilder.Core.dll index 9c58616d7d435bdaecc17dfc5c0df4cdf7bf2d7a..747bd52467f1ecf05e03c0fc63b23755c8406a8d 100644 GIT binary patch delta 82545 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 z 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 C+u1Sz delta 80760 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