From f761461e0bd733d5766cd75b0054454478162e16 Mon Sep 17 00:00:00 2001 From: "agile.zhou" Date: Fri, 4 Oct 2024 22:22:27 +0800 Subject: [PATCH] Refactor app search --- .../Controllers/AppController.cs | 171 +++++------------- .../IAppService.cs | 11 ++ src/AgileConfig.Server.Service/AppService.cs | 128 ++++++++++++- 3 files changed, 176 insertions(+), 134 deletions(-) diff --git a/src/AgileConfig.Server.Apisite/Controllers/AppController.cs b/src/AgileConfig.Server.Apisite/Controllers/AppController.cs index 3c297a34..6fe1eae5 100644 --- a/src/AgileConfig.Server.Apisite/Controllers/AppController.cs +++ b/src/AgileConfig.Server.Apisite/Controllers/AppController.cs @@ -35,156 +35,64 @@ public AppController(IAppService appService, _premissionService = premissionService; } - public async Task Search(string name, string id, string group, string sortField, string ascOrDesc, bool tableGrouped, int current = 1, int pageSize = 20) + public async Task Search(string name, string id, string group, string sortField, + string ascOrDesc, bool tableGrouped, int current = 1, int pageSize = 20) { if (current < 1) { throw new ArgumentException("current cant less then 1 ."); } + if (pageSize < 1) { throw new ArgumentException("pageSize cant less then 1 ."); } - var query = await _appService.GetAllAppsAsync(); - if (!string.IsNullOrWhiteSpace(name)) - { - query = query.Where(x => x.Name.Contains(name)).ToList(); - } - if (!string.IsNullOrWhiteSpace(id)) - { - query = query.Where(x => x.Id.Contains(id)).ToList(); - } - if (!string.IsNullOrWhiteSpace(group)) - { - query = query.Where(x => x.Group == group).ToList(); - } - - var appvms = new List(); - foreach (var app in query) + var appListVms = new List(); + long count = 0; + if (!tableGrouped) { - appvms.Add(await AppToListVM(app, false)); - } - if (tableGrouped) - { - var appGroups = appvms.GroupBy(x => x.Group); - var appGroupList = new List(); - foreach (var appGroup in appGroups) + var searchResult = + await _appService.SearchAsync(id, name, group, sortField, ascOrDesc, current, pageSize); + foreach (var app in searchResult.Apps) { - var first = appGroup.First(); - var children = new List(); - if (appGroup.Count() > 1) - { - foreach (var item in appGroup) - { - if (first.Id != item.Id) - { - children.Add(item); - } - } - } - - if (children.Count > 0) - { - first.children = children; - } - appGroupList.Add(first); + appListVms.Add(app.ToAppListVM()); } - appvms = appGroupList; - } - - if (tableGrouped) - { - if (sortField == "group" && ascOrDesc.StartsWith("desc")) - { - appvms = appvms.OrderByDescending(x => x.Group).ToList(); - } - else - { - appvms = appvms.OrderBy(x => x.Group).ToList(); - } + count = searchResult.Count; } else { - if (sortField == "createTime") - { - if (ascOrDesc.StartsWith("asc")) - { - appvms = appvms.OrderBy(x => x.CreateTime).ToList(); - } - else - { - appvms = appvms.OrderByDescending(x => x.CreateTime).ToList(); - } - } - if (sortField == "id") - { - if (ascOrDesc.StartsWith("asc")) - { - appvms = appvms.OrderBy(x => x.Id).ToList(); - } - else - { - appvms = appvms.OrderByDescending(x => x.Id).ToList(); - } - } - if (sortField == "name") + var searchResult = + await _appService.SearchGroupedAsync(id, name, group, sortField, ascOrDesc, current, pageSize); + foreach (var groupedApp in searchResult.GroupedApps) { - if (ascOrDesc.StartsWith("asc")) + var app = groupedApp.App; + var vm = app.ToAppListVM(); + vm.children = new List(); + foreach (var child in groupedApp.Children ?? []) { - appvms = appvms.OrderBy(x => x.Name).ToList(); - } - else - { - appvms = appvms.OrderByDescending(x => x.Name).ToList(); - } - } - if (sortField == "group") - { - if (ascOrDesc.StartsWith("asc")) - { - appvms = appvms.OrderBy(x => x.Group).ToList(); - } - else - { - appvms = appvms.OrderByDescending(x => x.Group).ToList(); + vm.children.Add(child.App.ToAppListVM()); } + + appListVms.Add(vm); } + + count = searchResult.Count; } - var count = appvms.Count; - var pageList = appvms.ToList().Skip((current - 1) * pageSize).Take(pageSize).ToList(); - await AppendInheritancedInfo(pageList); + await AppendInheritancedInfo(appListVms); + return Json(new { current, pageSize, success = true, total = count, - data = pageList + data = appListVms }); } - private async Task AppToListVM(App item, bool appendInheritancedInfo) - { - var vm = item.ToAppListVM(); - - if (appendInheritancedInfo) - { - var inheritancedApps = await _appService.GetInheritancedAppsAsync(item.Id); - vm.inheritancedApps = item.Type == AppType.Inheritance - ? new List() - : (inheritancedApps).Select(ia => ia.Id).ToList(); - vm.inheritancedAppNames = item.Type == AppType.Inheritance - ? new List() - : (inheritancedApps).Select(ia => ia.Name).ToList(); - vm.AppAdminName = (await _userService.GetUserAsync(item.AppAdmin))?.UserName; - } - - return vm; - } - private async Task AppendInheritancedInfo(List list) { foreach (var appListVm in list) @@ -213,7 +121,6 @@ public async Task Add([FromBody] AppVM model) var oldApp = await _appService.GetAsync(model.Id); if (oldApp != null) { - return Json(new { success = false, @@ -303,6 +210,7 @@ public async Task Edit([FromBody] AppVM model) { _tinyEventBus.Fire(new EditAppSuccessful(app, this.GetCurrentUserName())); } + return Json(new { success = result, @@ -318,8 +226,9 @@ public async Task All() foreach (var app in apps) { var vm = app.ToAppListVM(); - vm.inheritancedAppNames = app.Type == AppType.Inheritance ? new List() : - (await _appService.GetInheritancedAppsAsync(app.Id)).Select(ia => ia.Id).ToList(); + vm.inheritancedAppNames = app.Type == AppType.Inheritance + ? new List() + : (await _appService.GetInheritancedAppsAsync(app.Id)).Select(ia => ia.Id).ToList(); vms.Add(vm); } @@ -363,7 +272,8 @@ public async Task Get(string id) /// /// /// - [TypeFilter(typeof(PremissionCheckAttribute), Arguments = new object[] { "App.DisableOrEanble", Functions.App_Edit })] + [TypeFilter(typeof(PremissionCheckAttribute), + Arguments = new object[] { "App.DisableOrEanble", Functions.App_Edit })] [HttpPost] public async Task DisableOrEanble(string id) { @@ -440,6 +350,7 @@ public async Task InheritancedApps(string currentAppId) //过滤本身 apps.Remove(self); } + var vms = apps.Select(x => { return new @@ -467,8 +378,10 @@ public async Task SaveAppAuth([FromBody] AppAuthVM model) { ArgumentNullException.ThrowIfNull(model); - var result = await _appService.SaveUserAppAuth(model.AppId, model.EditConfigPermissionUsers, _premissionService.EditConfigPermissionKey); - var result1 = await _appService.SaveUserAppAuth(model.AppId, model.PublishConfigPermissionUsers, _premissionService.PublishConfigPermissionKey); + var result = await _appService.SaveUserAppAuth(model.AppId, model.EditConfigPermissionUsers, + _premissionService.EditConfigPermissionKey); + var result1 = await _appService.SaveUserAppAuth(model.AppId, model.PublishConfigPermissionUsers, + _premissionService.PublishConfigPermissionKey); return Json(new { @@ -485,8 +398,12 @@ public async Task GetUserAppAuth(string appId) { AppId = appId }; - result.EditConfigPermissionUsers = (await _appService.GetUserAppAuth(appId, _premissionService.EditConfigPermissionKey)).Select(x => x.Id).ToList(); - result.PublishConfigPermissionUsers = (await _appService.GetUserAppAuth(appId, _premissionService.PublishConfigPermissionKey)).Select(x => x.Id).ToList(); + result.EditConfigPermissionUsers = + (await _appService.GetUserAppAuth(appId, _premissionService.EditConfigPermissionKey)).Select(x => x.Id) + .ToList(); + result.PublishConfigPermissionUsers = + (await _appService.GetUserAppAuth(appId, _premissionService.PublishConfigPermissionKey)) + .Select(x => x.Id).ToList(); return Json(new { @@ -506,4 +423,4 @@ public async Task GetAppGroups() }); } } -} +} \ No newline at end of file diff --git a/src/AgileConfig.Server.IService/IAppService.cs b/src/AgileConfig.Server.IService/IAppService.cs index 9d363ac6..c1cd2c26 100644 --- a/src/AgileConfig.Server.IService/IAppService.cs +++ b/src/AgileConfig.Server.IService/IAppService.cs @@ -5,6 +5,11 @@ namespace AgileConfig.Server.IService { + public class GroupedApp + { + public App App { get; set; } + public List Children { get; set; } + } public interface IAppService : IDisposable { Task GetAsync(string id); @@ -20,6 +25,12 @@ public interface IAppService : IDisposable Task> GetAllAppsAsync(); + Task<(List Apps, long Count)> SearchAsync(string id, string name, string group,string sortField, string ascOrDesc, + int current, int pageSize); + + Task<(List GroupedApps, long Count)> SearchGroupedAsync(string id, string name, string group,string sortField, string ascOrDesc, + int current, int pageSize); + Task> GetAllInheritancedAppsAsync(); Task CountEnabledAppsAsync(); diff --git a/src/AgileConfig.Server.Service/AppService.cs b/src/AgileConfig.Server.Service/AppService.cs index 5318066c..1ba4a64d 100644 --- a/src/AgileConfig.Server.Service/AppService.cs +++ b/src/AgileConfig.Server.Service/AppService.cs @@ -4,8 +4,9 @@ using System.Collections.Generic; using System.Threading.Tasks; using System.Linq; +using System.Linq.Expressions; +using System.Reflection; using AgileConfig.Server.Data.Abstraction; -using static FreeSql.Internal.GlobalFilter; namespace AgileConfig.Server.Service { @@ -27,7 +28,7 @@ public AppService( IUserRepository userRepository, IUserAppAuthRepository userAppAuthRepository, ISettingService settingService - ) + ) { _appRepository = repository; _appInheritancedRepository = appInheritancedRepository; @@ -44,6 +45,7 @@ public async Task AddAsync(App app) return true; } + public async Task AddAsync(App app, List appInheritanceds) { await _appRepository.InsertAsync(app); @@ -54,13 +56,14 @@ public async Task AddAsync(App app, List appInheritanceds return true; } + public async Task DeleteAsync(App app) { app = await _appRepository.GetAsync(app.Id); if (app != null) { await _appRepository.DeleteAsync(app); - + var envs = await _settingService.GetEnvironmentList(); var updatedConfigIds = new List(); var updatedConfigPublishedIds = new List(); @@ -71,7 +74,8 @@ public async Task DeleteAsync(App app) using var configPublishedRepository = _configPublishedRepositoryAccessor(env); //怕有的同学误删app导致要恢复,所以保留配置项吧。 - var configs = await configRepository.QueryAsync(x => x.AppId == app.Id && x.Status == ConfigStatus.Enabled); + var configs = + await configRepository.QueryAsync(x => x.AppId == app.Id && x.Status == ConfigStatus.Enabled); var waitDeleteConfigs = new List(); foreach (var item in configs) { @@ -80,14 +84,16 @@ public async Task DeleteAsync(App app) // 因为根据 env 构造的 provider 最终可能都定位到 default provider 上去,所以可能重复更新数据行,这里进行判断以下。 continue; } + item.Status = ConfigStatus.Deleted; waitDeleteConfigs.Add(item); updatedConfigIds.Add(item.Id); } + await configRepository.UpdateAsync(waitDeleteConfigs); //删除发布的配置项 var publishedConfigs = await configPublishedRepository - .QueryAsync(x => x.AppId == app.Id && x.Status == ConfigStatus.Enabled) + .QueryAsync(x => x.AppId == app.Id && x.Status == ConfigStatus.Enabled) ; var waitDeletePublishedConfigs = new List(); foreach (var item in publishedConfigs) @@ -97,10 +103,12 @@ public async Task DeleteAsync(App app) // 因为根据 env 构造的 provider 最终可能都定位到 default provider 上去,所以可能重复更新数据行,这里进行判断以下。 continue; } + item.Status = ConfigStatus.Deleted; waitDeletePublishedConfigs.Add(item); updatedConfigPublishedIds.Add(item.Id); } + await configPublishedRepository.UpdateAsync(waitDeletePublishedConfigs); } } @@ -129,6 +137,109 @@ public Task> GetAllAppsAsync() return _appRepository.AllAsync(); } + public async Task<(List Apps, long Count)> SearchAsync(string id, string name, string group, + string sortField, string ascOrDesc, + int current, int pageSize) + { + Expression> exp = app => true; + + if (!string.IsNullOrWhiteSpace(id)) + { + exp = exp.And(a => a.Id.Contains(id)); + } + + if (!string.IsNullOrWhiteSpace(name)) + { + exp = exp.And(a => a.Name.Contains(name)); + } + + if (!string.IsNullOrWhiteSpace(group)) + { + exp = exp.And(a => a.Group == group); + } + + var apps = await _appRepository.QueryPageAsync(exp, current, pageSize, sortField, + ascOrDesc.StartsWith("asc") ? "ASC" : "DESC"); + var count = await _appRepository.CountAsync(exp); + + return (apps, count); + } + + public async Task<(List GroupedApps, long Count)> SearchGroupedAsync(string id, string name, + string group, string sortField, string ascOrDesc, int current, + int pageSize) + { + Expression> exp = app => true; + + if (!string.IsNullOrWhiteSpace(id)) + { + exp = exp.And(a => a.Id.Contains(id)); + } + + if (!string.IsNullOrWhiteSpace(name)) + { + exp = exp.And(a => a.Name.Contains(name)); + } + + if (!string.IsNullOrWhiteSpace(group)) + { + exp = exp.And(a => a.Group == group); + } + + var apps = await _appRepository.QueryAsync(exp); + + var appGroups = apps.GroupBy(x => x.Group); + var appGroupList = new List(); + foreach (var appGroup in appGroups) + { + var app = appGroup.First(); + var firstGroup = new GroupedApp() + { + App = app + }; + var children = new List(); + if (appGroup.Count() > 1) + { + foreach (var item in appGroup) + { + if (firstGroup.App.Id != item.Id) + { + children.Add(new GroupedApp() + { + App = item + }); + } + } + } + + if (children.Count > 0) + { + firstGroup.Children = children; + } + + appGroupList.Add(firstGroup); + } + + var sortProperty = new Dictionary() + { + { "id", typeof(App).GetProperty("Id") }, + { "name", typeof(App).GetProperty("Name") }, + { "group", typeof(App).GetProperty("Group") }, + { "createTime", typeof(App).GetProperty("CreateTime") } + }; + + if (sortProperty.TryGetValue(sortField, out var propertyInfo)) + { + appGroupList = ascOrDesc.StartsWith("asc") + ? appGroupList.OrderBy(x => propertyInfo.GetValue(x.App, null)).ToList() + : appGroupList.OrderByDescending(x => propertyInfo.GetValue(x.App, null)).ToList(); + } + + var page = appGroupList.Skip(current - 1 * pageSize).Take(pageSize).ToList(); + + return (page, appGroupList.Count); + } + public async Task UpdateAsync(App app) { await _appRepository.UpdateAsync(app); @@ -217,6 +328,7 @@ public async Task SaveUserAppAuth(string appId, List userIds, stri { userIds = new List(); } + foreach (var userId in userIds) { userAppAuthList.Add(new UserAppAuth @@ -227,7 +339,9 @@ public async Task SaveUserAppAuth(string appId, List userIds, stri Permission = permission }); } - var removeApps = await _userAppAuthRepository.QueryAsync(x => x.AppId == appId && x.Permission == permission); + + var removeApps = + await _userAppAuthRepository.QueryAsync(x => x.AppId == appId && x.Permission == permission); await _userAppAuthRepository.DeleteAsync(removeApps); await _userAppAuthRepository.InsertAsync(userAppAuthList); @@ -266,4 +380,4 @@ public async Task> GetAppGroups() return groups.Where(x => !string.IsNullOrEmpty(x)).ToList(); } } -} +} \ No newline at end of file